001: /*******************************************************************************
002: * Copyright (c) 2000, 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: * Dan Rubel <dan_rubel@instantiations.com>
011: * - Fix for bug 11490 - define hidden view (placeholder for view) in plugin.xml
012: * Chris Gross <schtoo@schtoo.com>
013: * - Fix for 99155 - allow standalone view placeholders
014: *******************************************************************************/package org.eclipse.ui.internal.registry;
015:
016: import java.util.HashSet;
017: import java.util.Set;
018:
019: import org.eclipse.core.runtime.IConfigurationElement;
020: import org.eclipse.core.runtime.Platform;
021: import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
022: import org.eclipse.ui.IPageLayout;
023: import org.eclipse.ui.IViewLayout;
024: import org.eclipse.ui.PlatformUI;
025: import org.eclipse.ui.internal.DirtyPerspectiveMarker;
026: import org.eclipse.ui.internal.PageLayout;
027: import org.eclipse.ui.internal.WorkbenchPlugin;
028:
029: /**
030: * A strategy to read perspective extension from the registry.
031: * A pespective extension is one of a view, viewAction, perspAction,
032: * newWizardAction, or actionSet.
033: */
034: public class PerspectiveExtensionReader extends RegistryReader {
035: private String targetID;
036:
037: private PageLayout pageLayout;
038:
039: private Set includeOnlyTags = null;
040:
041: private static final String VAL_LEFT = "left";//$NON-NLS-1$
042:
043: private static final String VAL_RIGHT = "right";//$NON-NLS-1$
044:
045: private static final String VAL_TOP = "top";//$NON-NLS-1$
046:
047: private static final String VAL_BOTTOM = "bottom";//$NON-NLS-1$
048:
049: private static final String VAL_STACK = "stack";//$NON-NLS-1$
050:
051: private static final String VAL_FAST = "fast";//$NON-NLS-1$
052:
053: private static final String VAL_TRUE = "true";//$NON-NLS-1$
054:
055: // VAL_FALSE added by dan_rubel@instantiations.com
056: // TODO: this logic is backwards... we should be checking for true, but
057: // technically this is API now...
058: private static final String VAL_FALSE = "false";//$NON-NLS-1$
059:
060: private IExtensionTracker tracker;
061:
062: /**
063: * PerspectiveExtensionReader constructor..
064: */
065: public PerspectiveExtensionReader() {
066: // do nothing
067: }
068:
069: /**
070: * Read the view extensions within a registry.
071: *
072: * @param extensionTracker the tracker
073: * @param id the id
074: * @param out the layout
075: */
076: public void extendLayout(IExtensionTracker extensionTracker,
077: String id, PageLayout out) {
078: tracker = extensionTracker;
079: targetID = id;
080: pageLayout = out;
081: readRegistry(Platform.getExtensionRegistry(),
082: PlatformUI.PLUGIN_ID,
083: IWorkbenchRegistryConstants.PL_PERSPECTIVE_EXTENSIONS);
084: }
085:
086: /**
087: * Returns whether the given tag should be included.
088: */
089: private boolean includeTag(String tag) {
090: return includeOnlyTags == null || includeOnlyTags.contains(tag);
091: }
092:
093: /**
094: * Process an action set.
095: */
096: private boolean processActionSet(IConfigurationElement element) {
097: String id = element
098: .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
099: if (id != null) {
100: pageLayout.addActionSet(id);
101: }
102: return true;
103: }
104:
105: /**
106: * Process an extension.
107: * Assumption: Extension is for current perspective.
108: */
109: private boolean processExtension(IConfigurationElement element) {
110: IConfigurationElement[] children = element.getChildren();
111: for (int nX = 0; nX < children.length; nX++) {
112: IConfigurationElement child = children[nX];
113: String type = child.getName();
114: if (includeTag(type)) {
115: boolean result = false;
116: if (type
117: .equals(IWorkbenchRegistryConstants.TAG_ACTION_SET)) {
118: result = processActionSet(child);
119: } else if (type
120: .equals(IWorkbenchRegistryConstants.TAG_VIEW)) {
121: result = processView(child);
122: } else if (type
123: .equals(IWorkbenchRegistryConstants.TAG_VIEW_SHORTCUT)) {
124: result = processViewShortcut(child);
125: } else if (type
126: .equals(IWorkbenchRegistryConstants.TAG_NEW_WIZARD_SHORTCUT)) {
127: result = processWizardShortcut(child);
128: } else if (type
129: .equals(IWorkbenchRegistryConstants.TAG_PERSP_SHORTCUT)) {
130: result = processPerspectiveShortcut(child);
131: } else if (type
132: .equals(IWorkbenchRegistryConstants.TAG_SHOW_IN_PART)) {
133: result = processShowInPart(child);
134: }
135: if (!result) {
136: WorkbenchPlugin.log("Unable to process element: " + //$NON-NLS-1$
137: type
138: + " in perspective extension: " + //$NON-NLS-1$
139: element.getDeclaringExtension()
140: .getUniqueIdentifier());
141: }
142: }
143: }
144: return true;
145: }
146:
147: /**
148: * Process a perspective shortcut
149: */
150: private boolean processPerspectiveShortcut(
151: IConfigurationElement element) {
152: String id = element
153: .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
154: if (id != null) {
155: pageLayout.addPerspectiveShortcut(id);
156: }
157: return true;
158: }
159:
160: /**
161: * Process a show in element.
162: */
163: private boolean processShowInPart(IConfigurationElement element) {
164: String id = element
165: .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
166: if (id != null) {
167: pageLayout.addShowInPart(id);
168: }
169: return true;
170: }
171:
172: // processView(IConfigurationElement) modified by dan_rubel@instantiations.com
173: /**
174: * Process a view
175: */
176: private boolean processView(IConfigurationElement element) {
177: // Get id, relative, and relationship.
178: String id = element
179: .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
180: String relative = element
181: .getAttribute(IWorkbenchRegistryConstants.ATT_RELATIVE);
182: String relationship = element
183: .getAttribute(IWorkbenchRegistryConstants.ATT_RELATIONSHIP);
184: String ratioString = element
185: .getAttribute(IWorkbenchRegistryConstants.ATT_RATIO);
186: boolean visible = !VAL_FALSE.equals(element
187: .getAttribute(IWorkbenchRegistryConstants.ATT_VISIBLE));
188: String closeable = element
189: .getAttribute(IWorkbenchRegistryConstants.ATT_CLOSEABLE);
190: String moveable = element
191: .getAttribute(IWorkbenchRegistryConstants.ATT_MOVEABLE);
192: String standalone = element
193: .getAttribute(IWorkbenchRegistryConstants.ATT_STANDALONE);
194: String showTitle = element
195: .getAttribute(IWorkbenchRegistryConstants.ATT_SHOW_TITLE);
196:
197: // Default to 'false'
198: String minVal = element
199: .getAttribute(IWorkbenchRegistryConstants.ATT_MINIMIZED);
200: boolean minimized = minVal != null && VAL_TRUE.equals(minVal);
201:
202: float ratio;
203:
204: if (id == null) {
205: logMissingAttribute(element,
206: IWorkbenchRegistryConstants.ATT_ID);
207: return false;
208: }
209: if (relationship == null) {
210: logMissingAttribute(element,
211: IWorkbenchRegistryConstants.ATT_RELATIONSHIP);
212: return false;
213: }
214: if (!VAL_FAST.equals(relationship) && relative == null) {
215: logError(
216: element,
217: "Attribute '" + IWorkbenchRegistryConstants.ATT_RELATIVE + "' not defined. This attribute is required when " + IWorkbenchRegistryConstants.ATT_RELATIONSHIP + "=\"" + relationship + "\"."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
218: return false;
219: }
220:
221: // Get the ratio.
222: if (ratioString == null) {
223: // The ratio has not been specified.
224: ratio = IPageLayout.NULL_RATIO;
225: } else {
226: try {
227: ratio = new Float(ratioString).floatValue();
228: } catch (NumberFormatException e) {
229: return false;
230: }
231: // If the ratio is outside the allowable range, mark it as invalid.
232: if (ratio < IPageLayout.RATIO_MIN
233: || ratio > IPageLayout.RATIO_MAX) {
234: ratio = IPageLayout.INVALID_RATIO;
235: }
236: }
237:
238: // Get relationship details.
239: boolean stack = false;
240: boolean fast = false;
241: int intRelation = 0;
242: if (relationship.equals(VAL_LEFT)) {
243: intRelation = IPageLayout.LEFT;
244: } else if (relationship.equals(VAL_RIGHT)) {
245: intRelation = IPageLayout.RIGHT;
246: } else if (relationship.equals(VAL_TOP)) {
247: intRelation = IPageLayout.TOP;
248: } else if (relationship.equals(VAL_BOTTOM)) {
249: intRelation = IPageLayout.BOTTOM;
250: } else if (relationship.equals(VAL_STACK)) {
251: stack = true;
252: } else if (relationship.equals(VAL_FAST)) {
253: fast = true;
254: } else {
255: return false;
256: }
257:
258: if (visible) {
259: // If adding a view (not just a placeholder), remove any existing placeholder.
260: // See bug 85948 [Perspectives] Adding register & expressions view by default to debug perspective fails
261: pageLayout.removePlaceholder(id);
262: }
263:
264: // If stack ..
265: if (stack) {
266: if (visible) {
267: pageLayout.stackView(id, relative);
268: } else {
269: pageLayout.stackPlaceholder(id, relative);
270: }
271: }
272:
273: // If the view is a fast view...
274: else if (fast) {
275: if (ratio == IPageLayout.NULL_RATIO) {
276: // The ratio has not been specified.
277: pageLayout.addFastView(id);
278: } else {
279: pageLayout.addFastView(id, ratio);
280: }
281: } else {
282:
283: // The view is a regular view.
284: // If the ratio is not specified or is invalid, use the default ratio.
285: if (ratio == IPageLayout.NULL_RATIO
286: || ratio == IPageLayout.INVALID_RATIO) {
287: ratio = IPageLayout.DEFAULT_VIEW_RATIO;
288: }
289:
290: if (visible) {
291: if (VAL_TRUE.equals(standalone)) {
292: pageLayout.addStandaloneView(id, !VAL_FALSE
293: .equals(showTitle), intRelation, ratio,
294: relative);
295: } else {
296: pageLayout.addView(id, intRelation, ratio,
297: relative, minimized);
298: }
299: } else {
300: // Fix for 99155, CGross (schtoo@schtoo.com)
301: // Adding standalone placeholder for standalone views
302: if (VAL_TRUE.equals(standalone)) {
303: pageLayout.addStandaloneViewPlaceholder(id,
304: intRelation, ratio, relative, !VAL_FALSE
305: .equals(showTitle));
306: } else {
307: pageLayout.addPlaceholder(id, intRelation, ratio,
308: relative);
309: }
310: }
311: }
312: IViewLayout viewLayout = pageLayout.getViewLayout(id);
313: // may be null if it's been filtered by activity
314: if (viewLayout != null) {
315: if (closeable != null) {
316: viewLayout.setCloseable(!VAL_FALSE.equals(closeable));
317: }
318: if (moveable != null) {
319: viewLayout.setMoveable(!VAL_FALSE.equals(moveable));
320: }
321: }
322:
323: return true;
324: }
325:
326: /**
327: * Process a view shortcut
328: */
329: private boolean processViewShortcut(IConfigurationElement element) {
330: String id = element
331: .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
332: if (id != null) {
333: pageLayout.addShowViewShortcut(id);
334: }
335: return true;
336: }
337:
338: /**
339: * Process a wizard shortcut
340: */
341: private boolean processWizardShortcut(IConfigurationElement element) {
342: String id = element
343: .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
344: if (id != null) {
345: pageLayout.addNewWizardShortcut(id);
346: }
347: return true;
348: }
349:
350: protected boolean readElement(IConfigurationElement element) {
351: String type = element.getName();
352: if (type
353: .equals(IWorkbenchRegistryConstants.TAG_PERSPECTIVE_EXTENSION)) {
354: String id = element
355: .getAttribute(IWorkbenchRegistryConstants.ATT_TARGET_ID);
356: if (targetID.equals(id) || "*".equals(id)) { //$NON-NLS-1$
357: if (tracker != null) {
358: tracker.registerObject(element
359: .getDeclaringExtension(),
360: new DirtyPerspectiveMarker(id),
361: IExtensionTracker.REF_STRONG);
362: }
363: return processExtension(element);
364: }
365: return true;
366: }
367: return false;
368: }
369:
370: /**
371: * Sets the tags to include. All others are ignored.
372: *
373: * @param tags the tags to include
374: */
375: public void setIncludeOnlyTags(String[] tags) {
376: includeOnlyTags = new HashSet();
377: for (int i = 0; i < tags.length; i++) {
378: includeOnlyTags.add(tags[i]);
379: }
380: }
381: }
|