package org.xmind.ui.internal.resourcemanager; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.MenuDetectEvent; import org.eclipse.swt.events.MenuDetectListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; 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.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.Section; import org.xmind.core.marker.IMarker; import org.xmind.core.marker.IMarkerGroup; import org.xmind.core.marker.IMarkerSheet; import org.xmind.gef.EditDomain; import org.xmind.gef.GEF; import org.xmind.gef.util.Properties; import org.xmind.ui.gallery.FramePart; import org.xmind.ui.gallery.GallerySelectTool; import org.xmind.ui.gallery.GalleryViewer; import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.internal.utils.ResourceUtils; import org.xmind.ui.mindmap.IResourceManager; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.texteditor.FloatingTextEditor; import org.xmind.ui.texteditor.IFloatingTextEditorListener; import org.xmind.ui.texteditor.TextEvent; import org.xmind.ui.util.MarkerImageDescriptor; import org.xmind.ui.viewers.IToolTipProvider; public class MarkerResourceManagerViewer extends ResourceManagerViewer { private static final int FRAME_HEIGHT = 32; private static final int FRAME_WIDTH = 32; private static final int RENAME_COMPOSITE_HEIGHT = 20; private static final int RENAME_COMPOSITE_WIDTH = 80; private FloatingTextEditor lastEditor; private static class MarkerCategorizedContentProvider implements ITreeContentProvider { public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @SuppressWarnings("unchecked") public Object[] getElements(Object inputElement) { if (inputElement instanceof List<?>) return ((List<IMarkerGroup>) inputElement).toArray(); else return null; } @SuppressWarnings("unchecked") public Object[] getChildren(Object parentElement) { if (parentElement instanceof List<?>) return ((List<IMarkerGroup>) parentElement).toArray(); else if (parentElement instanceof IMarkerGroup) { List<IMarker> markers = new ArrayList<IMarker>(); for (IMarker marker : ((IMarkerGroup) parentElement) .getMarkers()) if (!marker.isHidden()) markers.add(marker); return markers.toArray(); } else return null; } public Object getParent(Object element) { if (element instanceof IMarker) { IMarker marker = (IMarker) element; return marker.getParent(); } return null; } public boolean hasChildren(Object element) { return element instanceof IMarkerGroup || element instanceof List<?>; } } private class MarkerCategorizedLabelProvider extends CategorizedLabelProvider implements IToolTipProvider { @Override public String getText(Object element) { if (element instanceof IMarker) return ((IMarker) element).getName(); else if (element instanceof IMarkerGroup) return ((IMarkerGroup) element).getName(); else return super.getText(element); } @Override public Image getImage(Object element) { if (element instanceof IMarker) { IMarker marker = (IMarker) element; Image image = null; Dimension size = (Dimension) getProperties() .get(GalleryViewer.FrameContentSize); if (size == null) size = new Dimension(64, 64); ImageDescriptor imageDescriptor = MarkerImageDescriptor .createFromMarker(marker, size.width, size.height, false); image = getResourceManager().createImage(imageDescriptor); if (image != null) return image; } return super.getImage(element); } public String getToolTip(Object element) { if (element instanceof IMarker) { return getText((IMarker) element); } return ""; //$NON-NLS-1$ } } private Section activeSectionForSectionMenu; private IMarkerGroup activeMarkerGroupForSectionMenu; @Override public void createControl(Composite container) { super.createControl(container); setContentProvider(new MarkerCategorizedContentProvider()); setLabelProvider(new MarkerCategorizedLabelProvider()); EditDomain domain = new EditDomain(); domain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); setEditDomain(domain); initProperties(); createControl(container, SWT.WRAP); getControl() .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); setInput(getMarkerGroups()); } @Override protected void initNestedGalleryViewer(GalleryViewer galleryViewerer) { super.initNestedGalleryViewer(galleryViewerer); Properties properties = galleryViewerer.getProperties(); properties.set(GalleryViewer.HideTitle, Boolean.TRUE); } @Override protected void initProperties() { super.initProperties(); Properties properties = getProperties(); properties.set(GalleryViewer.FrameContentSize, new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); } @Override protected void configureSection(final Section section, final Object category) { super.configureSection(section, category); if (category instanceof IMarkerGroup) { final IMarkerGroup group = (IMarkerGroup) category; try { Field field = ExpandableComposite.class .getDeclaredField("textLabel"); //$NON-NLS-1$ field.setAccessible(true); Object textLabel = field.get(section); if (textLabel instanceof Control) { ((Control) textLabel) .addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { activeMarkerGroupForSectionMenu = null; activeSectionForSectionMenu = null; IStructuredSelection ss = getStructuredSelection(); if (ss != null && ss.isEmpty()) { activeSectionForSectionMenu = section; activeMarkerGroupForSectionMenu = group; } } }); } } catch (NoSuchFieldException e1) { e1.printStackTrace(); } catch (SecurityException e1) { e1.printStackTrace(); } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } getNestedViewer(category).getControl() .addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { activeMarkerGroupForSectionMenu = null; activeSectionForSectionMenu = null; } }); section.addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { activeMarkerGroupForSectionMenu = null; activeSectionForSectionMenu = null; IStructuredSelection ss = getStructuredSelection(); if (ss != null && ss.isEmpty()) { activeSectionForSectionMenu = section; activeMarkerGroupForSectionMenu = group; } } }); IMarkerSheet userSheet = MindMapUI.getResourceManager() .getUserMarkerSheet(); if (!userSheet.getMarkerGroups().contains(group)) return; createSectionTextClient(section, MindMapMessages.MarkerResourceManagerViewer_AddSection_title, category); } } private List<IMarkerGroup> getMarkerGroups() { ArrayList<IMarkerGroup> mgs = new ArrayList<IMarkerGroup>(); IResourceManager resourceManager = MindMapUI.getResourceManager(); IMarkerSheet userSheet = resourceManager.getUserMarkerSheet(); IMarkerSheet sysSheet = resourceManager.getSystemMarkerSheet(); for (IMarkerGroup group : sysSheet.getMarkerGroups()) { if (!group.isHidden()) mgs.add(group); } for (IMarkerGroup group : userSheet.getMarkerGroups()) { if (!group.isHidden()) mgs.add(group); } return mgs; } public boolean canEditMarkerGroup() { if (activeMarkerGroupForSectionMenu == null || activeSectionForSectionMenu == null || activeSectionForSectionMenu.isDisposed()) { return false; } IMarkerSheet userSheet = MindMapUI.getResourceManager() .getUserMarkerSheet(); if (!userSheet.getMarkerGroups() .contains(activeMarkerGroupForSectionMenu)) return false; IStructuredSelection ss = getStructuredSelection(); if (ss != null && !ss.isEmpty()) return false; return true; } public void renameMarkerGroup() { if (activeMarkerGroupForSectionMenu == null || activeSectionForSectionMenu == null || activeSectionForSectionMenu.isDisposed()) { activeMarkerGroupForSectionMenu = null; activeSectionForSectionMenu = null; return; } final IMarkerGroup markerGroup = activeMarkerGroupForSectionMenu; final Section section = activeSectionForSectionMenu; activeMarkerGroupForSectionMenu = null; activeSectionForSectionMenu = null; Rectangle textLabelBounds = null; final String groupName = markerGroup.getName(); for (Control control : section.getChildren()) if (control instanceof Label && groupName.equals(((Label) control).getText())) textLabelBounds = control.getBounds(); if (lastEditor != null) { lastEditor.close(); lastEditor = null; } final FloatingTextEditor editor = new FloatingTextEditor(section); if (textLabelBounds != null) { section.setText(""); //$NON-NLS-1$ int x = textLabelBounds.x - 2; int y = textLabelBounds.y - 2; editor.setInitialLocation(new Point(x, y)); editor.setInitialSize(new Point(100, 18)); } else { editor.setInitialLocation(new Point(100, 0)); editor.setInitialSize(new Point(100, 18)); } editor.setInput(new Document(groupName)); editor.open(); editor.doOperation(FloatingTextEditor.SELECT_ALL); editor.addFloatingTextEditorListener( new IFloatingTextEditorListener.Stub() { @Override public void editingFinished(TextEvent e) { String text = e.text; if (null == text || "".equals(text) //$NON-NLS-1$ || text.equals(groupName)) { section.setText(groupName); editor.close(); } else markerGroup.setName(text); MindMapUI.getResourceManager().saveUserMarkerSheet(); } @Override public void editingCanceled(TextEvent e) { refresh(); } }); final Listener listener = new Listener() { @Override public void handleEvent(Event event) { if (editor != null && !editor.isClosed()) { if (!editor.getControl().getBounds().contains(event.x, event.y)) editor.close(true); } } }; Display.getCurrent().addFilter(SWT.MouseDown, listener); editor.getControl().addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { if (listener != null) Display.getCurrent().removeFilter(SWT.MouseDown, listener); } }); lastEditor = editor; ITextViewer textViewer = editor.getTextViewer(); textViewer.getTextWidget().setBackground( getResourceManager().createColor(new RGB(255, 255, 255))); textViewer.getTextWidget().setForeground( getResourceManager().createColor(new RGB(0, 0, 0))); } @Override protected void handleClickSectionTextClient(Object category) { if (category instanceof IMarkerGroup) { List<IMarker> newMarkers = ResourceUtils .addMarkersFor((IMarkerGroup) category); refresh(); reveal(category); setSelection(new StructuredSelection(newMarkers), true); MindMapUI.getResourceManager().saveUserMarkerSheet(); } } public void startEditing(IMarker marker) { List<IMarkerGroup> markerGroups = getMarkerGroups(); for (IMarkerGroup markerGroup : markerGroups) { List<IMarker> styles = markerGroup.getMarkers(); if (styles.contains(marker)) { GalleryViewer galleryViewer = getNestedViewer(markerGroup); FramePart part = (FramePart) galleryViewer .findGraphicalPart(marker); renameMarker((Composite) galleryViewer.getControl(), marker, part.getFigure().getBounds()); break; } } } private void renameMarker(Composite composite, final IMarker marker, org.eclipse.draw2d.geometry.Rectangle bounds) { int x = bounds.x + (bounds.width - RENAME_COMPOSITE_WIDTH) / 2; int y = bounds.y + (bounds.height - RENAME_COMPOSITE_HEIGHT) / 2; final FloatingTextEditor editor = new FloatingTextEditor(composite); editor.setInitialLocation(new Point(x, y)); editor.setInitialSize( new Point(RENAME_COMPOSITE_WIDTH, RENAME_COMPOSITE_HEIGHT)); editor.setInput(new Document(marker.getName())); editor.open(); editor.doOperation(FloatingTextEditor.SELECT_ALL); editor.addFloatingTextEditorListener( new IFloatingTextEditorListener.Stub() { public void editingFinished(TextEvent e) { String text = e.text; if (null != text && !("".equals(text))) //$NON-NLS-1$ marker.setName(text); } }); } public void updateInput() { setInput(getMarkerGroups()); } public void deleteMarkerGroup() { IMarkerSheet markerSheet = MindMapUI.getResourceManager() .getUserMarkerSheet(); markerSheet.removeMarkerGroup(activeMarkerGroupForSectionMenu); try { MindMapUI.getResourceManager().saveUserMarkerSheet(); } catch (Exception e) { // TODO: handle exception } updateInput(); } public void activateGroup(IMarkerGroup markerGroup) { activeMarkerGroupForSectionMenu = markerGroup; activeSectionForSectionMenu = (Section) getSection(markerGroup); } }