blob: 35ccd5ad5973ebdb9b9cc2c8ddd348651b3cdca6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2016 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
*******************************************************************************/
package org.eclipse.ui.internal;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IViewLayout;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.e4.compatibility.ModeledPageLayout;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.registry.RegistryReader;
/**
* A strategy to read perspective extension from the registry.
* A pespective extension is one of a view, viewAction, perspAction,
* newWizardAction, or actionSet.
*/
public class PerspectiveExtensionReader extends RegistryReader {
private String targetID;
private ModeledPageLayout pageLayout;
private Set includeOnlyTags = null;
private static final String VAL_LEFT = "left";//$NON-NLS-1$
private static final String VAL_RIGHT = "right";//$NON-NLS-1$
private static final String VAL_TOP = "top";//$NON-NLS-1$
private static final String VAL_BOTTOM = "bottom";//$NON-NLS-1$
private static final String VAL_STACK = "stack";//$NON-NLS-1$
private static final String VAL_FAST = "fast";//$NON-NLS-1$
private static final String VAL_TRUE = "true";//$NON-NLS-1$
// VAL_FALSE added by dan_rubel@instantiations.com
// TODO: this logic is backwards... we should be checking for true, but
// technically this is API now...
private static final String VAL_FALSE = "false";//$NON-NLS-1$
private IExtensionTracker tracker;
/**
* PerspectiveExtensionReader constructor..
*/
public PerspectiveExtensionReader() {
// do nothing
}
/**
* Read the view extensions within a registry.
*
* @param extensionTracker the tracker
* @param id the id
* @param out the layout
*/
public void extendLayout(IExtensionTracker extensionTracker, String id, ModeledPageLayout out) {
tracker = extensionTracker;
targetID = id;
pageLayout = out;
readRegistry(Platform.getExtensionRegistry(), PlatformUI.PLUGIN_ID,
IWorkbenchRegistryConstants.PL_PERSPECTIVE_EXTENSIONS);
}
/**
* Returns whether the given tag should be included.
*/
private boolean includeTag(String tag) {
return includeOnlyTags == null || includeOnlyTags.contains(tag);
}
/**
* Process an action set.
*/
private boolean processActionSet(IConfigurationElement element) {
String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
if (id != null) {
pageLayout.addActionSet(id);
}
return true;
}
/**
* Process an extension.
* Assumption: Extension is for current perspective.
*/
private boolean processExtension(IConfigurationElement element) {
IConfigurationElement[] children = element.getChildren();
for (IConfigurationElement child : children) {
String type = child.getName();
if (includeTag(type)) {
boolean result = false;
if (type.equals(IWorkbenchRegistryConstants.TAG_ACTION_SET)) {
result = processActionSet(child);
} else if (type.equals(IWorkbenchRegistryConstants.TAG_VIEW)) {
result = processView(child);
} else if (type.equals(IWorkbenchRegistryConstants.TAG_VIEW_SHORTCUT)) {
result = processViewShortcut(child);
} else if (type.equals(IWorkbenchRegistryConstants.TAG_NEW_WIZARD_SHORTCUT)) {
result = processWizardShortcut(child);
} else if (type.equals(IWorkbenchRegistryConstants.TAG_PERSP_SHORTCUT)) {
result = processPerspectiveShortcut(child);
} else if (type.equals(IWorkbenchRegistryConstants.TAG_SHOW_IN_PART)) {
result = processShowInPart(child);
} else if (type.equals(IWorkbenchRegistryConstants.TAG_HIDDEN_MENU_ITEM)) {
result = processHiddenMenuItem(child);
} else if (type.equals(IWorkbenchRegistryConstants.TAG_HIDDEN_TOOLBAR_ITEM)) {
result = processHiddenToolBarItem(child);
}
if (!result) {
WorkbenchPlugin.log("Unable to process element: " + //$NON-NLS-1$
type
+ " in perspective extension: " + //$NON-NLS-1$
element.getDeclaringExtension()
.getUniqueIdentifier());
}
}
}
return true;
}
/**
* Process a perspective shortcut
*/
private boolean processPerspectiveShortcut(IConfigurationElement element) {
String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
if (id != null) {
pageLayout.addPerspectiveShortcut(id);
}
return true;
}
/**
* Process a show in element.
*/
private boolean processShowInPart(IConfigurationElement element) {
String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
if (id != null) {
pageLayout.addShowInPart(id);
}
return true;
}
/**
* Process a hidden menu item
*/
private boolean processHiddenMenuItem(IConfigurationElement element) {
String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
if (id != null) {
pageLayout.addHiddenMenuItemId(id);
}
return true;
}
/**
* Process a hidden toolbar item
*/
private boolean processHiddenToolBarItem(IConfigurationElement element) {
String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
if (id != null) {
pageLayout.addHiddenToolBarItemId(id);
}
return true;
}
// processView(IConfigurationElement) modified by dan_rubel@instantiations.com
/**
* Process a view
*/
private boolean processView(IConfigurationElement element) {
// Get id, relative, and relationship.
String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
String relative = element.getAttribute(IWorkbenchRegistryConstants.ATT_RELATIVE);
String relationship = element.getAttribute(IWorkbenchRegistryConstants.ATT_RELATIONSHIP);
String ratioString = element.getAttribute(IWorkbenchRegistryConstants.ATT_RATIO);
boolean visible = !VAL_FALSE.equals(element.getAttribute(IWorkbenchRegistryConstants.ATT_VISIBLE));
String closeable = element.getAttribute(IWorkbenchRegistryConstants.ATT_CLOSEABLE);
String moveable = element.getAttribute(IWorkbenchRegistryConstants.ATT_MOVEABLE);
String standalone = element.getAttribute(IWorkbenchRegistryConstants.ATT_STANDALONE);
String showTitle = element.getAttribute(IWorkbenchRegistryConstants.ATT_SHOW_TITLE);
// Default to 'false'
String minVal = element.getAttribute(IWorkbenchRegistryConstants.ATT_MINIMIZED);
boolean minimized = minVal != null && VAL_TRUE.equals(minVal);
float ratio;
if (id == null) {
logMissingAttribute(element, IWorkbenchRegistryConstants.ATT_ID);
return false;
}
if (relationship == null) {
logMissingAttribute(element, IWorkbenchRegistryConstants.ATT_RELATIONSHIP);
return false;
}
if (!VAL_FAST.equals(relationship) && relative == null) {
logError(element,
"Attribute '" + IWorkbenchRegistryConstants.ATT_RELATIVE //$NON-NLS-1$
+ "' not defined. This attribute is required when " //$NON-NLS-1$
+ IWorkbenchRegistryConstants.ATT_RELATIONSHIP + "=\"" + relationship + "\"."); //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
// Get the ratio.
if (ratioString == null) {
// The ratio has not been specified.
ratio = IPageLayout.NULL_RATIO;
} else {
try {
ratio = new Float(ratioString).floatValue();
} catch (NumberFormatException e) {
return false;
}
// If the ratio is outside the allowable range, mark it as invalid.
if (ratio < IPageLayout.RATIO_MIN || ratio > IPageLayout.RATIO_MAX) {
ratio = IPageLayout.INVALID_RATIO;
}
}
// Get relationship details.
boolean stack = false;
int intRelation = 0;
boolean fast = false;
if (relationship.equals(VAL_LEFT)) {
intRelation = IPageLayout.LEFT;
} else if (relationship.equals(VAL_RIGHT)) {
intRelation = IPageLayout.RIGHT;
} else if (relationship.equals(VAL_TOP)) {
intRelation = IPageLayout.TOP;
} else if (relationship.equals(VAL_BOTTOM)) {
intRelation = IPageLayout.BOTTOM;
} else if (relationship.equals(VAL_STACK)) {
stack = true;
} else if (relationship.equals(VAL_FAST)) {
fast = true;
} else {
return false;
}
if (visible) {
// If adding a view (not just a placeholder), remove any existing placeholder.
// See bug 85948 [Perspectives] Adding register & expressions view by default to debug perspective fails
pageLayout.removePlaceholder(id);
}
// If stack ..
if (stack) {
if (visible) {
pageLayout.stackView(id, relative, true);
} else {
pageLayout.stackView(id, relative, false);
}
}
// If the view is a fast view...
else if (fast) {
if (ratio == IPageLayout.NULL_RATIO) {
// The ratio has not been specified.
pageLayout.addFastView(id);
} else {
pageLayout.addFastView(id, ratio);
}
} else {
// The view is a regular view.
// If the ratio is not specified or is invalid, use the default ratio.
if (ratio == IPageLayout.NULL_RATIO
|| ratio == IPageLayout.INVALID_RATIO) {
ratio = IPageLayout.DEFAULT_VIEW_RATIO;
}
if (visible) {
if (VAL_TRUE.equals(standalone)) {
pageLayout.addStandaloneView(id, !VAL_FALSE
.equals(showTitle), intRelation, ratio, relative);
} else {
pageLayout.addView(id, intRelation, ratio, relative, minimized);
}
} else {
// Fix for 99155, CGross (schtoo@schtoo.com)
// Adding standalone placeholder for standalone views
if (VAL_TRUE.equals(standalone)) {
pageLayout.addStandaloneViewPlaceholder(id, intRelation,
ratio, relative, !VAL_FALSE.equals(showTitle));
} else {
pageLayout.addPlaceholder(id, intRelation, ratio, relative);
}
}
}
IViewLayout viewLayout = pageLayout.getViewLayout(id);
// may be null if it's been filtered by activity
if (viewLayout != null) {
if (closeable != null) {
viewLayout.setCloseable(!VAL_FALSE.equals(closeable));
}
if (moveable != null) {
viewLayout.setMoveable(!VAL_FALSE.equals(moveable));
}
}
return true;
}
/**
* Process a view shortcut
*/
private boolean processViewShortcut(IConfigurationElement element) {
String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
if (id != null) {
pageLayout.addShowViewShortcut(id);
}
return true;
}
/**
* Process a wizard shortcut
*/
private boolean processWizardShortcut(IConfigurationElement element) {
String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
if (id != null) {
pageLayout.addNewWizardShortcut(id);
}
return true;
}
@Override
protected boolean readElement(IConfigurationElement element) {
String type = element.getName();
if (type.equals(IWorkbenchRegistryConstants.TAG_PERSPECTIVE_EXTENSION)) {
String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_TARGET_ID);
if (targetID.equals(id) || "*".equals(id)) { //$NON-NLS-1$
if (tracker != null) {
tracker.registerObject(element.getDeclaringExtension(), new DirtyPerspectiveMarker(id), IExtensionTracker.REF_STRONG);
}
return processExtension(element);
}
return true;
}
return false;
}
/**
* Sets the tags to include. All others are ignored.
*
* @param tags the tags to include
*/
public void setIncludeOnlyTags(String[] tags) {
includeOnlyTags = new HashSet();
for (String tag : tags) {
includeOnlyTags.add(tag);
}
}
}