2011-04-20 4 views
4

우리는 소프트웨어 스택에서 사용되는 특정 전처리 지시어에 대한 구문 강조를 제공하는 Eclipse 용 플러그인을 작성하고 있습니다. 실제 코드를 컴파일하기 전에 외부 프로그램으로 바뀝니다 (<% FOO %>과 같은 태그가 다른 것으로 바뀌 었습니다. 예를 들어 버전 문자열).다른 편집기를 사용하여 동일한 파일 확장자를 처리하는 Eclipse 플러그인

그래서 플러그인은 각 태그에 주석을 제공하여이를 신속하게 식별합니다. 자바 에디터 나 PHP 에디터와 같이 이미 존재하는 에디터에 대해 독자적인 에디터를 구현하는 대신 주석이 제공됩니다.

이제 문제는 외부 프로그램에서 처리되는 파일의 파일 확장자가 모두 동일하다는 것입니다 (예 : .inc). 여기에는 Java 코드 또는 PHP 코드 (향후 다른 언어도 가능)가 포함될 수 있습니다.

내 플러그인에 컨텐츠 유형을 성공적으로 추가했으며 몇 가지 기준에 따라 다른 파일을 구별 할 수 있습니다. 그래서, 내가 자바 .inc 파일을 가지고 콘텐트 타입 inc file (java)을 지정할 때.

그러나 사용자는이 자동 검색을 덮어 쓸 수 있어야합니다 (자동 검색에 실패 할 수도 있음). 따라서 다른 편집기 (Java Editor, PHP Editor, ...)를 사용하여 하나의 파일 (foo.inc)을 열고이 연관을 저장할 수 있기를 원합니다. 내가 현재 생각하고

접근 방법 :

  • 내 프로젝트의 설정을 확인하고 적절한 편집기를 열려면 파일 열기 작업을 덮어 쓰기. 모두 파일 열기 동작 (파일 → 기본 메뉴의 파일 열기, 프로젝트 네비게이터에서 열기 ...)
  • 편집기를 구현하여 적절한 편집기를 엽니 다. 이것은 약간의 지연을 야기 할 해킹 된 접근법 인 것으로 보인다.
  • 파일의 "열어"컨텍스트 메뉴에서 사용자는 편집기를 변경할 수 있습니다. 프로그래밍 방식으로 변경하면 문제가 없지만이 선택 사항이 저장되는 API 또는 파일을 찾을 수 없습니다.
  • 프로젝트에 대해 다른 특성을 구현 한 다음 각 특성의 컨텍스트에서 다르게 파일 형식을 연결하십시오. 파일 별 연결이 아닌 프로젝트 별 연결 만 제공합니다.

더 좋은 해결책이 있습니까? 내가 열거 한 접근법에 대해 더 많이 알고 있습니까?

답변

3

org.eclipse.ui.navigator.resources.OpenActions을 덮어 쓰는 actionProvider을 등록하여 파일 열기 작업을 덮어 쓰는 방법을 찾았습니다. 나는이 모든 다른 것들을 모아서 작동시키는 것이 비교적 어렵 기 때문에 모든 코드를 제공한다.

플러그인부터 시작하겠습니다.XML 항목 다음 OpenActionProvider은 다음과 같습니다

<!-- overwrite OpenActions --> 
<extension 
     point="org.eclipse.ui.navigator.navigatorContent"> 
    <actionProvider 
     class="myplugin.navigator.OpenActionProvider" 
     id="myplugin.navigator.actions.open" 
     overrides="org.eclipse.ui.navigator.resources.OpenActions" 
     priority="highest"> 
     <enablement> 
     <and> 
      <instanceof 
        value="org.eclipse.core.resources.IFile"> 
      </instanceof> 
      <test 
        property="org.eclipse.core.resources.extension" 
        value="frm"> 
      </test> 
     </and> 
     </enablement> 
    </actionProvider> 
</extension> 
<extension 
     point="org.eclipse.ui.navigator.viewer"> 
    <viewerActionBinding 
     viewerId="org.eclipse.ui.navigator.ProjectExplorer"> 
     <includes> 
     <actionExtension 
       pattern="myplugin.navigator.actions.open"> 
     </actionExtension> 
     </includes> 
    </viewerActionBinding> 
</extension> 

