-行連携の実装方法

Outlineやビューなどでコンテンツの構造をツリー表示しますが、このツリーノードのダブルクリックでファイルを開き、かつ適切な行に飛ばす機能を作ることがEclipseでは簡単にできます。

  public static void openEditor(IFile file, int lineNumber) {
    IWorkbenchPage page = getWorkbenchPage();
      if(page != null) {
        try {
          IEditorPart part = page.openEditor(
            new FileEditorInput(file), ID_EDITOR_DICON);
          if( (part != null) && (lineNumber > 0) ) {
            IMarker marker = file.createMarker(IMarker.TEXT);
            marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
            IDE.gotoMarker(part, marker);
            marker.delete();
          }
        } catch (CoreException e) {
          KijimunaUI.reportException(e);
        }
      }
    }
  }

IWorkbenchPage#openEditor()一発でエディタがひらきます。エディタが開いたら、飛びたい行にマーカーを張って、IDE#gotoMarker()で行を選択してくれます。 普通のエディタならこれでOKなのですが、Kijimunaではひとつ問題があります。エディタが複数ページを持つMultiPageEditorPartなので、これだけではNG。

  public Object getAdapter(Class adapter) {
    if(adapter.equals(IGotoMarker.class)) {
      for(int i = 0; i < getPageCount(); i++) {
        IEditorPart editor = getEditor(i);
        if(editor instanceof IGotoMarker) {
          return editor;
        } else {
          Object obj = editor.getAdapter(IGotoMarker.class);
          if(obj != null) {
            return obj;
          }
        }
      }
    return null;
  }

エディタのほうで上記のようにgetAdapter()を実装します。IDE#gotoMarker()では、エディタがIGotoMarkerをgetAdapter()して得られれば、IGotoMarker#gotoMarker()を実行します。エディタで行を選択する機能そのものを自前で作るのも大変なのですが、たとえばTextEditorPartはこのIGotoMarkerを実装してますので、マルチページを順に調べてIGotoMarkerを探し、みつかればそれを用いて飛ばすこととしました。