/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.gef.ui.editor;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
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.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IEditorActionBarContributor;
import org.xmind.gef.Disposable;
import org.xmind.gef.EditDomain;
import org.xmind.gef.IGraphicalViewer;
import org.xmind.gef.IViewer;
import org.xmind.gef.ui.actions.ActionRegistry;
import org.xmind.gef.ui.actions.IActionRegistry;
import org.xmind.gef.ui.actions.ISelectionAction;
/**
* @author Brian Sun
*/
public abstract class GraphicalEditorPage extends Disposable
implements IGraphicalEditorPage, ISelectionChangedListener {
private IGraphicalEditor parent = null;
private Object input = null;
private Control control = null;
private EditDomain domain = null;
private IGraphicalViewer viewer = null;
private MenuManager contentPopupMenu = null;
private boolean active = false;
private IActionRegistry actionRegistry = null;
private List<ISelectionAction> selectionActions = null;
private IPanelContributor panelContributor = null;
protected void setPanelContributor(IPanelContributor contributor) {
this.panelContributor = contributor;
}
public IPanelContributor getPanelContributor() {
return panelContributor;
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getIndex()
*/
public int getIndex() {
return parent.findPage(this);
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getPageTitle()
*/
public String getPageTitle() {
return parent.getPageText(getIndex());
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getParentEditor()
*/
public IGraphicalEditor getParentEditor() {
return parent;
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#getSelectionProvider()
*/
public ISelectionProvider getSelectionProvider() {
return viewer;
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#init(org.xmind.gef.ui.editor.GraphicalEditor,
* java.lang.Object)
*/
public void init(IGraphicalEditor parent, Object input) {
this.parent = parent;
this.input = input;
if (input != null) {
installModelListeners(input);
}
IActionRegistry parentActionRegistry = (IActionRegistry) parent
.getAdapter(IActionRegistry.class);
if (parentActionRegistry != null) {
this.actionRegistry = new ActionRegistry(parentActionRegistry);
} else {
this.actionRegistry = new ActionRegistry();
}
initPageActions(getActionRegistry());
}
protected void installModelListeners(Object input) {
}
protected void uninstallModelListeners(Object input) {
}
public Object getInput() {
return input;
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#isActive()
*/
public boolean isActive() {
return active;
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setActive(boolean)
*/
public void setActive(boolean active) {
this.active = active;
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setIndex(int)
*/
public void setIndex(int index) {
parent.movePageTo(getIndex(), index);
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setPageTitle(java.lang.String)
*/
public void setPageTitle(String title) {
parent.setPageText(getIndex(), title);
}
public EditDomain getEditDomain() {
return domain;
}
public void setEditDomain(EditDomain domain) {
// if (this.domain != null && getViewer() != null) {
// this.domain.setViewer(null);
// }
this.domain = domain;
if (getViewer() != null) {
getViewer().setEditDomain(getEditDomain());
}
// if (domain != null && getViewer() != null) {
// domain.setViewer(getViewer());
// }
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#createPageControl(org.eclipse.swt.widgets.Composite)
*/
public void createPageControl(Composite parent) {
Panel panel = null;
if (panelContributor != null) {
panel = new Panel();
panelContributor.init(panel, this);
if (panel.isEmpty()) {
panel = null;
}
}
Composite container;
if (panel == null) {
container = parent;
} else {
panel.createControls(parent);
container = panel.getContainer();
}
viewer = createViewer();
initViewer(viewer);
createViewerControl(viewer, container);
createContentPopupMenu(viewer.getControl());
if (panel != null) {
panel.setContent(viewer.getControl());
panel.update();
}
hookViewer(viewer);
configureViewer(viewer);
updateSelectionActions(viewer.getSelection());
if (panelContributor != null) {
panelContributor.setViewer(viewer);
}
if (panel != null) {
control = panel.getContainer();
} else {
control = viewer.getControl();
}
}
/**
* @param parent
* @return
*/
protected abstract IGraphicalViewer createViewer();
protected abstract void createViewerControl(IGraphicalViewer viewer,
Composite parent);
public Control getControl() {
return control;
}
protected void createContentPopupMenu(Control control) {
if (contentPopupMenu == null) {
contentPopupMenu = createContentPopupMenu();
String menuId = getParentEditor().getSite().getId() + ".content"; //$NON-NLS-1$
initContentPopupMenu(contentPopupMenu);
registerContentPopupMenu(menuId, contentPopupMenu);
}
control.setMenu(contentPopupMenu.createContextMenu(control));
}
protected void registerContentPopupMenu(String menuId, MenuManager menu) {
getParentEditor().getSite().registerContextMenu(menuId, menu,
getSelectionProvider());
}
protected MenuManager createContentPopupMenu() {
return new MenuManager();
}
protected void initContentPopupMenu(MenuManager menu) {
if (isContentPopupMenuDynamic()) {
menu.setRemoveAllWhenShown(true);
menu.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
contributeToContentPopupMenu(manager);
}
});
} else {
contributeToContentPopupMenu(menu);
}
}
protected boolean isContentPopupMenuDynamic() {
return true;
}
protected void contributeToContentPopupMenu(IMenuManager menu) {
IEditorActionBarContributor contributor = getParentEditor()
.getEditorSite().getActionBarContributor();
if (contributor instanceof GraphicalEditorActionBarContributor) {
((GraphicalEditorActionBarContributor) contributor)
.contributeToContentPopupMenu(menu);
}
}
protected void initPageActions(IActionRegistry actionRegistry) {
}
protected void initViewer(IGraphicalViewer viewer) {
if (getEditDomain() != null) {
viewer.setEditDomain(getEditDomain());
}
viewer.getProperties().set(VIEWER_EDITOR_PAGE, this);
}
protected void configureViewer(IGraphicalViewer viewer) {
viewer.setInput(createViewerInput());
}
protected Object createViewerInput() {
return getInput();
}
protected void hookViewer(IGraphicalViewer viewer) {
viewer.addSelectionChangedListener(this);
}
protected void unhookViewer(IGraphicalViewer viewer) {
viewer.removeSelectionChangedListener(this);
}
/**
* @see org.xmind.gef.ui.editor.IGraphicalEditorPage#setFocus()
*/
public void setFocus() {
if (viewer == null)
return;
Control focusControl = viewer.getControl();
if (focusControl != null && !focusControl.isDisposed()) {
focusControl.setFocus();
}
}
public boolean isFocused() {
return hasFocusControl(getControl());
}
private boolean hasFocusControl(Control c) {
if (c == null || c.isDisposed())
return false;
if (c.isFocusControl())
return true;
if (c instanceof Composite) {
for (Control child : ((Composite) c).getChildren()) {
if (hasFocusControl(child))
return true;
}
}
return true;
}
public IGraphicalViewer getViewer() {
return viewer;
}
@SuppressWarnings("unchecked")
public Object getAdapter(Class adapter) {
if (adapter == IActionRegistry.class)
return getActionRegistry();
if (adapter == IGraphicalViewer.class || adapter == IViewer.class)
return getViewer();
if (adapter == EditDomain.class)
return getEditDomain();
return null;
}
protected IActionRegistry getActionRegistry() {
if (actionRegistry == null)
actionRegistry = new ActionRegistry();
return actionRegistry;
}
protected void addSelectionAction(ISelectionAction action) {
if (selectionActions == null)
selectionActions = new ArrayList<ISelectionAction>();
selectionActions.add(action);
}
public void selectionChanged(SelectionChangedEvent event) {
updateSelectionActions(event.getSelection());
}
protected void updateSelectionActions(ISelection selection) {
if (selectionActions != null) {
for (ISelectionAction action : selectionActions) {
action.setSelection(selection);
}
}
}
/**
* @see org.xmind.util.Disposable#clear()
*/
@Override
public void dispose() {
if (panelContributor != null) {
panelContributor.dispose();
}
if (selectionActions != null) {
for (ISelectionAction action : selectionActions) {
action.setSelection(null);
}
selectionActions = null;
}
if (actionRegistry != null) {
actionRegistry.dispose();
actionRegistry = null;
}
if (getInput() != null) {
uninstallModelListeners(getInput());
}
if (contentPopupMenu != null) {
contentPopupMenu.dispose();
contentPopupMenu = null;
}
if (viewer != null) {
unhookViewer(viewer);
// if (domain != null) {
// domain.setViewer(null);
// domain.dispose();
// }
if (viewer.getControl() != null
&& !viewer.getControl().isDisposed()) {
viewer.getControl().dispose();
}
// viewer = null;
}
super.dispose();
}
}