/* ****************************************************************************** * 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.ui.internal.prefs; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; 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.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.PlatformUI; import org.xmind.core.Core; import org.xmind.core.marker.IMarker; import org.xmind.core.marker.IMarkerGroup; import org.xmind.core.marker.IMarkerResource; import org.xmind.core.marker.IMarkerSheet; import org.xmind.core.util.FileUtils; import org.xmind.ui.internal.dialogs.DialogUtils; import org.xmind.ui.internal.wizards.MarkerExportWizard; import org.xmind.ui.internal.wizards.MarkerGroupContentProvider; import org.xmind.ui.internal.wizards.MarkerGroupLabelProvider; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.util.Logger; public class MarkerManagerPrefPage extends PreferencePage implements IWorkbenchPreferencePage, Listener { public static final String ID = "org.xmind.ui.MarkersPrefPage"; //$NON-NLS-1$ private TableViewer groupViewer; private TableViewer markerViewer; private Button addGroupButton; private Button removeGroupButton; private Button renameGroupButton; private Button exportGroupButton; private Button addMarkerButton; private Button removeMarkerButton; private Button renameMarkerButton; public MarkerManagerPrefPage() { super(PrefMessages.MarkersPage_title); } protected Control createContents(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 5; gridLayout.marginHeight = 5; gridLayout.verticalSpacing = 20; gridLayout.horizontalSpacing = 0; composite.setLayout(gridLayout); createGroupGroup(composite); createMarkerGroup(composite); parent.getDisplay().asyncExec(new Runnable() { public void run() { IMarkerSheet sheet = getSheet(); groupViewer.setInput(sheet); List<IMarkerGroup> groups = sheet.getMarkerGroups(); if (!groups.isEmpty()) { groupViewer.setSelection( new StructuredSelection(groups.get(0))); } refreshButtons(); } }); return composite; } private void createGroupGroup(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.verticalSpacing = 5; gridLayout.horizontalSpacing = 5; composite.setLayout(gridLayout); Label label = new Label(composite, SWT.NONE); label.setLayoutData( new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); label.setText(PrefMessages.MarkersPage_Groups_label); Composite groupContainer = new Composite(composite, SWT.NONE); groupContainer .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout gridLayout2 = new GridLayout(2, false); gridLayout2.marginWidth = 0; gridLayout2.marginHeight = 0; gridLayout2.verticalSpacing = 5; gridLayout2.horizontalSpacing = 5; groupContainer.setLayout(gridLayout2); createGroupViewer(groupContainer); createGroupControls(groupContainer); } private void createGroupViewer(Composite parent) { groupViewer = new TableViewer(parent, SWT.BORDER | SWT.SINGLE); groupViewer.getTable().setLinesVisible(true); groupViewer.setContentProvider(new MarkerGroupContentProvider()); final MarkerGroupLabelProvider labelProvider = new MarkerGroupLabelProvider(); groupViewer.setLabelProvider(labelProvider); groupViewer.getControl() .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); groupViewer .addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { markerViewer.setInput( ((IStructuredSelection) event.getSelection()) .getFirstElement()); refreshButtons(); } }); groupViewer.setColumnProperties(new String[] { "NAME" }); //$NON-NLS-1$ groupViewer.setCellEditors(new CellEditor[] { new TextCellEditor(groupViewer.getTable(), SWT.SINGLE) }); groupViewer.setCellModifier(new ICellModifier() { public void modify(Object element, String property, Object value) { if (element instanceof Widget) { element = ((Widget) element).getData(); } if (element instanceof IMarkerGroup) { changeGroupName((IMarkerGroup) element, value.toString()); } } public Object getValue(Object element, String property) { return labelProvider.getText(element); } public boolean canModify(Object element, String property) { return true; } }); groupViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { renameGroup(); } }); } private void createGroupControls(Composite parent) { Composite outer = new Composite(parent, SWT.NONE); outer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); GridLayout gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.verticalSpacing = 0; gridLayout.horizontalSpacing = 0; outer.setLayout(gridLayout); Composite inner = new Composite(outer, SWT.NONE); inner.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); GridLayout gridLayout2 = new GridLayout(1, false); gridLayout2.marginWidth = 0; gridLayout2.marginHeight = 0; gridLayout2.verticalSpacing = 5; gridLayout2.horizontalSpacing = 0; inner.setLayout(gridLayout2); addGroupButton = new Button(inner, SWT.PUSH); addGroupButton.setText(PrefMessages.MarkersPage_AddGroup_text); addGroupButton .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); hookWidget(addGroupButton, SWT.Selection); removeGroupButton = new Button(inner, SWT.PUSH); removeGroupButton.setText(PrefMessages.MarkersPage_RemoveGroup_text); removeGroupButton .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); hookWidget(removeGroupButton, SWT.Selection); renameGroupButton = new Button(inner, SWT.PUSH); renameGroupButton.setText(PrefMessages.MarkersPage_RenameGroup_text); renameGroupButton .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); hookWidget(renameGroupButton, SWT.Selection); exportGroupButton = new Button(inner, SWT.PUSH); exportGroupButton.setText(PrefMessages.MarkersPage_ExportGroup_text); exportGroupButton .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); hookWidget(exportGroupButton, SWT.Selection); } private void createMarkerGroup(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.verticalSpacing = 5; gridLayout.horizontalSpacing = 5; composite.setLayout(gridLayout); Label label = new Label(composite, SWT.NONE); label.setLayoutData( new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); label.setText(PrefMessages.MarkersPage_Markers_label); Composite markerContainer = new Composite(composite, SWT.NONE); markerContainer .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout gridLayout2 = new GridLayout(2, false); gridLayout2.marginWidth = 0; gridLayout2.marginHeight = 0; gridLayout2.verticalSpacing = 5; gridLayout2.horizontalSpacing = 5; markerContainer.setLayout(gridLayout2); createMarkerViewer(markerContainer); createMarkerControls(markerContainer); } /** * @param markerContainer */ private void createMarkerViewer(Composite parent) { markerViewer = new TableViewer(parent, SWT.SINGLE | SWT.BORDER); markerViewer.setContentProvider(new MarkerGroupContentProvider()); final MarkerGroupLabelProvider labelProvider = new MarkerGroupLabelProvider(); markerViewer.setLabelProvider(labelProvider); markerViewer.getControl() .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); markerViewer .addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { refreshButtons(); } }); markerViewer.setColumnProperties(new String[] { "NAME" }); //$NON-NLS-1$ markerViewer.setCellEditors(new CellEditor[] { new TextCellEditor(markerViewer.getTable(), SWT.SINGLE) }); markerViewer.setCellModifier(new ICellModifier() { public void modify(Object element, String property, Object value) { if (element instanceof Widget) { element = ((Widget) element).getData(); } if (element instanceof IMarker) { changeMarkerName((IMarker) element, value.toString()); } } public Object getValue(Object element, String property) { return labelProvider.getText(element); } public boolean canModify(Object element, String property) { return true; } }); markerViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { renameMarker(); } }); } /** * @param markerContainer */ private void createMarkerControls(Composite parent) { Composite outer = new Composite(parent, SWT.NONE); outer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); GridLayout gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.verticalSpacing = 0; gridLayout.horizontalSpacing = 0; outer.setLayout(gridLayout); Composite inner = new Composite(outer, SWT.NONE); inner.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); GridLayout gridLayout2 = new GridLayout(1, false); gridLayout2.marginWidth = 0; gridLayout2.marginHeight = 0; gridLayout2.verticalSpacing = 5; gridLayout2.horizontalSpacing = 0; inner.setLayout(gridLayout2); addMarkerButton = new Button(inner, SWT.PUSH); addMarkerButton.setText(PrefMessages.MarkersPage_AddMarker_text); addMarkerButton .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); hookWidget(addMarkerButton, SWT.Selection); removeMarkerButton = new Button(inner, SWT.PUSH); removeMarkerButton.setText(PrefMessages.MarkersPage_RemoveMarker_text); removeMarkerButton .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); hookWidget(removeMarkerButton, SWT.Selection); renameMarkerButton = new Button(inner, SWT.PUSH); renameMarkerButton.setText(PrefMessages.MarkersPage_RenameMarker_text); renameMarkerButton .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); hookWidget(renameMarkerButton, SWT.Selection); } private void hookWidget(Widget widget, int eventType) { widget.addListener(eventType, this); } /* * (non-Javadoc) * * @see org.eclipse.jface.preference.PreferencePage#performOk() */ public boolean performOk() { saveSheet(); return super.performOk(); } public void init(IWorkbench workbench) { } /* * (non-Javadoc) * * @see * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets. * Event) */ public void handleEvent(Event event) { if (event.widget == addGroupButton) { addGroup(); } else if (event.widget == removeGroupButton) { removeGroup(); } else if (event.widget == renameGroupButton) { renameGroup(); } else if (event.widget == exportGroupButton) { exportGroup(); } else if (event.widget == addMarkerButton) { addMarker(); } else if (event.widget == removeMarkerButton) { removeMarker(); } else if (event.widget == renameMarkerButton) { renameMarker(); } } /** * */ private void addGroup() { String name = createGroupName(); IMarkerGroup group = getSheet().createMarkerGroup(false); group.setName(name); getSheet().addMarkerGroup(group); groupViewer.refresh(); groupViewer.setSelection(new StructuredSelection(group), true); groupViewer.editElement(group, 0); } private String createGroupName() { int index = getSheet().getMarkerGroups().size() + 1; String name = NLS.bind(PrefMessages.MarkersPage_DefaultGroupName, index); while (isNameExisting(name)) { index++; name = NLS.bind(PrefMessages.MarkersPage_DefaultGroupName, index); } return name; } private boolean isNameExisting(String name) { for (IMarkerGroup group : getSheet().getMarkerGroups()) { if (name.equals(group.getName())) return true; } return false; } /** * */ private void removeGroup() { IStructuredSelection selection = (IStructuredSelection) groupViewer .getSelection(); if (selection.isEmpty()) return; List<IMarkerGroup> markerGroups = ((IMarkerSheet) groupViewer .getInput()).getMarkerGroups(); int index = markerGroups.indexOf(selection.getFirstElement()); IMarkerSheet sheet = getSheet(); for (Object group : selection.toList()) { List<IMarker> markers = ((IMarkerGroup) group).getMarkers(); for (IMarker marker : markers) { if (MindMapUI.getResourceManager().getRecentMarkerGroup() .getMarker(marker.getId()) != null) MindMapUI.getResourceManager().getRecentMarkerGroup() .removeMarker(marker); removeMarkerFile(marker); } sheet.removeMarkerGroup((IMarkerGroup) group); } groupViewer.refresh(); //select the next one markerGroups = ((IMarkerSheet) groupViewer.getInput()) .getMarkerGroups(); if (index >= markerGroups.size()) { index = markerGroups.size() - 1; } if (index >= 0) { if (!markerGroups.isEmpty()) { groupViewer.setSelection( new StructuredSelection(markerGroups.get(index))); } } } /** * */ private void renameGroup() { IStructuredSelection selection = (IStructuredSelection) groupViewer .getSelection(); if (selection.isEmpty()) return; groupViewer.editElement(selection.getFirstElement(), 0); } private void exportGroup() { MarkerExportWizard wizard = new MarkerExportWizard(); wizard.init(PlatformUI.getWorkbench(), null); WizardDialog dialog = new WizardDialog(getShell(), wizard); dialog.create(); dialog.open(); } /** * */ private void addMarker() { IStructuredSelection groupSelection = (IStructuredSelection) groupViewer .getSelection(); if (groupSelection.isEmpty()) return; IMarkerGroup targetGroup = (IMarkerGroup) groupSelection .getFirstElement(); String[] sourcePaths = selectImageFile(); if (sourcePaths == null) return; List<IMarker> newMarkers = new ArrayList<IMarker>(sourcePaths.length); for (String sourcePath : sourcePaths) { if (imageValid(sourcePath)) { String path = Core.getIdFactory().createId() + FileUtils.getExtension(sourcePath); IMarker marker = getSheet().createMarker(path); marker.setName(FileUtils.getFileName(sourcePath)); IMarkerResource resource = marker.getResource(); if (resource != null) { OutputStream os = resource.getOutputStream(); if (os != null) { try { FileInputStream is = new FileInputStream( sourcePath); FileUtils.transfer(is, os, true); } catch (IOException e) { Logger.log(e); } } } targetGroup.addMarker(marker); newMarkers.add(marker); } } markerViewer.refresh(); markerViewer.setSelection(new StructuredSelection(newMarkers), true); } private boolean imageValid(String sourcePath) { try { new Image(Display.getCurrent(), sourcePath).dispose(); return true; } catch (Throwable e) { } return false; } /** * @return */ private String[] selectImageFile() { FileDialog dialog = new FileDialog(getShell(), SWT.OPEN | SWT.MULTI); DialogUtils.makeDefaultImageSelectorDialog(dialog, true); String open = dialog.open(); if (open == null) return null; String parent = dialog.getFilterPath(); String[] fileNames = dialog.getFileNames(); String[] paths = new String[fileNames.length]; for (int i = 0; i < fileNames.length; i++) { paths[i] = new File(parent, fileNames[i]).getAbsolutePath(); } return paths; } /** * */ private void removeMarker() { IStructuredSelection selection = (IStructuredSelection) markerViewer .getSelection(); if (selection.isEmpty()) return; IStructuredSelection groupSelection = (IStructuredSelection) groupViewer .getSelection(); if (groupSelection.isEmpty()) return; List<IMarker> markers = ((IMarkerGroup) markerViewer.getInput()) .getMarkers(); int index = markers.indexOf(selection.getFirstElement()); IMarkerGroup group = (IMarkerGroup) groupSelection.getFirstElement(); for (Object marker : selection.toList()) { group.removeMarker((IMarker) marker); if (MindMapUI.getResourceManager().getRecentMarkerGroup() .getMarker(((IMarker) marker).getId()) != null) MindMapUI.getResourceManager().getRecentMarkerGroup() .removeMarker((IMarker) marker); removeMarkerFile((IMarker) marker); } markerViewer.refresh(); //select the next one markers = ((IMarkerGroup) markerViewer.getInput()).getMarkers(); if (index >= markers.size()) { index = markers.size() - 1; } if (index >= 0) { if (!markers.isEmpty()) { markerViewer.setSelection( new StructuredSelection(markers.get(index))); } } } private void removeMarkerFile(IMarker marker) { if (marker == null) return; String path = Core.getWorkspace() .getAbsolutePath("markers/" + marker.getResourcePath()); //$NON-NLS-1$ new File(path).delete(); } /** * */ private void renameMarker() { IStructuredSelection selection = (IStructuredSelection) markerViewer .getSelection(); if (selection.isEmpty()) return; markerViewer.editElement(selection.getFirstElement(), 0); } private void changeGroupName(IMarkerGroup group, String newName) { group.setName(newName); groupViewer.update(group, null); } private void refreshButtons() { IStructuredSelection groupSelection = (IStructuredSelection) groupViewer .getSelection(); removeGroupButton.setEnabled(!groupSelection.isEmpty()); renameGroupButton.setEnabled(!groupSelection.isEmpty()); exportGroupButton.setEnabled(!groupSelection.isEmpty()); addMarkerButton.setEnabled(!groupSelection.isEmpty()); IStructuredSelection markerSelection = (IStructuredSelection) markerViewer .getSelection(); removeMarkerButton.setEnabled(!markerSelection.isEmpty()); renameMarkerButton.setEnabled(!markerSelection.isEmpty()); } private void changeMarkerName(IMarker marker, String newName) { marker.setName(newName); markerViewer.update(marker, null); } private static IMarkerSheet getSheet() { return MindMapUI.getResourceManager().getUserMarkerSheet(); } private static void saveSheet() { MindMapUI.getResourceManager().saveUserMarkerSheet(); } }