package org.xmind.ui.internal.resourcemanager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.IParameter;
import org.eclipse.core.commands.Parameterization;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.util.Util;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.handlers.IHandlerService;
import org.xmind.core.style.IStyle;
import org.xmind.core.style.IStyleSheet;
import org.xmind.gef.EditDomain;
import org.xmind.gef.GEF;
import org.xmind.gef.IViewer;
import org.xmind.gef.part.IPart;
import org.xmind.gef.tool.ITool;
import org.xmind.gef.util.Properties;
import org.xmind.ui.gallery.GalleryEditTool;
import org.xmind.ui.gallery.GallerySelectTool;
import org.xmind.ui.gallery.GalleryViewer;
import org.xmind.ui.internal.MindMapMessages;
import org.xmind.ui.internal.handlers.IMindMapCommandConstants;
import org.xmind.ui.internal.views.StyleFigure;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.texteditor.FloatingTextEditor;
import org.xmind.ui.viewers.IToolTipProvider;
public class StyleResourceManagerViewer extends ResourceManagerViewer {
private static final int FRAME_HEIGHT = 72;
private static final int FRAME_WIDTH = 132;
//FIXME how to dispose cachedImageData???
public static Map<String, ImageData> cachedImageData = new HashMap<String, ImageData>();
private static final String EDIT_STYLE_COMMAND_ID = "org.xmind.ui.command.style.edit2"; //$NON-NLS-1$
private class StyleGalleryViewer extends GalleryViewer {
protected boolean isTitleEditable(IPart p) {
IStyleSheet styleSheet = MindMapUI.getResourceManager()
.getUserStyleSheet();
return styleSheet == null ? false
: styleSheet.getAllStyles().contains(p.getModel());
}
}
private static class StyleGroup {
public StyleGroup(String type) {
this.type = type;
}
private String type;
private List<IStyle> styles = new ArrayList<IStyle>();
public String getType() {
return type;
}
public String getName() {
if (IStyle.TOPIC.equals(type))
return MindMapMessages.StyleResourceManagerViewer_Topic;
if (IStyle.BOUNDARY.equals(type))
return MindMapMessages.StyleResourceManagerViewer_Boundary;
if (IStyle.MAP.equals(type))
return MindMapMessages.StyleResourceManagerViewer_Map;
if (IStyle.PARAGRAPH.equals(type))
return MindMapMessages.StyleResourceManagerViewer_Paragraph;
if (IStyle.RELATIONSHIP.equals(type))
return MindMapMessages.StyleResourceManagerViewer_Relationship;
if (IStyle.SUMMARY.equals(type))
return MindMapMessages.StyleResourceManagerViewer_Summary;
if (IStyle.TEXT.equals(type))
return MindMapMessages.StyleResourceManagerViewer_Text;
if (IStyle.THEME.equals(type))
return MindMapMessages.StyleResourceManagerViewer_Theme;
return ""; //$NON-NLS-1$
}
public List<IStyle> getItems() {
return styles;
}
public void addStyle(IStyle style) {
styles.add(style);
}
public int hashCode() {
return type.hashCode();
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj == null || !(obj instanceof StyleGroup))
return false;
if (((StyleGroup) obj).type.equals(this.type))
return true;
return false;
}
}
private static class StyleGalleryCore {
private List<StyleGroup> groups = new ArrayList<StyleGroup>();
private static StyleGalleryCore instance = new StyleGalleryCore();
public StyleGalleryCore() {
}
private StyleGroup getGroup(IStyle style) {
String type = style.getType();
if (type != null)
for (StyleGroup group : groups) {
if (type.equals(group.type))
return group;
}
StyleGroup group = new StyleGroup(type);
groups.add(group);
return group;
}
private List<StyleGroup> getElements() {
groups.clear();
Set<IStyle> systemStyles = MindMapUI.getResourceManager()
.getSystemStyleSheet()
.getStyles(IStyleSheet.AUTOMATIC_STYLES);
Set<IStyle> userStyles = MindMapUI.getResourceManager()
.getUserStyleSheet().getAllStyles();
for (IStyle style : systemStyles) {
StyleGroup group = getGroup(style);
group.addStyle(style);
}
for (IStyle style : userStyles) {
StyleGroup group = getGroup(style);
group.addStyle(style);
}
return groups;
}
public static StyleGalleryCore getInstance() {
return instance;
}
}
private class StyleCategorizedLabelProvider extends CategorizedLabelProvider
implements IToolTipProvider, IFontProvider {
@Override
public String getText(Object element) {
if (element instanceof IStyle) {
IStyle style = (IStyle) element;
return style.getName();
} else if (element instanceof StyleGroup)
return ((StyleGroup) element).getName();
return super.getText(element);
}
@Override
public Image getImage(Object element) {
if (element instanceof IStyle) {
final IStyle style = (IStyle) element;
Properties properties = StyleResourceManagerViewer.this
.getProperties();
ImageData imageData = cachedImageData.get(style.getId());
if (imageData == null) {
final Dimension size = (Dimension) properties
.get(GalleryViewer.FrameContentSize);
Image image = new Image(Display.getDefault(), size.width,
size.height);
GC gc = new GC(image);
Graphics graphics = new SWTGraphics(gc);
StyleFigure figure = new StyleFigure();
figure.setStyle(style);
figure.setSize(size);
figure.paint(graphics);
imageData = image.getImageData();
cachedImageData.put(style.getId(), imageData);
image.dispose();
gc.dispose();
graphics.dispose();
}
ImageDescriptor imageDescriptor = ImageDescriptor
.createFromImageData(imageData);
return getResourceManager().createImage(imageDescriptor);
}
return super.getImage(element);
}
public String getToolTip(Object element) {
if (element != null && element instanceof IStyle) {
IStyle style = (IStyle) element;
String typeName = style.getType();
String styleName = getText(style);
return typeName + "-" + styleName; //$NON-NLS-1$
}
return ""; //$NON-NLS-1$
}
@Override
public Font getFont(Object element) {
FontData data = getContainer().getFont().getFontData()[0];
if (Util.isMac()) {
data.setHeight(12);
} else {
data.setHeight(9);
}
data.setStyle(SWT.NONE);
FontDescriptor fontDescriptor = FontDescriptor.createFrom(data);
return getResourceManager().createFont(fontDescriptor);
}
}
private static class StyleCategorizedContentProvider
implements ITreeContentProvider {
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput,
Object newInput) {
}
public Object[] getElements(Object inputElement) {
if (inputElement instanceof StyleGalleryCore)
return ((StyleGalleryCore) inputElement).getElements()
.toArray();
else
return null;
}
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof StyleGalleryCore)
return ((StyleGalleryCore) parentElement).getElements()
.toArray();
else if (parentElement instanceof StyleGroup)
return ((StyleGroup) parentElement).getItems().toArray();
else
return null;
}
public Object getParent(Object element) {
StyleGalleryCore styleGalleryCore = StyleGalleryCore.getInstance();
if (element instanceof IStyle)
return styleGalleryCore.getGroup((IStyle) element);
else if (element instanceof StyleGroup)
return styleGalleryCore;
else
return null;
}
public boolean hasChildren(Object element) {
return element instanceof StyleGroup
|| element instanceof StyleGalleryCore;
}
}
private class StyleNestedViewerNameEditTool extends GalleryEditTool {
protected IDocument getTextContents(IPart source) {
return new org.eclipse.jface.text.Document(
((IStyle) source.getModel()).getName());
}
protected void handleTextModified(IPart source, IDocument document) {
//FIXME
((IStyle) source.getModel()).setName(document.get());
MindMapUI.getResourceManager().saveUserStyleSheet();
}
protected void hookEditor(FloatingTextEditor editor) {
super.hookEditor(editor);
getHelper().setPrefWidth(
FRAME_WIDTH + DEFAULT_FLOATING_TEXT_EDITOR_WIDTH_EXPAND);
}
}
@Override
public void createControl(Composite container) {
super.createControl(container);
setContentProvider(new StyleCategorizedContentProvider());
setLabelProvider(new StyleCategorizedLabelProvider());
EditDomain domain = new EditDomain();
domain.installTool(GEF.TOOL_SELECT,
new ResourceCategorizedSelectTool());
setEditDomain(domain);
initProperties();
createControl(container, SWT.WRAP);
getControl()
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
setInput(StyleGalleryCore.getInstance());
}
@Override
protected void initNestedGalleryViewer(GalleryViewer galleryViewerer) {
super.initNestedGalleryViewer(galleryViewerer);
Properties properties = galleryViewerer.getProperties();
properties.set(GalleryViewer.HideTitle, Boolean.FALSE);
galleryViewerer.getEditDomain().installTool(GEF.TOOL_EDIT,
new StyleNestedViewerNameEditTool());
}
@Override
protected void initProperties() {
super.initProperties();
Properties properties = getProperties();
properties.set(GalleryViewer.FrameContentSize,
new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
}
@Override
protected void configureSection(Section section, Object category) {
if (category instanceof StyleGroup) {
createSectionTextClient(section,
MindMapMessages.StyleResourceManagerViewer_AddSection_title,
category);
}
}
@Override
protected void handleClickSectionTextClient(Object category) {
if (category instanceof StyleGroup) {
StyleGroup group = (StyleGroup) category;
final IStyle dummyStyle = MindMapUI.getResourceManager()
.getSystemStyleSheet().createStyle(group.type);
openStyleEditDialog(dummyStyle);
}
}
protected void editStyle() {
IStructuredSelection selection = (IStructuredSelection) getSelection();
for (Object obj : selection.toArray()) {
if (obj instanceof IStyle) {
openStyleEditDialog((IStyle) obj);
}
}
}
private void openStyleEditDialog(final IStyle style) {
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
final IHandlerService handlers = (IHandlerService) window
.getService(IHandlerService.class);
final ICommandService commands = (ICommandService) window
.getService(ICommandService.class);
if (handlers == null || commands == null)
return;
final Command command = commands.getCommand(EDIT_STYLE_COMMAND_ID);
if (command == null || !command.isDefined())
return;
SafeRunner.run(new SafeRunnable() {
public void run() throws Exception {
IParameter param = command
.getParameter(IMindMapCommandConstants.RESOURCE_URI);
if (param == null)
return;
ParameterizedCommand pc = new ParameterizedCommand(command,
new Parameterization[] { new Parameterization(param,
MindMapUI.getResourceManager()
.toResourceURI(style)) });
handlers.executeCommand(pc, null);
}
});
}
public void startEditing(IStyle style) {
List<StyleGroup> styleGroups = StyleGalleryCore.getInstance()
.getElements();
for (StyleGroup styleGroup : styleGroups) {
List<IStyle> styles = styleGroup.getItems();
if (styles.contains(style)) {
GalleryViewer galleryViewer = getNestedViewer(styleGroup);
EditDomain domain = galleryViewer.getEditDomain();
ITool tool = domain.getDefaultTool();
((GallerySelectTool) tool).getStatus().setStatus(GEF.ST_ACTIVE,
true);
domain.handleRequest(GEF.REQ_EDIT, (IViewer) galleryViewer);
break;
}
}
}
protected GalleryViewer createNestedViewer() {
return new StyleGalleryViewer();
}
}