/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.ui.views.palette; import java.io.File; import java.util.Properties; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.dnd.DropTargetAdapter; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.FileTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.ui.IActionBars; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuManager; import org.jboss.tools.common.model.XModel; import org.jboss.tools.common.model.XModelException; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.event.ActionDeclinedException; import org.jboss.tools.common.model.event.XModelTreeEvent; import org.jboss.tools.common.model.event.XModelTreeListener; import org.jboss.tools.common.model.util.EclipseResourceUtil; import org.jboss.tools.common.model.util.IconUtil; import org.jboss.tools.common.model.ui.ModelUIPlugin; import org.jboss.tools.common.model.ui.dnd.DnDUtil; import org.jboss.tools.common.model.ui.dnd.ModelTransfer; import org.jboss.tools.common.model.ui.views.palette.model.*; import org.jboss.tools.common.model.ui.util.StringUtilities; public class PaletteAdapter implements IPaletteAdapter { private static final int TEXT_MARGIN = 4; private IPalettePageAdapter viewPart = null; private PaletteModel model = null; private ScrolledComposite pane = null; private PaletteModelListener modelListener = null; private PaletteDescriptionManager descriptionManager = null; private PaletteResizeManager resizeManager = null; private PaletteDropTargetManager dropManager = null; private QualifiedName persistentTabQualifiedName = new QualifiedName("", "Palette_tab"); //$NON-NLS-1$ //$NON-NLS-2$ private String selectedTab = null; private boolean fWindowsFlag; public void setPaletteViewPart(IPalettePageAdapter viewPart) { this.viewPart = viewPart; } public void initActionBars() { IActionBars bars = viewPart.getActionBars(); if(bars != null) { createPaletteTabs(); IMenuManager menuManager = bars.getMenuManager(); bars.getToolBarManager().add(new PaletteEditAction()); bars.getToolBarManager().add(new ShowHideTabsAction()); if (selectedTab != null) { ActionContributionItem item = (ActionContributionItem)menuManager.find(selectedTab); if (item != null) { item.getAction().run(); } } else { IContributionItem[] actions = menuManager.getItems(); if (actions.length > 0 && (actions[0] instanceof ActionContributionItem)) { ((ActionContributionItem)actions[0]).getAction().run(); } } } } public Control createControl(Composite composite) { String osName = System.getProperty("os.name"); //$NON-NLS-1$ fWindowsFlag = osName != null && osName.toUpperCase().indexOf("WINDOWS") != -1; //$NON-NLS-1$ try { selectedTab = ModelUIPlugin.getWorkspace().getRoot().getPersistentProperty(persistentTabQualifiedName); } catch (CoreException e) { ModelUIPlugin.getPluginLog().logError(e); } pane = new ScrolledComposite(composite, SWT.V_SCROLL); pane.setExpandHorizontal(true); pane.setExpandVertical(true); descriptionManager = new PaletteDescriptionManager(); resizeManager = new PaletteResizeManager(); dropManager = new PaletteDropTargetManager(); model = PaletteModel.getInstance(); createPaletteTabs(); // initActionBars(); modelListener = new PaletteModelListener(); model.addModelTreeListener(modelListener); return pane; } private void createPaletteTabs() { IActionBars bars = viewPart.getActionBars(); if(bars == null) return; IMenuManager menuManager = bars.getMenuManager(); IPaletteNode root = model.getRoot(); IPaletteNode[] nodes = root.getChildren(); if (nodes != null) { for (int i = 0; i < nodes.length; i++) { createPaletteTab(nodes[i], menuManager); } } } private void createPaletteTab(IPaletteNode node, IMenuManager manager) { String title = node.getTitle(); Composite tab = new Composite(pane, SWT.NONE); tab.setData(node); RowLayout layout = new RowLayout(SWT.HORIZONTAL); layout.pack = true; layout.justify = false; layout.marginLeft = 0; layout.marginTop = 0; layout.marginRight = 0; layout.marginBottom = 0; layout.spacing = 0; tab.setLayout(layout); IPaletteNode[] elems = node.getChildren(); if (elems != null) { for (int i = 0; i < elems.length; i++) { createPaletteElement(tab, elems[i]); } } manager.add(new PaletteTabAction(tab, title)); } private void createPaletteElement(Composite tab, IPaletteNode node) { ToolBar tlb = new ToolBar(tab, SWT.HORIZONTAL | SWT.FLAT); ToolItem item = new ToolItem(tlb, SWT.PUSH); item.setText(StringUtilities.dottedString(node.getTitle(), IconUtil.PALETTE_IMAGE_WIDTH - TEXT_MARGIN, tlb)); Image image = node.getImage(); if (image != null) { image.setBackground(tlb.getBackground()); image.setBackground(new org.eclipse.swt.graphics.Color(tlb.getDisplay(), 255, 0, 0)); item.setImage(image); if (fWindowsFlag) item.setDisabledImage(image); } item.setData(node); item.addSelectionListener(new PaletteSelectionListener(node)); } public void setEnabled(boolean enabled) { if (!fWindowsFlag) return; Control[] tabs = pane.getChildren(); for (int i = 0; i < tabs.length; i++) { if (tabs[i] instanceof Composite) { Control[] elems = ((Composite)tabs[i]).getChildren(); for (int j = 0; j < elems.length; j++) { if (elems[j] instanceof ToolBar) { ToolBar tlb = (ToolBar)elems[j]; for (int k = 0, c = tlb.getItemCount(); k < c; k++) { tlb.getItem(k).setEnabled(enabled); } } } } } } private void reload(XModelObject xtab) { model.reload(); IActionBars bars = viewPart.getActionBars(); IMenuManager menuManager = bars.getMenuManager(); String oldTitle = null; Control oldTab = pane.getContent(); Control[] oldTabs = pane.getChildren(); IContributionItem[] oldActions = menuManager.getItems(); createPaletteTabs(); for (int i = 0; i < oldActions.length; i++) { if (oldTitle == null && oldTab != null && oldActions[i] instanceof ActionContributionItem) { IAction action = ((ActionContributionItem)oldActions[i]).getAction(); if ((action instanceof PaletteTabAction) && ((PaletteTabAction)action).tab == oldTab) { oldTitle = action.getText(); } } menuManager.remove(oldActions[i]); } IAction newAction = null; IContributionItem[] newActions = menuManager.getItems(); if (xtab != null) { for (int i = 0; i < newActions.length; i++) { if (newActions[i] instanceof ActionContributionItem) { IAction action = ((ActionContributionItem)newActions[i]).getAction(); if ((action instanceof PaletteTabAction) && ((IPaletteNode)((Composite)((PaletteTabAction)action).tab).getData()).getXModelObject() == xtab) { newAction = action; break; } } } } if (newAction == null && oldTitle != null) { for (int i = 0; i < newActions.length; i++) { if (newActions[i] instanceof ActionContributionItem) { IAction action = ((ActionContributionItem)newActions[i]).getAction(); if (oldTitle.equalsIgnoreCase(action.getText())) { newAction = action; break; } } } } if (newAction == null) { if (newActions.length > 0 && (newActions[0] instanceof ActionContributionItem)) { newAction = ((ActionContributionItem)newActions[0]).getAction(); } } if (newAction != null) { newAction.run(); } for (int i = 0; i < oldTabs.length; i++) { oldTabs[i].dispose(); } setEnabled(viewPart.isEnabled()); } public void dispose() { dropManager.dispose(); descriptionManager.dispose(); if(model != null) model.removeModelTreeListener(modelListener); if(viewPart.getActionBars() != null) viewPart.getActionBars().getToolBarManager().removeAll(); try { if (selectedTab != null) { ModelUIPlugin.getWorkspace().getRoot().setPersistentProperty(persistentTabQualifiedName, selectedTab); } } catch (CoreException e) { ModelUIPlugin.getPluginLog().logError(e); } } public void setPaletteContents(PaletteContents contents) { } private class PaletteTabAction extends Action { private Composite tab; public PaletteTabAction(Composite tab, String text) { super(text); this.tab = tab; setId(text); } public Composite getTab() { return tab; } public void run() { if (pane.getContent() != null) { dropManager.dispose(); resizeManager.dispose(); descriptionManager.setEnabled(false); } viewPart.setContentDescription(getText()); pane.setContent(tab); descriptionManager.install(tab); resizeManager.install(tab); dropManager.install(tab); selectedTab = getId(); } } private class PaletteResizeManager extends ControlAdapter { Composite tab = null; public void install(Composite tab) { dispose(); this.tab = tab; resize(); tab.addControlListener(this); } public void dispose() { if (tab != null) { if (!tab.isDisposed()) { tab.removeControlListener(this); } tab = null; } } public void controlResized(ControlEvent event) { resize(); } private void resize() { int width = pane.getClientArea().width; if (width > 0) { int height = tab.computeSize(width, SWT.DEFAULT).y; pane.setMinHeight(height); } } } private class PaletteSelectionListener extends SelectionAdapter { IPaletteNode node; public PaletteSelectionListener(IPaletteNode node) { super(); this.node = node; } public void widgetSelected(SelectionEvent event) { viewPart.insertIntoEditor(((PaletteElement)node).getXModelObject()); } } private class PaletteDropTargetManager extends DropTargetAdapter { private DropTarget target = null; public void install(Composite tab) { dispose(); Transfer[] types = new Transfer[]{ ModelTransfer.getInstance(), FileTransfer.getInstance() }; target = new DropTarget(tab, DND.DROP_MOVE | DND.DROP_COPY); target.setTransfer(types); target.addDropListener(this); } public void dispose() { if (target != null) { if(!target.isDisposed()) { target.removeDropListener(this); target.dispose(); } target = null; } } public void dragOver(DropTargetEvent event) { XModelObject o = null; if(FileTransfer.getInstance().isSupportedType(event.currentDataType)) { File f = getFile(event); if(f != null) { IFile ef = EclipseResourceUtil.getFile(f.getAbsolutePath()); o = (ef == null) ? null : EclipseResourceUtil.getObjectByResource(ef); } } else if (event.currentDataType.type != ModelTransfer.MODEL_ID) { o = null; } else { o = getModelObject(event.x, event.y); } boolean enabled = o != null && DnDUtil.isPasteEnabled(o); event.detail = enabled ? DND.DROP_COPY : DND.DROP_NONE; } public void drop(DropTargetEvent event) { XModelObject o = null; if(FileTransfer.getInstance().isSupportedType(event.currentDataType)) { File f = getFile(event); if(f != null) { IFile ef = EclipseResourceUtil.getFile(f.getAbsolutePath()); o = (ef == null) ? null : EclipseResourceUtil.getObjectByResource(ef); } } else if(event.currentDataType.type != ModelTransfer.MODEL_ID) { o = null; } else { o = getModelObject(event.x, event.y); } if(o != null) { try { DnDUtil.paste(o, new Properties()); model.getXModel().saveOptions(); } catch (ActionDeclinedException ade) { //ignore - this exception is thrown to inform that user //selected cancel option in dialog. } catch (XModelException e) { message(e); } } else { event.detail = DND.DROP_NONE; } } private XModelObject getModelObject(int x, int y) { IPaletteNode node = null; Composite tab = (Composite)target.getControl(); Control[] controls = tab.getChildren(); for (int i = 0; i < controls.length; i++) { if (controls[i] instanceof ToolBar) { Rectangle area = controls[i].getBounds(); if (area.contains(x, y)) { ToolItem item = ((ToolBar)controls[i]).getItem(new Point(x - area.x, y - area.y)); if (item != null) { node = (IPaletteNode)item.getData(); } break; } } } if (node == null) { node = (IPaletteNode)tab.getData(); } return node.getXModelObject(); } private void message(Exception e) { ModelUIPlugin.getPluginLog().logError( e); } private File getFile(DropTargetEvent event) { String[] s = (String[])event.data; return(s == null || s.length == 0) ? null : new File(s[0]); } } private class PaletteModelListener implements XModelTreeListener { private boolean isTransaction = false; private boolean isDirty = false; private XModelObject lastAddedTab = null; public void nodeChanged(XModelTreeEvent event) { run(event); } public void structureChanged(XModelTreeEvent event) { run(event); } private void run(XModelTreeEvent event) { if("transaction_begin".equals(event.getInfo())) { //$NON-NLS-1$ isTransaction = true; return; } if("transaction_end".equals(event.getInfo())) { //$NON-NLS-1$ isTransaction = false; if(isDirty) { isDirty = false; reload(lastAddedTab); lastAddedTab = null; } return; } XModel xmodel = model.getXModel(); XModelObject exo = event.getModelObject(); boolean q = event.kind() == XModelTreeEvent.STRUCTURE_CHANGED && xmodel.getRoot().getPath().equals(exo.getPath()); XModelObject xroot = xmodel.getRoot("Palette"); //$NON-NLS-1$ if (xroot == null || isExist(xroot, event.getModelObject()) || q) { if (event.kind() == XModelTreeEvent.CHILD_ADDED && xroot != null && xroot.getPath().equals(exo.getPath())) { Object info = event.getInfo(); if (info instanceof XModelObject) { lastAddedTab = (XModelObject)info; } } if(isTransaction) { isDirty = true; } else { reload(lastAddedTab); lastAddedTab = null; } } } private boolean isExist(XModelObject root, XModelObject modelObject) { if (root == null || modelObject==null) { return false; } if (modelObject.getPath() == null || root.getPath() == null) { return false; } return (modelObject.getPath() + "/").startsWith(root.getPath() + "/"); //$NON-NLS-1$ //$NON-NLS-2$ } } private class PaletteEditAction extends Action { public PaletteEditAction() { super("Palette Editor", model.createImageDescriptor("palette_editor.gif")); //$NON-NLS-2$ setToolTipText("Palette Editor"); } public void run() { model.openEditor(pane.getShell()); } } private class ShowHideTabsAction extends Action { public ShowHideTabsAction() { super("Show/Hide tabs", model.createImageDescriptor("show-hide.gif")); //$NON-NLS-2$ setToolTipText("Show/Hide"); } public void run() { model.runShowHideDialog(); } } }