/* ****************************************************************************** * 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.tools; import static org.xmind.ui.mindmap.MindMapUI.LABEL_SEPARATOR; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.eclipse.jface.fieldassist.IContentProposal; import org.eclipse.jface.fieldassist.IContentProposalProvider; import org.eclipse.jface.viewers.IFilter; import org.xmind.core.ILabeled; import org.xmind.core.ISheet; import org.xmind.core.ISheetComponent; import org.xmind.core.util.ILabelRefCounter; import org.xmind.gef.part.IPart; import org.xmind.ui.util.MindMapUtils; public class LabelProposalProvider implements IContentProposalProvider { private static final String[] EMPTY = new String[0]; private String[] usedLabels; public LabelProposalProvider(IPart part) { this.usedLabels = findUsedLabels(part); } private String[] findUsedLabels(IPart part) { Object m = MindMapUtils.getRealModel(part); if (m instanceof ILabeled && m instanceof ISheetComponent) { ISheet sheet = ((ISheetComponent) m).getOwnedSheet(); if (sheet != null) { ILabelRefCounter counter = (ILabelRefCounter) sheet .getAdapter(ILabelRefCounter.class); if (counter != null) { String[] array = counter.getCountedRefs().toArray(EMPTY); Arrays.sort(array); return array; } } } return EMPTY; } public IContentProposal[] getProposals(String contents, int position) { Collection<String> labelsBefore = new ArrayList<String>(); int prevSepIndex = contents.lastIndexOf(LABEL_SEPARATOR, position - 1); if (prevSepIndex > 0) { fillLabelList(labelsBefore, prevSepIndex < 0 ? "" : contents.substring(0, prevSepIndex)); //$NON-NLS-1$ } Collection<String> labelsAfter = new ArrayList<String>(); int nextSepIndex = contents.indexOf(LABEL_SEPARATOR, position); if (nextSepIndex > 0) { fillLabelList(labelsAfter, contents.substring(nextSepIndex + 1, contents.length())); } List<String> propTexts = new ArrayList<String>(); for (int i = 0; i < usedLabels.length; i++) { String prop = usedLabels[i]; if (!labelsBefore.contains(prop) && !labelsAfter.contains(prop)) { propTexts.add(prop); } } String prefix = makeLabelText(labelsBefore); String suffix = makeLabelText(labelsAfter);//contents.substring( position ); IFilter filter = makeFilter(contents.substring(prevSepIndex + 1, position).trim()); List<IContentProposal> props = new ArrayList<IContentProposal>( propTexts.size()); for (String propText : propTexts) { if (filter.select(propText)) { props.add(makeContentProposal(prefix, suffix, propText)); } } if (!props.isEmpty()) { props.add(0, makeContentProposal(prefix, suffix, getCurrentLabel( contents, prevSepIndex, nextSepIndex))); } return props.toArray(new IContentProposal[props.size()]); } private String getCurrentLabel(String contents, int prevSepIndex, int nextSepIndex) { if (nextSepIndex < 0) nextSepIndex = contents.length(); return contents.substring(prevSepIndex + 1, nextSepIndex).trim(); } private IFilter makeFilter(final String filterText) { return new IFilter() { int filterLength = filterText.length(); public boolean select(Object toTest) { if (toTest instanceof String) { String propText = (String) toTest; return propText.length() > filterLength && propText.substring(0, filterLength) .equalsIgnoreCase(filterText); } return false; } }; } private String makeLabelText(Collection<String> labels) { StringBuffer sb = new StringBuffer(labels.size() * 10); for (String label : labels) { if (sb.length() > 0) { sb.append(LABEL_SEPARATOR); sb.append(' '); } sb.append(label); } return sb.toString(); } private void fillLabelList(Collection<String> labelList, String contents) { String[] labels = contents.split(LABEL_SEPARATOR); for (int i = 0; i < labels.length; i++) { labelList.add(labels[i].trim()); } } private IContentProposal makeContentProposal(final String prefix, final String suffix, final String proposal) { return new IContentProposal() { String content = null; int preLength = prefix.length(); int sufLength = suffix.length(); int propLength = proposal.length(); int cursorPosition = -1; public String getContent() { if (content == null) { StringBuffer sb = new StringBuffer(preLength + sufLength + propLength + 4); if (preLength > 0) { sb.append(prefix); sb.append(LABEL_SEPARATOR); sb.append(' '); } sb.append(proposal); if (sufLength > 0) { sb.append(LABEL_SEPARATOR); sb.append(' '); sb.append(suffix); } if (propLength > 0 || sufLength > 0) { sb.append(LABEL_SEPARATOR); sb.append(' '); } content = sb.toString(); } return content; } public String getDescription() { return null; } public String getLabel() { return getContent(); } public int getCursorPosition() { if (cursorPosition < 0) { cursorPosition = propLength; if (preLength > 0) { cursorPosition += preLength + 2; } if (propLength > 0 || sufLength > 0) { cursorPosition += 2; } } return cursorPosition; } @Override public String toString() { return getContent(); } }; } }