package org.xmind.ui.internal.properties;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
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.Listener;
import org.eclipse.swt.widgets.Shell;
import org.xmind.core.internal.command.Logger;
import org.xmind.core.style.IStyle;
import org.xmind.core.style.IStyleSheet;
import org.xmind.core.style.IStyled;
import org.xmind.core.util.Property;
import org.xmind.gef.EditDomain;
import org.xmind.gef.GEF;
import org.xmind.gef.IGraphicalViewer;
import org.xmind.gef.Request;
import org.xmind.gef.graphicalpolicy.IStyleSelector;
import org.xmind.gef.part.GraphicalEditPart;
import org.xmind.gef.part.IGraphicalPart;
import org.xmind.gef.part.IPart;
import org.xmind.gef.part.IPartFactory;
import org.xmind.gef.ui.properties.IPropertySectionPart;
import org.xmind.gef.util.Properties;
import org.xmind.ui.gallery.FrameFigure;
import org.xmind.ui.gallery.FramePart;
import org.xmind.ui.gallery.GalleryLayout;
import org.xmind.ui.gallery.GallerySelectTool;
import org.xmind.ui.gallery.GalleryViewer;
import org.xmind.ui.internal.MindMapMessages;
import org.xmind.ui.internal.MindMapUIPlugin;
import org.xmind.ui.internal.views.StyleFigure;
import org.xmind.ui.mindmap.IMindMap;
import org.xmind.ui.mindmap.IMindMapViewer;
import org.xmind.ui.mindmap.IResourceManager;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.properties.StyledPropertySectionPart;
import org.xmind.ui.style.StyleUtils;
import org.xmind.ui.util.MindMapUtils;
import org.xmind.ui.viewers.MButton;
public class StylesPropertySectionPart extends StyledPropertySectionPart
implements IStyleEditingDelegate {
private static Class<? extends IStyleEditingSectionPart> styleEditingSectionClass = null;
private static class StyleLabelProvider extends LabelProvider {
public String getText(Object element) {
if (element instanceof IStyle) {
IStyle style = (IStyle) element;
return style.getName();
}
return super.getText(element);
}
}
private static class StylePart extends GraphicalEditPart {
private HashMap<String, String> existedStyle;
public StylePart(Object model, HashMap<String, String> existedStyle) {
setModel(model);
this.existedStyle = existedStyle;
}
public IStyle getStyle() {
return (IStyle) super.getModel();
}
protected IFigure createFigure() {
return new StyleFigure();
}
protected void updateView() {
super.updateView();
StyleFigure styleFigure = (StyleFigure) getFigure();
styleFigure.setStyle(getStyle());
styleFigure.setExistedStyle(existedStyle);
Properties properties = ((GalleryViewer) getSite().getViewer())
.getProperties();
Dimension size = (Dimension) properties
.get(GalleryViewer.FrameContentSize);
if (size != null) {
getFigure().setPreferredSize(size);
}
}
}
private class StylePartFactory implements IPartFactory {
private IPartFactory factory;
private HashMap<String, String> existedStyle;
public StylePartFactory(IPartFactory factory,
HashMap<String, String> existedStyle) {
this.factory = factory;
this.existedStyle = existedStyle;
}
public IPart createPart(IPart context, Object model) {
if (context instanceof FramePart && model instanceof IStyle) {
IStyle style = (IStyle) model;
FrameFigure figure = ((FramePart) context).getFigure();
if (figure != null) {
figure.setToolTip(new Label(style.getName()));
}
return new StylePart(style, existedStyle);
}
return factory.createPart(context, model);
}
}
private class SelectStyleDialog extends PopupDialog
implements IOpenListener {
private Control handle;
private GalleryViewer viewer;
private IPropertySectionPart styleEditingSection;
public SelectStyleDialog(Shell parent, Control handle) {
super(parent, SWT.RESIZE, true, true, true, false, false, null,
null);
this.handle = handle;
}
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
viewer = new GalleryViewer();
Properties properties = viewer.getProperties();
properties.set(GalleryViewer.Horizontal, Boolean.TRUE);
properties.set(GalleryViewer.Wrap, Boolean.TRUE);
properties.set(GalleryViewer.FlatFrames, Boolean.TRUE);
properties.set(GalleryViewer.ImageConstrained, Boolean.TRUE);
properties.set(GalleryViewer.Layout,
new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT,
GalleryLayout.ALIGN_FILL, 1, 1, new Insets(5)));
properties.set(GalleryViewer.FrameContentSize,
new Dimension(48, 48));
properties.set(GalleryViewer.TitlePlacement,
GalleryViewer.TITLE_TOP);
properties.set(GalleryViewer.SingleClickToOpen, Boolean.TRUE);
properties.set(GalleryViewer.HideTitle, Boolean.TRUE);
properties.set(GalleryViewer.SolidFrames, Boolean.FALSE);
viewer.addOpenListener(this);
EditDomain editDomain = new EditDomain();
editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool());
viewer.setEditDomain(editDomain);
IGraphicalPart part = getGraphicalPart(getSelectedElements()[0]);
HashMap<String, String> existedStyle = generateExistedStyle(part);
viewer.setPartFactory(new StylePartFactory(viewer.getPartFactory(),
existedStyle));
viewer.setLabelProvider(new StyleLabelProvider());
viewer.createControl(composite);
GridData galleryData = new GridData(GridData.FILL, GridData.FILL,
true, true);
viewer.getControl().setLayoutData(galleryData);
final Display display = parent.getDisplay();
viewer.getControl().setBackground(
display.getSystemColor(SWT.COLOR_LIST_BACKGROUND));
viewer.setInput(getViewerInput());
if (styleEditingSection == null) {
styleEditingSection = createStyleEditingSectionPart();
}
if (styleEditingSection != null) {
Composite editItemParent = new Composite(composite, SWT.NONE);
editItemParent.setLayoutData(new GridData(GridData.FILL,
GridData.FILL, true, false));
styleEditingSection.createControl(editItemParent);
}
return composite;
}
@Override
protected void constrainShellSize() {
super.constrainShellSize();
if (styleEditingSection != null) {
styleEditingSection.setSelection(getCurrentSelection());
}
if (viewer != null) {
viewer.setInput(getViewerInput());
}
}
private HashMap<String, String> generateExistedStyle(
IGraphicalPart selectedPart) {
HashMap<String, String> stylePropertiesMap = new HashMap<String, String>();
IResourceManager resourceManager = MindMapUI.getResourceManager();
IStyleSheet defaultStyleSheet = resourceManager
.getDefaultStyleSheet();
IStyleSheet userStyleSheet = resourceManager.getUserStyleSheet();
Object model = MindMapUtils.getRealModel(selectedPart);
if (model instanceof IStyled) {
IStyled styled = (IStyled) model;
Set<String> propertyKeys = new HashSet<String>();
IGraphicalViewer viewer = getActiveViewer();
if (!(viewer instanceof IMindMapViewer))
return stylePropertiesMap;
IMindMap mindMap = ((IMindMapViewer) viewer).getMindMap();
String styleFamily = MindMapUtils.getFamily(styled, mindMap);
String userStyleId = styled.getStyleId();
IStyle userStyle = userStyleSheet.findStyle(userStyleId);
collectPropertyKey(userStyle, propertyKeys);
IStyle theme = mindMap.getSheet().getTheme();
if (theme != null) {
IStyle themeStyle = theme.getDefaultStyle(styleFamily);
collectPropertyKey(themeStyle, propertyKeys);
}
IStyle defaultStyle = defaultStyleSheet.findStyle(styleFamily);
collectPropertyKey(defaultStyle, propertyKeys);
IStyleSelector styleSelector = StyleUtils
.getStyleSelector(selectedPart);
for (String key : propertyKeys) {
stylePropertiesMap.put(key,
styleSelector.getStyleValue(selectedPart, key));
}
}
return stylePropertiesMap;
}
private void collectPropertyKey(IStyle style,
Set<String> propertyKeys) {
if (style == null)
return;
Iterator<Property> properties = style.properties();
while (properties.hasNext()) {
propertyKeys.add(properties.next().key);
}
}
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.addListener(SWT.Deactivate, new Listener() {
public void handleEvent(Event event) {
event.display.asyncExec(new Runnable() {
public void run() {
close();
}
});
}
});
}
@SuppressWarnings("unchecked")
protected List getBackgroundColorExclusions() {
List list = super.getBackgroundColorExclusions();
if (viewer != null) {
list.add(viewer.getControl());
}
return list;
}
@Override
protected Point getDefaultSize() {
return new Point(260, 300);
}
protected Point getInitialLocation(Point initialSize) {
if (handle != null && !handle.isDisposed()) {
Point loc = handle.toDisplay(handle.getLocation());
return new Point(loc.x, loc.y + handle.getBounds().height);
}
return super.getInitialLocation(initialSize);
}
protected IDialogSettings getDialogSettings() {
return MindMapUIPlugin.getDefault()
.getDialogSettings(MindMapUI.POPUP_DIALOG_SETTINGS_ID);
}
public void open(OpenEvent event) {
Object o = ((IStructuredSelection) event.getSelection())
.getFirstElement();
if (o instanceof IStyle) {
close();
final IStyle selectedStyle = (IStyle) o;
Display.getCurrent().asyncExec(new Runnable() {
public void run() {
applyStyle(selectedStyle);
}
});
selectStyleWidget.setText((selectedStyle).getName());
}
}
}
private MButton selectStyleWidget;
@Override
protected void doRefresh() {
selectStyleWidget
.setText(MindMapMessages.StylePropertySectionPart_text);
}
@Override
protected void createContent(Composite parent) {
selectStyleWidget = new MButton(parent, MButton.NORMAL);
selectStyleWidget.getControl().setLayoutData(
new GridData(GridData.FILL, GridData.FILL, true, false));
selectStyleWidget.getControl().setToolTipText(
MindMapMessages.StylePropertySectionPart_tooltip);
selectStyleWidget.addOpenListener(new IOpenListener() {
public void open(OpenEvent event) {
openSelectStyleDialog();
}
});
}
private void openSelectStyleDialog() {
if (selectStyleWidget != null && selectStyleWidget.getControl() != null
&& !selectStyleWidget.getControl().isDisposed()) {
Control handle = selectStyleWidget.getControl();
SelectStyleDialog selectStyleDialog = new SelectStyleDialog(
handle.getShell(), handle);
selectStyleDialog.open();
Shell shell = selectStyleDialog.getShell();
if (shell != null && !shell.isDisposed()) {
selectStyleWidget.setForceFocus(true);
shell.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
if (selectStyleWidget != null && !selectStyleWidget
.getControl().isDisposed()) {
selectStyleWidget.setForceFocus(false);
}
}
});
}
}
}
@Override
public void setFocus() {
if (selectStyleWidget != null
&& !selectStyleWidget.getControl().isDisposed()) {
selectStyleWidget.getControl().setFocus();
}
}
@Override
public void dispose() {
super.dispose();
selectStyleWidget = null;
}
private String getCurrentStyleType() {
ISelection selection = getCurrentSelection();
String type = null;
if (selection instanceof IStructuredSelection) {
for (Object obj : ((IStructuredSelection) selection).toList()) {
String t = null;
if (obj instanceof IStyled) {
t = ((IStyled) obj).getStyleType();
}
if (t == null)
return null;
if (type != null && !t.equals(type))
return null;
if (type == null) {
type = t;
}
}
}
return type;
}
private List<IStyle> getViewerInput() {
String type = getCurrentStyleType();
if (type == null)
return Collections.emptyList();
List<IStyle> list = new ArrayList<IStyle>();
Set<IStyle> systemStyles = MindMapUI.getResourceManager()
.getSystemStyleSheet().getStyles(IStyleSheet.AUTOMATIC_STYLES);
Set<IStyle> userStyles = MindMapUI.getResourceManager()
.getUserStyleSheet().getAllStyles();
for (IStyle style : systemStyles) {
if (type.equals(style.getType())) {
list.add(style);
}
}
for (IStyle style : userStyles) {
if (type.equals(style.getType()))
list.add(0, style);
}
return list;
}
private void applyStyle(IStyle style) {
Request request = fillTargets(new Request(MindMapUI.REQ_MODIFY_STYLE));
request.setParameter(MindMapUI.PARAM_RESOURCE, style);
sendRequest(request);
}
public void styleEditingFinished() {
openSelectStyleDialog();
}
private IStyleEditingSectionPart createStyleEditingSectionPart() {
if (styleEditingSectionClass == null)
return null;
try {
IStyleEditingSectionPart section = styleEditingSectionClass
.newInstance();
section.init(getContainer(), getContributedEditor());
section.setDelegate(this);
return section;
} catch (Exception e) {
Logger.log("Failed to create EditStyleContributionItem", e); //$NON-NLS-1$
return null;
}
}
public static void setStyleEditingSectionClass(
Class<? extends IStyleEditingSectionPart> cls) {
styleEditingSectionClass = cls;
}
}