은 다음 OpenEditorActionGroup은 다음과 같습니다

package myplugin.navigator; 

import org.eclipse.jface.action.IMenuManager; 
import org.eclipse.ui.IActionBars; 
import org.eclipse.ui.IViewPart; 
import org.eclipse.ui.actions.ActionContext; 
import org.eclipse.ui.navigator.CommonActionProvider; 
import org.eclipse.ui.navigator.ICommonActionConstants; 
import org.eclipse.ui.navigator.ICommonActionExtensionSite; 
import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite; 

public class OpenActionProvider extends CommonActionProvider { 
    private OpenEditorActionGroup fOpenGroup; 

    @Override 
    public void init(ICommonActionExtensionSite site) { 
      ICommonViewerWorkbenchSite workbenchSite = null; 
      if (site.getViewSite() instanceof ICommonViewerWorkbenchSite) { 
        workbenchSite = (ICommonViewerWorkbenchSite) site.getViewSite(); 
      } 
      if (workbenchSite != null) { 
        if (workbenchSite.getPart() != null && workbenchSite.getPart() instanceof IViewPart) { 
          IViewPart viewPart = (IViewPart) workbenchSite.getPart(); 

          fOpenGroup = new OpenEditorActionGroup(viewPart); 
        } 
      } 
    } 

    @Override 
    public void dispose() { 
      if (fOpenGroup != null) { 
        fOpenGroup.dispose(); 
        fOpenGroup = null; 
      } 
      super.dispose(); 
    } 

    @Override 
    public void fillActionBars(IActionBars actionBars) { 
      if (fOpenGroup == null) 
        return; 

      fOpenGroup.updateActionBars(); 
      actionBars.setGlobalActionHandler(ICommonActionConstants.OPEN, fOpenGroup.getOpenAction()); 
    } 

    @Override 
    public void fillContextMenu(IMenuManager menu) { 
      if (fOpenGroup == null) 
        return; 
      fOpenGroup.fillContextMenu(menu); 
    } 

    @Override 
    public void setContext(ActionContext context) { 
      super.setContext(context); 
      if (fOpenGroup == null) 
        return; 
      fOpenGroup.setContext(context); 
    } 
} 

다음 AbstractActionGroup 당신이 더 구현하고자한다, 단지 래퍼

package myplugin.navigator; 
import java.util.ArrayList; 
import java.util.List; 

import org.eclipse.core.resources.IFile; 
import org.eclipse.core.resources.IResource; 
import org.eclipse.core.runtime.IAdaptable; 
import org.eclipse.jface.action.IAction; 
import org.eclipse.jface.action.IMenuManager; 
import org.eclipse.jface.action.MenuManager; 
import org.eclipse.jface.viewers.ISelection; 
import org.eclipse.jface.viewers.IStructuredSelection; 
import org.eclipse.jface.viewers.StructuredSelection; 
import org.eclipse.ui.IActionBars; 
import org.eclipse.ui.IViewPart; 
import org.eclipse.ui.actions.OpenFileAction; 
import org.eclipse.ui.actions.OpenWithMenu; 
import org.eclipse.ui.navigator.ICommonMenuConstants; 


public class OpenEditorActionGroup extends AbstractActionGroup { 
    private OpenFileAction fOpenFileAction; 

    public OpenEditorActionGroup(IViewPart viewPart) { 
      super(viewPart); 
    } 

    @Override 
    protected void makeActions() { 
      fOpenFileAction= new OpenGenElementAction(getViewPart().getSite().getPage()); 
    } 

    public static IStructuredSelection convertSelectionToResources(ISelection s) { 
      List<Object> converted = new ArrayList<Object>(); 
      if (s instanceof StructuredSelection) { 
        Object[] elements = ((StructuredSelection) s).toArray(); 
        for (int i = 0; i < elements.length; i++) { 
          Object e = elements[i]; 
          if (e instanceof IResource) { 
            converted.add(e); 
          } else if (e instanceof IAdaptable) { 
            IResource r = (IResource) ((IAdaptable) e).getAdapter(IResource.class); 
            if (r != null) { 
              converted.add(r); 
            } 
          } 
        } 
      } 
      return new StructuredSelection(converted.toArray()); 
    } 


