Tabbed Properties ViewにCustomTabを追加する


GMFを使ってグラフィカルエディタを自動生成すると、以下のようにデフォルトでTabbed Properties Viewも付いてきます。デフォルトでは、

  • Core
  • Appearance
  • Rulers&Grid

のタブが含まれます。上記のうち、「Core」タブが通常のProperties Viewで表示されるEMFオブジェクトの属性を表示します。

ここでは、GMFのgenmodelおよび自動生成されたコードを修正することにより、新たにタブを追加する方法を紹介します。

GMF 2.0になって、genmodel(.gmfgenファイル)を編集することにより容易にカスタムタブを追加することができるようになりました。
例として、以下のような簡単な図書館モデルlib.ecoreを考えます。

まず、このEMFモデルを基に、GMFグラフ定義ファイル.gmfgraph、GMFツール定義ファイル.gmftool、GMFマップ定義ファイル.gmfmapを作成し、マップ定義ファイルを基に.gmfgenファイルを生成します。

次に、.gmfgenファイルを開き、以下のように、Property Sheet lib.diagram.sheetノードにCustom Property Tabノードを追加します。

この例では、Bookクラスの属性をEclipse Forms UIで表示するカスタムタブを追加してみましょう。追加したCustom Property Tabノードの各属性を次のように設定してみます。

  • Human readable label → Book details
  • Ientifier → bookdetails
  • Implementation Class → BookPropertySection

上記のうち、Implementation Classは、カスタムタブを実装するクラス名です。GMFで自動生成したコードのXX.sheetパッケージ(この例では、lib.diagram.sheetパッケージ)内に指定したクラスのひな形コードが生成されます。

次に、追加したCustom Property Tabノードに対し、以下のようにTyped Selection Filterノードを追加します。

Selection Filterとは、GMFキャンバス上でどのノードが選択されたときにカスタムタブを表示するかを指定するものです。ここでは、Bookクラスに対応するノードが選択された場合にのみ、このカスタムタブを表示させるようにします。そのためには、以下のように、追加したTyped Selection Filterノードの属性Types in selectionにBookEditPartクラスを指定します。(.gmfgen編集用エディタと連動するProperties Viewにおいて、属性Types in selectionを編集しようとすると以下のような画面が表示されます。)(BookEditPartクラスはGMFが自動生成したもので、キャンバス上でノードが選択された場合にSelectionListenerに渡されます)

なお、追加したTyped Selection Filterノードの属性Generated TypesにはabstractNavigatorItemを指定します。

これで、.gmfgenファイルの編集は終わりです。この.gmfgenファイルを基に、再度グラフィカルエディタを自動生成させます。すると、設定したとおり、XX.sheetパッケージ内にBookPropertySectionクラスのひな形コードが生成されます。
この例では、生成されたひな形コードを全部削除し、AbstractPropertySectionクラスを拡張したものに変更します。以下のサンプルコードは、Eclipse Forms UIを利用してBookクラスの属性titleおよびsummaryをSWTのTextクラスで表示するものです。GMFキャンバス上でBookクラスに対応するノードが選択されるとsetInput()メソッドが呼ばれ、選択されたノードに対応するBookEditPartクラスのインスタンスが渡されます。このインスタンスから、属性titleおよびsammaryの内容を抽出し上記Textに追加しています。

本来なら、上記Textで編集可能にすべきですが、そのためにはEMFコマンドフレームワークと連携すべきですし、そのためにはSWTのTextクラスより
CellEditorを利用する方が良いでしょうから、ここは簡単のために表示だけにしました。

public class BookPropertySection extends AbstractPropertySection {

	private Text titleText;
	private Text summaryText;
	
	@Override
	public void createControls(Composite parent,
			TabbedPropertySheetPage tabbedPropertySheetPage) {
		FormToolkit toolkit = new FormToolkit(parent.getDisplay());

		Form form = toolkit.createForm(parent);
		form.setText("Book details");

		TableWrapLayout layout = new TableWrapLayout();
		layout.numColumns = 2;
		Composite body = form.getBody();
		body.setLayout(layout);
		
		// title
		//
		Label titleLabel = toolkit.createLabel(body, "title:");
		titleLabel.setLayoutData(new TableWrapData(TableWrapData.RIGHT));
		titleText = toolkit.createText(body, "", SWT.BORDER);
		titleText.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
		
		// summary
		//
		Label summaryLabel = toolkit.createLabel(body, "summary:");
		summaryLabel.setLayoutData(new TableWrapData(TableWrapData.RIGHT));
		summaryText = toolkit.createText(body, "", SWT.BORDER|SWT.MULTI|SWT.H_SCROLL|SWT.V_SCROLL);
		summaryText.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));

	}

	@Override
	public void setInput(IWorkbenchPart part, ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			BookEditPart editPart = (BookEditPart) ((IStructuredSelection) selection).getFirstElement();
			View view = (View) editPart.getModel();
			Book book = (Book) view.getElement();
			
			if (null != book.getTitle())
				titleText.setText(book.getTitle());
			if (null != book.getSummary())
				summaryText.setText(book.getSummary());
		}
	}

}

これで再度グラフィカルエディタを起動すると、以下のようにキャンバス上でBookクラスに対応するノードが選択された場合にのみ、「Book details」というタブが表示され、Bookクラスの属性がEclise Forms UIで表示されます。