001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.parts;
011:
012: import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
013: import org.eclipse.jface.text.Document;
014: import org.eclipse.jface.text.IDocument;
015: import org.eclipse.jface.text.ITextOperationTarget;
016: import org.eclipse.jface.text.source.SourceViewer;
017: import org.eclipse.jface.viewers.ISelectionChangedListener;
018: import org.eclipse.jface.viewers.SelectionChangedEvent;
019: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
020: import org.eclipse.pde.internal.ui.editor.context.XMLDocumentSetupParticpant;
021: import org.eclipse.pde.internal.ui.editor.text.ColorManager;
022: import org.eclipse.pde.internal.ui.editor.text.IColorManager;
023: import org.eclipse.pde.internal.ui.editor.text.XMLConfiguration;
024: import org.eclipse.swt.SWT;
025: import org.eclipse.swt.custom.StyledText;
026: import org.eclipse.swt.events.DisposeEvent;
027: import org.eclipse.swt.events.DisposeListener;
028: import org.eclipse.swt.events.FocusAdapter;
029: import org.eclipse.swt.events.FocusEvent;
030: import org.eclipse.swt.layout.GridData;
031: import org.eclipse.swt.widgets.Composite;
032: import org.eclipse.ui.actions.ActionFactory;
033: import org.eclipse.ui.forms.widgets.FormToolkit;
034:
035: /**
036: * CSSourceViewerFactory
037: *
038: */
039: public class PDESourceViewer {
040:
041: private static XMLConfiguration fSourceConfiguration = null;
042:
043: private static IColorManager fColorManager = null;
044:
045: private static int fSourceViewerCount = 0;
046:
047: private SourceViewer fViewer;
048:
049: private PDEFormPage fPage;
050:
051: private IDocument fDocument;
052:
053: /**
054: * @param page
055: */
056: public PDESourceViewer(PDEFormPage page) {
057: // Create the underlying document
058: fDocument = new Document();
059: fPage = page;
060: }
061:
062: /**
063: * @return
064: */
065: public IDocument getDocument() {
066: return fDocument;
067: }
068:
069: /**
070: * @return
071: */
072: public SourceViewer getViewer() {
073: return fViewer;
074: }
075:
076: /**
077: * @return
078: */
079: private XMLConfiguration getConfiguration() {
080: if (fSourceConfiguration == null) {
081: // Get the color manager
082: fColorManager = ColorManager.getDefault();
083: // Create the source configuration
084: fSourceConfiguration = new XMLConfiguration(fColorManager);
085: }
086: return fSourceConfiguration;
087: }
088:
089: /**
090: * Utility method for creating a field for syntax highlighting
091: * @param parent
092: * @param heightHint
093: * @param widthHint
094: */
095: public void createUI(Composite parent, int heightHint, int widthHint) {
096: GridData data = new GridData(GridData.FILL_HORIZONTAL);
097: data.heightHint = heightHint;
098: data.widthHint = widthHint;
099: createUI(parent, data);
100: }
101:
102: public void createUI(Composite parent, GridData data) {
103: // Create the source viewer
104: int style = SWT.MULTI | SWT.WRAP | SWT.V_SCROLL;
105: fViewer = new SourceViewer(parent, null, style);
106: // Configure the source viewer
107: fViewer.configure(getConfiguration());
108: // Setup the underlying document
109: IDocumentSetupParticipant participant = new XMLDocumentSetupParticpant();
110: participant.setup(fDocument);
111: // Set the document on the source viewer
112: fViewer.setDocument(fDocument);
113: // Configure the underlying styled text widget
114: configureUIStyledText(data, fViewer.getTextWidget());
115: // Create style text listeners
116: createUIListenersStyledText(fViewer.getTextWidget());
117: }
118:
119: /**
120: *
121: */
122: public void createUIListeners() {
123: // Ensure the viewer was created
124: if (fViewer == null) {
125: return;
126: }
127: // Create source viewer listeners
128: // Create selection listener
129: fViewer
130: .addSelectionChangedListener(new ISelectionChangedListener() {
131: public void selectionChanged(
132: SelectionChangedEvent event) {
133: fPage.getPDEEditor().setSelection(
134: event.getSelection());
135: }
136: });
137: // Create focus listener
138: fViewer.getTextWidget().addFocusListener(new FocusAdapter() {
139: public void focusGained(FocusEvent e) {
140: fPage.getPDEEditor().getContributor()
141: .updateSelectableActions(null);
142: }
143: });
144: }
145:
146: /**
147: * @param textWidget
148: */
149: private void createUIListenersStyledText(StyledText textWidget) {
150: // Track the number of source viewers created
151: fSourceViewerCount++;
152: // The color manager and source viewer configuration should be disposed
153: // When the last source viewer is diposed, dispose of the color manager
154: // and source viewer configuration
155: textWidget.addDisposeListener(new DisposeListener() {
156: public void widgetDisposed(DisposeEvent e) {
157: fSourceViewerCount--;
158: if (fSourceViewerCount == 0) {
159: dispose();
160: }
161: }
162: });
163: }
164:
165: /**
166: *
167: */
168: private void dispose() {
169: // TODO: MP: CompCS: Profile Sleek when making static to ensure no leaks
170: // Dispose of the color manager
171: if (fColorManager != null) {
172: fColorManager.dispose();
173: fColorManager = null;
174: }
175: // Dispose of the source configuration
176: if (fSourceConfiguration != null) {
177: fSourceConfiguration.dispose();
178: fSourceConfiguration = null;
179: }
180: }
181:
182: /**
183: * @param heightHint
184: * @param widthHint
185: * @param styledText
186: */
187: private void configureUIStyledText(GridData data,
188: StyledText styledText) {
189: // Configure the underlying styled text widget
190: styledText.setMenu(fPage.getPDEEditor().getContextMenu());
191: // Force borders
192: styledText.setData(FormToolkit.KEY_DRAW_BORDER,
193: FormToolkit.TEXT_BORDER);
194: styledText.setLayoutData(data);
195: }
196:
197: /**
198: * The menu set on the underlying styled text widget of the source viewer
199: * needs to be set to null before being diposed; otherwise, the menu will
200: * be disposed along with the widget.
201: * @param viewer
202: */
203: public void unsetMenu() {
204: if (fViewer == null) {
205: return;
206: }
207: StyledText styledText = fViewer.getTextWidget();
208: if (styledText == null) {
209: return;
210: } else if (styledText.isDisposed()) {
211: return;
212: }
213: styledText.setMenu(null);
214: }
215:
216: /**
217: * Utility method used to tie global actions into source viewers.
218: *
219: * @param actionId
220: * @param viewer
221: * @return
222: */
223: public boolean doGlobalAction(String actionId) {
224: // Ensure the viewer was created
225: if (fViewer == null) {
226: return false;
227: } else if (actionId.equals(ActionFactory.CUT.getId())) {
228: fViewer.doOperation(ITextOperationTarget.CUT);
229: return true;
230: } else if (actionId.equals(ActionFactory.COPY.getId())) {
231: fViewer.doOperation(ITextOperationTarget.COPY);
232: return true;
233: } else if (actionId.equals(ActionFactory.PASTE.getId())) {
234: fViewer.doOperation(ITextOperationTarget.PASTE);
235: return true;
236: } else if (actionId.equals(ActionFactory.SELECT_ALL.getId())) {
237: fViewer.doOperation(ITextOperationTarget.SELECT_ALL);
238: return true;
239: } else if (actionId.equals(ActionFactory.DELETE.getId())) {
240: fViewer.doOperation(ITextOperationTarget.DELETE);
241: return true;
242: } else if (actionId.equals(ActionFactory.UNDO.getId())) {
243: // TODO: MP: Undo: Re-enable Undo
244: //fViewer.doOperation(ITextOperationTarget.UNDO);
245: return false;
246: } else if (actionId.equals(ActionFactory.REDO.getId())) {
247: // TODO: MP: Undo: Re-enable Redo
248: //fViewer.doOperation(ITextOperationTarget.REDO);
249: return false;
250: }
251: return false;
252: }
253:
254: /**
255: * @param viewer
256: * @return
257: */
258: public boolean canPaste() {
259: // Ensure the viewer was created
260: if (fViewer == null) {
261: return false;
262: }
263: return fViewer.canDoOperation(ITextOperationTarget.PASTE);
264: }
265: }
|