/* ****************************************************************************** * 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.Collections; import java.util.List; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ISelection; 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.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.Composite; import org.xmind.core.Core; import org.xmind.core.ITopic; import org.xmind.core.event.ICoreEventRegister; import org.xmind.gef.IViewer; import org.xmind.ui.branch.IBranchPolicyDescriptor; import org.xmind.ui.commands.CommandMessages; import org.xmind.ui.commands.ModifyTopicStructureCommand; import org.xmind.ui.mindmap.IBranchPart; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.properties.MindMapPropertySectionPartBase; import org.xmind.ui.resources.ImageDescriptorProvider; import org.xmind.ui.util.MindMapUtils; import org.xmind.ui.viewers.ImageCachedLabelProvider; import org.xmind.ui.viewers.MComboViewer; public class StructurePropertySectionPart extends MindMapPropertySectionPartBase { private static final List<IBranchPolicyDescriptor> NO_BRANCH_POLICY = Collections .emptyList(); private static final String FOLLOW = "org.xmind.ui.properties.structure.follow"; //$NON-NLS-1$ private static class BranchPolicyLabelProvider extends ImageCachedLabelProvider implements ImageDescriptorProvider { protected Image createImage(Object element) { if (element instanceof IBranchPolicyDescriptor) { IBranchPolicyDescriptor desc = (IBranchPolicyDescriptor) element; ImageDescriptor icon = desc.getIcon(); if (icon != null) return icon.createImage(false); } return null; } @Override public ImageDescriptor getImageDescriptor(Object element) { if (element instanceof IBranchPolicyDescriptor) { IBranchPolicyDescriptor desc = (IBranchPolicyDescriptor) element; return desc.getIcon(); } return null; } public String getText(Object element) { if (element instanceof IBranchPolicyDescriptor) { IBranchPolicyDescriptor desc = (IBranchPolicyDescriptor) element; return desc.getName(); } if (element instanceof String) { return PropertyMessages.FollowParentStructure_text; } return super.getText(element); } } private class BranchPolicySelectionChangedListener implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { if (isRefreshing()) return; Object o = ((IStructuredSelection) event.getSelection()) .getFirstElement(); if (o instanceof IBranchPolicyDescriptor) { changeStructure((IBranchPolicyDescriptor) o); } else { doFollowParentStructure(); } } } private MComboViewer structureViewer; // private Button followParentStructureCheck; protected GridLayout createLayout(Composite parent) { GridLayout layout = super.createLayout(parent); layout.verticalSpacing = 7; return layout; } protected void createContent(Composite parent) { structureViewer = new MComboViewer(parent, SWT.NONE); structureViewer.getControl().setLayoutData( new GridData(GridData.FILL, GridData.FILL, true, false)); structureViewer.getControl() .setToolTipText(PropertyMessages.Structure_toolTip); structureViewer.setContentProvider(new ArrayContentProvider()); structureViewer.setLabelProvider(new BranchPolicyLabelProvider()); structureViewer.addSelectionChangedListener( new BranchPolicySelectionChangedListener()); } public void setFocus() { if (structureViewer != null && !structureViewer.getControl().isDisposed()) structureViewer.getControl().setFocus(); } protected void doRefresh() { if (structureViewer != null && !structureViewer.getControl().isDisposed()) { List<IBranchPolicyDescriptor> enableds = getCurrentStructures(); if (getCurrentFollowParentStructure()) structureViewer.setInput(enableds); else { List<Object> list = new ArrayList<Object>(enableds); Object separator = new Object(); list.add(separator); list.add(FOLLOW); structureViewer.setSeparatorImitation(separator); structureViewer.setInput(list); } structureViewer.setSelection(getCurrentStructure()); structureViewer.getControl().setEnabled(!enableds.isEmpty()); } } protected void registerEventListener(Object source, ICoreEventRegister register) { if (source instanceof ITopic) { register.register(Core.StructureClass); } } private void changeStructure(IBranchPolicyDescriptor descriptor) { changeStructureClass(descriptor.getId()); } private void changeStructureClass(String newStructureClass) { List<ITopic> topics = getTopics(); if (!topics.isEmpty()) { ModifyTopicStructureCommand cmd = new ModifyTopicStructureCommand( topics, newStructureClass); cmd.setLabel(CommandMessages.Command_ModifyTopicStructure); saveAndRun(cmd); } } private List<ITopic> getTopics() { Object[] elements = getSelectedElements(); ArrayList<ITopic> list = new ArrayList<ITopic>(elements.length); for (Object o : elements) { if (o instanceof ITopic && !list.contains(o)) list.add((ITopic) o); } return list; } private List<IBranchPolicyDescriptor> getCurrentStructures() { List<IBranchPolicyDescriptor> list = null; IViewer viewer = getActiveViewer(); if (viewer != null) { for (Object o : getSelectedElements()) { if (o instanceof ITopic) { IBranchPart branch = MindMapUtils .findBranch(getGraphicalPart(o, viewer)); if (branch != null) { List<IBranchPolicyDescriptor> applicables = MindMapUI .getBranchPolicyManager() .getApplicableBranchPolicyDescriptors(branch); if (applicables.isEmpty()) return NO_BRANCH_POLICY; if (list == null) { list = new ArrayList<IBranchPolicyDescriptor>( applicables); } else { list.retainAll(applicables); } if (list.isEmpty()) return NO_BRANCH_POLICY; } } } } if (list == null || list.isEmpty()) return NO_BRANCH_POLICY; return list; } private ISelection getCurrentStructure() { String branchPolicyId = null; IViewer viewer = getActiveViewer(); if (viewer != null) { for (Object o : getSelectedElements()) { if (o instanceof ITopic) { IBranchPart branch = MindMapUtils .findBranch(getGraphicalPart(o, viewer)); if (branch != null) { String thisId = branch.getBranchPolicyId(); if (branchPolicyId == null) { branchPolicyId = thisId; } else if (!branchPolicyId.equals(thisId)) { branchPolicyId = null; break; } } } } } if (branchPolicyId != null) { IBranchPolicyDescriptor descriptor = MindMapUI .getBranchPolicyManager() .getBranchPolicyDescriptor(branchPolicyId); if (descriptor != null) { return new StructuredSelection(descriptor); } } return StructuredSelection.EMPTY; } private boolean getCurrentFollowParentStructure() { IViewer viewer = getActiveViewer(); if (viewer == null) return false; for (Object o : getSelectedElements()) { if (!(o instanceof ITopic)) return false; IBranchPart branch = MindMapUtils .findBranch(getGraphicalPart(o, viewer)); if (branch == null || !isFollowParentStructure(branch)) return false; } return true; } private boolean isFollowParentStructure(IBranchPart branch) { return branch.isCentral() || branch.getTopic().getStructureClass() == null; } private void doFollowParentStructure() { changeStructureClass(null); } public void dispose() { super.dispose(); structureViewer = null; } }