/*
 * Copyright 2006 Maskat Project.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.maskat.ide.tabbedproperties;

import java.util.Iterator;

import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyComposite;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.maskat.framework.eventdef.Bind;
import org.maskat.framework.eventdef.Event;
import org.maskat.framework.eventdef.Header;
import org.maskat.framework.eventdef.Param;
import org.maskat.framework.eventdef.Result;
import org.maskat.framework.eventdef.Source;
import org.maskat.framework.eventdef.Target;
import org.maskat.framework.screendef.ComponentDef;
import org.maskat.framework.screendef.IComponentDef;
import org.maskat.framework.screendef.LayoutDef;
import org.maskat.ide.editors.MaskatEditor;
import org.maskat.ide.gef.models.TabDef;
import org.maskat.ide.view.edit.AbstractNavigateFiller;
import org.maskat.ide.view.edit.DefaultNavigateFiller;

public abstract class EventPropertySection extends AbstractPropertySection implements
		ISelectionListener, IPropertyListener {

	private static final String TOENABLE = "有効にする", TODISABLE = "無効にする";

	private static final int MAX_TABLE_ITEM_COUNT = 10;

	private static int LEFTINDENT = 10, STANDARD_TEXT_WIDTH = 85,
			STANDARD_COMBO_WIDTH = 70, SHORT_LABEL_WIDTH = 50;

	private static int INDENT = 15;

	private Composite parentComp;

	private boolean eventEnabled;

	private Button btnEventEnable;

	private Label lblRemoteUrl, lblType, lblAsync;

	private Text txtRemoteUrl;

	private CCombo cmbType, cmbAsync;

	private Label lblStart, lblBefore, lblAfter, lblFinish;

	private Text txtStart, txtBefore, txtAfter, txtFinish;

	private Label lblTimeout, lblOnTimeoutError;

	private Text txtTimeout, txtOnTimeoutError;

	private Label lblHeader;

	private Table tblHeader;

	private Composite paramComp;

	private Label lblParam;

	private Button btnParamEnable;

	private Label lblRootNodeOfParam, lblNs, lblSoapOfParam;

	private Text txtRootNodeOfParam, txtNs;

	private CCombo cmbSoapOfParam;

	private Label lblSource, lblBindOfSource;

	private Table tblSource, tblBindOfSource;

	private Button btnSelectForSource;

	private Composite resultComp;

	private Label lblResult;

	private Button btnResultEnable;

	private Label lblRootNodeOfResult, lblOnErrorTele, lblSoapOfResult;

	private Text txtRootNodeOfResult, txtOnErrorTele;

	private CCombo cmbSoapOfResult;

	private Label lblTarget, lblBindOfTarget;

	private Table tblTarget, tblBindOfTarget;

	private Button btnSelectForTarget;

	private AbstractNavigateFiller sourceFiller, targetFiller;

	/**
	 * イベントXMLからイベントを読み込み、イベントXMLにイベント定義を書き込む時使われる名前
	 * 
	 * @return
	 */
	public abstract String getEventName();

	public void createControls(Composite parent,
			TabbedPropertySheetPage aTabbedPropertySheetPage) {
		super.createControls(parent, aTabbedPropertySheetPage);
		Composite rootParentComp = getWidgetFactory().createFlatFormComposite(parent);

		FormData data;
		parentComp = getWidgetFactory().createComposite(rootParentComp);
		data = new FormData();
		data.left = new FormAttachment(0);
		data.right = new FormAttachment(100);
		data.top = new FormAttachment(0);
		data.bottom = new FormAttachment(100);
		parentComp.setLayoutData(data);
		parentComp.setLayout(new FormLayout());

		int currentLeft = LEFTINDENT;

		btnEventEnable = getWidgetFactory().createButton(parentComp, "有効", SWT.TOGGLE);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft);
		data.right = new FormAttachment(0, 100);
		data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
		btnEventEnable.setLayoutData(data);
		btnEventEnable.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				eventEnabled = !eventEnabled;
				getEvent().setEnable(eventEnabled);
				syncEventState();
				editor.makeDirty(); // TODO CommandStack
				setEditMode(MaskatEditor.SCREEN_EDIT_MODE);
				super.widgetSelected(e);
			}
		});

		FormAttachment top = new FormAttachment(0, 40);
		FormAttachment topOfLabel = new FormAttachment(0, 42);
		// The top for label is a little lower.

		currentLeft = LEFTINDENT;
		lblRemoteUrl = getWidgetFactory().createLabel(parentComp, "remoteUrl");
		lblRemoteUrl.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft);
		data.right = new FormAttachment(0, currentLeft += SHORT_LABEL_WIDTH);
		data.top = topOfLabel;
		lblRemoteUrl.setLayoutData(data);

		txtRemoteUrl = getWidgetFactory().createText(parentComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += (STANDARD_TEXT_WIDTH + 50));
		data.top = top;
		txtRemoteUrl.setLayoutData(data);

		lblType = getWidgetFactory().createLabel(parentComp, "type");
		lblType.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += SHORT_LABEL_WIDTH);
		data.top = topOfLabel;
		lblType.setLayoutData(data);

		cmbType = getWidgetFactory().createCCombo(parentComp, SWT.READ_ONLY);
		cmbType.add("");
		cmbType.add("local");
		cmbType.add("remote");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_COMBO_WIDTH);
		data.top = top;
		cmbType.setLayoutData(data);

		lblAsync = getWidgetFactory().createLabel(parentComp, "async");
		lblAsync.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += SHORT_LABEL_WIDTH);
		data.top = topOfLabel;
		lblAsync.setLayoutData(data);

		cmbAsync = getWidgetFactory().createCCombo(parentComp, SWT.READ_ONLY);
		cmbAsync.add("");
		cmbAsync.add("true");
		cmbAsync.add("false");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_COMBO_WIDTH);
		data.top = top;
		cmbAsync.setLayoutData(data);

		top = new FormAttachment(0, 60);
		topOfLabel = new FormAttachment(0, 62);
		// The top for label is a little lower.

		currentLeft = LEFTINDENT;
		lblStart = getWidgetFactory().createLabel(parentComp, "start");
		lblStart.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft);
		data.right = new FormAttachment(0, currentLeft += SHORT_LABEL_WIDTH);
		data.top = topOfLabel;
		lblStart.setLayoutData(data);

		txtStart = getWidgetFactory().createText(parentComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_TEXT_WIDTH);
		data.top = top;
		txtStart.setLayoutData(data);

		lblBefore = getWidgetFactory().createLabel(parentComp, "before");
		lblBefore.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 60);
		data.right = new FormAttachment(0, currentLeft += SHORT_LABEL_WIDTH);
		data.top = topOfLabel;
		lblBefore.setLayoutData(data);

		txtBefore = getWidgetFactory().createText(parentComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += (STANDARD_TEXT_WIDTH + 10));
		data.top = top;
		txtBefore.setLayoutData(data);

		lblAfter = getWidgetFactory().createLabel(parentComp, "after");
		lblAfter.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += SHORT_LABEL_WIDTH);
		data.top = topOfLabel;
		lblAfter.setLayoutData(data);

		txtAfter = getWidgetFactory().createText(parentComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += (STANDARD_TEXT_WIDTH + 10));
		data.top = top;
		txtAfter.setLayoutData(data);

		lblFinish = getWidgetFactory().createLabel(parentComp, "finish");
		lblFinish.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += SHORT_LABEL_WIDTH);
		data.top = topOfLabel;
		lblFinish.setLayoutData(data);

		txtFinish = getWidgetFactory().createText(parentComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += (STANDARD_TEXT_WIDTH + 10));
		data.top = top;
		txtFinish.setLayoutData(data);

		top = new FormAttachment(0, 80);
		topOfLabel = new FormAttachment(0, 82);
		// The top for label is a little lower.

		currentLeft = LEFTINDENT;
		lblTimeout = getWidgetFactory().createLabel(parentComp, "timeout");
		lblTimeout.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft);
		data.right = new FormAttachment(0, currentLeft += SHORT_LABEL_WIDTH);
		data.top = topOfLabel;
		lblTimeout.setLayoutData(data);

		txtTimeout = getWidgetFactory().createText(parentComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_TEXT_WIDTH);
		data.top = top;
		txtTimeout.setLayoutData(data);

		lblOnTimeoutError = getWidgetFactory().createLabel(parentComp, "onTimeoutError");
		lblOnTimeoutError.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 20);
		data.right = new FormAttachment(0, currentLeft += (STANDARD_LABEL_WIDTH + 5));
		data.top = topOfLabel;
		lblOnTimeoutError.setLayoutData(data);

		txtOnTimeoutError = getWidgetFactory().createText(parentComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_TEXT_WIDTH);
		data.top = top;
		txtOnTimeoutError.setLayoutData(data);

		top = new FormAttachment(0, 110);
		currentLeft = LEFTINDENT;
		lblHeader = getWidgetFactory().createLabel(parentComp, "header");
		lblHeader.setAlignment(SWT.LEFT);
		lblHeader.setFont(BIG_BOLD_FONT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft);
		data.right = new FormAttachment(0, currentLeft += (SHORT_LABEL_WIDTH + 30));
		data.top = top;
		lblHeader.setLayoutData(data);

		currentLeft = LEFTINDENT;
		top = new FormAttachment(0, 135);
		tblHeader = getWidgetFactory().createTable(parentComp,
				SWT.SINGLE | SWT.FULL_SELECTION);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft);
		data.right = new FormAttachment(0, 211);
		data.top = top;
		data.bottom = new FormAttachment(0, 214);
		TableColumn tableColumn = new TableColumn(tblHeader, SWT.NONE);
		tableColumn.setText("name");
		tableColumn.setWidth(90);
		tableColumn = new TableColumn(tblHeader, SWT.NONE);
		tableColumn.setText("value");
		tableColumn.setWidth(90);
		tblHeader.setLayoutData(data);
		tblHeader.setHeaderVisible(true);
		tblHeader.setLinesVisible(true);

		for (int i = 0; i < MAX_TABLE_ITEM_COUNT; i++) {
			TableItem item = new TableItem(tblHeader, SWT.NONE);
			item.setText(new String[] { "", "" });
		}

		top = new FormAttachment(tblHeader, 0);

		paramComp = getWidgetFactory().createComposite(parentComp);
		data = new FormData();
		data.left = new FormAttachment(0);
		data.right = new FormAttachment(100);
		data.top = top;
		data.bottom = new FormAttachment(tblHeader, 190, SWT.BOTTOM);
		paramComp.setLayoutData(data);
		paramComp.setLayout(new FormLayout());

		createControlsOfParam();

		top = new FormAttachment(paramComp, 0);

		resultComp = getWidgetFactory().createComposite(parentComp);
		data = new FormData();
		data.left = new FormAttachment(0);
		data.right = new FormAttachment(100);
		data.top = top;
		data.bottom = new FormAttachment(paramComp, 190, SWT.BOTTOM);
		resultComp.setLayoutData(data);
		resultComp.setLayout(new FormLayout());

		createControlsOfResult();

		PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService()
				.addSelectionListener(this);
	}

	public void dispose() {
		PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService()
				.removeSelectionListener(this);
		if (this.editor != null) {
			editor.removePropertyListener(this);
		}
		super.dispose();
	}

	/**
	 * param編集関連のコンポーネントを作る
	 * 
	 */
	private void createControlsOfParam() {
		FormData data;
		FormAttachment topOfLabel;
		TableColumn tableColumn;

		FormAttachment top = new FormAttachment(0, 4);
		int currentLeft = LEFTINDENT;
		lblParam = getWidgetFactory().createLabel(paramComp, "param");
		lblParam.setAlignment(SWT.LEFT);
		lblParam.setFont(BIG_BOLD_FONT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft);
		data.right = new FormAttachment(0, currentLeft += (SHORT_LABEL_WIDTH + 30));
		data.top = top;
		lblParam.setLayoutData(data);

		currentLeft = LEFTINDENT;
		top = new FormAttachment(0, 30);
		topOfLabel = new FormAttachment(0, 32);
		btnParamEnable = getWidgetFactory().createButton(paramComp, "有効", SWT.TOGGLE);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += INDENT);
		data.right = new FormAttachment(0, currentLeft += (STANDARD_TEXT_WIDTH + 5));
		data.top = top;
		btnParamEnable.setLayoutData(data);

		btnParamEnable.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				Param theParam = getEvent().getParam();
				theParam.setEnable(!theParam.isEnable());
				syncEventState();
				editor.makeDirty(); // TODO CommandStack
				if (editor.editMode == MaskatEditor.SOURCE_EDIT_MODE)
					setEditMode(MaskatEditor.SCREEN_EDIT_MODE);
				super.widgetSelected(e);
			}
		});

		lblRootNodeOfParam = getWidgetFactory().createLabel(paramComp, "rootNode");
		lblRootNodeOfParam.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 20);
		data.right = new FormAttachment(0, currentLeft += (STANDARD_LABEL_WIDTH + 5));
		data.top = topOfLabel;
		lblRootNodeOfParam.setLayoutData(data);

		txtRootNodeOfParam = getWidgetFactory().createText(paramComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_TEXT_WIDTH);
		data.top = top;
		txtRootNodeOfParam.setLayoutData(data);

		lblNs = getWidgetFactory().createLabel(paramComp, "ns");
		lblNs.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 20);
		data.right = new FormAttachment(0, currentLeft += STANDARD_LABEL_WIDTH);
		data.top = topOfLabel;
		lblNs.setLayoutData(data);

		txtNs = getWidgetFactory().createText(paramComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_TEXT_WIDTH);
		data.top = top;
		txtNs.setLayoutData(data);

		lblSoapOfParam = getWidgetFactory().createLabel(paramComp, "soap");
		lblSoapOfParam.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 20);
		data.right = new FormAttachment(0, currentLeft += STANDARD_LABEL_WIDTH);
		data.top = topOfLabel;
		lblSoapOfParam.setLayoutData(data);

		cmbSoapOfParam = getWidgetFactory().createCCombo(paramComp, SWT.READ_ONLY);
		cmbSoapOfParam.add("");
		cmbSoapOfParam.add("true");
		cmbSoapOfParam.add("false");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_COMBO_WIDTH);
		data.top = top;
		cmbSoapOfParam.setLayoutData(data);

		top = new FormAttachment(0, 55);
		currentLeft = LEFTINDENT;

		lblSource = getWidgetFactory().createLabel(paramComp, "source");
		lblSource.setAlignment(SWT.LEFT);
		lblSource.setFont(BIG_BOLD_FONT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += INDENT);
		data.right = new FormAttachment(0, currentLeft += STANDARD_LABEL_WIDTH);
		data.top = top;
		lblSource.setLayoutData(data);

		lblBindOfSource = getWidgetFactory().createLabel(paramComp, "bind");
		lblBindOfSource.setAlignment(SWT.LEFT);
		lblBindOfSource.setFont(BIG_BOLD_FONT);
		data = new FormData();
		data.left = new FormAttachment(0, 610);
		data.right = new FormAttachment(0, 610 + STANDARD_LABEL_WIDTH);
		data.top = top;
		lblBindOfSource.setLayoutData(data);

		currentLeft = LEFTINDENT;
		top = new FormAttachment(0, 80);
		tblSource = getWidgetFactory().createTable(paramComp,
				SWT.SINGLE | SWT.FULL_SELECTION);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += INDENT);
		data.right = new FormAttachment(0, 600);
		data.top = top;
		data.bottom = new FormAttachment(0, 170);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("obj");
		tableColumn.setWidth(55);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("node");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("childNode");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("idxRef");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("fromkey");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("type");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("sendBlankElement");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("teleType");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("regexp");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblSource, SWT.NONE);
		tableColumn.setText("desc");
		tableColumn.setWidth(60);
		tblSource.setLayoutData(data);
		tblSource.setHeaderVisible(true);
		tblSource.setLinesVisible(true);

		for (int i = 0; i < MAX_TABLE_ITEM_COUNT; i++) {
			TableItem item = new TableItem(tblSource, SWT.NONE);
			item.setText(new String[] { "", "", "", "", "", "", "", "", "", "" });
		}
		sourceFiller = new SourceNavigateFiller();

		currentLeft = LEFTINDENT;

		tblBindOfSource = getWidgetFactory().createTable(paramComp,
				SWT.SINGLE | SWT.FULL_SELECTION);
		data = new FormData();
		data.left = new FormAttachment(0, 610);
		data.right = new FormAttachment(0, 751);
		data.top = top;
		data.bottom = new FormAttachment(0, 150);
		tableColumn = new TableColumn(tblBindOfSource, SWT.NONE);
		tableColumn.setText("node");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblBindOfSource, SWT.NONE);
		tableColumn.setText("fromkey");
		tableColumn.setWidth(60);
		tblBindOfSource.setLayoutData(data);
		tblBindOfSource.setHeaderVisible(true);
		tblBindOfSource.setLinesVisible(true);

		for (int i = 0; i < MAX_TABLE_ITEM_COUNT; i++) {
			TableItem item = new TableItem(tblBindOfSource, SWT.NONE);
			item.setText(new String[] { "", "" });
		}

		currentLeft = LEFTINDENT;
		top = new FormAttachment(0, 170);

		btnSelectForSource = getWidgetFactory().createButton(paramComp, "画面上からobjを選択",
				SWT.TOGGLE);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += INDENT);
		data.right = new FormAttachment(0, 150);
		data.top = top;
		btnSelectForSource.setLayoutData(data);
		btnSelectForSource.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (editor.editMode == MaskatEditor.SOURCE_EDIT_MODE) {
					setEditMode(MaskatEditor.SCREEN_EDIT_MODE);
				} else {
					setEditMode(MaskatEditor.SOURCE_EDIT_MODE);
				}
				btnSelectForTarget.setSelection(false);
			}
		});
	}

	/**
	 * result関連コンポーネント作成
	 * 
	 */
	private void createControlsOfResult() {
		FormData data;
		FormAttachment topOfLabel;
		TableColumn tableColumn;
		FormAttachment top = new FormAttachment(0, 4);
		int currentLeft = LEFTINDENT;
		lblResult = getWidgetFactory().createLabel(resultComp, "result");
		lblResult.setAlignment(SWT.LEFT);
		lblResult.setFont(BIG_BOLD_FONT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft);
		data.right = new FormAttachment(0, currentLeft += (SHORT_LABEL_WIDTH + 30));
		data.top = top;
		lblResult.setLayoutData(data);

		top = new FormAttachment(0, 25);
		topOfLabel = new FormAttachment(0, 27);
		currentLeft = LEFTINDENT;

		btnResultEnable = getWidgetFactory().createButton(resultComp, "有効", SWT.TOGGLE);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += INDENT);
		data.right = new FormAttachment(0, currentLeft += (STANDARD_TEXT_WIDTH + 5));
		data.top = top;
		btnResultEnable.setLayoutData(data);

		btnResultEnable.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				Result theResult = getEvent().getResult();
				theResult.setEnable(!theResult.isEnable());
				syncEventState();
				editor.makeDirty(); // TODO CommandStack
				if (editor.editMode == MaskatEditor.TARGET_EDIT_MODE)
					setEditMode(MaskatEditor.SCREEN_EDIT_MODE);
				super.widgetSelected(e);
			}
		});

		lblRootNodeOfResult = getWidgetFactory().createLabel(resultComp, "rootNode");
		lblRootNodeOfResult.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 20);
		data.right = new FormAttachment(0, currentLeft += (STANDARD_LABEL_WIDTH + 5));
		data.top = topOfLabel;
		lblRootNodeOfResult.setLayoutData(data);

		txtRootNodeOfResult = getWidgetFactory().createText(resultComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_TEXT_WIDTH);
		data.top = top;
		txtRootNodeOfResult.setLayoutData(data);

		lblOnErrorTele = getWidgetFactory().createLabel(resultComp, "onErrorTele");
		lblOnErrorTele.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 20);
		data.right = new FormAttachment(0, currentLeft += STANDARD_LABEL_WIDTH);
		data.top = topOfLabel;
		lblOnErrorTele.setLayoutData(data);

		txtOnErrorTele = getWidgetFactory().createText(resultComp, "");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_TEXT_WIDTH);
		data.top = top;
		txtOnErrorTele.setLayoutData(data);

		lblSoapOfResult = getWidgetFactory().createLabel(resultComp, "soap");
		lblSoapOfResult.setAlignment(SWT.RIGHT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 20);
		data.right = new FormAttachment(0, currentLeft += STANDARD_LABEL_WIDTH);
		data.top = topOfLabel;
		lblSoapOfResult.setLayoutData(data);

		cmbSoapOfResult = getWidgetFactory().createCCombo(resultComp, SWT.READ_ONLY);
		cmbSoapOfResult.add("");
		cmbSoapOfResult.add("true");
		cmbSoapOfResult.add("false");
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += 10);
		data.right = new FormAttachment(0, currentLeft += STANDARD_COMBO_WIDTH);
		data.top = top;
		cmbSoapOfResult.setLayoutData(data);

		top = new FormAttachment(0, 45);
		currentLeft = LEFTINDENT;

		lblTarget = getWidgetFactory().createLabel(resultComp, "target");
		lblTarget.setAlignment(SWT.LEFT);
		lblTarget.setFont(BIG_BOLD_FONT);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += INDENT);
		data.right = new FormAttachment(0, currentLeft += STANDARD_LABEL_WIDTH);
		data.top = top;
		lblTarget.setLayoutData(data);

		lblBindOfTarget = getWidgetFactory().createLabel(resultComp, "bind");
		lblBindOfTarget.setAlignment(SWT.LEFT);
		lblBindOfTarget.setFont(BIG_BOLD_FONT);
		data = new FormData();
		data.left = new FormAttachment(0, 410);
		data.right = new FormAttachment(0, 410 + STANDARD_LABEL_WIDTH);
		data.top = top;
		lblBindOfTarget.setLayoutData(data);

		currentLeft = LEFTINDENT;
		top = new FormAttachment(0, 66);
		tblTarget = getWidgetFactory().createTable(resultComp,
				SWT.SINGLE | SWT.FULL_SELECTION);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft + INDENT);
		data.right = new FormAttachment(0, 346);
		data.top = top;
		data.bottom = new FormAttachment(0, 150);
		tableColumn = new TableColumn(tblTarget, SWT.NONE);
		tableColumn.setText("out");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblTarget, SWT.NONE);
		tableColumn.setText("in");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblTarget, SWT.NONE);
		tableColumn.setText("inkey");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblTarget, SWT.NONE);
		tableColumn.setText("type");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblTarget, SWT.NONE);
		tableColumn.setText("teleType");
		tableColumn.setWidth(60);
		tblTarget.setLayoutData(data);
		tblTarget.setHeaderVisible(true);
		tblTarget.setLinesVisible(true);

		for (int i = 0; i < MAX_TABLE_ITEM_COUNT; i++) {
			TableItem item = new TableItem(tblTarget, SWT.NONE);
			item.setText(new String[] { "", "", "", "", "" });
		}
		targetFiller = new TargetNavigateFiller();

		tblBindOfTarget = getWidgetFactory().createTable(resultComp,
				SWT.SINGLE | SWT.FULL_SELECTION);
		data = new FormData();
		data.left = new FormAttachment(0, 410);
		data.right = new FormAttachment(0, 551);
		data.top = top;
		data.bottom = new FormAttachment(0, 140);
		tableColumn = new TableColumn(tblBindOfTarget, SWT.NONE);
		tableColumn.setText("node");
		tableColumn.setWidth(60);
		tableColumn = new TableColumn(tblBindOfTarget, SWT.NONE);
		tableColumn.setText("tokey");
		tableColumn.setWidth(60);
		tblBindOfTarget.setLayoutData(data);
		tblBindOfTarget.setHeaderVisible(true);
		tblBindOfTarget.setLinesVisible(true);

		for (int i = 0; i < MAX_TABLE_ITEM_COUNT; i++) {
			TableItem item = new TableItem(tblBindOfTarget, SWT.NONE);
			item.setText(new String[] { "", "" });
		}

		currentLeft = LEFTINDENT;
		top = new FormAttachment(0, 150);

		btnSelectForTarget = getWidgetFactory().createButton(resultComp, "画面上からoutを選択",
				SWT.TOGGLE);
		data = new FormData();
		data.left = new FormAttachment(0, currentLeft += INDENT);
		data.right = new FormAttachment(0, 150);
		data.top = top;
		btnSelectForTarget.setLayoutData(data);
		btnSelectForTarget.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (editor.editMode == MaskatEditor.TARGET_EDIT_MODE) {
					setEditMode(MaskatEditor.SCREEN_EDIT_MODE);
				} else {
					setEditMode(MaskatEditor.TARGET_EDIT_MODE);
				}
				btnSelectForSource.setSelection(false);
			}
		});
	}

	public static Font BIG_BOLD_FONT = new Font(null, "Arial", 12, SWT.BOLD);

	private void syncEventState() {
		Event theEvent = getEvent();
		eventEnabled = theEvent.isEnable();
		if (eventEnabled) {
			btnEventEnable.setText(TODISABLE);
			btnEventEnable.setSelection(true);

			FormData data = (FormData) parentComp.getLayoutData();
			data.bottom = new FormAttachment(100, 0);
			reLayout();
		} else {
			btnEventEnable.setText(TOENABLE);
			btnEventEnable.setSelection(false);

			FormData data = (FormData) parentComp.getLayoutData();
			data.bottom = new FormAttachment(0, 35);
			reLayout();
		}

		for (int i = 0; i < parentComp.getChildren().length; i++) {
			if (parentComp.getChildren()[i] != btnEventEnable)
				parentComp.getChildren()[i].setEnabled(eventEnabled);
		}
		syncParamState(eventEnabled);
		syncResultState(eventEnabled);
	}

	private void syncParamState(boolean eventEnabled) {
		Param theParam = getEvent().getParam();
		if (theParam == null)
			return;

		if (theParam.isEnable()) {
			btnParamEnable.setText(TODISABLE);
			btnParamEnable.setSelection(true);

			FormData data = (FormData) paramComp.getLayoutData();
			data.bottom = new FormAttachment(tblHeader, 200, SWT.BOTTOM);
			reLayout();
		} else {
			btnParamEnable.setText(TOENABLE);
			btnParamEnable.setSelection(false);

			FormData data = (FormData) paramComp.getLayoutData();
			data.bottom = new FormAttachment(tblHeader, 55, SWT.BOTTOM);
			reLayout();
		}

		if (eventEnabled) {
			btnParamEnable.setEnabled(true);
			for (int i = 0; i < paramComp.getChildren().length; i++) {
				if (paramComp.getChildren()[i] != btnParamEnable)
					paramComp.getChildren()[i].setEnabled(theParam.isEnable());
			}
		} else {
			for (int i = 0; i < paramComp.getChildren().length; i++) {
				paramComp.getChildren()[i].setEnabled(false);
			}
		}
	}

	private void syncResultState(boolean eventEnabled) {
		Result theResult = getEvent().getResult();
		if (theResult == null)
			return;

		if (theResult.isEnable()) {
			btnResultEnable.setText(TODISABLE);
			btnResultEnable.setSelection(true);

			FormData data = (FormData) resultComp.getLayoutData();
			data.bottom = new FormAttachment(paramComp, 200, SWT.BOTTOM);
			reLayout();
		} else {
			btnResultEnable.setText(TOENABLE);
			btnResultEnable.setSelection(false);

			FormData data = (FormData) resultComp.getLayoutData();
			data.bottom = new FormAttachment(paramComp, 48, SWT.BOTTOM);
			reLayout();
		}

		if (eventEnabled) {
			btnResultEnable.setEnabled(true);
			for (int i = 0; i < resultComp.getChildren().length; i++) {
				if (resultComp.getChildren()[i] != btnResultEnable)
					resultComp.getChildren()[i].setEnabled(theResult.isEnable());
			}
		} else {
			for (int i = 0; i < resultComp.getChildren().length; i++) {
				resultComp.getChildren()[i].setEnabled(false);
			}
		}
	}

	private void reLayout() {
		Composite comp = parentComp.getParent();
		while (comp != null && !(comp instanceof TabbedPropertyComposite)) {
			comp = comp.getParent();
		}
		if (comp instanceof TabbedPropertyComposite) {
			ScrolledComposite sc = ((TabbedPropertyComposite) comp)
					.getScrolledComposite();
			sc.setMinSize(sc.computeSize(SWT.DEFAULT, SWT.DEFAULT));
			sc.layout(false);
		}
	}

	private LayoutDef layoutDef;

	private String componentName;

	// componentDefはComponentDef或いはTabDef
	private Object model;

	// private CommandStack cs;

	private MaskatEditor editor;

	private FocusListener lsnRemoteUrl, lsnType, lsnAsync, lsnStart, lsnBefore, lsnAfter,
			lsnFinish, lsnTimeout, lsnOnTimeoutError, lsnRootNodeOfParam, lsnNs,
			lsnSoapOfParam, lsnRootNodeOfResult, lsnOnErrorTele, lsnSoapOfResult;

	private TableListenerForEditor lsnHeaderTable, lsnSourceTable, lsnTargetTable,
			lsnBindOfSource, lsnBindOfTarget;

	private TableKeyListenerForEditor keyLsnHeader, keyLsnSource, keyLsnTarget,
			keyLsnBindOfSource, keyLsnBindOfTarget;

	public void setInput(IWorkbenchPart part, ISelection selection) {
		super.setInput(part, selection);
		if (part instanceof MaskatEditor) {
			// cs = (CommandStack) part.getAdapter(CommandStack.class);
			if (this.editor != null) {
				editor.removePropertyListener(this);
				// remove self from the old editor
			}
			editor = (MaskatEditor) part;
			editor.addPropertyListener(this);
		}
	}

	public void refresh() {
		ISelection selection = this.getSelection();
		if (selection instanceof StructuredSelection) {
			StructuredSelection ss = (StructuredSelection) selection;
			if (ss.getFirstElement() instanceof AbstractGraphicalEditPart) {
				AbstractGraphicalEditPart agep = (AbstractGraphicalEditPart) ss
						.getFirstElement();
				if (agep.getModel() instanceof ComponentDef
						|| agep.getModel() instanceof TabDef) {
					model = agep.getModel();

					if (model instanceof ComponentDef) {
						layoutDef = ((ComponentDef) model).getLayoutDef();
						componentName = ((ComponentDef) model).getName();
					}
					if (model instanceof TabDef) {
						layoutDef = ((TabDef) model).getParent().getLayoutDef();
						componentName = ((TabDef) model).getName();
					}

					renew();
				}
			}
		}
	}

	private void renew() {

		lsnRemoteUrl = registerListener(txtRemoteUrl, lsnRemoteUrl, new TextValueWatcher(
				txtRemoteUrl, getEvent(), "remoteUrl", editor));
		lsnType = registerListener(cmbType, lsnType, new CComboValueWatcher(cmbType,
				getEvent(), "type", editor));
		lsnAsync = registerListener(cmbAsync, lsnAsync, new CComboValueWatcher(cmbAsync,
				getEvent(), "async", editor));
		lsnStart = registerListener(txtStart, lsnStart, new TextValueWatcher(txtStart,
				getEvent(), "start", editor));
		lsnBefore = registerListener(txtBefore, lsnBefore, new TextValueWatcher(
				txtBefore, getEvent(), "before", editor));
		lsnAfter = registerListener(txtAfter, lsnAfter, new TextValueWatcher(txtAfter,
				getEvent(), "after", editor));
		lsnFinish = registerListener(txtFinish, lsnFinish, new TextValueWatcher(
				txtFinish, getEvent(), "finish", editor));
		lsnTimeout = registerListener(txtTimeout, lsnTimeout, new TextValueWatcher(
				txtTimeout, getEvent(), "timeout", editor));
		lsnOnTimeoutError = registerListener(txtOnTimeoutError, lsnOnTimeoutError,
				new TextValueWatcher(txtOnTimeoutError, getEvent(), "onTimeoutError",
						editor));

		ControlWrapper[] controls = new ControlWrapper[2];
		controls[0] = ControlWrapper.newTextWrapper();
		controls[1] = ControlWrapper.newTextWrapper();

		String[] propNames = new String[] { "name", "value" };

		lsnHeaderTable = registerTableListener(tblHeader, lsnHeaderTable,
				new TableListenerForEditor(tblHeader, controls, propNames, getEvent(),
						Header.class, this.editor));

		keyLsnHeader = registerKeyListener(tblHeader, keyLsnHeader,
				new TableKeyListenerForEditor(tblHeader, propNames, getEvent(),
						Header.class, editor));

		lsnRootNodeOfParam = registerListener(txtRootNodeOfParam, lsnRootNodeOfParam,
				new TextValueWatcher(txtRootNodeOfParam, getEvent().getParam(),
						"rootNode", editor));
		lsnNs = registerListener(txtNs, lsnNs, new TextValueWatcher(txtNs, getEvent()
				.getParam(), "ns", editor));
		lsnSoapOfParam = registerListener(cmbSoapOfParam, lsnSoapOfParam,
				new CComboValueWatcher(cmbSoapOfParam, getEvent().getParam(), "soap",
						editor));

		controls = new ControlWrapper[10];
		for (int i = 0; i < controls.length; i++) {
			controls[i] = ControlWrapper.newTextWrapper();
		}
		propNames = new String[] { "obj", "node", "childNode", "idxRef", "fromkey",
				"type", "sendBlankElement", "teleType", "regexp", "desc" };

		lsnSourceTable = registerTableListener(tblSource, lsnSourceTable,
				new TableListenerForEditor(tblSource, controls, propNames, getEvent()
						.getParam(), Source.class, this.editor));

		keyLsnSource = registerKeyListener(tblSource, keyLsnSource,
				new TableKeyListenerForEditor(tblSource, propNames,
						getEvent().getParam(), Source.class, editor));

		tblSource.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				syncBindOfSource();
			}
		});

		lsnRootNodeOfResult = registerListener(txtRootNodeOfResult, lsnRootNodeOfResult,
				new TextValueWatcher(txtRootNodeOfResult, getEvent().getResult(),
						"rootNode", editor));
		lsnOnErrorTele = registerListener(txtOnErrorTele, lsnOnErrorTele,
				new TextValueWatcher(txtOnErrorTele, getEvent().getResult(),
						"onErrorTele", editor));
		lsnSoapOfResult = registerListener(cmbSoapOfResult, lsnSoapOfResult,
				new CComboValueWatcher(cmbSoapOfResult, getEvent().getResult(), "soap",
						editor));

		controls = new ControlWrapper[5];
		for (int i = 0; i < controls.length; i++) {
			controls[i] = ControlWrapper.newTextWrapper();
		}
		propNames = new String[] { "out", "in", "inkey", "type", "teleType" };

		lsnTargetTable = registerTableListener(tblTarget, lsnTargetTable,
				new TableListenerForEditor(tblTarget, controls, propNames, getEvent()
						.getResult(), Target.class, this.editor));

		keyLsnTarget = registerKeyListener(tblTarget, keyLsnTarget,
				new TableKeyListenerForEditor(tblTarget, propNames, getEvent()
						.getResult(), Target.class, editor));

		tblTarget.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				syncBindOfTarget();
			}
		});
		if (lsnBindOfSource != null)
			lsnBindOfSource.outOfFocus();

		if (lsnBindOfTarget != null)
			lsnBindOfTarget.outOfFocus();

		syncEventState();
		setAllEventDataToControls();
	}

	private TableKeyListenerForEditor registerKeyListener(Table tbl,
			TableKeyListenerForEditor oldListener, TableKeyListenerForEditor newListener) {
		if (oldListener != null) {
			tbl.removeKeyListener(oldListener);
		}
		tbl.addKeyListener(newListener);
		return newListener;
	}

	private TableListenerForEditor registerTableListener(Table tbl,
			TableListenerForEditor oldListener, TableListenerForEditor newListener) {
		if (oldListener != null) {
			tbl.removeMouseListener(oldListener);
			oldListener.outOfFocus();
		}
		tbl.addMouseListener(newListener);
		return newListener;

	}

	private FocusListener registerListener(Control control, FocusListener oldListener,
			FocusListener newListener) {
		if (oldListener != null)
			control.removeFocusListener(oldListener);
		control.addFocusListener(newListener);
		return newListener;
	}

	private Event getEvent() {
		Event result = null;
		if (model instanceof LayoutDef) {
			// layoutのイベント属性
			result = layoutDef.getLayoutEvtDefSrc().getDefs()[0]
					.findEvent(getEventName());
		} else {
			result = layoutDef.getLayoutEvtDefSrc().findComponent(componentName)
					.findEvent(getEventName());
		}
		if (result == null)
			result = createEvent();
		return result;
	}

	private Event createEvent() {
		if (layoutDef == null || layoutDef.getLayoutEvtDefSrc() == null) {
			return null;
		}
		Event newEvent = new Event(getEventName());
		newEvent.setEnable(false);
		if (model instanceof LayoutDef) {
			layoutDef.getLayoutEvtDefSrc().getDefs()[0].addChild(newEvent);
			return newEvent;
		}
		layoutDef.getLayoutEvtDefSrc().findComponent(componentName).addChild(newEvent);
		return newEvent;
	}

	private String getDisp(String value) {
		if (value == null)
			return "";
		return value;
	}

	private void setAllEventDataToControls() {
		if (getEvent() == null)
			return;
		Event theEvent = getEvent();
		txtRemoteUrl.setText(getDisp(theEvent.getRemoteUrl()));
		cmbType.setText(getDisp(theEvent.getType()));
		cmbAsync.setText(getDisp(theEvent.getAsync()));
		txtStart.setText(getDisp(theEvent.getStart()));
		txtBefore.setText(getDisp(theEvent.getBefore()));
		txtAfter.setText(getDisp(theEvent.getAfter()));
		txtFinish.setText(getDisp(theEvent.getFinish()));
		txtTimeout.setText(getDisp(theEvent.getTimeout()));
		txtOnTimeoutError.setText(getDisp(theEvent.getOnTimeoutError()));
		// set headers
		Iterator headersIt = theEvent.getTypedChildren(Header.class);
		tblHeader.clearAll();
		int idx = 0;
		for (; headersIt != null && headersIt.hasNext();) {
			Header header = (Header) headersIt.next();
			TableItem item = tblHeader.getItem(idx++);
			item.setText(new String[] { header.getName(), header.getValue() });
			if (idx >= MAX_TABLE_ITEM_COUNT)
				break;
		}

		// set all the values from the event to the controls

		Param theParam = theEvent.getParam();
		tblSource.clearAll();
		//tblBindOfSource.removeMouseListener(lsnBindOfSource);
		syncBindOfSource();

		idx = 0;
		if (theParam != null) {
			txtRootNodeOfParam.setText(getDisp(theParam.getRootNode()));
			txtNs.setText(getDisp(theParam.getNs()));
			cmbSoapOfParam.setText(getDisp(theParam.getSoap()));
			// source
			Iterator sourceIt = theParam.getTypedChildren(Source.class);
			for (; sourceIt != null && sourceIt.hasNext();) {
				Source source = (Source) sourceIt.next();
				TableItem item = tblSource.getItem(idx++);
				item.setText(new String[] { source.getObj(), source.getNode(),
						source.getChildNode(), source.getIdxRef(), source.getFromkey(),
						source.getType(), source.getSendBlankElement(),
						source.getTeleType(), source.getRegexp(), source.getDesc() });
				if (idx >= MAX_TABLE_ITEM_COUNT)
					break;
			}
		}

		Result theResult = theEvent.getResult();
		tblTarget.clearAll();
		//tblBindOfTarget.removeMouseListener(lsnBindOfTarget);
		syncBindOfTarget();

		idx = 0;
		if (theResult != null) {
			txtRootNodeOfResult.setText(getDisp(theResult.getRootNode()));
			txtOnErrorTele.setText(getDisp(theResult.getOnErrorTele()));
			cmbSoapOfResult.setText(getDisp(theResult.getSoap()));
			// target
			Iterator targetIt = theResult.getTypedChildren(Target.class);
			for (; targetIt != null && targetIt.hasNext();) {
				Target target = (Target) targetIt.next();
				TableItem item = tblTarget.getItem(idx++);
				item.setText(new String[] { target.getOut(), target.getIn(),
						target.getInkey(), target.getType(), target.getTeleType() });
				if (idx >= MAX_TABLE_ITEM_COUNT)
					break;
			}
		}

	}

	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
		if (selection instanceof StructuredSelection) {
			if (((StructuredSelection) selection).size() > 1)
				return;

			if (part != editor)
				return;

			if (editor.gettingFocus) {
				editor.gettingFocus = false;
				return;
			}

			Object obj = ((StructuredSelection) selection).getFirstElement();
			if (obj instanceof AbstractGraphicalEditPart) {
				AbstractGraphicalEditPart ssG = (AbstractGraphicalEditPart) obj;
				Object model = ssG.getModel();
				if (model instanceof IComponentDef) {
					IComponentDef cm = (IComponentDef) model;
					if (editor.editMode == MaskatEditor.SOURCE_EDIT_MODE) {
						sourceFiller.acceptString(cm.getName());
					}
					if (editor.editMode == MaskatEditor.TARGET_EDIT_MODE) {
						targetFiller.acceptString(cm.getName());
					}
				}
			}
		}

	}

	private void setEditMode(int mode) {
		editor.editMode = mode;
		editor.syncMousePointerWithMode();
		if (mode == MaskatEditor.SOURCE_EDIT_MODE) {
			btnSelectForSource.setSelection(true);
			btnSelectForTarget.setSelection(false);
		} else if (mode == MaskatEditor.TARGET_EDIT_MODE) {
			btnSelectForSource.setSelection(false);
			btnSelectForTarget.setSelection(true);
		} else {
			btnSelectForSource.setSelection(false);
			btnSelectForTarget.setSelection(false);
		}
	}

	private class SourceNavigateFiller extends DefaultNavigateFiller {

		public SourceNavigateFiller() {
			super(tblSource);
			targetColumn = 0;
		}

		public TableItem addNewLine(String value) {
			return null;
		}

		public void fillStringToTable(TableItem item, String value) {
			if (item == null)
				return;
			int idx = tblSource.indexOf(item);
			if (idx == -1)
				return;

			Source source = (Source) getEvent().getParam().getChildByTypeIdx(
					Source.class, idx);
			while (source == null) {
				getEvent().getParam().addChild(new Source());
				source = (Source) getEvent().getParam().getChildByTypeIdx(Source.class,
						idx);
			}
			source.setObj(value);
			editor.makeDirty(); // TODO CommandStack
			super.fillStringToTable(item, value);
		}
	}

	private class TargetNavigateFiller extends DefaultNavigateFiller {

		public TargetNavigateFiller() {
			super(tblTarget);
			targetColumn = 0;
		}

		public TableItem addNewLine(String value) {
			return null;
		}

		public void fillStringToTable(TableItem item, String value) {
			if (item == null)
				return;
			int idx = tblTarget.indexOf(item);
			if (idx == -1)
				return;

			Target target = (Target) getEvent().getResult().getChildByTypeIdx(
					Target.class, idx);
			while (target == null) {
				getEvent().getResult().addChild(new Target());
				target = (Target) getEvent().getResult().getChildByTypeIdx(Target.class,
						idx);
			}
			target.setOut(value);
			editor.makeDirty(); // TODO CommandStack
			super.fillStringToTable(item, value);
		}
	}

	public void propertyChanged(Object source, int propId) {
		if (propId == MaskatEditor.PROP_SAVE) {
			renew();
		}
	}

	private void syncBindOfSource() {
		tblBindOfSource.clearAll();
		int idx = tblSource.getSelectionIndex();
		if (idx == -1) {
			return;
		}
		Source source = (Source) getEvent().getParam().getChildByTypeIdx(Source.class,
				idx);
		while (source == null) {
			getEvent().getParam().addChild(new Source());
			source = (Source) getEvent().getParam().getChildByTypeIdx(Source.class, idx);
		}
		int lineIdx = 0;
		for (Iterator it = source.getTypedChildren(Bind.class); it != null
				&& it.hasNext();) {
			Bind bind = (Bind) it.next();

			TableItem item = tblBindOfSource.getItem(lineIdx++);
			item.setText(new String[] { bind.getNode(), bind.getFromkey() });
			if (lineIdx >= MAX_TABLE_ITEM_COUNT)
				break;
		}
		ControlWrapper[] controls = new ControlWrapper[2];
		for (int i = 0; i < controls.length; i++) {
			controls[i] = ControlWrapper.newTextWrapper();
		}
		String[] propNames = new String[] { "node", "fromkey" };
		// TODO whatif source is null!!!
		lsnBindOfSource = registerTableListener(tblBindOfSource, lsnBindOfSource,
				new TableListenerForEditor(tblBindOfSource, controls, propNames, source,
						Bind.class, editor));

		keyLsnBindOfSource = registerKeyListener(tblBindOfSource, keyLsnBindOfSource,
				new TableKeyListenerForEditor(tblBindOfSource, propNames, source,
						Bind.class, editor));
	}

	private void syncBindOfTarget() {
		tblBindOfTarget.clearAll();
		int idx = tblTarget.getSelectionIndex();
		if (idx == -1) {
			return;
		}
		Target target = (Target) getEvent().getResult().getChildByTypeIdx(
				Target.class, idx);
		while (target == null) {
			getEvent().getResult().addChild(new Target());
			target = (Target) getEvent().getResult().getChildByTypeIdx(
					Target.class, idx);
		}
		int lineIdx = 0;
		for (Iterator it = target.getTypedChildren(Bind.class); it != null
				&& it.hasNext();) {
			Bind bind = (Bind) it.next();

			TableItem item = tblBindOfTarget.getItem(lineIdx++);
			item.setText(new String[] { bind.getNode(), bind.getTokey() });
			if (lineIdx >= MAX_TABLE_ITEM_COUNT)
				break;
		}
		ControlWrapper[] controls = new ControlWrapper[2];
		for (int i = 0; i < controls.length; i++) {
			controls[i] = ControlWrapper.newTextWrapper();
		}
		String[] propNames = new String[] { "node", "tokey" };
		lsnBindOfTarget = registerTableListener(tblBindOfTarget, lsnBindOfTarget,
				new TableListenerForEditor(tblBindOfTarget, controls, propNames,
						target, Bind.class, editor));

		keyLsnBindOfTarget = registerKeyListener(tblBindOfTarget,
				keyLsnBindOfTarget, new TableKeyListenerForEditor(
						tblBindOfTarget, propNames, target, Bind.class, editor));
	}
}
