/** * Դ�������ƣ�ColumnViewerBlock.java * �������Ȩ���������ӹɷ����޹�˾ ��Ȩ���� * ϵͳ���ƣ�JRES Studio * ģ�����ƣ�com.hundsun.ares.studio.jres.ui * ����˵����$desc * ����ĵ��� * ���ߣ���Ҷ�� */ package com.hundsun.ares.studio.ui.editor.blocks; import java.util.ArrayList; import java.util.EventObject; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CommandStack; import org.eclipse.emf.common.command.CommandStackListener; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; import org.eclipse.jface.viewers.ColumnViewerEditorActivationListener; import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; import org.eclipse.jface.viewers.ColumnViewerEditorDeactivationEvent; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.jface.window.ToolTip; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.forms.widgets.FormToolkit; import com.hundsun.ares.studio.core.IARESResource; import com.hundsun.ares.studio.ui.editor.ARESEditorPlugin; import com.hundsun.ares.studio.ui.editor.GlobalActionHandlerProviderSupport; import com.hundsun.ares.studio.ui.editor.IGlobalActionHandlerProvider; import com.hundsun.ares.studio.ui.editor.IGlobalActionHandlerProviderListener; import com.hundsun.ares.studio.ui.editor.actions.IActionIDConstant; import com.hundsun.ares.studio.ui.editor.actions.IUpdateAction; import com.hundsun.ares.studio.ui.editor.editable.IEditableControl; import com.hundsun.ares.studio.ui.editor.viewers.RefreshViewerJob; import com.hundsun.ares.studio.ui.editor.viewers.SynRefreshViewerJob; import com.hundsun.ares.studio.ui.util.ARESEMFClipboard; import com.hundsun.ares.studio.ui.util.IJRESClipboardListener; import com.hundsun.ares.studio.ui.validate.IProblemPool; import com.hundsun.ares.studio.ui.viewers.link.JRESColumnViewerEditorActivationStrategy; /** * @author gongyf * */ // TODO: Ӧ��֧��Block�ڷDZ༭���Ļ�����ʹ�ã������ڶԻ����� // 1. toolkit֧��Ϊnull���Ի����ж���û��toolkit�� �Ի���ʹ��Form��ʽҲ��̫Э�� // 2. ֻ�������õ�EditControl����Ϊnull // 3. ProblemPool����Ϊnull public abstract class ColumnViewerBlock<T extends ColumnViewer> implements ISelectionChangedListener, ISelectionProvider, IPropertyListener, CommandStackListener, IGlobalActionHandlerProvider { protected EditingDomain editingDomain; protected IARESResource resource; protected IProblemPool problemPool; protected static final String SAVED_WIDTHES = "saved_width"; protected static final String SAVED_COLUMNS = "saved_column"; /** * ��ǰ���װ���� */ private Map<String, IColumnViewerBlockDecorator<T> > decorators; private GlobalActionHandlerProviderSupport support = new GlobalActionHandlerProviderSupport(this); // ��¼��ǰ�Ƿ񼤻���ȫ�ֿ�ݼ� private boolean globalActionHandleEnabled = false; private IActionBars actionBars; private Control control; private T columnViewer; private ActionRegistry actionRegistry; private List<String> selectionActions; private List<String> stackActions; private List<String> propertyActions; private List<String> clipboardActions; private IEditableControl editableControl; public EditingDomain getEditingDomain() { return editingDomain; } public IARESResource getARESResource() { return resource; } public IProblemPool getProblemPool() { return problemPool; } private IJRESClipboardListener clipboardListener = new IJRESClipboardListener() { @Override public void clipboardChanged(ARESEMFClipboard clipboard) { updateActions(getClipboardActions()); } @Override public void clipboardAboutToBeChanged(ARESEMFClipboard clipboard) { } }; /** * �༭��ID */ abstract protected String getID(); /** * * ��ȡװ�����б���һ�λ����������չ���е����� * @return the decorators */ public Map<String, IColumnViewerBlockDecorator<T> > getDecorators() { if (decorators == null) { decorators = new HashMap<String, IColumnViewerBlockDecorator<T>>(); // ����չ�����ȡ IExtensionRegistry reg = Platform.getExtensionRegistry(); IConfigurationElement[] elements = reg.getConfigurationElementsFor(ARESEditorPlugin.PLUGIN_ID , "BlockDecorators"); for (IConfigurationElement element : elements) { try { String id = element.getAttribute("id"); String blockId = element.getAttribute("blockId"); if (StringUtils.equals(blockId, getID())) { IColumnViewerBlockDecorator<T> decorator = (IColumnViewerBlockDecorator<T>) element.createExecutableExtension("class"); decorators.put(id, decorator); } } catch (Exception e) { } } configureDecorators(decorators); } return decorators; } /** * ������Ҫ��װ���� * @param decorators */ protected void configureDecorators(Map<String, IColumnViewerBlockDecorator<T> > decorators) { } /** * @return the support */ protected GlobalActionHandlerProviderSupport getProviderSupport() { return support; } /* (non-Javadoc) * @see com.hundsun.ares.studio.jres.ui.form.IGlobalActionHandlerProvider#addGlobalActionHandlerProviderListener(com.hundsun.ares.studio.jres.ui.form.IGlobalActionHandlerProviderListener) */ @Override public void addGlobalActionHandlerProviderListener( IGlobalActionHandlerProviderListener listener) { getProviderSupport().addListener(listener); } /* (non-Javadoc) * @see com.hundsun.ares.studio.jres.ui.form.IGlobalActionHandlerProvider#removeGlobalActionHandlerProviderListener(com.hundsun.ares.studio.jres.ui.form.IGlobalActionHandlerProviderListener) */ @Override public void removeGlobalActionHandlerProviderListener( IGlobalActionHandlerProviderListener listener) { getProviderSupport().removeListener(listener); } /* (non-Javadoc) * @see com.hundsun.ares.studio.jres.ui.form.IGlobalActionHandlerProvider#clearGlobalActions(org.eclipse.ui.IActionBars) */ @Override final public void clearGlobalActions(IActionBars actionBars) { globalActionHandleEnabled = false; doClearGlobalActions(actionBars); this.actionBars = null; } /* (non-Javadoc) * @see com.hundsun.ares.studio.jres.ui.form.IGlobalActionHandlerProvider#shareGlobalActions(org.eclipse.ui.IActionBars) */ @Override final public void shareGlobalActions(IActionBars actionBars) { globalActionHandleEnabled = true; doShareGlobalActions(actionBars); this.actionBars = actionBars; } protected void doShareGlobalActions(IActionBars actionBars) { actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), getActionRegistry().getAction(IActionIDConstant.CV_COPY)); actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), getActionRegistry().getAction(IActionIDConstant.CV_PASTE)); actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), getActionRegistry().getAction(IActionIDConstant.CV_DELETE)); } protected void doClearGlobalActions(IActionBars actionBars) { actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), null); actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), null); actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), null); } /** * �����ؼ� * @param parent * @param toolkit */ public void createControl(Composite parent, FormToolkit toolkit) { // ���������� ARESEMFClipboard.getInstance().addClipboardListener(clipboardListener); Composite client = toolkit.createComposite(parent); Control viewer = createColumnViewer(client, toolkit); if (needButtonGroupArea()) { Control buttons = createViewerButtons(client, toolkit); GridLayoutFactory.swtDefaults().numColumns(2).applyTo(client); GridDataFactory.fillDefaults().hint(getViewerPreferredSize()).grab(true, true).applyTo(viewer); GridDataFactory.fillDefaults().grab(false, true).applyTo(buttons); } else { // ռ�����пռ� GridLayoutFactory.swtDefaults().applyTo(client); GridDataFactory.fillDefaults().hint(getViewerPreferredSize()).grab(true, true).applyTo(viewer); } control = client; } /** * ��ȡ�����ͼ����Ѵ�С * @return */ protected Point getViewerPreferredSize() { return new Point(100, 100); } /** * �Ƿ���Ҫ������ť�� * @return */ protected boolean needButtonGroupArea() { return true; } /** * @return the control */ public Control getControl() { return control; } /** * @param editableControl the editableControl to set */ public void setEditableControl(IEditableControl editableControl) { this.editableControl = editableControl; } /** * @return the editableControl */ public IEditableControl getEditableControl() { return editableControl; } /* (non-Javadoc) * @see org.eclipse.emf.common.command.CommandStackListener#commandStackChanged(java.util.EventObject) */ @Override public void commandStackChanged(EventObject event) { RefreshViewerJob.refresh(getColumnViewer(), null, false); Command cmd = ((CommandStack)event.getSource()).getMostRecentCommand(); if (cmd != null) { SynRefreshViewerJob.refresh(getColumnViewer(), cmd.getAffectedObjects().toArray() ,cmd , getHeadColumnFeature()); } updateActions(getStackActions()); } /** * * * @return */ protected EStructuralFeature getHeadColumnFeature(){ return null; } /* (non-Javadoc) * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object, int) */ @Override public void propertyChanged(Object source, int propId) { updateActions(getPropertyActions()); } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) */ @Override public void addSelectionChangedListener(ISelectionChangedListener listener) { if (getColumnViewer() != null) { getColumnViewer().addSelectionChangedListener(listener); } } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection() */ @Override public ISelection getSelection() { if (getColumnViewer() != null) { return getColumnViewer().getSelection(); } return StructuredSelection.EMPTY; } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) */ @Override public void removeSelectionChangedListener( ISelectionChangedListener listener) { if (getColumnViewer() != null) { getColumnViewer().removeSelectionChangedListener(listener); } } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection) */ @Override public void setSelection(ISelection selection) { if (getColumnViewer() != null) { getColumnViewer().setSelection(selection); } } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) */ @Override public void selectionChanged(SelectionChangedEvent event) { updateActions(getSelectionActions()); } /** * �������� * @param input */ public void setInput(Object input) { if (getColumnViewer() != null) { getColumnViewer().setInput(input); updateActions(getPropertyActions()); updateActions(getSelectionActions()); updateActions(getStackActions()); for (IColumnViewerBlockDecorator<T> d : getDecorators().values()) { d.inputChanged(this); } } } /** * �ڲ�����{@link #setColumnViewer(ColumnViewer)} ��{@link #configureColumnViewer(ColumnViewer)} * @param parent * @param toolkit * @return */ protected Control createColumnViewer(Composite parent, FormToolkit toolkit) { T viewer = doCreateColumnViewer(parent, toolkit); setColumnViewer(viewer); configureColumnViewer(getColumnViewer()); // CellEditor���ֺ���Ҫ���ε���ݼ� viewer.getColumnViewerEditor().addEditorActivationListener(new ColumnViewerEditorActivationListener() { @Override public void beforeEditorDeactivated( ColumnViewerEditorDeactivationEvent event) { } @Override public void beforeEditorActivated(ColumnViewerEditorActivationEvent event) { } @Override public void afterEditorDeactivated(ColumnViewerEditorDeactivationEvent event) { if (globalActionHandleEnabled && actionBars != null) { doShareGlobalActions(actionBars); } } @Override public void afterEditorActivated(ColumnViewerEditorActivationEvent event) { if (actionBars != null) { doClearGlobalActions(actionBars); } } }); addDoubleClickListener(viewer); return viewer.getControl(); } /** * ������˫������ * TASK #9521 ���б��˫�������������� * @param viewer */ protected void addDoubleClickListener(final ColumnViewer viewer) { viewer.getControl().addMouseListener(new MouseAdapter() { @Override public void mouseDoubleClick(MouseEvent e) { ViewerCell cell = viewer.getCell(new Point(e.x, e.y)); //cellΪnull ��ʾ�ǵ�Ԫ��Ϊ���� if(null == cell){ IAction action = getAddAction(); if(action != null){ action.run(); } } } }); } /** * Ĭ�ϵ���������action��˫������ʱ���� * TASK #9521 ���б��˫�������������� * @return */ protected IAction getAddAction(){ return getActionRegistry().getAction(IActionIDConstant.CV_ADD); } /** * ������� * @param parent * @param toolkit * @return */ protected abstract T doCreateColumnViewer(Composite parent, FormToolkit toolkit); protected Control createViewerButtons(Composite parent, FormToolkit toolkit) { ToolBar toolbar = new ToolBar(parent, SWT.VERTICAL); ToolBarManager manager = new ToolBarManager(toolbar); createToolbarItems(manager); toolkit.adapt(toolbar); manager.update(true); return toolbar; } // 2012-09-05 sundl ��Toolbar�滻 // /** // * ��ӿ��ư�ť // * @param manager // */ // protected void createButtons(ButtonGroupManager manager) { // // } protected void createToolbarItems(ToolBarManager manager) { } /** * ��ñ��������ṩ�� * @return */ protected abstract IContentProvider getColumnViewerContentProvider(); protected abstract void createMenus(IMenuManager menuManager); protected abstract void createColumns(T viewer); protected ColumnViewerEditorActivationStrategy createColumnViewerEditorActivationStrategy(T viewer) { // ˫�������޸ĵ�Ԫ�� ColumnViewerEditorActivationStrategy actSupport = new JRESColumnViewerEditorActivationStrategy(viewer); return actSupport; } protected void addToolTipSupport(T viewer){ ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.RECREATE); } protected void configureColumnViewer(T viewer) { viewer.setUseHashlookup(true); createColumns(viewer); viewer.setContentProvider(getColumnViewerContentProvider()); MenuManager menuManager = new MenuManager("#popup"); menuManager.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { manager.removeAll(); createMenus(manager); // װ��������װ�� for (IColumnViewerBlockDecorator<T> d : getDecorators().values()) { d.decorateMenu(ColumnViewerBlock.this, manager); } } }); Menu menu = menuManager.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); // �������tooltip��ʾ addToolTipSupport(viewer); // ��Ϊ��ť�����DZ����صģ����Ա���ȱ�񴴽���ɺ��ʼ������ initializeActionRegistry(); // ֻ������ if (getEditableControl() != null) { // getEditableControl().addEditableUnit(new JresDefaultEditableUnit(viewer.getControl())); } restoreState(getDialogSettings()); viewer.getControl().addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { onDispose(); } }); // ֻ�м����ʱ�򣬿�ݼ�����Ч viewer.getControl().addListener(SWT.Activate, new Listener() { @Override public void handleEvent(Event event) { getProviderSupport().fireProviderActived(); } }); viewer.getControl().addListener(SWT.Deactivate, new Listener() { @Override public void handleEvent(Event event) { getProviderSupport().fireProviderDeactived(); } }); // ����һЩ�Զ���Ŀ�ݼ�����Щ��ݼ�ֻ��Ҫ��Action�ж��岢��ӵ�ActionRegister�м��� viewer.getControl().addKeyListener(new KeyListener() { @Override public void keyReleased(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { // �鿴��ǰAction�Ƿ�����Ҫ�Ŀ�ݼ� for (Iterator<IAction> iterator = getActionRegistry().getActions(); iterator .hasNext();) { IAction action = iterator.next(); if (action.getAccelerator() != 0 && action.getAccelerator() == (e.stateMask | e.keyCode)) { if (action.isEnabled()) { action.run(); return; } } } } }); // װ��������װ�� for (IColumnViewerBlockDecorator<T> d : getDecorators().values()) { d.decorateViewer(this, viewer); } } private IDialogSettings getDialogSettings() { IDialogSettings settings = ARESEditorPlugin.getDefault().getDialogSettings(); IDialogSettings blockSettings = settings.getSection(getID()); if (blockSettings == null) { blockSettings = settings.addNewSection(getID()); } return blockSettings; } /** * ���ؼ����ٵ�ʱ�򴥷� */ protected void onDispose () { ARESEMFClipboard.getInstance().removeClipboardListener(clipboardListener); storeState(getDialogSettings()); } protected void storeState(IDialogSettings settings) { } protected void restoreState(IDialogSettings settings) { } protected void initializeActionRegistry() { createActions(); updateActions(getPropertyActions()); updateActions(getStackActions()); updateActions(getSelectionActions()); updateActions(getClipboardActions()); } protected void createActions() { } /** * @param columnViewer the columnViewer to set */ protected void setColumnViewer(T columnViewer) { if (this.columnViewer != null) { this.columnViewer.removeSelectionChangedListener(this); } this.columnViewer = columnViewer; if (this.columnViewer != null) { this.columnViewer.addSelectionChangedListener(this); } } /** * @return the columnViewer */ public T getColumnViewer() { return columnViewer; } /** * @return the selectionActions */ protected List<String> getSelectionActions() { if (selectionActions == null) { selectionActions = new ArrayList<String>(); } return selectionActions; } /** * @return the stackActions */ protected List<String> getStackActions() { if (stackActions == null) { stackActions = new ArrayList<String>(); } return stackActions; } /** * @return the propertyActions */ protected List<String> getPropertyActions() { if (propertyActions == null) { propertyActions = new ArrayList<String>(); } return propertyActions; } /** * @return the clipboardActions */ protected List<String> getClipboardActions() { if (clipboardActions == null) { clipboardActions = new ArrayList<String>(); } return clipboardActions; } /** * @return the actionRegistry */ public ActionRegistry getActionRegistry() { if (actionRegistry == null) actionRegistry = new ActionRegistry(); return actionRegistry; } protected void updateActions(final List<String> actionIds) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { ActionRegistry registry = getActionRegistry(); Iterator<String> iter = actionIds.iterator(); while (iter.hasNext()) { IAction action = registry.getAction(iter.next()); if (action instanceof IUpdateAction) ((IUpdateAction) action).update(); } } }); } }