    @Override 
    public void fillContextMenu(IMenuManager menu) { 
      System.out.println("fillcontextmenu"); 
      if (getContext() == null) 
        return; 
     IStructuredSelection celements = (IStructuredSelection)getContext().getSelection(); 
      IStructuredSelection selection = convertSelectionToResources(celements); 

      fOpenFileAction.selectionChanged(celements); 
      if (!fOpenFileAction.isEnabled()) 
        return; 
      menu.appendToGroup(ICommonMenuConstants.GROUP_OPEN, fOpenFileAction); 
      fillOpenWithMenu(menu, selection); 
    } 

입니다 이들 :

package myplugin.navigator; 
import org.eclipse.core.runtime.Assert; 
import org.eclipse.jface.action.IMenuManager; 
import org.eclipse.jface.resource.ImageDescriptor; 
import org.eclipse.ui.IActionBars; 
import org.eclipse.ui.IViewPart; 
import org.eclipse.ui.actions.ActionGroup; 

public abstract class AbstractActionGroup extends ActionGroup { 
    private final IViewPart fViewPart; 

    public AbstractActionGroup(IViewPart viewPart) { 
      Assert.isNotNull(viewPart); 
      fViewPart = viewPart; 
      makeActions(); 
    } 

    protected IViewPart getViewPart() { 
      return fViewPart; 
    } 

    protected ImageDescriptor getImageDescriptor(String relativePath) { 
      return ImageDescriptor.createFromURL(null); 
    } 

    protected abstract void makeActions(); 
    @Override 
    public abstract void fillContextMenu(IMenuManager menu); 
    @Override 
    public abstract void fillActionBars(IActionBars actionBars); 
    @Override 
    public abstract void updateActionBars(); 
} 

그리고 마지막으로 OpenGenElementAction 자체 :

package myplugin.navigator; 

import org.eclipse.core.resources.IFile; 
import org.eclipse.core.resources.IResource; 
import org.eclipse.jface.viewers.IStructuredSelection; 
import org.eclipse.ui.IEditorDescriptor; 
import org.eclipse.ui.IEditorPart; 
import org.eclipse.ui.IWorkbenchPage; 
import org.eclipse.ui.PartInitException; 
import org.eclipse.ui.PlatformUI; 
import org.eclipse.ui.actions.OpenFileAction; 
import org.eclipse.ui.editors.text.EditorsUI; 
import org.eclipse.ui.part.FileEditorInput; 

public class OpenGenElementAction extends OpenFileAction { 
    private IFile selectedFile = null; 
    private final IWorkbenchPage workbenchPage; 

    public OpenGenElementAction(IWorkbenchPage page) { 
      super(page); 
      workbenchPage = page; 
    } 

    @Override 
    public boolean isEnabled() { 
      return true; 
    } 

    @Override 
    public void run() { 
      System.out.println("RUN"); 
    } 

    @Override 
    protected boolean updateSelection(IStructuredSelection selection) { 
      if (selection.size() != 1) 
        return super.updateSelection(selection); 
      Object element = selection.getFirstElement(); 
      if (element instanceof IFile) { 
        selectedFile = (IFile)element; 
      } 

      return selectedFile != null || super.updateSelection(selection); 
    } 
} 
+0

나중에이 코드가 패키지 탐색기와 Project Navigator에서 작동하지 않는다는 것을 알게되었습니다. ( – Michael

+0

게시 해 주셔서 감사합니다! – ernesto

0

당신은 특정 파일 이름보다는 확장을 등록하여 프로그래밍 방식으로 직접 IEditorRegistry을 공격 할 수있다. "IEditorRegistry에 도움"

http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fui%2FIEditorRegistry.html

방법 :에서

봐는

void setDefaultEditor(String fileNameOrExtension, String editorId) 
     Sets the default editor id for the files that match 
     that specified file name or extension. 

전체 이름 및/또는 와일드 카드를 받아들입니다. 대부분의 openEditor 호출 (메뉴, 툴바 등)은이 레지스트리를 호출하여 적절한 편집기를 가져옵니다. 이 파일 이름을 구체적으로 등록하는 편집기를 열 때 후크를 설정하십시오.

이름이 같고 언어가 다른 두 개의 파일이 있지만 접근 방식에 비해 구현이 빠르고 쉽습니다.

관련 문제