org.xmind.ui.internal.properties.NumberingPropertySectionPart.java Source code

Java tutorial

Introduction

Here is the source code for org.xmind.ui.internal.properties.NumberingPropertySectionPart.java

Source

/* ******************************************************************************
 * 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.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.xmind.core.Core;
import org.xmind.core.INumbering;
import org.xmind.core.ITopic;
import org.xmind.core.event.CoreEvent;
import org.xmind.core.event.ICoreEventRegister;
import org.xmind.gef.Request;
import org.xmind.gef.draw2d.graphics.GraphicsUtils;
import org.xmind.ui.internal.MindMapMessages;
import org.xmind.ui.internal.MindMapUIPlugin;
import org.xmind.ui.mindmap.INumberFormatDescriptor;
import org.xmind.ui.mindmap.INumberSeparatorDescriptor;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.properties.MindMapPropertySectionPartBase;
import org.xmind.ui.util.MindMapUtils;
import org.xmind.ui.viewers.MComboViewer;

public class NumberingPropertySectionPart extends MindMapPropertySectionPartBase {

    private static final Object INHERIT = new Object();

    private class NumberFormatLabelProvider extends LabelProvider {
        public String getText(Object element) {
            if (element instanceof INumberFormatDescriptor) {
                INumberFormatDescriptor desc = (INumberFormatDescriptor) element;
                String name = desc.getName();
                String description = desc.getDescription();
                if (description == null || "".equals(description)) //$NON-NLS-1$
                    return name;
                return NLS.bind("{0} ({1})", name, description); //$NON-NLS-1$
            }
            return super.getText(element);
        }
    }

    private class NumberSeparatorLabelProvider extends LabelProvider {
        public String getText(Object element) {
            if (element instanceof INumberSeparatorDescriptor) {
                INumberSeparatorDescriptor desc = (INumberSeparatorDescriptor) element;
                String name = desc.getName();
                String description = desc.getDescription();
                if (description == null || "".equals(description)) //$NON-NLS-1$
                    return name;
                return NLS.bind("{0} ({1})", name, description); //$NON-NLS-1$
            }
            return super.getText(element);
        }
    }

    private class NumberDepthLabelProvider extends LabelProvider {
        @Override
        public String getText(Object element) {
            if (INHERIT.equals(element))
                return MindMapMessages.NumberingProperty_NumberDepthLabelProvider_Inherit_text;
            if (element instanceof String) {
                String depth = (String) element;
                return NLS.bind("{0} {1}", depth, //$NON-NLS-1$
                        MindMapMessages.NumberingProperty_NumberDepthLabelProvider_Levels_text);
            }
            return super.getText(element);
        }
    }

    private class NumberFormatSelectionChangedListener implements ISelectionChangedListener {

        public void selectionChanged(SelectionChangedEvent event) {
            if (isRefreshing())
                return;

            Object o = ((IStructuredSelection) event.getSelection()).getFirstElement();
            if (o instanceof INumberFormatDescriptor) {
                MindMapUIPlugin.getDefault().getUsageDataCollector().increase("NumberingTypeCount:" //$NON-NLS-1$
                        + ((INumberFormatDescriptor) o).getId());
                changeNumberFormat(((INumberFormatDescriptor) o).getId());
            }
        }

    }

    private class SeparatorFormatSelectionChangedListener implements ISelectionChangedListener {

        public void selectionChanged(SelectionChangedEvent event) {
            if (isRefreshing())
                return;

            Object o = ((IStructuredSelection) event.getSelection()).getFirstElement();

            if (o instanceof INumberSeparatorDescriptor) {
                changeNumberSeparator(((INumberSeparatorDescriptor) o).getId());
            }

        }

    }

    private class NumberDepthSelectionChangedListener implements ISelectionChangedListener {

        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            if (isRefreshing())
                return;

            Object o = ((IStructuredSelection) event.getSelection()).getFirstElement();

            if (INHERIT == o) {
                changeNumberDepth(null);
            } else if (o instanceof String) {
                MindMapUIPlugin.getDefault().getUsageDataCollector().increase("NumberDepthCount" + o); //$NON-NLS-1$
                changeNumberDepth((String) o);
            }
        }
    }

    private MComboViewer formatViewer;

    private Button tieredCheck;

    private MComboViewer depthViewer;

    private MComboViewer separatorViewer;

    private Text prefixInput;

    private Text suffixInput;

    private Text numberLabel;

    protected void createContent(Composite parent) {
        Composite line1 = createLine(parent);
        line1.setLayout(generateGridLayout(1));
        createNumberingFormatLine(line1);

        Composite line2 = createLine(parent);
        line2.setLayout(generateGridLayout(1));
        createTieredCheckLine(line2);

        Composite line3 = createLine(parent);
        line3.setLayout(generateGridLayout(2));
        createNumberingDepthLine(line3);

        Composite line4 = createLine(parent);
        line4.setLayout(generateGridLayout(2));
        createNumberingSeparatorLine(line4);

        Composite line5 = createLine(parent);
        line5.setLayout(generateGridLayout(3));
        createPrefixAndSuffixLine(line5);
        prefixInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        numberLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
        suffixInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    }

    private GridLayout generateGridLayout(int cols) {
        GridLayout gridLayout = new GridLayout(cols, false);
        gridLayout.marginWidth = 0;
        gridLayout.marginHeight = 0;
        gridLayout.horizontalSpacing = 3;
        gridLayout.verticalSpacing = 3;
        return gridLayout;
    }

    private Composite createLine(Composite parent) {
        Composite line = new Composite(parent, SWT.NONE);
        line.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
        return line;
    }

    private void createNumberingFormatLine(Composite parent) {
        formatViewer = new MComboViewer(parent, MComboViewer.NORMAL);
        formatViewer.getControl().setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
        formatViewer.setContentProvider(new ArrayContentProvider());
        formatViewer.setLabelProvider(new NumberFormatLabelProvider());
        List<INumberFormatDescriptor> descriptors = MindMapUI.getNumberFormatManager().getDescriptors();
        List<Object> list = new ArrayList<Object>(descriptors.size() + 1);
        Object separator = new Object();
        INumberFormatDescriptor defaultDescriptor = MindMapUI.getNumberFormatManager()
                .getDescriptor(MindMapUI.DEFAULT_NUMBER_FORMAT);
        for (INumberFormatDescriptor desc : descriptors) {
            if (desc != null && defaultDescriptor != null && desc != defaultDescriptor) {
                list.add(desc);
            }
        }
        if (defaultDescriptor != null) {
            list.add(separator);
            list.add(defaultDescriptor);
        }
        formatViewer.setSeparatorImitation(separator);
        formatViewer.setInput(list);
        formatViewer.addSelectionChangedListener(new NumberFormatSelectionChangedListener());
    }

    private void createNumberingSeparatorLine(Composite parent) {
        Label separatorLabel = new Label(parent, SWT.NONE);
        separatorLabel.setText(PropertyMessages.Separator_label);

        separatorViewer = new MComboViewer(parent, MComboViewer.NORMAL);
        separatorViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        separatorViewer.setContentProvider(new ArrayContentProvider());
        separatorViewer.setLabelProvider(new NumberSeparatorLabelProvider());
        List<INumberSeparatorDescriptor> descriptions = MindMapUI.getNumberSeparatorManager().getDescriptors();
        List<Object> list = new ArrayList<Object>(descriptions.size() + 1);
        Object separator = new Object();
        INumberSeparatorDescriptor defautDescriptor = MindMapUI.getNumberSeparatorManager()
                .getDescriptor(MindMapUI.DEFAULT_NUMBER_SEPARATOR);
        if (defautDescriptor != null) {
            list.add(defautDescriptor);
            list.add(separator);
        }
        for (INumberSeparatorDescriptor desc : descriptions) {
            if (desc != null && defautDescriptor != null && desc != defautDescriptor) {
                list.add(desc);
            }
        }
        separatorViewer.setSeparatorImitation(separator);
        separatorViewer.setInput(list);
        separatorViewer.addSelectionChangedListener(new SeparatorFormatSelectionChangedListener());

    }

    private void createPrefixAndSuffixLine(Composite parent) {
        prefixInput = new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.CENTER);
        prefixInput.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
        prefixInput.setToolTipText(PropertyMessages.Prefix_toolTip);
        Listener eventHandler = new Listener() {
            public void handleEvent(Event event) {
                if (event.type == SWT.FocusIn) {
                    if (event.widget == prefixInput)
                        prefixInput.selectAll();
                    else
                        suffixInput.selectAll();
                } else {
                    if (event.widget == prefixInput)
                        changePrefix(prefixInput.getText());
                    else
                        changeSuffix(suffixInput.getText());
                }
            }
        };
        prefixInput.addListener(SWT.DefaultSelection, eventHandler);
        prefixInput.addListener(SWT.FocusOut, eventHandler);
        prefixInput.addListener(SWT.FocusIn, eventHandler);

        numberLabel = new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY | SWT.CENTER);
        numberLabel.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false));
        numberLabel.setEditable(false);
        numberLabel.setBackground(numberLabel.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

        suffixInput = new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.CENTER);
        suffixInput.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
        suffixInput.setToolTipText(PropertyMessages.Suffix_toolTip);
        suffixInput.addListener(SWT.DefaultSelection, eventHandler);
        suffixInput.addListener(SWT.FocusOut, eventHandler);
        suffixInput.addListener(SWT.FocusIn, eventHandler);
    }

    private void createTieredCheckLine(Composite parent) {
        tieredCheck = new Button(parent, SWT.CHECK);
        tieredCheck.setText(MindMapMessages.NumberingProperty_TieredCheck_text);
        tieredCheck.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                changePrepending(tieredCheck.getSelection());
            }
        });
    }

    private void createNumberingDepthLine(Composite parent) {
        Label label = new Label(parent, SWT.NONE);
        label.setText(PropertyMessages.Depth_label);

        depthViewer = new MComboViewer(parent, MComboViewer.NORMAL);
        depthViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        depthViewer.setContentProvider(new ArrayContentProvider());
        depthViewer.setLabelProvider(new NumberDepthLabelProvider());
        @SuppressWarnings("nls")
        String[] values = new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
        List<Object> input = new ArrayList<Object>(values.length + 1);
        input.addAll(Arrays.asList(values));
        Object sep = new Object();
        input.add(sep);
        input.add(INHERIT);
        depthViewer.setSeparatorImitation(sep);
        depthViewer.setInput(input);
        depthViewer.addSelectionChangedListener(new NumberDepthSelectionChangedListener());
    }

    public void setFocus() {
        if (formatViewer != null && !formatViewer.getControl().isDisposed()) {
            formatViewer.getControl().setFocus();
        }
    }

    public void dispose() {
        super.dispose();
        formatViewer = null;
        prefixInput = null;
        numberLabel = null;
        suffixInput = null;
        separatorViewer = null;
        depthViewer = null;
        tieredCheck = null;
    }

    protected void doRefresh() {
        Object o = ((IStructuredSelection) getCurrentSelection()).getFirstElement();
        if (o instanceof ITopic) {
            ITopic topic = (ITopic) o;
            ITopic parent = topic.getParent();
            if (parent == null)
                parent = topic;
            INumbering numbering;
            if (ITopic.ATTACHED.equals(topic.getType())) {
                numbering = parent.getNumbering();
            } else {
                numbering = null;
            }
            boolean hasFormat = false;
            if (formatViewer != null && !formatViewer.getControl().isDisposed()) {
                String format = numbering == null ? null : numbering.getComputedFormat();
                if (format == null) {
                    format = MindMapUI.DEFAULT_NUMBER_FORMAT;
                } else if (parent.getNumbering().getNumberFormat() == null
                        && !topic.getNumbering().isInherited(0)) {
                    format = MindMapUI.DEFAULT_NUMBER_FORMAT;
                } else {
                    hasFormat = !MindMapUI.DEFAULT_NUMBER_FORMAT.equals(format);
                }
                INumberFormatDescriptor descriptor = MindMapUI.getNumberFormatManager().getDescriptor(format);
                formatViewer.setSelection(
                        descriptor == null ? StructuredSelection.EMPTY : new StructuredSelection(descriptor));
            }
            if (depthViewer != null && !depthViewer.getControl().isDisposed()) {
                Object select = INHERIT;
                if (numbering != null) {
                    if (numbering.getDepth() != null)
                        select = numbering.getDepth();
                    else if (numbering.getNumberFormat() != null && !numbering.isInherited(1))
                        select = "3"; //$NON-NLS-1$

                    depthViewer.setSelection(new StructuredSelection(select));

                    if (MindMapUI.DEFAULT_NUMBER_FORMAT.equals(numbering.getNumberFormat())) {
                        depthViewer.setEnabled(false);
                    } else {
                        depthViewer.setEnabled(
                                numbering.getNumberFormat() != null || topic.getNumbering().isInherited(0));
                    }
                }
            }
            if (separatorViewer != null && !separatorViewer.getControl().isDisposed()) {
                String separator = numbering == null ? null : numbering.getComputedSeparator();
                if (separator == null)
                    separator = MindMapUI.DEFAULT_NUMBER_SEPARATOR;
                INumberSeparatorDescriptor descriptor = MindMapUI.getNumberSeparatorManager()
                        .getDescriptor(separator);
                separatorViewer.setSelection(
                        descriptor == null ? StructuredSelection.EMPTY : new StructuredSelection(descriptor));
            }
            if (tieredCheck != null) {
                tieredCheck.setSelection(numbering != null && numbering.prependsParentNumbers());
            }
            if (prefixInput != null && !prefixInput.isDisposed()) {
                String prefix = numbering == null ? null : numbering.getPrefix();
                prefixInput.setText(prefix == null ? "" : prefix); //$NON-NLS-1$
            }
            if (suffixInput != null && !suffixInput.isDisposed()) {
                String suffix = numbering == null ? null : numbering.getSuffix();
                suffixInput.setText(suffix == null ? "" : suffix); //$NON-NLS-1$
            }
            if (numberLabel != null && !numberLabel.isDisposed()) {
                String number;
                number = MindMapUtils.getNumberingText(topic, hasFormat ? null : MindMapUI.PREVIEW_NUMBER_FORMAT,
                        hasFormat ? null : MindMapUI.DEFAULT_NUMBER_SEPARATOR);
                if (number == null || "".equals(number)) { //$NON-NLS-1$
                    numberLabel.setText(" "); //$NON-NLS-1$
                } else {
                    number = GraphicsUtils.getNormal().constrain(number, 100, JFaceResources.getDefaultFont(),
                            GraphicsUtils.TRAIL);
                    numberLabel.setText(number);
                }
                if (hasFormat) {
                    numberLabel.setForeground(numberLabel.getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND));
                } else {
                    numberLabel.setForeground(numberLabel.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
                }
            }
        }
    }

    protected void registerEventListener(Object source, ICoreEventRegister register) {
        if (source instanceof ITopic) {
            ITopic parent = ((ITopic) source).getParent();
            if (parent == null)
                parent = (ITopic) source;
            register.setNextSourceFrom(parent);
            register.register(Core.TopicAdd);
            register.register(Core.TopicRemove);
            INumbering numbering = parent.getNumbering();
            register.setNextSourceFrom(numbering);
            register.register(Core.NumberFormat);
            register.register(Core.NumberingPrefix);
            register.register(Core.NumberingSuffix);
            register.register(Core.NumberPrepending);
            register.register(Core.NumberingSeparator);
            register.register(Core.NumberingDepth);
        }
    }

    public void handleCoreEvent(CoreEvent event) {
        String type = event.getType();
        if (Core.TopicAdd.equals(type) || Core.TopicRemove.equals(type)) {
            if (!ITopic.ATTACHED.equals(event.getData()))
                return;
        }
        super.handleCoreEvent(event);
    }

    private void changeNumberFormat(String formatId) {
        if (formatId != null) {
            Object o = ((IStructuredSelection) getCurrentSelection()).getFirstElement();
            if (o instanceof ITopic) {
                ITopic topic = ((ITopic) o).getParent();
                if (topic == null)
                    topic = (ITopic) o;
                //                if (formatId.equals(topic.getNumbering().getParentFormat()))
                if (formatId.equals(topic.getNumbering().getNumberFormat()))
                    formatId = null;
            }
        }
        sendRequest(fillTargets(new Request(MindMapUI.REQ_MODIFY_NUMBERING))
                .setParameter(MindMapUI.PARAM_NUMBERING_FORMAT, formatId));
    }

    private void changeNumberSeparator(String separatorId) {
        if (separatorId != null) {
            Object o = ((IStructuredSelection) getCurrentSelection()).getFirstElement();
            if (o instanceof ITopic) {
                ITopic topic = ((ITopic) o).getParent();
                if (topic == null)
                    topic = (ITopic) o;
                if (separatorId.equals(topic.getNumbering().getSeparator()))
                    separatorId = null;
            }
        }
        sendRequest(fillTargets(new Request(MindMapUI.REQ_MODIFY_NUMBERING))
                .setParameter(MindMapUI.PARAM_NUMBERING_SEPARATOR, separatorId));
    }

    private void changeNumberDepth(String depth) {
        sendRequest(fillTargets(new Request(MindMapUI.REQ_MODIFY_NUMBERING))
                .setParameter(MindMapUI.PARAM_NUMBERING_DEPTH, depth));
    }

    private void changePrepending(boolean prepend) {
        sendRequest(fillTargets(new Request(MindMapUI.REQ_MODIFY_NUMBERING))
                .setParameter(MindMapUI.PARAM_NUMBERING_PREPENDING, Boolean.valueOf(prepend)));
    }

    private void changePrefix(String newPrefix) {
        sendRequest(fillTargets(new Request(MindMapUI.REQ_MODIFY_NUMBERING)
                .setParameter(MindMapUI.PARAM_NUMBERING_PREFIX, newPrefix)));
    }

    private void changeSuffix(String newSuffix) {
        sendRequest(fillTargets(new Request(MindMapUI.REQ_MODIFY_NUMBERING)
                .setParameter(MindMapUI.PARAM_NUMBERING_SUFFIX, newSuffix)));
    }
}