### Eclipse Workspace Patch 1.0 #P org.eclipse.mylyn.wikitext.tasks.ui Index: plugin.properties =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.wikitext.tasks.ui/plugin.properties,v retrieving revision 1.2 diff -u -r1.2 plugin.properties --- plugin.properties 9 Jan 2009 04:37:29 -0000 1.2 +++ plugin.properties 16 Jan 2009 17:16:34 -0000 @@ -18,4 +18,19 @@ taskEditorExtension.name.2 = Textile Bugzilla Dialect taskEditorExtension.name.3 = TracWiki taskEditorExtension.name.4 = MediaWiki -taskEditorExtension.name.5 = Confluence \ No newline at end of file +taskEditorExtension.name.5 = Confluence + +structureBridge.name.0 = WikiText Structure Bridge +uiBridge.name.0 = WikiText Context UI Bridge + +commands.category.name=WikiText Context +commands.category.description=WikiText Task-Focused Interface Commands +command.description.0 = Toggle Active Folding +command.name.0 = Toggle Active Folding +action.label.0 = Focus Editor on Active Task +action.tooltip.0 = Automatically Fold Uninteresting Elements + +InterestIncrementAction.label = Mark as Landmark +InterestIncrementAction.tooltip = Mark the selected element as a landmark +InterestDecrementAction.label = Remove from Context +InterestDecrementAction.tooltip = Mark selected element as uninteresting Index: build.properties =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.wikitext.tasks.ui/build.properties,v retrieving revision 1.1 diff -u -r1.1 build.properties --- build.properties 4 Dec 2008 19:14:52 -0000 1.1 +++ build.properties 16 Jan 2009 17:16:34 -0000 @@ -4,4 +4,5 @@ .,\ plugin.properties,\ about.html,\ - plugin.xml + plugin.xml,\ + icons/ Index: plugin.xml =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.wikitext.tasks.ui/plugin.xml,v retrieving revision 1.1 diff -u -r1.1 plugin.xml --- plugin.xml 4 Dec 2008 19:14:52 -0000 1.1 +++ plugin.xml 16 Jan 2009 17:16:34 -0000 @@ -2,6 +2,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: META-INF/MANIFEST.MF =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.wikitext.tasks.ui/META-INF/MANIFEST.MF,v retrieving revision 1.2 diff -u -r1.2 MANIFEST.MF --- META-INF/MANIFEST.MF 4 Dec 2008 19:29:15 -0000 1.2 +++ META-INF/MANIFEST.MF 16 Jan 2009 17:16:34 -0000 @@ -17,6 +17,10 @@ org.eclipse.core.resources, org.eclipse.mylyn.tasks.ui;bundle-version="[3.0.2,4.0.0)", org.eclipse.mylyn.tasks.core;bundle-version="[3.0.2,4.0.0)", + org.eclipse.mylyn.context.core;bundle-version="[3.0,4.0.0)", + org.eclipse.mylyn.context.ui;bundle-version="[3.0,4.0.0)", + org.eclipse.mylyn.monitor.core;bundle-version="[3.0,4.0.0)", + org.eclipse.mylyn.monitor.ui;bundle-version="[3.0,4.0.0)", org.eclipse.mylyn.wikitext.confluence.core;bundle-version="[0.9.3,1.0.0)", org.eclipse.mylyn.wikitext.confluence.ui;bundle-version="[0.9.3,1.0.0)", org.eclipse.mylyn.wikitext.mediawiki.core;bundle-version="[0.9.3,1.0.0)", @@ -30,6 +34,9 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin -Export-Package: org.eclipse.mylyn.internal.wikitext.tasks.ui.editor;x-internal:=true, +Export-Package: org.eclipse.mylyn.internal.wikitext.tasks.ui;x-internal:=true, + org.eclipse.mylyn.internal.wikitext.tasks.ui.actions;x-internal:=true, + org.eclipse.mylyn.internal.wikitext.tasks.ui.editor;x-internal:=true, org.eclipse.mylyn.internal.wikitext.tasks.ui.util;x-internal:=true, org.eclipse.mylyn.wikitext.tasks.ui.editor +Bundle-Activator: org.eclipse.mylyn.internal.wikitext.tasks.ui.WikiTextTasksUiPlugin Index: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextUiStartup.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextUiStartup.java diff -N src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextUiStartup.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextUiStartup.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009 David Green and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * David Green - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.wikitext.tasks.ui; + +import org.eclipse.mylyn.context.ui.IContextUiStartup; + +/** + * @author David Green + */ +public class WikiTextContextUiStartup implements IContextUiStartup { + + public void lazyStartup() { + WikiTextTasksUiPlugin.getDefault().contextUiStartup(); + } + +} Index: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/ActiveFoldingEditorTracker.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/ActiveFoldingEditorTracker.java diff -N src/org/eclipse/mylyn/internal/wikitext/tasks/ui/ActiveFoldingEditorTracker.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/wikitext/tasks/ui/ActiveFoldingEditorTracker.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2009 David Green and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * David Green - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.wikitext.tasks.ui; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.mylyn.internal.wikitext.ui.editor.IFoldingStructure; +import org.eclipse.mylyn.monitor.ui.AbstractEditorTracker; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; + +/** + * + * based on implementation of ActiveFoldingEditorTracker in org.eclipse.mylyn.java.ui + * + * @author David Green + */ +public class ActiveFoldingEditorTracker extends AbstractEditorTracker { + + private final Map partToListener = new HashMap(); + + public ActiveFoldingEditorTracker(IWorkbench workbench) { + install(workbench); + } + + @Override + public void install(IWorkbench workbench) { + super.install(workbench); + for (IWorkbenchWindow window : workbench.getWorkbenchWindows()) { + for (IWorkbenchPage page : window.getPages()) { + for (IEditorReference reference : page.getEditorReferences()) { + IEditorPart editorPart = reference.getEditor(false); + if (editorPart != null) { + editorOpened(editorPart); + } + } + } + } + } + + @Override + protected void editorBroughtToTop(IEditorPart part) { + // nothing to do + } + + @Override + protected void editorClosed(IEditorPart part) { + ActiveFoldingListener listener = partToListener.remove(part); + if (listener != null) { + listener.dispose(); + } + } + + @Override + protected void editorOpened(IEditorPart part) { + IFoldingStructure foldingStructure = (IFoldingStructure) part.getAdapter(IFoldingStructure.class); + if (foldingStructure == null) { + return; + } + if (partToListener.containsKey(part)) { + return; + } + partToListener.put(part, new ActiveFoldingListener(part, foldingStructure)); + } + +} Index: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextLabelProvider.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextLabelProvider.java diff -N src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextLabelProvider.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextLabelProvider.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009 David Green and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * David Green - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.wikitext.tasks.ui; + +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.mylyn.context.core.AbstractContextStructureBridge; +import org.eclipse.mylyn.context.core.ContextCore; +import org.eclipse.mylyn.context.core.IInteractionElement; +import org.eclipse.swt.graphics.Image; + +/** + * + * @author David Green + */ +public class WikiTextLabelProvider implements ILabelProvider { + + public Image getImage(Object element) { + // no images yet, see bug 260483 + return null; + } + + public String getText(Object element) { + if (element instanceof IInteractionElement) { + IInteractionElement interactionElement = (IInteractionElement) element; + String handleIdentifier = interactionElement.getHandleIdentifier(); + AbstractContextStructureBridge structureBridge = ContextCore.getStructureBridge(interactionElement.getContentType()); + return structureBridge.getLabel(structureBridge.getObjectForHandle(handleIdentifier)); + } else { + AbstractContextStructureBridge structureBridge = ContextCore.getStructureBridge(element); + return structureBridge == null ? element.toString() : structureBridge.getLabel(element); + } + } + + public void addListener(ILabelProviderListener listener) { + // no need + } + + public void dispose() { + // nothing to do + } + + public boolean isLabelProperty(Object element, String property) { + return true; + } + + public void removeListener(ILabelProviderListener listener) { + // no need + } + +} Index: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextStructureBridge.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextStructureBridge.java diff -N src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextStructureBridge.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextStructureBridge.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,296 @@ +/******************************************************************************* + * Copyright (c) 2009 David Green and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * David Green - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.wikitext.tasks.ui; + +import java.io.BufferedInputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.content.IContentDescription; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.mylyn.context.core.AbstractContextStructureBridge; +import org.eclipse.mylyn.context.core.ContextCore; +import org.eclipse.mylyn.wikitext.core.WikiText; +import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage; +import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineItem; +import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineParser; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PlatformUI; + +/** + * A Mylyn {@link AbstractContextStructureBridge context structure bridge} for wikitext files. + * + * @author David Green + */ +public class WikiTextContextStructureBridge extends AbstractContextStructureBridge { + + private static final char HANDLE_FILE_SEPARATOR = ';'; + + public static final String CONTENT_TYPE = WikiText.CONTENT_TYPE; + + @Override + public boolean acceptsObject(Object object) { + if (object instanceof OutlineItem) { + return true; + } else if (object instanceof IFile) { + IFile file = (IFile) object; + + try { + IContentDescription description = file.getContentDescription(); + if (description != null) { + IContentType contentType = description.getContentType(); + if (contentType != null) { + if (isWikiText(contentType)) { + return true; + } + } + } + } catch (CoreException e) { + // ignore + } + + String languageName = WikiText.getMarkupLanguageNameForFilename(file.getName()); + return languageName != null; + } + return false; + } + + private boolean isWikiText(IContentType contentType) { + if (WikiText.CONTENT_TYPE.equals(contentType.getId())) { + return true; + } + IContentType baseType = contentType.getBaseType(); + if (baseType != null) { + return isWikiText(baseType); + } + return false; + } + + @Override + public boolean canBeLandmark(String handle) { + if (handle == null) { + return false; + } else { + return handle.indexOf(HANDLE_FILE_SEPARATOR) != -1; + } + } + + @Override + public boolean canFilter(Object element) { + return true; + } + + @Override + public List getChildHandles(String handle) { + Object object = getObjectForHandle(handle); + if (object instanceof OutlineItem) { + OutlineItem item = (OutlineItem) object; + if (!item.getChildren().isEmpty()) { + List handles = new ArrayList(item.getChildren().size()); + for (OutlineItem child : item.getChildren()) { + handles.add(getHandleIdentifier(child)); + } + return handles; + } + } + return Collections.emptyList(); + } + + @Override + public String getContentType() { + return CONTENT_TYPE; + } + + @Override + public String getContentType(String elementHandle) { + if (elementHandle.indexOf(HANDLE_FILE_SEPARATOR) == -1) { + return parentContentType; + } + return CONTENT_TYPE; + } + + @Override + public String getHandleForOffsetInObject(Object object, int offset) { + IResource resource = null; + try { + if (object instanceof IResource) { + resource = (IResource) object; + } else if (object instanceof IMarker) { + resource = ((IMarker) object).getResource(); + } else { + try { + // works with ConcreteMarker without creating a compile-time dependency on internals + IMarker marker = (IMarker) object.getClass().getMethod("getMarker").invoke(object); //$NON-NLS-1$ + resource = marker.getResource(); + } catch (Exception e) { + // ignore + } + } + } catch (Exception e) { + return null; + } + if (resource instanceof IFile) { + IFile file = (IFile) resource; + if (acceptsObject(file)) { + OutlineItem outline = getOutline(file); + if (outline != null) { + OutlineItem item = outline.findNearestMatchingOffset(offset); + if (item != null) { + return getHandleIdentifier(item); + } + } + } + } + return null; + } + + @Override + public String getLabel(Object object) { + if (object instanceof OutlineItem) { + OutlineItem item = (OutlineItem) object; + if (item.getParent() == null) { + return getFile(item).getName(); + } else { + return item.getLabel(); + } + } + return ""; //$NON-NLS-1$ + } + + @Override + public Object getObjectForHandle(String handle) { + if (handle == null) { + return null; + } + int idxOfSeparator = handle.indexOf(HANDLE_FILE_SEPARATOR); + String filename = handle; + if (idxOfSeparator != -1) { + filename = handle.substring(0, idxOfSeparator); + } + IFile file; + try { + file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(filename)); + } catch (Exception e) { + // be error-tolerant since we don't know much about the handle at this point + return null; + } + if (file != null) { + if (idxOfSeparator != -1) { + String headingId = handle.substring(idxOfSeparator + 1); + OutlineItem outline = getOutline(file); + if (outline != null) { + OutlineItem item = outline.findItemById(headingId); + return item; + } + } else { + return file; + } + } + return null; + } + + @Override + public String getParentHandle(String handle) { + Object object = getObjectForHandle(handle); + if (object instanceof OutlineItem) { + OutlineItem item = (OutlineItem) object; + if (item.getParent() != null) { + return getHandleIdentifier(item.getParent()); + } else { + return getHandleIdentifier(getFile(item)); + } + } else if (object instanceof IFile) { + AbstractContextStructureBridge parentBridge = ContextCore.getStructureBridge(parentContentType); + return parentBridge.getParentHandle(handle); + } + return null; + } + + @Override + public boolean isDocument(String handle) { + Object object = getObjectForHandle(handle); + if (object instanceof OutlineItem) { + OutlineItem item = (OutlineItem) object; + return item.getParent() == null; + } + return false; + } + + @Override + public String getHandleIdentifier(Object object) { + if (object instanceof OutlineItem) { + OutlineItem item = (OutlineItem) object; + return item.getResourcePath() + HANDLE_FILE_SEPARATOR + item.getId(); + } else if (object instanceof IFile && acceptsObject(object)) { + return ((IFile) object).getFullPath().toString(); + } + return null; + } + + private IPath getFullPath(OutlineItem item) { + String resourcePath = item.getResourcePath(); + return resourcePath == null ? null : new Path(resourcePath); + } + + private OutlineItem getOutline(IFile file) { + // FIXME: is editor integration the way to go?? we probably need some kind of core model + IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); + if (editorPart != null) { + OutlineItem outline = (OutlineItem) editorPart.getAdapter(OutlineItem.class); + if (outline != null) { + return outline; + } + } + MarkupLanguage markupLanguage = WikiText.getMarkupLanguageForFilename(file.getName()); + if (markupLanguage != null) { + OutlineParser parser = new OutlineParser(markupLanguage); + try { + String contents = getContents(file); + OutlineItem outline = parser.parse(contents); + outline.setResourcePath(file.getFullPath().toString()); + return outline; + } catch (Exception e) { + // ignore + return null; + } + } + return null; + } + + private String getContents(IFile file) throws Exception { + String charset = file.getCharset(); + StringWriter writer = new StringWriter(); + Reader reader = new InputStreamReader(new BufferedInputStream(file.getContents()), charset); + int i; + while ((i = reader.read()) != -1) { + writer.write(i); + } + return writer.toString(); + } + + IFile getFile(OutlineItem item) { + IPath fullPath = getFullPath(item); + + return fullPath == null ? null : ResourcesPlugin.getWorkspace().getRoot().getFile(fullPath); + } +} Index: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextTasksUiPlugin.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextTasksUiPlugin.java diff -N src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextTasksUiPlugin.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextTasksUiPlugin.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2009 David Green and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * David Green - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.wikitext.tasks.ui; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.mylyn.monitor.ui.MonitorUi; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * + * @author David Green + */ +public class WikiTextTasksUiPlugin extends AbstractUIPlugin { + /** + * the preference key for active folding + */ + public static final String PREF_ACTIVE_FOLDING_ENABLED = "org.eclipse.mylyn.context.ui.editor.folding.enabled"; //$NON-NLS-1$ + + private static WikiTextTasksUiPlugin plugin; + + private WikiTextUserInteractionMonitor userInteractionMonitor; + + private ActiveFoldingEditorTracker activeFoldingEditorTracker; + + public WikiTextTasksUiPlugin() { + plugin = this; + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + } + + @Override + public void stop(BundleContext context) throws Exception { + if (userInteractionMonitor != null) { + MonitorUi.getSelectionMonitors().remove(userInteractionMonitor); + userInteractionMonitor = null; + } + if (activeFoldingEditorTracker != null) { + activeFoldingEditorTracker.dispose(PlatformUI.getWorkbench()); + activeFoldingEditorTracker = null; + } + plugin = null; + super.stop(context); + } + + public static WikiTextTasksUiPlugin getDefault() { + return plugin; + } + + public void log(Throwable ce) { + if (ce instanceof CoreException) { + getLog().log(((CoreException) ce).getStatus()); + } else { + log(IStatus.ERROR, ce.getMessage(), ce); + } + } + + public void log(int severity, String message, Throwable exception) { + if (message == null) { + message = ""; //$NON-NLS-1$ + } + ILog log = getLog(); + IStatus status = null; + if (exception instanceof CoreException) { + status = ((CoreException) exception).getStatus(); + } + if (status == null) { + status = new Status(severity, getPluginId(), severity, message, exception); + } + log.log(status); + } + + public String getPluginId() { + return getBundle().getSymbolicName(); + } + + public IStatus createStatus(int statusCode, Throwable exception) { + return createStatus(null, statusCode, exception); + } + + public IStatus createStatus(String message, int statusCode, Throwable exception) { + if (message == null && exception != null) { + message = exception.getClass().getName() + ": " + exception.getMessage(); //$NON-NLS-1$ + } + Status status = new Status(statusCode, getPluginId(), statusCode, message, exception); + return status; + } + + void contextUiStartup() { + userInteractionMonitor = new WikiTextUserInteractionMonitor(); + MonitorUi.getSelectionMonitors().add(userInteractionMonitor); + + activeFoldingEditorTracker = new ActiveFoldingEditorTracker(PlatformUI.getWorkbench()); + } + +} Index: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/actions/ToggleActiveFoldingEditorActionDelegate.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/actions/ToggleActiveFoldingEditorActionDelegate.java diff -N src/org/eclipse/mylyn/internal/wikitext/tasks/ui/actions/ToggleActiveFoldingEditorActionDelegate.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/wikitext/tasks/ui/actions/ToggleActiveFoldingEditorActionDelegate.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 David Green and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * David Green - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.wikitext.tasks.ui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.mylyn.internal.wikitext.tasks.ui.WikiTextTasksUiPlugin; +import org.eclipse.ui.IEditorActionDelegate; +import org.eclipse.ui.IEditorPart; + +public class ToggleActiveFoldingEditorActionDelegate implements IEditorActionDelegate { + + public void setActiveEditor(IAction action, IEditorPart targetEditor) { + action.setChecked(isActiveFoldingEnabled()); + } + + private boolean isActiveFoldingEnabled() { + return WikiTextTasksUiPlugin.getDefault().getPluginPreferences().getBoolean( + WikiTextTasksUiPlugin.PREF_ACTIVE_FOLDING_ENABLED); + } + + public void run(IAction action) { + WikiTextTasksUiPlugin.getDefault().getPluginPreferences().setValue(WikiTextTasksUiPlugin.PREF_ACTIVE_FOLDING_ENABLED, + action.isChecked()); + } + + public void selectionChanged(IAction action, ISelection selection) { + // ignore + + } + +} Index: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextUserInteractionMonitor.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextUserInteractionMonitor.java diff -N src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextUserInteractionMonitor.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextUserInteractionMonitor.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2009 David Green and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * David Green - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.wikitext.tasks.ui; + +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.mylyn.monitor.ui.AbstractUserInteractionMonitor; +import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineItem; +import org.eclipse.ui.IWorkbenchPart; + +/** + * + * @author David Green + */ +class WikiTextUserInteractionMonitor extends AbstractUserInteractionMonitor { + + @Override + protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection, boolean contributeToContext) { + if (selection instanceof ITextSelection) { + OutlineItem item = (OutlineItem) part.getAdapter(OutlineItem.class); + if (item != null) { + OutlineItem relevantItem = item.findNearestMatchingOffset(((ITextSelection) selection).getOffset()); + if (relevantItem == null) { + relevantItem = item; + } + handleElementSelection(part, relevantItem, contributeToContext); + } + } else if (selection instanceof IStructuredSelection) { + for (Object element : ((IStructuredSelection) selection).toArray()) { + if (element instanceof OutlineItem) { + handleElementSelection(part, element, contributeToContext); + } + } + } + } + +} Index: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/ActiveFoldingListener.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/ActiveFoldingListener.java diff -N src/org/eclipse/mylyn/internal/wikitext/tasks/ui/ActiveFoldingListener.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/wikitext/tasks/ui/ActiveFoldingListener.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2009 David Green and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * David Green - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.wikitext.tasks.ui; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Preferences; +import org.eclipse.core.runtime.Preferences.IPropertyChangeListener; +import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; +import org.eclipse.mylyn.context.core.AbstractContextListener; +import org.eclipse.mylyn.context.core.AbstractContextStructureBridge; +import org.eclipse.mylyn.context.core.ContextCore; +import org.eclipse.mylyn.context.core.IInteractionContext; +import org.eclipse.mylyn.context.core.IInteractionElement; +import org.eclipse.mylyn.internal.wikitext.ui.editor.IFoldingStructure; +import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineItem; +import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineItem.Visitor; +import org.eclipse.ui.IEditorPart; + +/** + * + * based on implementation of ActiveFoldingListener in org.eclipse.mylyn.java.ui + * + * @author David Green + */ +class ActiveFoldingListener extends AbstractContextListener { + + private final IEditorPart part; + + private final IFoldingStructure foldingStructure; + + private IPropertyChangeListener preferenceListener = new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + if (WikiTextTasksUiPlugin.PREF_ACTIVE_FOLDING_ENABLED.equals(event.getProperty())) { + Object newValue = event.getNewValue(); + updateFolding(Boolean.TRUE.toString().equals(newValue.toString())); + } + } + }; + + private boolean foldingEnabled; + + private final AbstractContextStructureBridge bridge; + + public ActiveFoldingListener(IEditorPart part, IFoldingStructure foldingStructure) { + this.part = part; + this.foldingStructure = foldingStructure; + bridge = ContextCore.getStructureBridge(WikiTextContextStructureBridge.CONTENT_TYPE); + ContextCore.getContextManager().addListener(this); + Preferences pluginPreferences = WikiTextTasksUiPlugin.getDefault().getPluginPreferences(); + pluginPreferences.addPropertyChangeListener(preferenceListener); + updateFolding(pluginPreferences.getBoolean(WikiTextTasksUiPlugin.PREF_ACTIVE_FOLDING_ENABLED)); + } + + private void updateFolding(boolean foldingEnabled) { + this.foldingEnabled = foldingEnabled; + updateFolding(); + } + + private void updateFolding() { + if (!foldingStructure.isFoldingEnabled()) { + return; + } + if (!foldingEnabled || !ContextCore.getContextManager().isContextActive()) { + foldingStructure.expandAll(); + } else { + OutlineItem outline = (OutlineItem) part.getAdapter(OutlineItem.class); + if (outline != null) { + final List toExpand = new ArrayList(); + outline.accept(new Visitor() { + public boolean visit(OutlineItem item) { + String identifier = bridge.getHandleIdentifier(item); + IInteractionElement element = ContextCore.getContextManager().getElement(identifier); + if (element != null && element.getInterest().isInteresting()) { + toExpand.add(item); + } + return true; + } + }); + if (toExpand.isEmpty()) { + foldingStructure.collapseAll(); + } else { + foldingStructure.expandElementsExclusive(toExpand); + } + } + } + } + + @Override + public void contextActivated(IInteractionContext context) { + if (foldingStructure.isFoldingEnabled()) { + updateFolding(); + } + } + + @Override + public void contextCleared(IInteractionContext context) { + if (foldingStructure.isFoldingEnabled()) { + if (!foldingEnabled || !ContextCore.getContextManager().isContextActive()) { + foldingStructure.expandAll(); + } else { + foldingStructure.collapseAll(); + } + } + } + + @Override + public void contextDeactivated(IInteractionContext context) { + if (foldingStructure.isFoldingEnabled()) { + foldingStructure.expandAll(); + } + } + + @Override + public void interestChanged(List elements) { + if (foldingStructure.isFoldingEnabled()) { + updateFolding(); + } + } + + public void dispose() { + if (preferenceListener != null) { + WikiTextTasksUiPlugin.getDefault().getPluginPreferences().removePropertyChangeListener(preferenceListener); + preferenceListener = null; + } + ContextCore.getContextManager().removeListener(this); + } + +} Index: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextUiBridge.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextUiBridge.java diff -N src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextUiBridge.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/wikitext/tasks/ui/WikiTextContextUiBridge.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2009 David Green and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * David Green - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.wikitext.tasks.ui; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.mylyn.context.core.AbstractContextStructureBridge; +import org.eclipse.mylyn.context.core.ContextCore; +import org.eclipse.mylyn.context.core.IInteractionElement; +import org.eclipse.mylyn.context.ui.AbstractContextUiBridge; +import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineItem; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.part.IShowInTarget; +import org.eclipse.ui.part.ShowInContext; +import org.eclipse.ui.views.contentoutline.ContentOutlinePage; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; + +/** + * a UI context bridge for WikiText. + * + * @author David Green + */ +public class WikiTextContextUiBridge extends AbstractContextUiBridge { + + public WikiTextContextUiBridge() { + } + + @Override + public boolean acceptsEditor(IEditorPart editorPart) { + return editorPart.getAdapter(OutlineItem.class) != null; + } + + @Override + public List getContentOutlineViewers(IEditorPart editorPart) { + List viewers = new ArrayList(); + if (acceptsEditor(editorPart)) { + try { + IContentOutlinePage outlinePage = (IContentOutlinePage) editorPart.getAdapter(IContentOutlinePage.class); + if (outlinePage != null) { + Method method = ContentOutlinePage.class.getDeclaredMethod("getTreeViewer", new Class[] {}); //$NON-NLS-1$ + method.setAccessible(true); + viewers.add((TreeViewer) method.invoke(outlinePage, new Object[] {})); + } + } catch (Exception e) { + // ignore + } + } + return viewers; + } + + @Override + public String getContentType() { + return WikiTextContextStructureBridge.CONTENT_TYPE; + } + + @Override + public Object getObjectForTextSelection(TextSelection selection, IEditorPart editor) { + OutlineItem outline = (OutlineItem) editor.getAdapter(OutlineItem.class); + if (outline != null && selection != null) { + return outline.findNearestMatchingOffset(selection.getOffset()); + } + return outline; + } + + @Override + public IInteractionElement getElement(IEditorInput input) { + Object adapter = input.getAdapter(OutlineItem.class); + if (adapter != null) { + String handle = ContextCore.getStructureBridge(adapter).getHandleIdentifier(adapter); + return ContextCore.getContextManager().getElement(handle); + } + return null; + } + + @Override + public void open(IInteractionElement element) { + AbstractContextStructureBridge structureBridge = ContextCore.getStructureBridge(WikiTextContextStructureBridge.CONTENT_TYPE); + if (structureBridge instanceof WikiTextContextStructureBridge) { + Object object = structureBridge.getObjectForHandle(element.getHandleIdentifier()); + OutlineItem item = null; + if (object instanceof OutlineItem) { + item = (OutlineItem) object; + object = ((WikiTextContextStructureBridge) structureBridge).getFile(item); + } + if (object instanceof IFile) { + FileEditorInput editorInput = new FileEditorInput((IFile) object); + try { + IEditorPart editor = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow() + .getActivePage() + .openEditor(editorInput, "org.eclipse.mylyn.wikitext.ui.editor.markupEditor"); //$NON-NLS-1$ + if (item != null && editor instanceof IShowInTarget) { + ((IShowInTarget) editor).show(new ShowInContext(editorInput, new StructuredSelection(item))); + } + } catch (PartInitException e) { + WikiTextTasksUiPlugin.getDefault().log(e); + } + } + } + + } + + @Override + public void close(IInteractionElement element) { + try { + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + if (page != null) { + List editors = new ArrayList(4); + for (IEditorReference reference : page.getEditorReferences()) { + try { + if (reference.getEditorInput() instanceof IFileEditorInput) { + IFileEditorInput input = (IFileEditorInput) reference.getEditorInput(); + if (input.getFile().getFullPath().toString().equals(element.getHandleIdentifier())) { + editors.add(reference); + } + } + } catch (PartInitException e) { + // ignore + } + } + if (!editors.isEmpty()) { + page.closeEditors(editors.toArray(new IEditorReference[editors.size()]), true); + } + } + } catch (Throwable t) { + WikiTextTasksUiPlugin.getDefault().log(t); + } + } + +}