/* ******************************************************************************
* 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;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IFindReplaceTarget;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.xmind.core.IBoundary;
import org.xmind.core.INotes;
import org.xmind.core.IPlainNotesContent;
import org.xmind.core.IRelationship;
import org.xmind.core.ISheet;
import org.xmind.core.ISheetComponent;
import org.xmind.core.ITopic;
import org.xmind.core.IWorkbook;
import org.xmind.gef.EditDomain;
import org.xmind.gef.GEF;
import org.xmind.gef.IGraphicalViewer;
import org.xmind.gef.Request;
import org.xmind.gef.part.IPart;
import org.xmind.gef.ui.editor.IGraphicalEditor;
import org.xmind.gef.ui.editor.IGraphicalEditorPage;
import org.xmind.ui.IWordContext;
import org.xmind.ui.IWordContextProvider;
import org.xmind.ui.internal.e4models.IModelConstants;
import org.xmind.ui.internal.utils.E4Utils;
import org.xmind.ui.mindmap.IMindMapImages;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.util.MindMapUtils;
/**
* @author Frank Shaka
*/
public class MindMapWordContextProvider implements IWordContextProvider {
private class TopicWordContext implements IWordContext {
private ITopic topic;
private static final String TYPE = "topic"; //$NON-NLS-1$
public TopicWordContext(ITopic topic) {
this.topic = topic;
}
public String getContent() {
return topic.getTitleText();
}
public ImageDescriptor getIcon() {
return MindMapUI.getImages().getTopicIcon(topic, true);
}
public String getName() {
return topic.getTitleText();
}
public boolean replaceWord(int start, int length, String replacement) {
return replaceText(topic, replaceString(topic.getTitleText(), start,
length, replacement));
}
public void reveal() {
revealElement(topic, false);
}
public void revealWord(int start, int length) {
revealInvalidWord(topic, start, length, GEF.REQ_EDIT);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TopicWordContext)
if (this.topic != null
&& this.topic.equals(((TopicWordContext) obj).topic))
return true;
return false;
}
@Override
public int hashCode() {
int result = 17;
result += result * topic.hashCode();
result += result * TYPE.hashCode();
return result;
}
}
private class LabelWordContext implements IWordContext {
private ITopic topic;
private static final String TYPE = "label"; //$NON-NLS-1$
public LabelWordContext(ITopic topic) {
super();
this.topic = topic;
}
public String getContent() {
return MindMapUtils.getLabelText(topic.getLabels());
}
public ImageDescriptor getIcon() {
return MindMapUI.getImages().get(IMindMapImages.LABEL, true);
}
public String getName() {
return NLS.bind(MindMapMessages.WordContext_Label_pattern,
topic.getTitleText());
}
public boolean replaceWord(int start, int length, String replacement) {
return replaceText(topic,
replaceString(MindMapUtils.getLabelText(topic.getLabels()),
start, length, replacement),
MindMapUI.REQ_MODIFY_LABEL);
}
public void reveal() {
editor.getSite().getSelectionProvider()
.setSelection(new StructuredSelection(topic));
}
public void revealWord(int start, int length) {
revealInvalidWord(topic, start, length, MindMapUI.REQ_EDIT_LABEL);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof LabelWordContext)
if (this.topic != null
&& this.topic.equals(((LabelWordContext) obj).topic))
return true;
return false;
}
@Override
public int hashCode() {
int result = 17;
result += result * topic.hashCode();
result += result * TYPE.hashCode();
return result;
}
}
private class NotesWordContext implements IWordContext {
private ITopic topic;
private static final String TYPE = "notes"; //$NON-NLS-1$
public NotesWordContext(ITopic topic) {
super();
this.topic = topic;
}
public String getContent() {
IPlainNotesContent plainNotesContent = (IPlainNotesContent) topic
.getNotes().getContent(INotes.PLAIN);
if (plainNotesContent == null)
return ""; //$NON-NLS-1$
return plainNotesContent.getTextContent();
}
public ImageDescriptor getIcon() {
return MindMapUI.getImages().get(IMindMapImages.NOTES, true);
}
public String getName() {
return NLS.bind(MindMapMessages.WordContext_Notes_pattern,
topic.getTitleText());
}
public boolean replaceWord(int start, int length, String replacement) {
revealWord(start, length);
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
MPart part = E4Utils.findPart(window,
IModelConstants.PART_ID_NOTES);
if (part != null) {
Object obj = part.getObject();
if (obj instanceof IAdaptable) {
ITextViewer viewer = (ITextViewer) ((IAdaptable) obj)
.getAdapter(ITextViewer.class);
if (viewer != null) {
String toFind = viewer.getTextWidget().getText(start,
start + length - 1);
IFindReplaceTarget target = (IFindReplaceTarget) ((IAdaptable) obj)
.getAdapter(IFindReplaceTarget.class);
if (target != null) {
int r = target.findAndSelect(start, toFind, true,
true, false);
if (r > -1) {
target.replaceSelection(replacement);
return true;
}
}
}
}
}
return false;
}
public void reveal() {
revealElement(topic, false);
SafeRunner.run(new SafeRunnable() {
public void run() throws Exception {
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
if (window != null)
E4Utils.showPart(
IModelConstants.COMMAND_SHOW_MODEL_PART, window,
IModelConstants.PART_ID_NOTES, null,
IModelConstants.PART_STACK_ID_RIGHT);
}
});
}
public void revealWord(int start, int length) {
reveal();
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
MPart part = E4Utils.findPart(window,
IModelConstants.PART_ID_NOTES);
if (part != null) {
Object obj = part.getObject();
if (obj instanceof IAdaptable) {
ITextViewer viewer = (ITextViewer) ((IAdaptable) obj)
.getAdapter(ITextViewer.class);
if (viewer != null) {
viewer.setSelectedRange(start, length);
}
}
}
}
@Override
public boolean equals(Object obj) {
if (obj instanceof NotesWordContext)
if (this.topic != null
&& this.topic.equals(((NotesWordContext) obj).topic))
return true;
return false;
}
@Override
public int hashCode() {
int result = 17;
result += result * topic.hashCode();
result += result * TYPE.hashCode();
return result;
}
}
private class BoundaryWordContext implements IWordContext {
private IBoundary boundary;
public BoundaryWordContext(IBoundary boundary) {
this.boundary = boundary;
}
public String getContent() {
return boundary.getTitleText();
}
public ImageDescriptor getIcon() {
return MindMapUI.getImages().getElementIcon(boundary, true);
}
public String getName() {
return boundary.getTitleText();
}
public boolean replaceWord(int start, int length, String replacement) {
return replaceText(boundary, replaceString(boundary.getTitleText(),
start, length, replacement));
}
public void reveal() {
revealElement(boundary, false);
}
public void revealWord(int start, int length) {
revealInvalidWord(boundary, start, length, GEF.REQ_EDIT);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof BoundaryWordContext)
if (this.boundary != null && this.boundary
.equals(((BoundaryWordContext) obj).boundary))
return true;
return false;
}
@Override
public int hashCode() {
return 17 * boundary.hashCode();
}
}
private class RelationshipWordContext implements IWordContext {
private IRelationship relationship;
public RelationshipWordContext(IRelationship relationship) {
this.relationship = relationship;
}
public String getContent() {
return relationship.getTitleText();
}
public ImageDescriptor getIcon() {
return MindMapUI.getImages().getElementIcon(relationship, true);
}
public String getName() {
return relationship.getTitleText();
}
public boolean replaceWord(int start, int length, String replacement) {
return replaceText(relationship, replaceString(
relationship.getTitleText(), start, length, replacement));
}
public void reveal() {
revealElement(relationship, false);
}
public void revealWord(int start, int length) {
revealInvalidWord(relationship, start, length, GEF.REQ_EDIT);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof RelationshipWordContext)
if (this.relationship != null && this.relationship
.equals(((RelationshipWordContext) obj).relationship))
return true;
return false;
}
@Override
public int hashCode() {
return 17 * relationship.hashCode();
}
}
private IGraphicalEditor editor;
/**
*
*/
public MindMapWordContextProvider(IGraphicalEditor editor) {
this.editor = editor;
}
/*
* (non-Javadoc)
* @see org.xmind.ui.IWordContextProvider#getWordContexts()
*/
public List<IWordContext> getWordContexts() {
List<IWordContext> contexts = new ArrayList<IWordContext>();
IWorkbook workbook = (IWorkbook) editor.getAdapter(IWorkbook.class);
if (workbook != null) {
for (ISheet sheet : workbook.getSheets()) {
getContexts(sheet.getRootTopic(), contexts);
for (IRelationship relationship : sheet.getRelationships()) {
contexts.add(new RelationshipWordContext(relationship));
}
}
}
return contexts;
}
private void getContexts(ITopic topic, List<IWordContext> contexts) {
contexts.add(new TopicWordContext(topic));
if (!topic.getLabels().isEmpty()) {
contexts.add(new LabelWordContext(topic));
}
if (!topic.getNotes().isEmpty()) {
contexts.add(new NotesWordContext(topic));
}
for (IBoundary boundary : topic.getBoundaries()) {
contexts.add(new BoundaryWordContext(boundary));
}
for (ITopic child : topic.getAllChildren()) {
getContexts(child, contexts);
}
}
private void revealElement(Object element, boolean makeActive) {
if (makeActive) {
editor.getSite().getPage().activate(editor);
}
editor.getSite().getSelectionProvider()
.setSelection(new StructuredSelection(element));
}
private void revealInvalidWord(ISheetComponent element, int start,
int length, String reqType) {
revealElement(element, true);
IGraphicalEditorPage page = editor.findPage(element.getOwnedSheet());
if (page != null) {
IGraphicalViewer viewer = page.getViewer();
EditDomain domain = page.getEditDomain();
IPart part = viewer.findPart(element);
if (part != null) {
Request request = new Request(reqType).setPrimaryTarget(part)
.setDomain(domain).setViewer(viewer)
.setParameter(GEF.PARAM_FOCUS, Boolean.FALSE)
.setParameter(GEF.PARAM_TEXT_SELECTION,
new TextSelection(start, length));
domain.handleRequest(request);
}
}
}
private boolean replaceText(ISheetComponent element, String newText) {
return replaceText(element, newText, GEF.REQ_MODIFY);
}
private boolean replaceText(ISheetComponent element, String newText,
String reqType) {
revealElement(element, false);
IGraphicalEditorPage page = editor.findPage(element.getOwnedSheet());
if (page != null) {
IGraphicalViewer viewer = page.getViewer();
EditDomain domain = page.getEditDomain();
IPart part = viewer.findPart(element);
if (part != null) {
Request request = new Request(reqType).setPrimaryTarget(part)
.setDomain(domain).setViewer(viewer)
.setParameter(GEF.PARAM_TEXT, newText);
domain.handleRequest(request);
return true;
}
}
return false;
}
private static String replaceString(String text, int start, int length,
String replacement) {
return text.substring(0, start) + replacement
+ text.substring(start + length);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof MindMapWordContextProvider) {
MindMapWordContextProvider provider = (MindMapWordContextProvider) obj;
if (editor != null && editor.equals(provider.editor))
return true;
}
return false;
}
@Override
public int hashCode() {
return 17 * editor.hashCode();
}
}