/* * ***************************************************************************** * * 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.properties; import java.util.Arrays; import java.util.Set; import java.util.TreeSet; import org.eclipse.draw2d.PositionConstants; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.IOpenListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.OpenEvent; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.ToolBar; import org.xmind.gef.GEF; import org.xmind.gef.IViewer; import org.xmind.gef.Request; import org.xmind.gef.graphicalpolicy.IStyleSelector; import org.xmind.gef.part.IGraphicalPart; import org.xmind.ui.color.ColorPicker; import org.xmind.ui.color.ColorSelection; import org.xmind.ui.color.IColorSelection; import org.xmind.ui.color.PaletteContents; import org.xmind.ui.commands.CommandMessages; import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.IMindMapImages; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.properties.StyledPropertySectionPart; import org.xmind.ui.resources.FontUtils; import org.xmind.ui.richtext.AlignmentGroup; import org.xmind.ui.richtext.TextCaseGroup; import org.xmind.ui.style.StyleUtils; import org.xmind.ui.style.Styles; import org.xmind.ui.style.TextStyleData; import org.xmind.ui.viewers.MComboViewer; public class FontPropertySectionPart extends StyledPropertySectionPart { private class FontLabelProvider extends LabelProvider { } private class FontSelectionChangedListener implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { if (isRefreshing()) return; Object o = ((IStructuredSelection) event.getSelection()) .getFirstElement(); if (o instanceof String) { changeFontName((String) o); MindMapUIPlugin.getDefault().getUsageDataCollector() .increase("FontChangeCount"); //$NON-NLS-1$ } } } private class SizeLabelProvider extends LabelProvider { } private class SizeSelectionChangedListener implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { if (isRefreshing()) return; Object o = ((IStructuredSelection) event.getSelection()) .getFirstElement(); if (o instanceof String) { try { int i = Integer.parseInt((String) o); FONT_SIZE_LIST.add(i); changeFontSize(i); } catch (NumberFormatException e) { } } else if (o instanceof Integer) { changeFontSize(((Integer) o).intValue()); } } } private class BoldAction extends Action { public BoldAction() { super(null, MindMapUI.getImages().get(IMindMapImages.TEXT_BOLD, true)); setToolTipText(PropertyMessages.Bold_toolTip); setChecked(false); } public void run() { super.run(); changeBold(isChecked()); } } private class ItalicAction extends Action { public ItalicAction() { super(null, MindMapUI.getImages().get(IMindMapImages.TEXT_ITALIC, true)); setToolTipText(PropertyMessages.Italic_toolTip); setChecked(false); } public void run() { super.run(); changeItalic(isChecked()); } } private class StrikeoutAction extends Action { public StrikeoutAction() { super(null, MindMapUI.getImages().get(IMindMapImages.TEXT_STRIKEOUT, true)); setToolTipText(PropertyMessages.Strikeout_toolTip); setChecked(false); } public void run() { super.run(); changeStrikeout(isChecked()); } } private class AlignLeftAction extends Action { public AlignLeftAction() { super(PropertyMessages.TextAlignLeft_text, MindMapUI.getImages().get(IMindMapImages.ALIGN_LEFT, true)); setToolTipText(PropertyMessages.TextAlignLeft_toolTip); setChecked(false); } public void run() { changeAlignLeft(); } } private class AlignCenterAction extends Action { public AlignCenterAction() { super(PropertyMessages.TextAlignCenter_text, MindMapUI.getImages() .get(IMindMapImages.ALIGN_CENTER, true)); setToolTipText(PropertyMessages.TextAlignCenter_toolTip); setChecked(false); } public void run() { changeAlignCenter(); } } private class AlignRightAction extends Action { public AlignRightAction() { super(PropertyMessages.TextAlignRight_text, MindMapUI.getImages() .get(IMindMapImages.ALIGN_RIGHT, true)); setToolTipText(PropertyMessages.TextAlignRight_toolTip); setChecked(false); } public void run() { changeAlignRight(); } } private class ColorOpenListener implements IOpenListener { public void open(OpenEvent event) { changeTextColor((IColorSelection) event.getSelection()); } } private class TextManualAction extends Action { public TextManualAction() { super(PropertyMessages.TextManual_text, MindMapUI.getImages() .get(IMindMapImages.TEXT_MANUAL, true)); setToolTipText(PropertyMessages.TextManual_toolTip); setChecked(false); } public void run() { changeTextManual(); } } private class TextUppercaseAction extends Action { public TextUppercaseAction() { super(PropertyMessages.TextUppercase_text, MindMapUI.getImages() .get(IMindMapImages.TEXT_UPPERCASE, true)); setToolTipText(PropertyMessages.TextUppercase_toolTip); setChecked(false); } public void run() { changeTextUppercase(); } } private class TextLowercaseAction extends Action { public TextLowercaseAction() { super(PropertyMessages.TextLowercase_text, MindMapUI.getImages() .get(IMindMapImages.TEXT_LOWERCASE, true)); setToolTipText(PropertyMessages.TextLowercase_toolTip); setChecked(false); } public void run() { changeTextLowercase(); } } private class TextCapitalizeAction extends Action { public TextCapitalizeAction() { super(PropertyMessages.TextCapitalize_text, MindMapUI.getImages() .get(IMindMapImages.TEXT_CAPITALIZE, true)); setToolTipText(PropertyMessages.TextCapitalize_toolTip); setChecked(false); } public void run() { changeTextCapitalize(); } } private static Set<Integer> FONT_SIZE_LIST = new TreeSet<Integer>(); private IAction boldAction; private IAction italicAction; private IAction strikeoutAction; private MComboViewer fontViewer; private MComboViewer sizeViewer; private TextStyleData currentTextStyle; private ColorPicker textColorPicker; private AlignmentGroup alignGroup; private IAction alignLeftAction; private IAction alignCenterAction; private IAction alignRightAction; private TextCaseGroup caseGroup; private IAction manualAction; private IAction uppercaseAction; private IAction lowercaseAction; private IAction capitalizeAction; protected void createContent(Composite parent) { Composite line1 = new Composite(parent, SWT.NONE); line1.setLayoutData( new GridData(GridData.FILL, GridData.FILL, true, false)); GridLayout layout1 = new GridLayout(1, false); layout1.marginWidth = 0; layout1.marginHeight = 0; layout1.horizontalSpacing = 3; layout1.verticalSpacing = 3; line1.setLayout(layout1); createLineContent1(line1); Composite line2 = new Composite(parent, SWT.NONE); line2.setLayoutData( new GridData(GridData.FILL, GridData.FILL, true, false)); GridLayout layout2 = new GridLayout(2, false); layout2.marginWidth = 0; layout2.marginHeight = 0; layout2.horizontalSpacing = 3; layout2.verticalSpacing = 3; line2.setLayout(layout2); createLineContent2(line2); } private void createLineContent1(Composite parent) { fontViewer = new MComboViewer(parent, MComboViewer.FILTERED); fontViewer.getControl().setLayoutData( new GridData(GridData.FILL, GridData.FILL, true, false)); fontViewer.getControl() .setToolTipText(PropertyMessages.FontFamily_toolTip); fontViewer.setContentProvider(new ArrayContentProvider()); fontViewer.setLabelProvider(new FontLabelProvider()); // fontViewer.getControl().setEnabled(false); fontViewer.setInput(FontUtils.getAvailableFontNames()); TextStyleData ts = calcCurrentTextStyle(); if (ts != null && ts.name != null) { fontViewer.setSelection(new StructuredSelection(ts.name)); } fontViewer.addSelectionChangedListener( new FontSelectionChangedListener()); // IFontNameListCallback callback = new IFontNameListCallback() { // public void setAvailableFontNames(List<String> fontNames) { // if (fontViewer == null || fontViewer.getControl().isDisposed()) // return; // fontViewer.getControl().setEnabled(true); // fontViewer.setInput(fontNames); // TextStyleData ts = calcCurrentTextStyle(); // if (ts != null && ts.name != null) { // fontViewer.setSelection(new StructuredSelection(ts.name)); // } // fontViewer // .addSelectionChangedListener(new FontSelectionChangedListener()); // } // }; // FontUtils.fetchAvailableFontNames(parent.getDisplay(), callback); // ToolBarManager fontBar = new ToolBarManager(SWT.FLAT); // fontBar.add(new ChooseFontAction()); // ToolBar barControl = fontBar.createControl(parent); // barControl.setLayoutData( // new GridData(GridData.END, GridData.CENTER, false, false)); } private void createLineContent2(Composite parent) { sizeViewer = new MComboViewer(parent, MComboViewer.FILTERED); sizeViewer.getControl().setLayoutData( new GridData(GridData.FILL, GridData.FILL, true, false)); sizeViewer.getControl() .setToolTipText(PropertyMessages.FontSize_toolTip); sizeViewer.setContentProvider(new ArrayContentProvider()); sizeViewer.setLabelProvider(new SizeLabelProvider()); sizeViewer.setPermitsUnprovidedElement(true); if (FONT_SIZE_LIST.isEmpty()) { FONT_SIZE_LIST.addAll(Arrays.asList(8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 36, 48, 56)); } sizeViewer.setInput(FONT_SIZE_LIST); sizeViewer.addSelectionChangedListener( new SizeSelectionChangedListener()); ToolBarManager styleBar = new ToolBarManager(SWT.FLAT); styleBar.add(boldAction = new BoldAction()); styleBar.add(italicAction = new ItalicAction()); styleBar.add(strikeoutAction = new StrikeoutAction()); textColorPicker = new ColorPicker(ColorPicker.AUTO | ColorPicker.CUSTOM, PaletteContents.getDefault()); textColorPicker.getAction() .setToolTipText(PropertyMessages.TextColor_toolTip); textColorPicker.addOpenListener(new ColorOpenListener()); styleBar.add(textColorPicker); alignGroup = new AlignmentGroup(); alignGroup.add(alignLeftAction = new AlignLeftAction()); alignGroup.add(alignCenterAction = new AlignCenterAction()); alignGroup.add(alignRightAction = new AlignRightAction()); styleBar.add(alignGroup); caseGroup = new TextCaseGroup(); caseGroup.add(manualAction = new TextManualAction()); caseGroup.add(uppercaseAction = new TextUppercaseAction()); caseGroup.add(lowercaseAction = new TextLowercaseAction()); caseGroup.add(capitalizeAction = new TextCapitalizeAction()); styleBar.add(caseGroup); ToolBar barControl = styleBar.createControl(parent); barControl.setLayoutData( new GridData(GridData.END, GridData.CENTER, false, false)); } protected void doRefresh() { TextStyleData ts = calcCurrentTextStyle(); currentTextStyle = ts; if (fontViewer != null && !fontViewer.getControl().isDisposed() && fontViewer.getControl().isEnabled()) { fontViewer.setSelection( ts == null || ts.name == null ? StructuredSelection.EMPTY : new StructuredSelection(ts.name)); } if (sizeViewer != null && !sizeViewer.getControl().isDisposed()) { sizeViewer.setSelection(ts == null || ts.height < 0 ? StructuredSelection.EMPTY : new StructuredSelection(Integer.valueOf(ts.height))); } if (boldAction != null) boldAction.setChecked(ts != null && ts.bold); if (italicAction != null) italicAction.setChecked(ts != null && ts.italic); if (strikeoutAction != null) strikeoutAction.setChecked(ts != null && ts.strikeout); if (textColorPicker != null) updateColorPicker(textColorPicker); switch (ts == null ? PositionConstants.LEFT : ts.align) { case PositionConstants.LEFT: if (alignLeftAction != null) alignLeftAction.setChecked(ts != null); break; case PositionConstants.CENTER: if (alignCenterAction != null) alignCenterAction.setChecked(ts != null); break; case PositionConstants.RIGHT: if (alignRightAction != null) alignRightAction.setChecked(ts != null); break; } switch (ts == null ? GEF.MANUAL : ts.textCase) { case GEF.MANUAL: if (manualAction != null) manualAction.setChecked(ts != null); break; case GEF.UPPERCASE: if (uppercaseAction != null) uppercaseAction.setChecked(ts != null); break; case GEF.LOWERCASE: if (lowercaseAction != null) lowercaseAction.setChecked(ts != null); break; case GEF.CAPITALIZE: if (capitalizeAction != null) capitalizeAction.setChecked(ts != null); break; } } private void updateColorPicker(ColorPicker picker) { if (currentTextStyle == null || currentTextStyle.color == null) { picker.setSelection(ColorSelection.EMPTY); picker.setAutoColor(null); } else { IGraphicalPart part = getGraphicalPart(getSelectedElements()[0]); IStyleSelector ss = getStyleSelector(part); String autoValue = ss.getAutoValue(part, Styles.TextColor); RGB autoColor = StyleUtils.convertRGB(Styles.TextColor, autoValue); picker.setAutoColor(autoColor); String userValue = ss.getUserValue(part, Styles.TextColor); int type; if (userValue == null) { type = IColorSelection.AUTO; userValue = autoValue; } else { type = IColorSelection.CUSTOM; } if (type != IColorSelection.AUTO && Styles.NONE.equals(userValue)) { type = IColorSelection.NONE; } RGB color = StyleUtils.convertRGB(Styles.TextColor, userValue); picker.setSelection(new ColorSelection(type, color)); } } protected TextStyleData calcCurrentTextStyle() { TextStyleData textStyle = null; IViewer viewer = getActiveViewer(); if (viewer != null) { for (Object o : getSelectedElements()) { IGraphicalPart part = getGraphicalPart(o, viewer); if (part != null) { IStyleSelector ss = getStyleSelector(part); TextStyleData ts = calcTextStyle(part, ss); if (ts == null) return null; textStyle = mergeStyle(textStyle, ts); if (textStyle.name == null && textStyle.height < 0 && textStyle.color == null && !textStyle.italic && !textStyle.bold && !textStyle.underline && !textStyle.strikeout /* && textStyle.align == 0 */) { textStyle = null; break; } } } } return textStyle; } private TextStyleData mergeStyle(TextStyleData source, TextStyleData target) { if (source == null) return new TextStyleData(target); if (source.name != null && !source.name.equals(target.name)) source.name = null; if (source.height > 0 && source.height != target.height) source.height = -1; if (source.italic && !target.italic) source.italic = false; if (source.bold && !target.bold) source.bold = false; if (source.color != null && !source.color.equals(target.color)) source.color = null; if (source.strikeout && !target.strikeout) source.strikeout = false; if (source.underline && !target.underline) source.underline = false; if (source.align != target.align) source.align = SWT.LEFT; if (source.textCase != target.textCase) source.textCase = GEF.MANUAL; return source; } private TextStyleData calcTextStyle(IGraphicalPart part, IStyleSelector ss) { return StyleUtils.getTextStyleData(part, ss, null); } public void setFocus() { if (fontViewer != null && !fontViewer.getControl().isDisposed()) { fontViewer.getControl().setFocus(); } } public void dispose() { super.dispose(); fontViewer = null; sizeViewer = null; currentTextStyle = null; boldAction = null; italicAction = null; strikeoutAction = null; currentTextStyle = null; textColorPicker = null; alignLeftAction = null; alignCenterAction = null; alignRightAction = null; manualAction = null; uppercaseAction = null; lowercaseAction = null; capitalizeAction = null; } private void changeFontName(String name) { sendRequest( addStyle(createStyleRequest(CommandMessages.Command_ModifyFont), Styles.FontFamily, name)); } private void changeFontSize(int fontHeight) { sendRequest( addStyle(createStyleRequest(CommandMessages.Command_ModifyFont), Styles.FontSize, StyleUtils.addUnitPoint(fontHeight))); } private void changeBold(boolean bold) { sendRequest( addStyle(createStyleRequest(CommandMessages.Command_ModifyFont), Styles.FontWeight, bold ? Styles.FONT_WEIGHT_BOLD : Styles.NORMAL)); } private void changeItalic(boolean italic) { sendRequest( addStyle(createStyleRequest(CommandMessages.Command_ModifyFont), Styles.FontStyle, italic ? Styles.FONT_STYLE_ITALIC : Styles.NORMAL)); } private void changeStrikeout(boolean strikeout) { String decoration = null; if (currentTextStyle != null && currentTextStyle.underline) { decoration = Styles.TEXT_DECORATION_UNDERLINE; } if (decoration == null) { decoration = strikeout ? Styles.TEXT_DECORATION_LINE_THROUGH : Styles.NORMAL; } else if (strikeout) { decoration = decoration + " " + Styles.TEXT_DECORATION_LINE_THROUGH; //$NON-NLS-1$ } sendRequest( addStyle(createStyleRequest(CommandMessages.Command_ModifyFont), Styles.TextDecoration, decoration)); } private void changeAlignLeft() { Request leftReq = createStyleRequest( CommandMessages.Command_TextAlignLeft); Request request = addStyle(leftReq, Styles.TextAlign, Styles.ALIGN_LEFT); sendRequest(request); } private void changeAlignCenter() { Request centerReq = createStyleRequest( CommandMessages.Command_TextAlignCenter); Request request = addStyle(centerReq, Styles.TextAlign, Styles.ALIGN_CENTER); sendRequest(request); } private void changeAlignRight() { Request rightReq = createStyleRequest( CommandMessages.Command_TextAlignRight); Request request = addStyle(rightReq, Styles.TextAlign, Styles.ALIGN_RIGHT); sendRequest(request); } private void changeTextColor(IColorSelection selection) { changeColor(selection, Styles.TextColor, CommandMessages.Command_ModifyTextColor); } private void changeTextManual() { Request manualReq = createStyleRequest( CommandMessages.Command_TextManual); Request request = addStyle(manualReq, Styles.TextCase, Styles.MANUAL); sendRequest(request); } private void changeTextUppercase() { Request manualReq = createStyleRequest( CommandMessages.Command_TextUppercase); Request request = addStyle(manualReq, Styles.TextCase, Styles.UPPERCASE); sendRequest(request); } private void changeTextLowercase() { Request manualReq = createStyleRequest( CommandMessages.Command_TextLowercase); Request request = addStyle(manualReq, Styles.TextCase, Styles.LOWERCASE); sendRequest(request); } private void changeTextCapitalize() { Request manualReq = createStyleRequest( CommandMessages.Command_TextCapitalize); Request request = addStyle(manualReq, Styles.TextCase, Styles.CAPITALIZE); sendRequest(request); } }