| /******************************************************************************* |
| * Copyright (c) 2001, 2004 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| * Jens Lukowski/Innoopract - initial renaming/restructuring |
| * |
| *******************************************************************************/ |
| package org.eclipse.wst.sse.ui.internal; |
| |
| import java.io.IOException; |
| import java.lang.reflect.Method; |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.ResourceBundle; |
| import java.util.Timer; |
| import java.util.TimerTask; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IStorage; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.ILog; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; |
| import org.eclipse.emf.common.command.Command; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.GroupMarker; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.IStatusLineManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.text.DefaultInformationControl; |
| import org.eclipse.jface.text.DocumentEvent; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IDocumentListener; |
| import org.eclipse.jface.text.IInformationControl; |
| import org.eclipse.jface.text.IInformationControlCreator; |
| import org.eclipse.jface.text.IRegion; |
| import org.eclipse.jface.text.ITextHover; |
| import org.eclipse.jface.text.ITextOperationTarget; |
| import org.eclipse.jface.text.ITextViewer; |
| import org.eclipse.jface.text.ITextViewerExtension; |
| import org.eclipse.jface.text.ITextViewerExtension2; |
| import org.eclipse.jface.text.source.ICharacterPairMatcher; |
| import org.eclipse.jface.text.source.ISourceViewer; |
| import org.eclipse.jface.text.source.IVerticalRuler; |
| import org.eclipse.jface.text.source.LineChangeHover; |
| import org.eclipse.jface.text.source.SourceViewerConfiguration; |
| import org.eclipse.jface.text.source.projection.ProjectionSupport; |
| import org.eclipse.jface.text.source.projection.ProjectionViewer; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.StyledText; |
| import org.eclipse.swt.dnd.DND; |
| import org.eclipse.swt.dnd.DropTarget; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.events.MouseMoveListener; |
| import org.eclipse.swt.events.MouseTrackAdapter; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IEditorActionBarContributor; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IEditorSite; |
| import org.eclipse.ui.IFileEditorInput; |
| import org.eclipse.ui.IPageLayout; |
| import org.eclipse.ui.IStorageEditorInput; |
| import org.eclipse.ui.IWorkbenchActionConstants; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.editors.text.EditorsUI; |
| import org.eclipse.ui.editors.text.ITextEditorHelpContextIds; |
| import org.eclipse.ui.editors.text.TextEditor; |
| import org.eclipse.ui.help.IWorkbenchHelpSystem; |
| import org.eclipse.ui.ide.IDEActionFactory; |
| import org.eclipse.ui.part.EditorActionBarContributor; |
| import org.eclipse.ui.part.IShowInTargetList; |
| import org.eclipse.ui.progress.IWorkbenchSiteProgressService; |
| import org.eclipse.ui.progress.UIJob; |
| import org.eclipse.ui.texteditor.ChainedPreferenceStore; |
| import org.eclipse.ui.texteditor.DefaultRangeIndicator; |
| import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; |
| import org.eclipse.ui.texteditor.IDocumentProvider; |
| import org.eclipse.ui.texteditor.IDocumentProviderExtension; |
| import org.eclipse.ui.texteditor.IElementStateListener; |
| import org.eclipse.ui.texteditor.IStatusField; |
| import org.eclipse.ui.texteditor.ITextEditor; |
| import org.eclipse.ui.texteditor.ITextEditorActionConstants; |
| import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; |
| import org.eclipse.ui.texteditor.IUpdate; |
| import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; |
| import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; |
| import org.eclipse.ui.texteditor.TextOperationAction; |
| import org.eclipse.ui.views.contentoutline.IContentOutlinePage; |
| import org.eclipse.ui.views.properties.IPropertySheetPage; |
| import org.eclipse.wst.sse.core.internal.document.IDocumentCharsetDetector; |
| import org.eclipse.wst.sse.core.internal.encoding.EncodingMemento; |
| import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener; |
| import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; |
| import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager; |
| import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; |
| import org.eclipse.wst.sse.core.internal.text.IExecutionDelegatable; |
| import org.eclipse.wst.sse.core.internal.undo.IStructuredTextUndoManager; |
| import org.eclipse.wst.sse.core.internal.util.StringUtils; |
| import org.eclipse.wst.sse.ui.internal.actions.ActionDefinitionIds; |
| import org.eclipse.wst.sse.ui.internal.actions.StructuredTextEditorActionConstants; |
| import org.eclipse.wst.sse.ui.internal.contentoutline.StructuredTextEditorContentOutlinePage; |
| import org.eclipse.wst.sse.ui.internal.debug.BreakpointRulerAction; |
| import org.eclipse.wst.sse.ui.internal.debug.EditBreakpointAction; |
| import org.eclipse.wst.sse.ui.internal.debug.ManageBreakpointAction; |
| import org.eclipse.wst.sse.ui.internal.debug.ToggleBreakpointAction; |
| import org.eclipse.wst.sse.ui.internal.debug.ToggleBreakpointsTarget; |
| import org.eclipse.wst.sse.ui.internal.editor.EditorExecutionContext; |
| import org.eclipse.wst.sse.ui.internal.editor.EditorModelUtil; |
| import org.eclipse.wst.sse.ui.internal.editor.IHelpContextIds; |
| import org.eclipse.wst.sse.ui.internal.editor.StructuredModelDocumentProvider; |
| import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder; |
| import org.eclipse.wst.sse.ui.internal.hyperlink.OpenHyperlinkAction; |
| import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames; |
| import org.eclipse.wst.sse.ui.internal.projection.IStructuredTextFoldingProvider; |
| import org.eclipse.wst.sse.ui.internal.properties.ConfigurablePropertySheetPage; |
| import org.eclipse.wst.sse.ui.internal.properties.ShowPropertiesAction; |
| import org.eclipse.wst.sse.ui.internal.provisional.StructuredTextViewerConfiguration; |
| import org.eclipse.wst.sse.ui.internal.provisional.extensions.ConfigurationPointCalculator; |
| import org.eclipse.wst.sse.ui.internal.provisional.extensions.ISourceEditingTextTools; |
| import org.eclipse.wst.sse.ui.internal.provisional.extensions.breakpoint.NullSourceEditingTextTools; |
| import org.eclipse.wst.sse.ui.internal.provisional.views.contentoutline.ContentOutlineConfiguration; |
| import org.eclipse.wst.sse.ui.internal.provisional.views.contentoutline.StructuredContentOutlineConfiguration; |
| import org.eclipse.wst.sse.ui.internal.provisional.views.properties.PropertySheetConfiguration; |
| import org.eclipse.wst.sse.ui.internal.provisional.views.properties.StructuredPropertySheetConfiguration; |
| import org.eclipse.wst.sse.ui.internal.selection.SelectionHistory; |
| import org.eclipse.wst.sse.ui.internal.selection.StructureSelectEnclosingAction; |
| import org.eclipse.wst.sse.ui.internal.selection.StructureSelectHistoryAction; |
| import org.eclipse.wst.sse.ui.internal.selection.StructureSelectNextAction; |
| import org.eclipse.wst.sse.ui.internal.selection.StructureSelectPreviousAction; |
| import org.eclipse.wst.sse.ui.internal.text.DocumentRegionEdgeMatcher; |
| import org.eclipse.wst.sse.ui.internal.util.Assert; |
| |
| public class StructuredTextEditor extends TextEditor { |
| |
| class InternalDocumentListener implements IDocumentListener { |
| // This is for the IDocumentListener interface |
| public void documentAboutToBeChanged(DocumentEvent event) { |
| fDirtyBeforeDocumentEvent = isDirty(); |
| } |
| |
| // This is for the IDocumentListener interface |
| public void documentChanged(DocumentEvent event) { |
| if (isEditorInputReadOnly()) { |
| // stop listening to document event |
| // caused by the undo after validateEdit |
| final int offset = event.getOffset() + event.getLength(); |
| final IStructuredModel internalModel = getInternalModel(); |
| fCurrentRunnable = new Runnable() { |
| public void run() { |
| if (!fEditorDisposed) { |
| IStatus status = validateEdit(getSite().getShell()); |
| if (status != null && status.isOK()) { |
| // nothing to do if 'ok' |
| } |
| else { |
| if (internalModel != null) { |
| internalModel.getUndoManager().undo(); |
| getSourceViewer().setSelectedRange(offset, 0); |
| if (!fDirtyBeforeDocumentEvent) { |
| // reset dirty state if |
| // model not dirty before |
| // document event |
| internalModel.setDirtyState(false); |
| } |
| } |
| } |
| } |
| fCurrentRunnable = null; |
| } |
| }; |
| /* |
| * We need to ensure that this is run via 'asyncExec' since |
| * these notifications can come from a non-ui thread. |
| * |
| * The non-ui thread call would occur when creating a new file |
| * under ClearCase (or other library) control. The creation of |
| * the new file would trigger a validateEdit call, on another |
| * thread, that would prompt the user to add the new file to |
| * version control. |
| */ |
| Display display = getDisplay(); |
| if (display != null) { |
| if (Thread.currentThread() != display.getThread()) |
| // future_TODO: there's probably a better |
| // way than relying on asycnExec |
| display.asyncExec(fCurrentRunnable); |
| else |
| fCurrentRunnable.run(); |
| } |
| } |
| } |
| } |
| |
| class InternalElementStateListener implements IElementStateListener { |
| |
| public void elementContentAboutToBeReplaced(Object element) { |
| // nothing to do |
| } |
| |
| public void elementContentReplaced(Object element) { |
| // nothing to do |
| } |
| |
| public void elementDeleted(Object element) { |
| // nothing to do |
| } |
| |
| public void elementDirtyStateChanged(Object element, boolean isDirty) { |
| // nothing to do |
| } |
| |
| public void elementMoved(Object originalElement, Object movedElement) { |
| // nothing to do |
| } |
| } |
| |
| class InternalModelStateListener implements IModelStateListener { |
| public void modelAboutToBeChanged(IStructuredModel model) { |
| if (getTextViewer() != null) { |
| // getTextViewer().setRedraw(false); |
| } |
| } |
| |
| public void modelAboutToBeReinitialized(IStructuredModel structuredModel) { |
| if (getTextViewer() != null) { |
| // getTextViewer().setRedraw(false); |
| getTextViewer().unconfigure(); |
| SourceViewerConfiguration config = getSourceViewerConfiguration(); |
| if (config instanceof StructuredTextViewerConfiguration) { |
| ((StructuredTextViewerConfiguration) config).unConfigure(getSourceViewer()); |
| } |
| } |
| } |
| |
| public void modelChanged(IStructuredModel model) { |
| if (getTextViewer() != null) { |
| // getTextViewer().setRedraw(true); |
| // Since the model can be changed on a background |
| // thread, we will update menus on display thread, |
| // if we are not already on display thread, |
| // and if there is not an update already pending. |
| // (we can get lots of 'modelChanged' events in rapid |
| // succession, so only need to do one. |
| if (!fUpdateMenuTextPending) { |
| runOnDisplayThreadIfNeededed(new Runnable() { |
| public void run() { |
| updateMenuText(); |
| fUpdateMenuTextPending = false; |
| } |
| }); |
| } |
| |
| } |
| } |
| |
| public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) { |
| // do nothing |
| } |
| |
| public void modelReinitialized(IStructuredModel structuredModel) { |
| try { |
| if (getSourceViewer() != null) { |
| SourceViewerConfiguration cfg = getSourceViewerConfiguration(); |
| if (cfg != null && cfg instanceof StructuredTextViewerConfiguration) { |
| initializeSourceViewerConfiguration(((StructuredTextViewerConfiguration) cfg)); |
| } |
| getSourceViewer().configure(cfg); |
| } |
| } |
| catch (Exception e) { |
| // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=1166 |
| // investigate each error case post beta |
| Logger.logException("problem trying to configure after model change", e); //$NON-NLS-1$ |
| } |
| finally { |
| // so we don't freeze workbench (eg. during page language or |
| // content type change) |
| ((ITextViewerExtension) getSourceViewer()).setRedraw(true); |
| } |
| } |
| |
| // Note: this one should probably be used to |
| // control viewer |
| // instead of viewer having its own listener |
| public void modelResourceDeleted(IStructuredModel model) { |
| // do nothing |
| } |
| |
| public void modelResourceMoved(IStructuredModel originalmodel, IStructuredModel movedmodel) { |
| // do nothing |
| } |
| |
| /** |
| * This 'Runnable' should be very brief, and should not "call out" to |
| * other code especially if it depends on the state of the model. |
| * |
| * @param r |
| */ |
| private void runOnDisplayThreadIfNeededed(Runnable r) { |
| // if there is no Display at all (that is, running headless), |
| // or if we are already running on the display thread, then |
| // simply execute the runnable. |
| if (getDisplay() == null || (Thread.currentThread() == getDisplay().getThread())) { |
| r.run(); |
| } |
| else { |
| // otherwise force the runnable to run on the display thread. |
| getDisplay().asyncExec(r); |
| } |
| } |
| } |
| |
| class MouseTracker extends MouseTrackAdapter implements MouseMoveListener { |
| /** The tracker's subject control. */ |
| private Control fSubjectControl; |
| |
| /** |
| * Creates a new mouse tracker. |
| */ |
| public MouseTracker() { |
| // do nothing |
| } |
| |
| public void mouseHover(MouseEvent event) { |
| // System.out.println("hover: "+event.x + "x" + event.y); |
| hoverX = event.x; |
| hoverY = event.y; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) |
| */ |
| public void mouseMove(MouseEvent e) { |
| hoverX = e.x; |
| hoverY = e.y; |
| } |
| |
| /** |
| * Starts this mouse tracker. The given control becomes this tracker's |
| * subject control. Installs itself as mouse track listener on the |
| * subject control. |
| * |
| * @param subjectControl |
| * the subject control |
| */ |
| public void start(Control subjectControl) { |
| fSubjectControl = subjectControl; |
| if (fSubjectControl != null && !fSubjectControl.isDisposed()) { |
| fSubjectControl.addMouseMoveListener(this); |
| fSubjectControl.addMouseTrackListener(this); |
| fSubjectControl.addDisposeListener(new DisposeListener() { |
| public void widgetDisposed(DisposeEvent e) { |
| stop(); |
| } |
| }); |
| } |
| } |
| |
| /** |
| * Stops this mouse tracker. Removes itself as mouse track, mouse |
| * move, and shell listener from the subject control. |
| */ |
| public void stop() { |
| if (fSubjectControl != null && !fSubjectControl.isDisposed()) { |
| fSubjectControl.removeMouseMoveListener(this); |
| fSubjectControl.removeMouseTrackListener(this); |
| fSubjectControl = null; |
| } |
| } |
| } |
| |
| class ShowInTargetListAdapter implements IShowInTargetList { |
| /** |
| * Array of ID Strings that define the default show in targets for |
| * this editor. |
| * |
| * @see org.eclipse.ui.part.IShowInTargetList#getShowInTargetIds() |
| * @return the array of ID Strings that define the default show in |
| * targets for this editor. |
| */ |
| public String[] getShowInTargetIds() { |
| return fShowInTargetIds; |
| } |
| } |
| |
| class TimeOutExpired extends TimerTask { |
| |
| public void run() { |
| getDisplay().syncExec(new Runnable() { |
| public void run() { |
| if (getDisplay() != null && !getDisplay().isDisposed()) |
| endBusyStateInternal(); |
| } |
| }); |
| } |
| |
| } |
| |
| protected final static char[] BRACKETS = {'{', '}', '(', ')', '[', ']'}; |
| private static final long BUSY_STATE_DELAY = 1000; |
| protected static final String DOT = "."; //$NON-NLS-1$ |
| private static final String EDITOR_CONTEXT_MENU_ID = "org.eclipse.wst.sse.ui.StructuredTextEditor.EditorContext"; //$NON-NLS-1$ |
| private static final String EDITOR_CONTEXT_MENU_POSTFIX = ".source.EditorContext"; //$NON-NLS-1$ |
| private static final String RULER_CONTEXT_MENU_ID = "org.eclipse.wst.sse.ui.StructuredTextEditor.RulerContext"; //$NON-NLS-1$ |
| private static final String RULER_CONTEXT_MENU_POSTFIX = ".source.RulerContext"; //$NON-NLS-1$ |
| /** Non-NLS strings */ |
| private static final String EDITOR_KEYBINDING_SCOPE_ID = "org.eclipse.wst.sse.ui.structuredTextEditorScope"; //$NON-NLS-1$ |
| |
| public static final String GROUP_NAME_ADDITIONS = "additions"; //$NON-NLS-1$ |
| public static final String GROUP_NAME_FORMAT = "Format"; //$NON-NLS-1$ |
| public static final String GROUP_NAME_FORMAT_EXT = "Format.ext"; //$NON-NLS-1$ |
| private static final String REDO_ACTION_DESC = SSEUIMessages.Redo___0___UI_; //$NON-NLS-1$ = "Redo: {0}." |
| private static final String REDO_ACTION_DESC_DEFAULT = SSEUIMessages.Redo_Text_Change__UI_; //$NON-NLS-1$ = "Redo Text Change." |
| private static final String REDO_ACTION_TEXT = SSEUIMessages._Redo__0___Ctrl_Y_UI_; //$NON-NLS-1$ = "&Redo {0} @Ctrl+Y" |
| private static final String REDO_ACTION_TEXT_DEFAULT = SSEUIMessages._Redo_Text_Change__Ctrl_Y_UI_; //$NON-NLS-1$ = "&Redo Text Change @Ctrl+Y" |
| protected static final String SSE_MODEL_ID = "org.eclipse.wst.sse.core"; //$NON-NLS-1$ |
| /** |
| * Constant for representing an error status. This is considered a value |
| * object. |
| */ |
| static final protected IStatus STATUS_ERROR = new Status(IStatus.ERROR, SSEUIPlugin.ID, IStatus.INFO, "ERROR", null); //$NON-NLS-1$ |
| /** |
| * Constant for representing an ok status. This is considered a value |
| * object. |
| */ |
| static final protected IStatus STATUS_OK = new Status(IStatus.OK, SSEUIPlugin.ID, IStatus.OK, "OK", null); //$NON-NLS-1$ |
| private final static String UNDERSCORE = "_"; //$NON-NLS-1$ |
| |
| /** Translatable strings */ |
| private static final String UNDO_ACTION_DESC = SSEUIMessages.Undo___0___UI_; //$NON-NLS-1$ = "Undo: {0}." |
| private static final String UNDO_ACTION_DESC_DEFAULT = SSEUIMessages.Undo_Text_Change__UI_; //$NON-NLS-1$ = "Undo Text Change." |
| private static final String UNDO_ACTION_TEXT = SSEUIMessages._Undo__0___Ctrl_Z_UI_; //$NON-NLS-1$ = "&Undo {0} @Ctrl+Z" |
| private static final String UNDO_ACTION_TEXT_DEFAULT = SSEUIMessages._Undo_Text_Change__Ctrl_Z_UI_; //$NON-NLS-1$ = "&Undo Text Change @Ctrl+Z" |
| |
| // development time/debug variables only |
| private int adapterRequests; |
| private long adapterTime; |
| private boolean fBackgroundJobEnded; |
| private boolean fBusyState; |
| private Timer fBusyTimer; |
| Runnable fCurrentRunnable = null; |
| boolean fDirtyBeforeDocumentEvent = false; |
| private ExtendedEditorDropTargetAdapter fDropAdapter; |
| private DropTarget fDropTarget; |
| private boolean fEditorDisposed = false; |
| private IEditorPart fEditorPart; |
| private IDocumentListener fInternalDocumentListener; |
| private InternalModelStateListener fInternalModelStateListener; |
| |
| private MouseTracker fMouseTracker; |
| protected IContentOutlinePage fOutlinePage; |
| /** This editor's projection model updater */ |
| private IStructuredTextFoldingProvider fProjectionModelUpdater; |
| /** This editor's projection support */ |
| private ProjectionSupport fProjectionSupport; |
| protected IPropertySheetPage fPropertySheetPage; |
| private String fRememberTitle; |
| String[] fShowInTargetIds = new String[]{IPageLayout.ID_RES_NAV}; |
| private IAction fShowPropertiesAction = null; |
| private IStructuredModel fStructuredModel; |
| /** The text context menu to be disposed. */ |
| private Menu fTextContextMenu; |
| /** The text context menu manager to be disposed. */ |
| private MenuManager fTextContextMenuManager; |
| /** The ruler context menu to be disposed. */ |
| private Menu fRulerContextMenu; |
| /** The ruler context menu manager to be disposed. */ |
| private MenuManager fRulerContextMenuManager; |
| |
| private boolean fUpdateMenuTextPending; |
| int hoverX = -1; |
| int hoverY = -1; |
| private InternalElementStateListener internalElementStateListener = new InternalElementStateListener(); |
| private boolean shouldClose = false; |
| private long startPerfTime; |
| |
| public StructuredTextEditor() { |
| |
| super(); |
| initializeDocumentProvider(null); |
| } |
| |
| private void aboutToSaveModel() { |
| if (getInternalModel() != null) { |
| getInternalModel().aboutToChangeModel(); |
| } |
| } |
| |
| private void abstractTextEditorContextMenuAboutToShow(IMenuManager menu) { |
| menu.add(new Separator(ITextEditorActionConstants.GROUP_UNDO)); |
| menu.add(new Separator(ITextEditorActionConstants.GROUP_COPY)); |
| menu.add(new Separator(ITextEditorActionConstants.GROUP_PRINT)); |
| menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT)); |
| menu.add(new Separator(ITextEditorActionConstants.GROUP_FIND)); |
| menu.add(new Separator(IWorkbenchActionConstants.GROUP_ADD)); |
| menu.add(new Separator(ITextEditorActionConstants.GROUP_REST)); |
| menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
| menu.add(new Separator(ITextEditorActionConstants.GROUP_SAVE)); |
| |
| if (isEditable()) { |
| addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.UNDO); |
| addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.REVERT_TO_SAVED); |
| addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.CUT); |
| addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY); |
| addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.PASTE); |
| addAction(menu, ITextEditorActionConstants.GROUP_SAVE, ITextEditorActionConstants.SAVE); |
| } |
| else { |
| addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY); |
| } |
| |
| // from AbstractDecoratedTextEditor |
| IAction preferencesAction = getAction(ITextEditorActionConstants.CONTEXT_PREFERENCES); |
| menu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, new Separator(ITextEditorActionConstants.GROUP_SETTINGS)); |
| menu.appendToGroup(ITextEditorActionConstants.GROUP_SETTINGS, preferencesAction); |
| } |
| |
| protected void addContextMenuActions(IMenuManager menu) { |
| // Only offer actions that affect the text if the viewer allows |
| // modification and supports any of these operations |
| IAction formatAll = getAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT); |
| IAction formatSelection = getAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS); |
| IAction cleanupAll = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CLEANUP_DOCUMENT); |
| boolean enableFormatMenu = (formatAll != null && formatAll.isEnabled()) || (formatSelection != null && formatSelection.isEnabled()) || (cleanupAll != null && cleanupAll.isEnabled()); |
| |
| if (getSourceViewer().isEditable() && enableFormatMenu) { |
| String label = SSEUIMessages.FormatMenu_label; //$NON-NLS-1$ = "Format" |
| MenuManager subMenu = new MenuManager(label, GROUP_NAME_FORMAT); |
| subMenu.add(new GroupMarker(GROUP_NAME_FORMAT_EXT)); |
| addAction(subMenu, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT); |
| addAction(subMenu, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS); |
| subMenu.add(new GroupMarker(GROUP_NAME_ADDITIONS)); |
| addAction(menu, ITextEditorActionConstants.GROUP_EDIT, StructuredTextEditorActionConstants.ACTION_NAME_CLEANUP_DOCUMENT); |
| menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, subMenu); |
| } |
| |
| // Some Design editors (DTD) rely on this view for their own uses |
| menu.appendToGroup(IWorkbenchActionConstants.GROUP_ADD, fShowPropertiesAction); |
| } |
| |
| private void addExtendedContextMenuActions(IMenuManager menu) { |
| IEditorActionBarContributor c = getEditorSite().getActionBarContributor(); |
| if (c instanceof IPopupMenuContributor) { |
| ((IPopupMenuContributor) c).contributeToPopupMenu(menu); |
| } |
| else { |
| ExtendedEditorActionBuilder builder = new ExtendedEditorActionBuilder(); |
| IExtendedContributor pmc = builder.readActionExtensions(getConfigurationPoints()); |
| if (pmc != null) { |
| pmc.setActiveEditor(this); |
| pmc.contributeToPopupMenu(menu); |
| } |
| } |
| } |
| |
| |
| |
| protected void addExtendedRulerContextMenuActions(IMenuManager menu) { |
| // none at this level |
| } |
| |
| /** |
| * |
| */ |
| public void beginBackgroundOperation() { |
| fBackgroundJobEnded = false; |
| // if already in busy state, no need to do anything |
| // and, we only start, or reset, the timed busy |
| // state when we get the "endBackgroundOperation" call. |
| if (!inBusyState()) { |
| beginBusyStateInternal(); |
| } |
| } |
| |
| // private void addFindOccurrencesAction(String matchType, String |
| // matchText, IMenuManager menu) { |
| // |
| // AbstractFindOccurrencesAction action = new |
| // AbstractFindOccurrencesAction(getFileInEditor(), new |
| // SearchUIConfiguration(), (IStructuredDocument) getDocument(), |
| // matchType, matchText, getProgressMonitor()); |
| // action.setText("Occurrences of \"" + matchText + "\" in File"); |
| // menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, action); |
| // } |
| |
| /** |
| * |
| */ |
| private void beginBusyStateInternal() { |
| |
| fBusyState = true; |
| startBusyTimer(); |
| |
| ISourceViewer viewer = getSourceViewer(); |
| if (viewer instanceof StructuredTextViewer) { |
| ((StructuredTextViewer) viewer).beginBackgroundUpdate(); |
| |
| } |
| showBusy(true); |
| } |
| |
| /** |
| * Instead of us closing directly, we have to close with our containing |
| * (multipage) editor, if it exists. |
| */ |
| public void close(final boolean save) { |
| if (getSite() == null) { |
| // if site hasn't been set yet, then we're not |
| // completely open |
| // so set a flag not to open |
| shouldClose = true; |
| } |
| else { |
| if (getEditorPart() != null) { |
| Display display = getSite().getShell().getDisplay(); |
| display.asyncExec(new Runnable() { |
| |
| public void run() { |
| getSite().getPage().closeEditor(getEditorPart(), save); |
| } |
| }); |
| } |
| else { |
| super.close(save); |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages() |
| */ |
| protected String[] collectContextMenuPreferencePages() { |
| List allIds = new ArrayList(0); |
| |
| // get contributed preference pages |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] configurationIds = getConfigurationPoints(); |
| for (int i = 0; i < configurationIds.length; i++) { |
| String[] definitions = builder.getDefinitions("preferencepages", configurationIds[i]); //$NON-NLS-1$ |
| for (int j = 0; j < definitions.length; j++) { |
| String someIds = definitions[j]; |
| if (someIds != null && someIds.length() > 0) { |
| // supports multiple comma-delimited page IDs in one |
| // element |
| String[] ids = StringUtils.unpack(someIds); |
| for (int k = 0; k < ids.length; k++) { |
| // trim, just to keep things clean |
| String id = ids[k].trim(); |
| if (!allIds.contains(id)) { |
| allIds.add(id); |
| } |
| } |
| } |
| } |
| } |
| |
| // add pages contributed by super |
| String[] superPages = super.collectContextMenuPreferencePages(); |
| for (int m = 0; m < superPages.length; m++) { |
| // trim, just to keep things clean |
| String id = superPages[m].trim(); |
| if (!allIds.contains(id)) { |
| allIds.add(id); |
| } |
| } |
| |
| return (String[]) allIds.toArray(new String[0]); |
| } |
| |
| /** |
| * Compute and set double-click action for the source editor, depending on |
| * the input. |
| */ |
| private void computeAndSetDoubleClickAction(IStructuredModel model) { |
| if (model == null) |
| return; |
| // If we're editing a breakpoint-supported input, make double-clicking |
| // on the ruler toggle a breakpoint instead of toggling a bookmark. |
| String ext = BreakpointRulerAction.getFileExtension(getEditorInput()); |
| if (BreakpointProviderBuilder.getInstance().isAvailable(model.getContentTypeIdentifier(), ext)) { |
| setAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, getAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS)); |
| } |
| else { |
| // The Default Text Editor uses editorContribution to perform this |
| // mapping, but since it relies on the IEditorSite ID, it can't be |
| // relied on for MultiPageEditorParts. Instead, force the action |
| // registration manually. |
| // setAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, new MarkerRulerAction(SSEUIMessages.getResourceBundle(), "Editor_ManageBookmarks_", this, getVerticalRuler(), IMarker.BOOKMARK, true)); //$NON-NLS-1$ |
| // add bookmark action is already registered in AbstractDecoratedTextEditor, so just get it |
| setAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, getAction(IDEActionFactory.BOOKMARK.getId())); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.ExtendedTextEditor#configureSourceViewerDecorationSupport(org.eclipse.ui.texteditor.SourceViewerDecorationSupport) |
| */ |
| protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) { |
| support.setCharacterPairMatcher(createCharacterPairMatcher()); |
| support.setMatchingCharacterPainterPreferenceKeys(EditorPreferenceNames.MATCHING_BRACKETS, EditorPreferenceNames.MATCHING_BRACKETS_COLOR); |
| |
| super.configureSourceViewerDecorationSupport(support); |
| } |
| |
| protected void createActions() { |
| super.createActions(); |
| ResourceBundle resourceBundle = SSEUIMessages.getResourceBundle(); |
| IWorkbenchHelpSystem helpSystem = SSEUIPlugin.getDefault().getWorkbench().getHelpSystem(); |
| // TextView Action - moving the selected text to |
| // the clipboard |
| // override the cut/paste/delete action to make |
| // them run on read-only |
| // files |
| Action action = new TextOperationAction(resourceBundle, "Editor_Cut_", this, ITextOperationTarget.CUT, true); //$NON-NLS-1$ |
| action.setActionDefinitionId(IWorkbenchActionDefinitionIds.CUT); |
| setAction(ITextEditorActionConstants.CUT, action); |
| helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.CUT_ACTION); |
| // TextView Action - inserting the clipboard |
| // content at the current |
| // position |
| // override the cut/paste/delete action to make |
| // them run on read-only |
| // files |
| action = new TextOperationAction(resourceBundle, "Editor_Paste_", this, ITextOperationTarget.PASTE, true); //$NON-NLS-1$ |
| action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE); |
| setAction(ITextEditorActionConstants.PASTE, action); |
| helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.PASTE_ACTION); |
| // TextView Action - deleting the selected text or |
| // if selection is |
| // empty the character at the right of the current |
| // position |
| // override the cut/paste/delete action to make |
| // them run on read-only |
| // files |
| action = new TextOperationAction(resourceBundle, "Editor_Delete_", this, ITextOperationTarget.DELETE, true); //$NON-NLS-1$ |
| action.setActionDefinitionId(IWorkbenchActionDefinitionIds.DELETE); |
| setAction(ITextEditorActionConstants.DELETE, action); |
| helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.DELETE_ACTION); |
| // SourceView Action - requesting information at |
| // the current insertion |
| // position |
| action = new TextOperationAction(SSEUIMessages.getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION + UNDERSCORE, this, ISourceViewer.INFORMATION, true); |
| action.setActionDefinitionId(ActionDefinitionIds.INFORMATION); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION, true); |
| // SourceView Action - requesting content assist to |
| // show completetion |
| // proposals for the current insert position |
| action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS + UNDERSCORE, this, ISourceViewer.CONTENTASSIST_PROPOSALS, true); |
| helpSystem.setHelp(action, IHelpContextIds.CONTMNU_CONTENTASSIST_HELPID); |
| action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, true); |
| // SourceView Action - requesting content assist to |
| // show the content |
| // information for the current insert position |
| action = new TextOperationAction(SSEUIMessages.getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION + UNDERSCORE, this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION); |
| action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, true); |
| // StructuredTextViewer Action - requesting |
| // correction assist to show |
| // correction proposals for the current position |
| action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX + UNDERSCORE, this, StructuredTextViewer.QUICK_FIX, true); |
| action.setActionDefinitionId(ActionDefinitionIds.QUICK_FIX); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX, true); |
| // StructuredTextViewer Action - requesting format |
| // of the whole |
| // document |
| action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT + UNDERSCORE, this, StructuredTextViewer.FORMAT_DOCUMENT); |
| helpSystem.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_DOC_HELPID); |
| action.setActionDefinitionId(ActionDefinitionIds.FORMAT_DOCUMENT); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true); |
| markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true); |
| // StructuredTextViewer Action - requesting format |
| // of the active |
| // elements |
| action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS + UNDERSCORE, this, StructuredTextViewer.FORMAT_ACTIVE_ELEMENTS); |
| helpSystem.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_ELEMENTS_HELPID); |
| action.setActionDefinitionId(ActionDefinitionIds.FORMAT_ACTIVE_ELEMENTS); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true); |
| markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true); |
| // StructuredTextEditor Action - add breakpoints |
| action = new ToggleBreakpointAction(this, getVerticalRuler()); |
| setAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS, action); |
| // StructuredTextEditor Action - manage breakpoints |
| action = new ManageBreakpointAction(this, getVerticalRuler()); |
| setAction(ActionDefinitionIds.MANAGE_BREAKPOINTS, action); |
| // StructuredTextEditor Action - edit breakpoints |
| action = new EditBreakpointAction(this, getVerticalRuler()); |
| setAction(ActionDefinitionIds.EDIT_BREAKPOINTS, action); |
| // StructuredTextViewer Action - open file on selection |
| action = new OpenHyperlinkAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE + UNDERSCORE, this, getSourceViewer()); |
| action.setActionDefinitionId(ActionDefinitionIds.OPEN_FILE); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE, action); |
| |
| fShowPropertiesAction = new ShowPropertiesAction(); |
| |
| SelectionHistory selectionHistory = new SelectionHistory(this); |
| action = new StructureSelectEnclosingAction(this, selectionHistory); |
| action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_ENCLOSING); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_ENCLOSING, action); |
| |
| action = new StructureSelectNextAction(this, selectionHistory); |
| action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_NEXT); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_NEXT, action); |
| |
| action = new StructureSelectPreviousAction(this, selectionHistory); |
| action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_PREVIOUS); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_PREVIOUS, action); |
| |
| action = new StructureSelectHistoryAction(this, selectionHistory); |
| action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_HISTORY); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_HISTORY, action); |
| selectionHistory.setHistoryAction((StructureSelectHistoryAction) action); |
| } |
| |
| protected LineChangeHover createChangeHover() { |
| return new StructuredLineChangeHover(); |
| } |
| |
| protected ICharacterPairMatcher createCharacterPairMatcher() { |
| ICharacterPairMatcher matcher = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; matcher == null && i < ids.length; i++) { |
| matcher = (ICharacterPairMatcher) builder.getConfiguration(DocumentRegionEdgeMatcher.ID, ids[i]); |
| } |
| if (matcher == null) { |
| matcher = new ICharacterPairMatcher() { |
| |
| public void clear() { |
| } |
| |
| public void dispose() { |
| } |
| |
| public int getAnchor() { |
| return ICharacterPairMatcher.LEFT; |
| } |
| |
| public IRegion match(IDocument iDocument, int i) { |
| return null; |
| } |
| }; |
| } |
| return matcher; |
| } |
| |
| /** |
| * Create a preference store that combines the source editor preferences |
| * with the base editor's preferences. |
| * |
| * @return IPreferenceStore |
| */ |
| private IPreferenceStore createCombinedPreferenceStore() { |
| IPreferenceStore sseEditorPrefs = SSEUIPlugin.getDefault().getPreferenceStore(); |
| IPreferenceStore baseEditorPrefs = EditorsUI.getPreferenceStore(); |
| return new ChainedPreferenceStore(new IPreferenceStore[]{sseEditorPrefs, baseEditorPrefs}); |
| } |
| |
| private ContentOutlineConfiguration createContentOutlineConfiguration() { |
| ContentOutlineConfiguration cfg = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; cfg == null && i < ids.length; i++) { |
| cfg = (ContentOutlineConfiguration) builder.getConfiguration(ContentOutlineConfiguration.ID, ids[i]); |
| } |
| return cfg; |
| } |
| |
| protected void createModelDependentFields() { |
| // none at this level |
| } |
| |
| /** |
| * Use StructuredTextViewerConfiguration if a viewerconfiguration has not |
| * already been set. Also initialize StructuredTextViewer. |
| * |
| * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite) |
| */ |
| public void createPartControl(Composite parent) { |
| if (getSourceViewerConfiguration() == null) { |
| StructuredTextViewerConfiguration newViewerConfiguration = createSourceViewerConfiguration(); |
| setSourceViewerConfiguration(newViewerConfiguration); |
| } |
| |
| super.createPartControl(parent); |
| |
| // instead of calling setInput twice, use initializeSourceViewer() to |
| // handle source viewer initialization previously handled by setInput |
| initializeSourceViewer(); |
| |
| // update editor context menu, vertical ruler context menu, infopop |
| if (getInternalModel() != null) { |
| updateEditorControlsForContentType(getInternalModel().getContentTypeIdentifier()); |
| } |
| else { |
| updateEditorControlsForContentType(null); |
| } |
| } |
| |
| protected PropertySheetConfiguration createPropertySheetConfiguration() { |
| PropertySheetConfiguration cfg = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; cfg == null && i < ids.length; i++) { |
| cfg = (PropertySheetConfiguration) builder.getConfiguration(PropertySheetConfiguration.ID, ids[i]); |
| } |
| return cfg; |
| } |
| |
| /** |
| * Loads the Show In Target IDs from the Extended Configuration extension |
| * point. |
| * |
| * @return |
| */ |
| private String[] createShowInTargetIds() { |
| List allIds = new ArrayList(0); |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] configurationIds = getConfigurationPoints(); |
| for (int i = 0; i < configurationIds.length; i++) { |
| String[] definitions = builder.getDefinitions("showintarget", configurationIds[i]); //$NON-NLS-1$ |
| for (int j = 0; j < definitions.length; j++) { |
| String someIds = definitions[j]; |
| if (someIds != null && someIds.length() > 0) { |
| String[] ids = StringUtils.unpack(someIds); |
| for (int k = 0; k < ids.length; k++) { |
| // trim, just to keep things clean |
| String id = ids[k].trim(); |
| if (!allIds.contains(id)) { |
| allIds.add(id); |
| } |
| } |
| } |
| } |
| } |
| |
| if (!allIds.contains(IPageLayout.ID_RES_NAV)) { |
| allIds.add(IPageLayout.ID_RES_NAV); |
| } |
| if (!allIds.contains(IPageLayout.ID_OUTLINE)) { |
| allIds.add(IPageLayout.ID_OUTLINE); |
| } |
| return (String[]) allIds.toArray(new String[0]); |
| } |
| |
| /** |
| * @return |
| */ |
| private ISourceEditingTextTools createSourceEditingTextTools() { |
| ISourceEditingTextTools tools = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; tools == null && i < ids.length; i++) { |
| tools = (ISourceEditingTextTools) builder.getConfiguration(NullSourceEditingTextTools.ID, ids[i]); |
| } |
| if (tools == null) { |
| tools = NullSourceEditingTextTools.getInstance(); |
| } |
| try { |
| Method method = tools.getClass().getMethod("setTextEditor", new Class[]{StructuredTextEditor.class}); //$NON-NLS-1$ |
| if (method == null) { |
| method = tools.getClass().getMethod("setTextEditor", new Class[]{ITextEditor.class}); //$NON-NLS-1$ |
| } |
| if (method == null) { |
| method = tools.getClass().getMethod("setTextEditor", new Class[]{IEditorPart.class}); //$NON-NLS-1$ |
| } |
| if (method != null) { |
| if (!method.isAccessible()) { |
| method.setAccessible(true); |
| } |
| method.invoke(tools, new Object[]{this}); |
| } |
| } |
| catch (Exception e) { |
| Logger.logException("Problem creating ISourceEditingTextTools implementation", e); //$NON-NLS-1$ |
| } |
| |
| return tools; |
| } |
| |
| /** |
| * Creates the source viewer to be used by this editor |
| */ |
| protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) { |
| fAnnotationAccess = createAnnotationAccess(); |
| fOverviewRuler = createOverviewRuler(getSharedColors()); |
| StructuredTextViewer sourceViewer = createStructedTextViewer(parent, verticalRuler, styles); |
| initSourceViewer(sourceViewer); |
| return sourceViewer; |
| } |
| |
| private StructuredTextViewerConfiguration createSourceViewerConfiguration() { |
| StructuredTextViewerConfiguration cfg = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; cfg == null && i < ids.length; i++) { |
| cfg = (StructuredTextViewerConfiguration) builder.getConfiguration(StructuredTextViewerConfiguration.ID, ids[i]); |
| } |
| if (cfg == null) { |
| cfg = new StructuredTextViewerConfiguration(); |
| cfg.setDeclaringID(getClass().getName() + "#default"); //$NON-NLS-1$ |
| } |
| initializeSourceViewerConfiguration(cfg); |
| return cfg; |
| } |
| |
| protected StructuredTextViewer createStructedTextViewer(Composite parent, IVerticalRuler verticalRuler, int styles) { |
| return new StructuredTextViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles); |
| } |
| |
| /** |
| * @see DekstopPart#dispose |
| */ |
| public void dispose() { |
| Logger.trace("Source Editor", "StructuredTextEditor::dispose entry"); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) { |
| System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$ |
| System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$ |
| System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$ |
| } |
| |
| // dispose of document folding support |
| if (fProjectionModelUpdater != null) { |
| fProjectionModelUpdater.uninstall(); |
| fProjectionModelUpdater = null; |
| } |
| |
| if (fProjectionSupport != null) { |
| fProjectionSupport.dispose(); |
| fProjectionSupport = null; |
| } |
| |
| // subclass may not have mouse tracker created |
| // need to check for null before stopping |
| if (fMouseTracker != null) { |
| fMouseTracker.stop(); |
| fMouseTracker = null; |
| } |
| |
| // dispose of menus that were being tracked |
| if (fTextContextMenu != null) { |
| fTextContextMenu.dispose(); |
| } |
| if (fRulerContextMenu != null) { |
| fRulerContextMenu.dispose(); |
| } |
| if (fTextContextMenuManager != null) { |
| fTextContextMenuManager.removeMenuListener(getContextMenuListener()); |
| fTextContextMenuManager.removeAll(); |
| fTextContextMenuManager.dispose(); |
| } |
| if (fRulerContextMenuManager != null) { |
| fRulerContextMenuManager.removeMenuListener(getContextMenuListener()); |
| fRulerContextMenuManager.removeAll(); |
| fRulerContextMenuManager.dispose(); |
| } |
| |
| // added this 2/19/2004 to match the 'add' in |
| // intializeDocumentProvider. |
| if (getDocumentProvider() != null) |
| getDocumentProvider().removeElementStateListener(internalElementStateListener); |
| |
| // added this 2/20/2004 based on probe results -- |
| // seems should be handled by setModel(null), but |
| // that's a more radical change. |
| // and, technically speaking, should not be needed, |
| // but makes a memory leak |
| // less severe. |
| if (fStructuredModel != null) { |
| if (fStructuredModel.getStructuredDocument() != null) { |
| fStructuredModel.getStructuredDocument().removeDocumentListener(getInternalDocumentListener()); |
| } |
| fStructuredModel.removeModelStateListener(getInternalModelStateListener()); |
| } |
| |
| IDocument doc = getDocumentProvider().getDocument(getEditorInput()); |
| if (doc != null) { |
| doc.removeDocumentListener(getInternalDocumentListener()); |
| if (doc instanceof IExecutionDelegatable) { |
| ((IExecutionDelegatable) doc).setExecutionDelegate(null); |
| } |
| } |
| |
| fEditorDisposed = true; |
| disposeModelDependentFields(); |
| // some things in the configuration need to clean |
| // up after themselves |
| SourceViewerConfiguration config = getSourceViewerConfiguration(); |
| if (config instanceof StructuredTextViewerConfiguration) { |
| ((StructuredTextViewerConfiguration) config).unConfigure(getSourceViewer()); |
| } |
| |
| if (fDropTarget != null) |
| fDropTarget.dispose(); |
| |
| setPreferenceStore(null); |
| |
| // strictly speaking, but following null outs |
| // should not be needed, |
| // but in the event of a memory leak, they make the |
| // memory leak less |
| // severe |
| fDropAdapter = null; |
| fDropTarget = null; |
| |
| super.dispose(); |
| Logger.trace("Source Editor", "StructuredTextEditor::dispose exit"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#disposeDocumentProvider() |
| */ |
| protected void disposeDocumentProvider() { |
| if (fStructuredModel != null && !(getDocumentProvider() instanceof IModelProvider)) { |
| fStructuredModel.releaseFromEdit(); |
| } |
| super.disposeDocumentProvider(); |
| } |
| |
| /** |
| * Disposes model specific editor helpers such as statusLineHelper. |
| * Basically any code repeated in update() & dispose() should be placed |
| * here. |
| */ |
| private void disposeModelDependentFields() { |
| // none at this level |
| } |
| |
| /** |
| * @see ITextEditor#doRevertToSaved |
| */ |
| public void doRevertToSaved() { |
| super.doRevertToSaved(); |
| if (fOutlinePage != null && fOutlinePage instanceof IUpdate) { |
| ((IUpdate) fOutlinePage).update(); |
| } |
| // reset undo |
| IDocument doc = getDocumentProvider().getDocument(getEditorInput()); |
| if (doc instanceof IStructuredDocument) { |
| ((IStructuredDocument) doc).getUndoManager().getCommandStack().flush(); |
| } |
| |
| // update menu text |
| updateMenuText(); |
| } |
| |
| public void doSave(IProgressMonitor progressMonitor) { |
| try { |
| aboutToSaveModel(); |
| updateEncodingMemento(); |
| super.doSave(progressMonitor); |
| } |
| finally { |
| savedModel(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput) |
| */ |
| protected void doSetInput(IEditorInput input) throws CoreException { |
| try { |
| // TODO: if opened in more than one editor, this will cause |
| // problems. |
| IEditorInput oldInput = getEditorInput(); |
| if (oldInput != null) { |
| IDocument olddoc = getDocumentProvider().getDocument(oldInput); |
| if (olddoc != null && olddoc instanceof IExecutionDelegatable) { |
| ((IExecutionDelegatable) olddoc).setExecutionDelegate(null); |
| } |
| } |
| |
| if (fStructuredModel != null && !(getDocumentProvider() instanceof IModelProvider)) { |
| fStructuredModel.releaseFromEdit(); |
| } |
| |
| super.doSetInput(input); |
| |
| IDocument newDocument = getDocumentProvider().getDocument(input); |
| if (newDocument instanceof IExecutionDelegatable) { |
| ((IExecutionDelegatable) newDocument).setExecutionDelegate(new EditorExecutionContext(this)); |
| } |
| |
| IStructuredModel model = null; |
| // if we have a Model provider, get the model from it |
| if (getDocumentProvider() instanceof IModelProvider) { |
| model = ((IModelProvider) getDocumentProvider()).getModel(getEditorInput()); |
| if (!model.isShared()) { |
| EditorModelUtil.addFactoriesTo(model); |
| } |
| } |
| else { |
| if (newDocument instanceof IStructuredDocument) { |
| // corresponding releaseFromEdit occurs in |
| // dispose() |
| model = StructuredModelManager.getModelManager().getModelForEdit((IStructuredDocument) newDocument); |
| EditorModelUtil.addFactoriesTo(model); |
| } |
| |
| else { |
| logUnexpectedDocumentKind(input); |
| } |
| } |
| |
| if (fStructuredModel != null || model != null) { |
| setModel(model); |
| } |
| |
| if (getInternalModel() != null) { |
| updateEditorControlsForContentType(getInternalModel().getContentTypeIdentifier()); |
| } |
| else { |
| updateEditorControlsForContentType(null); |
| } |
| |
| if (fProjectionModelUpdater != null) |
| fProjectionModelUpdater.initialize(); |
| |
| // start editor with smart insert mode |
| setInsertMode(SMART_INSERT); |
| } |
| catch (CoreException exception) { |
| // dispose editor |
| dispose(); |
| |
| throw new CoreException(exception.getStatus()); |
| } |
| } |
| |
| /** |
| * Sets up this editor's context menu before it is made visible. |
| * |
| * @param menu |
| * the menu |
| */ |
| public void editorContextMenuAboutToShow(IMenuManager menu) { |
| // To be consistant with the Java Editor, we want |
| // to remove |
| // ShiftRight and ShiftLeft from the context menu. |
| // |
| // ShiftRight and ShiftLeft were added in the super |
| // implemenation of |
| // this method. We want to skip it and call |
| // AbstractTextEditor's |
| // implementation directly. The easiest way is to |
| // copy the method here. |
| |
| // super.editorContextMenuAboutToShow(menu); |
| abstractTextEditorContextMenuAboutToShow(menu); |
| |
| addContextMenuActions(menu); |
| addExtendedContextMenuActions(menu); |
| } |
| |
| /** |
| * This is the public method to be called to notifiy us that document is |
| * being updated by backround job. |
| */ |
| public void endBackgroundOperation() { |
| fBackgroundJobEnded = true; |
| // note, we don't immediately end our 'internal busy' state, |
| // since we may get many calls in a short period of |
| // time. We always wait for the time out. |
| resetBusyState(); |
| } |
| |
| /** |
| * Note this method can be called indirectly from background job operation |
| * ... but expected to be gaurded there with ILock, plus, can be called |
| * directly from timer thread, so the timer's run method guards with ILock |
| * too. |
| */ |
| private void endBusyStateInternal() { |
| if (fBackgroundJobEnded) { |
| fBusyTimer.cancel(); |
| showBusy(false); |
| |
| ISourceViewer viewer = getSourceViewer(); |
| if (viewer instanceof StructuredTextViewer) { |
| ((StructuredTextViewer) viewer).endBackgroundUpdate(); |
| } |
| fBusyState = false; |
| } |
| else { |
| // we will only be in this branch for a back ground job that is |
| // taking |
| // longer than our normal time-out period (meaning we got notified |
| // of |
| // the timeout "inbetween" calls to 'begin' and |
| // 'endBackgroundOperation'. |
| // (which, remember, can only happen since there are many calls to |
| // begin/end in a short period of time, and we only "reset" on the |
| // 'ends'). |
| // In this event, there's really nothing to do, we're still in |
| // "busy state" |
| // and should start a new reset cycle once endBackgroundjob is |
| // called. |
| } |
| } |
| |
| public Object getAdapter(Class required) { |
| if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) { |
| startPerfTime = System.currentTimeMillis(); |
| } |
| Object result = null; |
| // text editor |
| if (ITextEditor.class.equals(required)) { |
| result = this; |
| } |
| else if (IWorkbenchSiteProgressService.class.equals(required)) { |
| return getEditorPart().getSite().getAdapter(IWorkbenchSiteProgressService.class); |
| } |
| // content outline page |
| else if (IContentOutlinePage.class.equals(required)) { |
| if (fOutlinePage == null || fOutlinePage.getControl() == null || fOutlinePage.getControl().isDisposed()) { |
| ContentOutlineConfiguration cfg = createContentOutlineConfiguration(); |
| if (cfg != null) { |
| if (cfg instanceof StructuredContentOutlineConfiguration) { |
| ((StructuredContentOutlineConfiguration) cfg).setEditor(this); |
| } |
| StructuredTextEditorContentOutlinePage outlinePage = new StructuredTextEditorContentOutlinePage(); |
| outlinePage.setConfiguration(cfg); |
| outlinePage.setViewerSelectionManager(getViewerSelectionManager()); |
| // note: model might be null at this point, but |
| // if so, once model is set in editor, |
| // update will be called and set it |
| outlinePage.setModel(getInternalModel()); |
| fOutlinePage = outlinePage; |
| } |
| } |
| result = fOutlinePage; |
| } |
| // property sheet page, but only if the input's editable |
| else if (IPropertySheetPage.class.equals(required) && isEditable()) { |
| if (fPropertySheetPage == null || fPropertySheetPage.getControl() == null || fPropertySheetPage.getControl().isDisposed()) { |
| PropertySheetConfiguration cfg = createPropertySheetConfiguration(); |
| if (cfg != null) { |
| if (cfg instanceof StructuredPropertySheetConfiguration) { |
| ((StructuredPropertySheetConfiguration) cfg).setEditor(this); |
| } |
| ConfigurablePropertySheetPage propertySheetPage = new ConfigurablePropertySheetPage(); |
| propertySheetPage.setConfiguration(cfg); |
| propertySheetPage.setViewerSelectionManager(getViewerSelectionManager()); |
| // note: model might be null at this point, but |
| // if so, once model is set in editor, |
| // update will be called and set it |
| propertySheetPage.setModel(getInternalModel()); |
| fPropertySheetPage = propertySheetPage; |
| } |
| } |
| result = fPropertySheetPage; |
| } |
| else if (ViewerSelectionManager.class.equals(required)) { |
| result = getViewerSelectionManager(); |
| } |
| else if (IDocument.class.equals(required)) { |
| result = getDocumentProvider().getDocument(getEditorInput()); |
| } |
| else if (ISourceEditingTextTools.class.equals(required)) { |
| result = createSourceEditingTextTools(); |
| } |
| else if (IToggleBreakpointsTarget.class.equals(required)) { |
| result = ToggleBreakpointsTarget.getInstance(); |
| } |
| else if (IShowInTargetList.class.equals(required)) { |
| return new ShowInTargetListAdapter(); |
| } |
| else { |
| // Document document = getDOMDocument(); |
| // if (document != null && document instanceof INodeNotifier) { |
| // result = ((INodeNotifier) document).getAdapterFor(required); |
| // } |
| if (result == null) { |
| if (getInternalModel() != null) { |
| result = getInternalModel().getAdapter(required); |
| } |
| else { |
| result = super.getAdapter(required); |
| } |
| } |
| // others |
| if (result == null) |
| result = super.getAdapter(required); |
| } |
| if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) { |
| long stop = System.currentTimeMillis(); |
| adapterRequests++; |
| adapterTime += (stop - startPerfTime); |
| } |
| if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) { |
| System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$ |
| System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$ |
| System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$ |
| } |
| return result; |
| } |
| |
| |
| private String[] getConfigurationPoints() { |
| String contentTypeIdentifierID = null; |
| if (getInternalModel() != null) |
| contentTypeIdentifierID = getInternalModel().getContentTypeIdentifier(); |
| return ConfigurationPointCalculator.getConfigurationPoints(this, contentTypeIdentifierID, ConfigurationPointCalculator.SOURCE, StructuredTextEditor.class); |
| } |
| |
| /** |
| * added checks to overcome bug such that if we are shutting down in an |
| * error condition, then viewer will have already been disposed. |
| */ |
| protected String getCursorPosition() { |
| String result = null; |
| // this may be too expensive in terms of |
| // performance, to do this check |
| // every time, just to gaurd against error |
| // condition. |
| // perhaps there's a better way? |
| if (getSourceViewer() != null && getSourceViewer().getTextWidget() != null && !getSourceViewer().getTextWidget().isDisposed()) { |
| result = super.getCursorPosition(); |
| } |
| else { |
| result = "0:0"; //$NON-NLS-1$ |
| } |
| return result; |
| } |
| |
| Display getDisplay() { |
| return PlatformUI.getWorkbench().getDisplay(); |
| } |
| |
| public IEditorPart getEditorPart() { |
| if (fEditorPart == null) |
| return this; |
| return fEditorPart; |
| } |
| |
| /** |
| * @deprecated - used only by Search and there are alternate means besides |
| * making this API |
| * @return the IFile from the currently active editor |
| */ |
| public IFile getFileInEditor() { |
| IFile result = null; |
| IStructuredModel model = getInternalModel(); |
| if (model != null) { |
| result = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(model.getBaseLocation())); |
| } |
| return result; |
| } |
| |
| private IDocumentListener getInternalDocumentListener() { |
| if (fInternalDocumentListener == null) { |
| fInternalDocumentListener = new InternalDocumentListener(); |
| } |
| return fInternalDocumentListener; |
| } |
| |
| private IStructuredModel getInternalModel() { |
| return fStructuredModel; |
| } |
| |
| private InternalModelStateListener getInternalModelStateListener() { |
| if (fInternalModelStateListener == null) { |
| fInternalModelStateListener = new InternalModelStateListener(); |
| } |
| return fInternalModelStateListener; |
| } |
| |
| /** |
| * @deprecated - This method allowed for uncontrolled access to the model |
| * instance and will be removed in the future. It is |
| * recommended that the current document provider be asked for |
| * the current document and the IModelManager then asked for |
| * the corresponding model with |
| * getExistingModelFor*(IDocument). |
| */ |
| public IStructuredModel getModel() { |
| if (getDocumentProvider() == null) { |
| // this indicated an error in startup sequence |
| Logger.trace(getClass().getName(), "Program Info Only: document provider was null when model requested"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| boolean initialModelNull = false; |
| if (fStructuredModel == null) |
| initialModelNull = true; |
| if (fStructuredModel == null) { |
| // lazily set the model instance, although this is an ABNORMAL |
| // CODE PATH |
| if (getDocumentProvider() instanceof IModelProvider) { |
| fStructuredModel = ((IModelProvider) getDocumentProvider()).getModel(getEditorInput()); |
| } |
| else { |
| IDocument doc = getDocumentProvider().getDocument(getEditorInput()); |
| if (doc instanceof IStructuredDocument) { |
| IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(doc); |
| if (model == null) { |
| model = StructuredModelManager.getModelManager().getModelForEdit((IStructuredDocument) doc); |
| } |
| fStructuredModel = model; |
| } |
| } |
| // factories will not be re-added if already exists |
| EditorModelUtil.addFactoriesTo(fStructuredModel); |
| |
| if (initialModelNull && fStructuredModel != null) { |
| /* |
| * DMW: 9/1/2002 -- why is update called here? No change has |
| * been indicated? I'd like to remove, but will leave for now |
| * to avoid breaking this hack. Should measure/breakpoint to |
| * see how large the problem is. May cause performance |
| * problems. |
| * |
| * DMW: 9/8/2002 -- not sure why this was here initially, but |
| * the intent/hack must have been to call update if this was |
| * the first time fStructuredModel was set. So, I added the |
| * logic to check for that "first time" case. It would appear |
| * we don't really need. may remove in future when can test |
| * more. |
| */ |
| update(); |
| } |
| } |
| return fStructuredModel; |
| } |
| |
| public int getOrientation() { |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=88714 |
| return SWT.LEFT_TO_RIGHT; |
| } |
| |
| private IStatusLineManager getStatusLineManager() { |
| IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); |
| if (window == null) |
| return null; |
| IWorkbenchPage page = window.getActivePage(); |
| if (page == null) |
| return null; |
| IEditorPart editor = page.getActiveEditor(); |
| if (editor == null) |
| return null; |
| IEditorActionBarContributor contributor = editor.getEditorSite().getActionBarContributor(); |
| if (contributor instanceof EditorActionBarContributor) { |
| return ((EditorActionBarContributor) contributor).getActionBars().getStatusLineManager(); |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the editor's source viewer. This method was created to expose |
| * the protected final getSourceViewer() method. |
| * |
| * @return the editor's source viewer |
| */ |
| public StructuredTextViewer getTextViewer() { |
| return (StructuredTextViewer) getSourceViewer(); |
| } |
| |
| /** |
| * @deprecated |
| * |
| * will be made protected or removed in M4 |
| * |
| * @return |
| */ |
| public ViewerSelectionManager getViewerSelectionManager() { |
| if (getTextViewer() != null) |
| return getTextViewer().getViewerSelectionManager(); |
| return null; |
| } |
| |
| protected void handleCursorPositionChanged() { |
| super.handleCursorPositionChanged(); |
| updateStatusField(StructuredTextEditorActionConstants.STATUS_CATEGORY_OFFSET); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent) |
| */ |
| protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { |
| String property = event.getProperty(); |
| |
| if (EditorPreferenceNames.EDITOR_TEXT_HOVER_MODIFIERS.equals(property)) { |
| updateHoverBehavior(); |
| } |
| |
| if (IStructuredTextFoldingProvider.FOLDING_ENABLED.equals(property)) { |
| if (getSourceViewer() instanceof ProjectionViewer) { |
| // install projection support if it has not even been |
| // installed yet |
| if (isFoldingEnabled() && (fProjectionSupport == null) && (fProjectionModelUpdater == null)) { |
| installProjectionSupport(); |
| } |
| ProjectionViewer pv = (ProjectionViewer) getSourceViewer(); |
| if (pv.isProjectionMode() != isFoldingEnabled()) { |
| if (pv.canDoOperation(ProjectionViewer.TOGGLE)) |
| pv.doOperation(ProjectionViewer.TOGGLE); |
| } |
| } |
| return; |
| } |
| super.handlePreferenceStoreChanged(event); |
| } |
| |
| /** |
| * @return |
| */ |
| private boolean inBusyState() { |
| return fBusyState; |
| } |
| |
| public void init(IEditorSite site, IEditorInput input) throws PartInitException { |
| // if we've gotten an error elsewhere, before |
| // we've actually opened, then don't open. |
| if (shouldClose) { |
| setSite(site); |
| close(false); |
| } |
| else { |
| super.init(site, input); |
| } |
| } |
| |
| public void initializeDocumentProvider(IDocumentProvider documentProvider) { |
| if (getDocumentProvider() != null) |
| getDocumentProvider().removeElementStateListener(internalElementStateListener); |
| if (documentProvider != null) { |
| setDocumentProvider(documentProvider); |
| } |
| if (documentProvider != null) |
| documentProvider.addElementStateListener(internalElementStateListener); |
| } |
| |
| protected void initializeDrop(ITextViewer textViewer) { |
| int operations = DND.DROP_COPY | DND.DROP_MOVE; |
| fDropTarget = new DropTarget(textViewer.getTextWidget(), operations); |
| fDropAdapter = new ReadOnlyAwareDropTargetAdapter(); |
| fDropAdapter.setTargetEditor(this); |
| fDropAdapter.setTargetIDs(getConfigurationPoints()); |
| fDropAdapter.setTextViewer(textViewer); |
| fDropTarget.setTransfer(fDropAdapter.getTransfers()); |
| fDropTarget.addDropListener(fDropAdapter); |
| } |
| |
| protected void initializeEditor() { |
| super.initializeEditor(); |
| // FIXME: here's where to add back in our custom encoding support |
| fEncodingSupport = null; |
| setPreferenceStore(createCombinedPreferenceStore()); |
| |
| setRangeIndicator(new DefaultRangeIndicator()); |
| setEditorContextMenuId(EDITOR_CONTEXT_MENU_ID); |
| initializeDocumentProvider(null); |
| // set the infopop for source viewer |
| String helpId = getHelpContextId(); |
| // no infopop set or using default text editor help, use default |
| if (helpId == null || ITextEditorHelpContextIds.TEXT_EDITOR.equals(helpId)) |
| helpId = IHelpContextIds.XML_SOURCE_VIEW_HELPID; |
| setHelpContextId(helpId); |
| // defect 203158 - disable ruler context menu for |
| // beta |
| // setRulerContextMenuId(RULER_CONTEXT_MENU_ID); |
| configureInsertMode(SMART_INSERT, true); |
| |
| // enable the base source editor activity when editor opens |
| try { |
| // FIXME: - commented out to avoid minor dependancy during |
| // transition to org.eclipse |
| // WTPActivityBridge.getInstance().enableActivity(CORE_SSE_ACTIVITY_ID, |
| // true); |
| } |
| catch (Exception t) { |
| // if something goes wrong with enabling activity, just log the |
| // error but dont |
| // have it break the editor |
| Logger.log(Logger.WARNING_DEBUG, t.getMessage(), t); |
| } |
| } |
| |
| /** |
| * Updates the editor context menu by creating a new context menu with the |
| * given menu id |
| * |
| * @param contextMenuId |
| * Cannot be null |
| */ |
| private void updateEditorContextMenuId(String contextMenuId) { |
| // update editor context menu id if updating to a new id or if context |
| // menu is not already set up |
| if (!contextMenuId.equals(getEditorContextMenuId()) || (fTextContextMenu == null)) { |
| setEditorContextMenuId(contextMenuId); |
| |
| if (getSourceViewer() != null) { |
| StyledText styledText = getSourceViewer().getTextWidget(); |
| if (styledText != null) { |
| // dispose of previous context menu |
| if (fTextContextMenu != null) { |
| fTextContextMenu.dispose(); |
| } |
| if (fTextContextMenuManager != null) { |
| fTextContextMenuManager.removeMenuListener(getContextMenuListener()); |
| fTextContextMenuManager.removeAll(); |
| fTextContextMenuManager.dispose(); |
| } |
| |
| fTextContextMenuManager = new MenuManager(getEditorContextMenuId(), getEditorContextMenuId()); |
| fTextContextMenuManager.setRemoveAllWhenShown(true); |
| fTextContextMenuManager.addMenuListener(getContextMenuListener()); |
| |
| fTextContextMenu = fTextContextMenuManager.createContextMenu(styledText); |
| styledText.setMenu(fTextContextMenu); |
| |
| getSite().registerContextMenu(getEditorContextMenuId(), fTextContextMenuManager, getSelectionProvider()); |
| |
| // also register this menu for source page part and |
| // structured text editor ids |
| String partId = getSite().getId(); |
| if (partId != null) { |
| getSite().registerContextMenu(partId + EDITOR_CONTEXT_MENU_POSTFIX, fTextContextMenuManager, getSelectionProvider()); |
| } |
| getSite().registerContextMenu(EDITOR_CONTEXT_MENU_ID, fTextContextMenuManager, getSelectionProvider()); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Updates editor context menu, vertical ruler menu, help context id for |
| * new content type |
| * |
| * @param contentType |
| */ |
| private void updateEditorControlsForContentType(String contentType) { |
| if (contentType == null) { |
| updateEditorContextMenuId(EDITOR_CONTEXT_MENU_ID); |
| updateRulerContextMenuId(RULER_CONTEXT_MENU_ID); |
| updateHelpContextId(ITextEditorHelpContextIds.TEXT_EDITOR); |
| } |
| else { |
| updateEditorContextMenuId(contentType + EDITOR_CONTEXT_MENU_POSTFIX); |
| updateRulerContextMenuId(contentType + RULER_CONTEXT_MENU_POSTFIX); |
| updateHelpContextId(contentType + "_source_HelpId"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Updates the help context of the editor with the given help context id |
| * |
| * @param helpContextId |
| * Cannot be null |
| */ |
| private void updateHelpContextId(String helpContextId) { |
| if (!helpContextId.equals(getHelpContextId())) { |
| setHelpContextId(helpContextId); |
| |
| if (getSourceViewer() != null) { |
| StyledText styledText = getSourceViewer().getTextWidget(); |
| if (styledText != null) { |
| IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem(); |
| helpSystem.setHelp(styledText, getHelpContextId()); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Updates the editor vertical ruler menu by creating a new vertical ruler |
| * context menu with the given menu id |
| * |
| * @param rulerMenuId |
| * Cannot be null |
| */ |
| private void updateRulerContextMenuId(String rulerMenuId) { |
| // update ruler context menu id if updating to a new id or if context |
| // menu is not already set up |
| if (!rulerMenuId.equals(getRulerContextMenuId()) || (fRulerContextMenu == null)) { |
| setRulerContextMenuId(rulerMenuId); |
| |
| if (getVerticalRuler() != null) { |
| // dispose of previous ruler context menu |
| if (fRulerContextMenu != null) { |
| fRulerContextMenu.dispose(); |
| } |
| if (fRulerContextMenuManager != null) { |
| fRulerContextMenuManager.removeMenuListener(getContextMenuListener()); |
| fRulerContextMenuManager.removeAll(); |
| fRulerContextMenuManager.dispose(); |
| } |
| |
| fRulerContextMenuManager = new MenuManager(getRulerContextMenuId(), getRulerContextMenuId()); |
| fRulerContextMenuManager.setRemoveAllWhenShown(true); |
| fRulerContextMenuManager.addMenuListener(getContextMenuListener()); |
| |
| Control rulerControl = getVerticalRuler().getControl(); |
| fRulerContextMenu = fRulerContextMenuManager.createContextMenu(rulerControl); |
| rulerControl.setMenu(fRulerContextMenu); |
| rulerControl.addMouseListener(getRulerMouseListener()); |
| |
| getSite().registerContextMenu(getRulerContextMenuId(), fRulerContextMenuManager, getSelectionProvider()); |
| |
| // also register this menu for source page part and structured |
| // text editor ids |
| String partId = getSite().getId(); |
| if (partId != null) { |
| getSite().registerContextMenu(partId + RULER_CONTEXT_MENU_POSTFIX, fRulerContextMenuManager, getSelectionProvider()); |
| } |
| getSite().registerContextMenu(RULER_CONTEXT_MENU_ID, fRulerContextMenuManager, getSelectionProvider()); |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.editors.text.TextEditor#initializeKeyBindingScopes() |
| */ |
| protected void initializeKeyBindingScopes() { |
| setKeyBindingScopes(new String[]{EDITOR_KEYBINDING_SCOPE_ID}); |
| } |
| |
| /** |
| * Initializes the editor's source viewer and other items that were source |
| * viewer-dependent. |
| */ |
| private void initializeSourceViewer() { |
| if (getViewerSelectionManager() != null) |
| getViewerSelectionManager().setModel(getInternalModel()); |
| |
| computeAndSetDoubleClickAction(getInternalModel()); |
| |
| IAction contentAssistAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS); |
| if (contentAssistAction instanceof IUpdate) { |
| ((IUpdate) contentAssistAction).update(); |
| } |
| IAction openHyperlinkAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE); |
| if (openHyperlinkAction instanceof OpenHyperlinkAction) { |
| ((OpenHyperlinkAction) openHyperlinkAction).setHyperlinkDetectors(getSourceViewerConfiguration().getHyperlinkDetectors(getSourceViewer())); |
| } |
| |
| // do not even install projection support until folding is actually |
| // enabled |
| if (isFoldingEnabled()) { |
| installProjectionSupport(); |
| } |
| } |
| |
| /** |
| * Performs any necessary setup for a new or unconfigured |
| * StructuredTextViewerConfiguration |
| * |
| * @param configuration |
| */ |
| void initializeSourceViewerConfiguration(StructuredTextViewerConfiguration configuration) { |
| configuration.setEditorPart(this); |
| configuration.setPreferenceStore(getPreferenceStore()); |
| |
| IResource resource = null; |
| IFile file = (IFile) getEditorInput().getAdapter(IFile.class); |
| if (file != null) { |
| resource = file.getProject(); |
| } |
| configuration.configureOn(resource); |
| } |
| |
| protected void initSourceViewer(StructuredTextViewer sourceViewer) { |
| // ensure decoration support is configured |
| getSourceViewerDecorationSupport(sourceViewer); |
| fMouseTracker = new MouseTracker(); |
| fMouseTracker.start(sourceViewer.getTextWidget()); |
| initializeDrop(sourceViewer); |
| } |
| |
| protected void installEncodingSupport() { |
| // TODO: install our custom support that can |
| // update document appropriately |
| // super.installEncodingSupport(); |
| } |
| |
| /** |
| * Install everything necessary to get document folding working and enable |
| * document folding |
| */ |
| private void installProjectionSupport() { |
| ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); |
| |
| fProjectionSupport = new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors()); |
| fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$ |
| fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$ |
| fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() { |
| public IInformationControl createInformationControl(Shell parent) { |
| return new DefaultInformationControl(parent); |
| } |
| }); |
| fProjectionSupport.install(); |
| |
| IStructuredTextFoldingProvider updater = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; updater == null && i < ids.length; i++) { |
| updater = (IStructuredTextFoldingProvider) builder.getConfiguration(IStructuredTextFoldingProvider.ID, ids[i]); |
| } |
| |
| fProjectionModelUpdater = updater; |
| if (fProjectionModelUpdater != null) |
| fProjectionModelUpdater.install(projectionViewer); |
| |
| if (isFoldingEnabled()) |
| projectionViewer.doOperation(ProjectionViewer.TOGGLE); |
| } |
| |
| |
| /** |
| * Return whether document folding should be enabled according to the |
| * preference store settings. |
| * |
| * @return <code>true</code> if document folding should be enabled |
| */ |
| private boolean isFoldingEnabled() { |
| IPreferenceStore store = getPreferenceStore(); |
| // check both preference store and vm argument |
| return (store.getBoolean(IStructuredTextFoldingProvider.FOLDING_ENABLED) && (System.getProperty("org.eclipse.wst.sse.ui.foldingenabled") != null)); //$NON-NLS-1$ |
| } |
| |
| private void logUnexpectedDocumentKind(IEditorInput input) { |
| // display a dialog informing user of uknown content type |
| if (SSEUIPlugin.getDefault().getPreferenceStore().getBoolean(EditorPreferenceNames.SHOW_UNKNOWN_CONTENT_TYPE_MSG)) { |
| Job job = new UIJob(SSEUIMessages.StructuredTextEditor_0) { |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| UnknownContentTypeDialog dialog = new UnknownContentTypeDialog(getSite().getShell(), SSEUIPlugin.getDefault().getPreferenceStore(), EditorPreferenceNames.SHOW_UNKNOWN_CONTENT_TYPE_MSG); |
| dialog.open(); |
| return Status.OK_STATUS; |
| } |
| }; |
| job.schedule(); |
| } |
| |
| Logger.log(Logger.WARNING, "StructuredTextEditor being used without StructuredDocument"); //$NON-NLS-1$ |
| String name = null; |
| if (input != null) { |
| name = input.getName(); |
| } |
| else { |
| name = "input was null"; //$NON-NLS-1$ |
| } |
| Logger.log(Logger.WARNING, " Input Name: " + name); //$NON-NLS-1$ |
| String implClass = null; |
| IDocument document = getDocumentProvider().getDocument(input); |
| if (document != null) { |
| implClass = document.getClass().getName(); |
| } |
| else { |
| implClass = "document was null"; //$NON-NLS-1$ |
| } |
| Logger.log(Logger.WARNING, " Unexpected IDocument implementation: " + implClass); //$NON-NLS-1$ |
| } |
| |
| /* |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert() |
| */ |
| protected void performRevert() { |
| ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); |
| projectionViewer.setRedraw(false); |
| try { |
| |
| boolean projectionMode = projectionViewer.isProjectionMode(); |
| if (projectionMode) { |
| projectionViewer.disableProjection(); |
| if (fProjectionModelUpdater != null) |
| fProjectionModelUpdater.uninstall(); |
| } |
| |
| super.performRevert(); |
| |
| if (projectionMode) { |
| if (fProjectionModelUpdater != null) |
| fProjectionModelUpdater.install(projectionViewer); |
| projectionViewer.enableProjection(); |
| } |
| |
| } |
| finally { |
| projectionViewer.setRedraw(true); |
| } |
| } |
| |
| /** |
| * This method was made public for use by editors that use |
| * StructuredTextEditor (like PageDesigner) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#rememberSelection() |
| */ |
| public void rememberSelection() { |
| super.rememberSelection(); |
| } |
| |
| /** |
| * both starts and resets the busy state timer |
| */ |
| private void resetBusyState() { |
| // reset the "busy" timeout |
| if (fBusyTimer != null) { |
| fBusyTimer.cancel(); |
| } |
| startBusyTimer(); |
| } |
| |
| /** |
| * This method was made public for use by editors that use |
| * StructuredTextEditor (like PageDesigner) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#restoreSelection() |
| */ |
| public void restoreSelection() { |
| // catch odd case where source viewer has no text |
| // widget (defect |
| // 227670) |
| if ((getSourceViewer() != null) && (getSourceViewer().getTextWidget() != null)) |
| super.restoreSelection(); |
| } |
| |
| protected void rulerContextMenuAboutToShow(IMenuManager menu) { |
| IStructuredModel internalModel = getInternalModel(); |
| if (internalModel != null) { |
| boolean debuggingAvailable = BreakpointProviderBuilder.getInstance().isAvailable(internalModel.getContentTypeIdentifier(), BreakpointRulerAction.getFileExtension(getEditorInput())); |
| if (debuggingAvailable) { |
| menu.add(getAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS)); |
| menu.add(getAction(ActionDefinitionIds.MANAGE_BREAKPOINTS)); |
| menu.add(getAction(ActionDefinitionIds.EDIT_BREAKPOINTS)); |
| menu.add(new Separator()); |
| } |
| super.rulerContextMenuAboutToShow(menu); |
| addExtendedRulerContextMenuActions(menu); |
| } |
| } |
| |
| /** |
| * Overridden to expose part activation handling for multi-page editors |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#safelySanityCheckState(org.eclipse.ui.IEditorInput) |
| */ |
| public void safelySanityCheckState(IEditorInput input) { |
| super.safelySanityCheckState(input); |
| } |
| |
| private void savedModel() { |
| if (getInternalModel() != null) { |
| getInternalModel().changedModel(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#selectAndReveal(int, |
| * int, int, int) |
| */ |
| protected void selectAndReveal(int selectionStart, int selectionLength, int revealStart, int revealLength) { |
| super.selectAndReveal(selectionStart, selectionLength, revealStart, revealLength); |
| getTextViewer().notifyViewerSelectionManager(selectionStart, selectionLength); |
| } |
| |
| /** |
| * Ensure that the correct IDocumentProvider is used. For direct models, a |
| * special provider is used. For StorageEditorInputs, use a custom |
| * provider that creates a usable ResourceAnnotationModel. For everything |
| * else, use the base support. |
| * |
| * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#setDocumentProvider(org.eclipse.ui.IEditorInput) |
| */ |
| protected void setDocumentProvider(IEditorInput input) { |
| if (input instanceof IStructuredModel) { |
| // largely untested |
| setDocumentProvider(StructuredModelDocumentProvider.getInstance()); |
| } |
| else if (input instanceof IStorageEditorInput && !(input instanceof IFileEditorInput)) { |
| setDocumentProvider(StorageModelProvider.getInstance()); |
| } |
| else { |
| super.setDocumentProvider(input); |
| } |
| } |
| |
| public void setEditorPart(IEditorPart editorPart) { |
| fEditorPart = editorPart; |
| } |
| |
| /** |
| * @deprecated - use setInput as if we were a text editor - may be REMOVED |
| * AT ANY TIME |
| * |
| */ |
| public void setModel(IFileEditorInput input) { |
| setInput(input); |
| } |
| |
| /** |
| * Sets the model field within this editor. |
| * |
| * @deprecated - can eventually be eliminated |
| */ |
| private void setModel(IStructuredModel newModel) { |
| Assert.isNotNull(getDocumentProvider(), "document provider can not be null when setting model"); //$NON-NLS-1$ |
| if (fStructuredModel != null) { |
| if (fStructuredModel.getStructuredDocument() != null) { |
| fStructuredModel.getStructuredDocument().removeDocumentListener(getInternalDocumentListener()); |
| } |
| fStructuredModel.removeModelStateListener(getInternalModelStateListener()); |
| } |
| fStructuredModel = newModel; |
| if (fStructuredModel != null) { |
| if (fStructuredModel.getStructuredDocument() != null) { |
| fStructuredModel.getStructuredDocument().addDocumentListener(getInternalDocumentListener()); |
| } |
| fStructuredModel.addModelStateListener(getInternalModelStateListener()); |
| } |
| // update() should be called whenever the model is |
| // set or changed |
| update(); |
| } |
| |
| /** |
| * Sets the editor's source viewer configuration which it uses to |
| * configure it's internal source viewer. This method was overwritten so |
| * that viewer configuration could be set after editor part was created. |
| */ |
| protected void setSourceViewerConfiguration(SourceViewerConfiguration config) { |
| super.setSourceViewerConfiguration(config); |
| StructuredTextViewer stv = getTextViewer(); |
| if (stv != null) { |
| // there should be no need to unconfigure |
| // before configure because |
| // configure will |
| // also unconfigure before configuring |
| stv.unconfigure(); |
| stv.configure(config); |
| } |
| } |
| |
| public void showBusy(boolean busy) { |
| if (busy) { |
| fRememberTitle = getPartName(); |
| // update title and/or fonts and/or background |
| // |
| // temp solution, for testing, uses "busy" |
| setPartName(SSEUIMessages.busy); //$NON-NLS-1$ |
| } |
| else { |
| // reset to what it was |
| setPartName(fRememberTitle); |
| } |
| } |
| |
| private void startBusyTimer() { |
| // TODO: we need a resetable timer, so not so |
| // many created |
| fBusyTimer = new Timer(true); |
| fBusyTimer.schedule(new TimeOutExpired(), BUSY_STATE_DELAY); |
| } |
| |
| |
| private void statusError(IStatus status) { |
| statusError(status.getMessage()); |
| ErrorDialog.openError(getSite().getShell(), null, null, status); |
| } |
| |
| private void statusError(String message) { |
| IStatusLineManager manager = getStatusLineManager(); |
| if (manager == null) |
| return; |
| manager.setErrorMessage(message); |
| getSite().getShell().getDisplay().beep(); |
| } |
| |
| /** |
| * update() should be called whenever the model is set or changed (as in |
| * swapped) |
| */ |
| public void update() { |
| if (fOutlinePage != null && fOutlinePage instanceof StructuredTextEditorContentOutlinePage) { |
| ContentOutlineConfiguration cfg = createContentOutlineConfiguration(); |
| if (cfg instanceof StructuredContentOutlineConfiguration) { |
| ((StructuredContentOutlineConfiguration) cfg).setEditor(this); |
| } |
| ((StructuredTextEditorContentOutlinePage) fOutlinePage).setConfiguration(cfg); |
| ((StructuredTextEditorContentOutlinePage) fOutlinePage).setModel(getInternalModel()); |
| ((StructuredTextEditorContentOutlinePage) fOutlinePage).setViewerSelectionManager(getViewerSelectionManager()); |
| } |
| if (fPropertySheetPage != null && fPropertySheetPage instanceof ConfigurablePropertySheetPage) { |
| PropertySheetConfiguration cfg = createPropertySheetConfiguration(); |
| if (cfg instanceof StructuredPropertySheetConfiguration) { |
| ((StructuredPropertySheetConfiguration) cfg).setEditor(this); |
| } |
| ((ConfigurablePropertySheetPage) fPropertySheetPage).setConfiguration(cfg); |
| ((ConfigurablePropertySheetPage) fPropertySheetPage).setModel(getInternalModel()); |
| ((ConfigurablePropertySheetPage) fPropertySheetPage).setViewerSelectionManager(getViewerSelectionManager()); |
| } |
| if (getViewerSelectionManager() != null) |
| getViewerSelectionManager().setModel(getInternalModel()); |
| disposeModelDependentFields(); |
| |
| fShowInTargetIds = createShowInTargetIds(); |
| |
| |
| updateSourceViewerConfiguration(); |
| |
| createModelDependentFields(); |
| computeAndSetDoubleClickAction(getInternalModel()); |
| } |
| |
| /** |
| * Updates all content dependent actions. |
| */ |
| protected void updateContentDependentActions() { |
| super.updateContentDependentActions(); |
| // super.updateContentDependentActions only updates |
| // the enable/disable |
| // state of all |
| // the content dependent actions. |
| // StructuredTextEditor's undo and redo actions |
| // have a detail label and |
| // description. |
| // They needed to be updated. |
| if (!fEditorDisposed) |
| updateMenuText(); |
| } |
| |
| private void updateEncodingMemento() { |
| boolean failed = false; |
| IStructuredModel internalModel = getInternalModel(); |
| if (internalModel != null) { |
| IStructuredDocument doc = internalModel.getStructuredDocument(); |
| EncodingMemento memento = doc.getEncodingMemento(); |
| IDocumentCharsetDetector detector = internalModel.getModelHandler().getEncodingDetector(); |
| if (memento != null && detector != null) |
| detector.set(doc); |
| try { |
| detector.getEncoding(); |
| } |
| catch (IOException e) { |
| failed = true; |
| } |
| // be sure to use the new instance |
| // but only if no exception occurred. |
| // (we may find cases we need to do more error recover there) |
| // should be near impossible to get IOException from processing |
| // the |
| // *document* |
| if (!failed) { |
| doc.setEncodingMemento(memento); |
| } |
| } |
| } |
| |
| /* |
| * Update the hovering behavior depending on the preferences. |
| */ |
| private void updateHoverBehavior() { |
| SourceViewerConfiguration configuration = getSourceViewerConfiguration(); |
| String[] types = configuration.getConfiguredContentTypes(getSourceViewer()); |
| |
| for (int i = 0; i < types.length; i++) { |
| |
| String t = types[i]; |
| |
| ISourceViewer sourceViewer = getSourceViewer(); |
| if (sourceViewer instanceof ITextViewerExtension2) { |
| // Remove existing hovers |
| ((ITextViewerExtension2) sourceViewer).removeTextHovers(t); |
| |
| int[] stateMasks = configuration.getConfiguredTextHoverStateMasks(getSourceViewer(), t); |
| |
| if (stateMasks != null) { |
| for (int j = 0; j < stateMasks.length; j++) { |
| int stateMask = stateMasks[j]; |
| ITextHover textHover = configuration.getTextHover(sourceViewer, t, stateMask); |
| ((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, stateMask); |
| } |
| } |
| else { |
| ITextHover textHover = configuration.getTextHover(sourceViewer, t); |
| ((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); |
| } |
| } |
| else |
| sourceViewer.setTextHover(configuration.getTextHover(sourceViewer, t), t); |
| } |
| } |
| |
| |
| protected void updateMenuText() { |
| if (fStructuredModel != null && !fStructuredModel.isModelStateChanging() && getTextViewer().getTextWidget() != null) { |
| // performance: don't force an update of the action bars unless |
| // required as it is expensive |
| String previousUndoText = null; |
| String previousUndoDesc = null; |
| String previousRedoText = null; |
| String previousRedoDesc = null; |
| boolean updateActions = false; |
| IAction undoAction = getAction(ITextEditorActionConstants.UNDO); |
| IAction redoAction = getAction(ITextEditorActionConstants.REDO); |
| if (undoAction != null) { |
| previousUndoText = undoAction.getText(); |
| previousUndoDesc = undoAction.getDescription(); |
| updateActions = updateActions || previousUndoText == null || previousUndoDesc == null; |
| undoAction.setText(UNDO_ACTION_TEXT_DEFAULT); |
| undoAction.setDescription(UNDO_ACTION_DESC_DEFAULT); |
| } |
| if (redoAction != null) { |
| previousRedoText = redoAction.getText(); |
| previousRedoDesc = redoAction.getDescription(); |
| updateActions = updateActions || previousRedoText == null || previousRedoDesc == null; |
| redoAction.setText(REDO_ACTION_TEXT_DEFAULT); |
| redoAction.setDescription(REDO_ACTION_DESC_DEFAULT); |
| } |
| if (fStructuredModel.getUndoManager() != null) { |
| IStructuredTextUndoManager undoManager = fStructuredModel.getUndoManager(); |
| // get undo command |
| Command undoCommand = undoManager.getUndoCommand(); |
| // set undo label and description |
| undoAction.setEnabled(undoManager.undoable()); |
| if (undoCommand != null) { |
| String label = undoCommand.getLabel(); |
| if (label != null) { |
| String customText = MessageFormat.format(UNDO_ACTION_TEXT, new String[]{label}); |
| updateActions = updateActions || customText == null || previousUndoText == null || !customText.equals(previousUndoText); |
| undoAction.setText(customText); |
| } |
| String desc = undoCommand.getDescription(); |
| if (desc != null) { |
| String customDesc = MessageFormat.format(UNDO_ACTION_DESC, new String[]{desc}); |
| updateActions = updateActions || customDesc == null || previousRedoDesc == null || !customDesc.equals(previousUndoDesc); |
| undoAction.setDescription(customDesc); |
| } |
| } |
| // get redo command |
| Command redoCommand = undoManager.getRedoCommand(); |
| // set redo label and description |
| redoAction.setEnabled(undoManager.redoable()); |
| if (redoCommand != null) { |
| String label = redoCommand.getLabel(); |
| if (label != null) { |
| String customText = MessageFormat.format(REDO_ACTION_TEXT, new String[]{label}); |
| updateActions = updateActions || customText == null || previousRedoText == null || !customText.equals(previousRedoText); |
| redoAction.setText(customText); |
| } |
| String desc = redoCommand.getDescription(); |
| if (desc != null) { |
| String customDesc = MessageFormat.format(REDO_ACTION_DESC, new String[]{desc}); |
| updateActions = updateActions || customDesc == null || previousRedoDesc == null || !customDesc.equals(previousRedoDesc); |
| redoAction.setDescription(customDesc); |
| } |
| } |
| } |
| // tell the action bars to update |
| if (updateActions) { |
| if (getEditorSite().getActionBars() != null) { |
| getEditorSite().getActionBars().updateActionBars(); |
| } |
| else if (getEditorPart() != null && getEditorPart().getEditorSite().getActionBars() != null) { |
| getEditorPart().getEditorSite().getActionBars().updateActionBars(); |
| } |
| } |
| } |
| } |
| |
| private void updateSourceViewerConfiguration() { |
| SourceViewerConfiguration configuration = getSourceViewerConfiguration(); |
| // no need to update source viewer configuration if one does not exist |
| // yet |
| if (configuration == null) { |
| return; |
| } |
| |
| // structuredtextviewer only works with |
| // structuredtextviewerconfiguration |
| if (!(configuration instanceof StructuredTextViewerConfiguration)) { |
| configuration = createSourceViewerConfiguration(); |
| setSourceViewerConfiguration(configuration); |
| } |
| else { |
| StructuredTextViewerConfiguration newViewerConfiguration = createSourceViewerConfiguration(); |
| if (!((StructuredTextViewerConfiguration) configuration).getDeclaringID().equals(newViewerConfiguration.getDeclaringID())) { |
| // d282894 use newViewerConfiguration |
| configuration = newViewerConfiguration; |
| setSourceViewerConfiguration(configuration); |
| } |
| |
| // update the configuration's resource |
| IResource resource = null; |
| if (getEditorInput() instanceof IFileEditorInput) { |
| resource = ((IFileEditorInput) getEditorInput()).getFile(); |
| if (resource.getType() != IResource.PROJECT) |
| resource = resource.getProject(); |
| ((StructuredTextViewerConfiguration) configuration).configureOn(resource); |
| } |
| } |
| |
| if (getSourceViewer() != null) { |
| getSourceViewer().configure(configuration); |
| IAction contentAssistAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS); |
| if (contentAssistAction instanceof IUpdate) { |
| ((IUpdate) contentAssistAction).update(); |
| } |
| IAction openHyperlinkAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE); |
| if (openHyperlinkAction instanceof OpenHyperlinkAction) { |
| ((OpenHyperlinkAction) openHyperlinkAction).setHyperlinkDetectors(getSourceViewerConfiguration().getHyperlinkDetectors(getSourceViewer())); |
| } |
| } |
| // eventually will replace above with something |
| // like what follows |
| // it, but some of our "processors" require too |
| // much initialization |
| // during configuration. |
| // SourceViewerConfiguration configuration = |
| // getSourceViewerConfiguration(); |
| // |
| // // should always be an instance of our special |
| // configuration, but |
| // just in case |
| // // not, we'll do nothing if it isn't. |
| // if (configuration!= null && configuration |
| // instanceof |
| // StructuredTextViewerConfiguration) { |
| // |
| // IResource resource = null; |
| // if (getEditorInput() instanceof |
| // IFileEditorInput) { |
| // resource = ((IFileEditorInput) |
| // getEditorInput()).getFile(); |
| // if (resource.getType() != IResource.PROJECT) |
| // resource = resource.getProject(); |
| // // note: configureOn is responsible for updating |
| // what ever |
| // // in our configuration is sensitive to resource |
| // ((StructuredTextViewerConfiguration) |
| // configuration).configureOn(resource); |
| // } |
| // |
| // } |
| } |
| |
| protected void updateStatusField(String category) { |
| super.updateStatusField(category); |
| |
| if (category == null) |
| return; |
| |
| if (StructuredTextEditorActionConstants.STATUS_CATEGORY_OFFSET.equals(category)) { |
| IStatusField field = getStatusField(category); |
| if (field != null) { |
| Point selection = getTextViewer().getTextWidget().getSelection(); |
| int offset1 = widgetOffset2ModelOffset(getSourceViewer(), selection.x); |
| int offset2 = widgetOffset2ModelOffset(getSourceViewer(), selection.y); |
| String text = null; |
| if (offset1 != offset2) |
| text = "[" + offset1 + "-" + offset2 + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| else |
| text = "[ " + offset1 + " ]"; //$NON-NLS-1$ //$NON-NLS-2$ |
| field.setText(text == null ? fErrorLabel : text); |
| } |
| } |
| } |
| |
| /** |
| * @deprecated - will be removed in M4 Use getDocumentProvider and |
| * IDocumentProviderExtension instead |
| */ |
| public IStatus validateEdit(Shell context) { |
| IStatus status = STATUS_OK; |
| IEditorInput input = getEditorInput(); |
| if (input instanceof IFileEditorInput) { |
| if (input == null) { |
| String msg = SSEUIMessages.Error_opening_file_UI_; //$NON-NLS-1$ |
| status = new Status(IStatus.ERROR, SSEUIPlugin.ID, IStatus.INFO, msg, null); |
| } |
| else { |
| validateState(input); |
| sanityCheckState(input); |
| if (isEditorInputReadOnly()) { |
| String fname = input.getName(); |
| if (input instanceof IStorageEditorInput) { |
| try { |
| IStorage s = ((IStorageEditorInput) input).getStorage(); |
| if (s != null) { |
| IPath path = s.getFullPath(); |
| if (path != null) { |
| fname += path.toString(); |
| } |
| else { |
| fname += s.getName(); |
| } |
| } |
| } |
| catch (CoreException e) { // IStorage is just for |
| // file name, |
| // and it's an optional, |
| // therefore |
| // it is safe to ignore this |
| // exception. |
| } |
| } |
| String msg = NLS.bind(SSEUIMessages._UI_File_is_read_only, new Object[]{fname}); |
| status = new Status(IStatus.ERROR, SSEUIPlugin.ID, IStatus.INFO, msg, null); |
| } |
| } |
| } |
| return status; |
| } |
| |
| protected void validateState(IEditorInput input) { |
| IDocumentProvider provider = getDocumentProvider(); |
| if (provider instanceof IDocumentProviderExtension) { |
| IDocumentProviderExtension extension = (IDocumentProviderExtension) provider; |
| try { |
| boolean wasReadOnly = isEditorInputReadOnly(); |
| extension.validateState(input, getSite().getShell()); |
| if (getSourceViewer() != null) |
| getSourceViewer().setEditable(isEditable()); |
| if (wasReadOnly != isEditorInputReadOnly()) |
| updateStateDependentActions(); |
| } |
| catch (CoreException x) { |
| ILog log = Platform.getLog(Platform.getBundle(PlatformUI.PLUGIN_ID)); |
| log.log(x.getStatus()); |
| statusError(x.getStatus()); |
| } |
| } |
| } |
| } |