diff options
author | Curtis D'Entremont | 2006-12-06 20:18:32 +0000 |
---|---|---|
committer | Curtis D'Entremont | 2006-12-06 20:18:32 +0000 |
commit | 7d6f3ea1266bab42c2e7cdb5e4e3f1eb86239689 (patch) | |
tree | 26736a1af364e341afd314688c10033344c12610 /org.eclipse.ui.intro.universal | |
parent | ef3e44249d5dc044c2ae2feb07f809e72afb68f5 (diff) | |
download | eclipse.platform.ua-7d6f3ea1266bab42c2e7cdb5e4e3f1eb86239689.tar.gz eclipse.platform.ua-7d6f3ea1266bab42c2e7cdb5e4e3f1eb86239689.tar.xz eclipse.platform.ua-7d6f3ea1266bab42c2e7cdb5e4e3f1eb86239689.zip |
165168 [Help] Better control of how help content is arranged and ordered
Diffstat (limited to 'org.eclipse.ui.intro.universal')
5 files changed, 244 insertions, 79 deletions
diff --git a/org.eclipse.ui.intro.universal/META-INF/MANIFEST.MF b/org.eclipse.ui.intro.universal/META-INF/MANIFEST.MF index c07e72fce..3e6bffbbf 100644 --- a/org.eclipse.ui.intro.universal/META-INF/MANIFEST.MF +++ b/org.eclipse.ui.intro.universal/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ Export-Package: org.eclipse.ui.internal.intro.universal;x-internal:=true, org.eclipse.ui.internal.intro.universal.util;x-internal:=true, org.eclipse.ui.intro.universal Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.1.0,4.0.0)", + org.eclipse.help;bundle-version="[3.3.0,4.0.0)", org.eclipse.ui;bundle-version="[3.2.0,4.0.0)", org.eclipse.ui.intro;bundle-version="[3.2.0,4.0.0)" Eclipse-LazyStart: true diff --git a/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/GroupData.java b/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/GroupData.java index a6a79306f..df1571694 100644 --- a/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/GroupData.java +++ b/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/GroupData.java @@ -12,6 +12,7 @@ package org.eclipse.ui.internal.intro.universal; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; import org.eclipse.ui.intro.config.IntroElement; import org.w3c.dom.Element; @@ -59,7 +60,7 @@ public class GroupData { return fDefault; } - public void addAnchors(ArrayList result) { + public void addAnchors(List result) { for (int i = 0; i < children.size(); i++) { BaseData edata = (BaseData) children.get(i); String id = edata.getId(); diff --git a/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/PageData.java b/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/PageData.java index eb58e65e7..5c2e6cb69 100644 --- a/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/PageData.java +++ b/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/PageData.java @@ -12,6 +12,7 @@ package org.eclipse.ui.internal.intro.universal; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; @@ -57,7 +58,7 @@ public class PageData { groups.add(gd); } - public void addAnchors(ArrayList result, String groupId) { + public void addAnchors(List result, String groupId) { GroupData group = findGroup(groupId); if (group==null) return; group.addAnchors(result); @@ -66,11 +67,8 @@ public class PageData { public String resolvePath(String extensionId) { if (isHidden(extensionId)) return null; - GroupData ddata = null; for (int i=0; i<groups.size(); i++) { GroupData gdata = (GroupData)groups.get(i); - if (gdata.isDefault()) - ddata=gdata; if (gdata.contains(extensionId)) { IPath resolvedPath = new Path(id); resolvedPath = resolvedPath.append(gdata.getPath()); @@ -78,12 +76,21 @@ public class PageData { return resolvedPath.toString(); } } - // resolve as default - IPath resolvedPath = new Path(id).append(ddata.getPath()); - resolvedPath = resolvedPath.append(IUniversalIntroConstants.DEFAULT_ANCHOR); - return resolvedPath.toString(); + return null; } - + + public String resolveDefaultPath() { + for (int i=0; i<groups.size(); i++) { + GroupData gdata = (GroupData)groups.get(i); + if (gdata.isDefault()) { + IPath resolvedPath = new Path(id).append(gdata.getPath()); + resolvedPath = resolvedPath.append(IUniversalIntroConstants.DEFAULT_ANCHOR); + return resolvedPath.toString(); + } + } + return null; + } + public boolean isHidden(String extensionId) { return hidden!=null && hidden.contains(extensionId); } diff --git a/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/UniversalIntroConfigurer.java b/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/UniversalIntroConfigurer.java index 55536e730..611e307c0 100644 --- a/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/UniversalIntroConfigurer.java +++ b/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/UniversalIntroConfigurer.java @@ -12,19 +12,24 @@ package org.eclipse.ui.internal.intro.universal; import java.io.IOException; import java.net.URL; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.StringTokenizer; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProduct; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Preferences; +import org.eclipse.help.internal.util.ProductPreferences; +import org.eclipse.help.internal.util.SequenceResolver; import org.eclipse.jface.action.Action; import org.eclipse.ui.internal.intro.universal.util.ImageUtil; +import org.eclipse.ui.internal.intro.universal.util.PreferenceArbiter; import org.eclipse.ui.intro.IIntroSite; import org.eclipse.ui.intro.config.IntroConfigurer; import org.eclipse.ui.intro.config.IntroElement; @@ -36,10 +41,12 @@ import org.osgi.framework.Bundle; * * @since 3.2 */ - public class UniversalIntroConfigurer extends IntroConfigurer implements IUniversalIntroConstants { - private ArrayList introData = new ArrayList(); + + private IntroData primaryIntroData; + private IntroData[] secondaryIntroData; + private SequenceResolver sequenceResolver; public UniversalIntroConfigurer() { loadData(); @@ -94,23 +101,51 @@ public class UniversalIntroConfigurer extends IntroConfigurer implements * @see org.eclipse.ui.intro.config.IntroConfigurer#getMixinStyle(java.lang.String) */ public String getMixinStyle(String pageId, String extensionId) { - if (introData.size() > 0) { - // TODO getting the active product one only - // Eventually we should consult the data from all the products - IntroData idata = (IntroData) introData.get(0); - PageData pdata = idata.getPage(pageId); - if (pdata != null) { - ExtensionData ed = pdata.findExtension(extensionId, false); - if (ed!=null) { - int importance = ed.getImportance(); - if (importance != ExtensionData.HIDDEN) - return ExtensionData.IMPORTANCE_STYLE_TABLE[importance]; - } + // if active product has a preference, use it + if (primaryIntroData != null) { + int importance = getImportance(primaryIntroData, pageId, extensionId); + if (importance >= 0) { + return ExtensionData.IMPORTANCE_STYLE_TABLE[importance]; + } + } + // else, find the most referenced importance style from other products + int[] importanceRefs = new int[ExtensionData.IMPORTANCE_TABLE.length]; + for (int i=0;i<secondaryIntroData.length;++i) { + IntroData data = secondaryIntroData[i]; + int importance = getImportance(data, pageId, extensionId); + if (importance >= 0) { + ++importanceRefs[importance]; + } + } + int maxIndex = 0; + for (int i=1;i<importanceRefs.length;++i) { + if (importanceRefs[i] > importanceRefs[maxIndex]) { + maxIndex = i; } } + if (importanceRefs[maxIndex] > 0) { + return ExtensionData.IMPORTANCE_STYLE_TABLE[maxIndex]; + } + // nobody has a preference return null; } + /* + * Returns the given extension's importance as specified by the + * given intro data. + */ + private int getImportance(IntroData data, String pageId, String extensionId) { + PageData pdata = data.getPage(pageId); + if (pdata != null) { + ExtensionData ed = pdata.findExtension(extensionId, false); + if (ed != null) { + return ed.getImportance(); + } + } + // none specified + return -1; + } + private String resolveVariable(Bundle bundle, String value) { if (value != null) { String path = null; @@ -421,53 +456,38 @@ public class UniversalIntroConfigurer extends IntroConfigurer implements } private void loadData() { - // add intro data for this product first - String dataFile = getVariable(VAR_INTRO_DATA); - String pid = Platform.getProduct().getId(); - if (dataFile != null) - introData.add(new IntroData(pid, dataFile, true)); - IConfigurationElement[] products = Platform.getExtensionRegistry() - .getConfigurationElementsFor( - "org.eclipse.core.runtime.products"); //$NON-NLS-1$ - for (int i = 0; i < products.length; i++) { - IConfigurationElement product = products[i]; - IExtension extension = product.getDeclaringExtension(); - String uid = extension.getUniqueIdentifier(); - // skip this product - if (pid.equals(uid)) - continue; - addIntroDataFor(uid, product); + // load the active product's intro data first + IProduct product = Platform.getProduct(); + if (product != null) { + String dataFile = getVariable(VAR_INTRO_DATA); + if (dataFile != null) { + primaryIntroData = new IntroData(product.getId(), dataFile, true); + } } - } - - private void addIntroDataFor(String pid, IConfigurationElement product) { - IConfigurationElement[] children = product.getChildren("property"); //$NON-NLS-1$ - for (int i = 0; i < children.length; i++) { - IConfigurationElement child = children[i]; - String name = child.getAttribute("name"); //$NON-NLS-1$ - if (name != null && name.equals(VAR_INTRO_DATA)) { - String value = child.getAttribute("value"); //$NON-NLS-1$ - String bid = child.getDeclaringExtension() - .getNamespaceIdentifier(); - Bundle bundle = Platform.getBundle(bid); + // load all other installed (but not running) products' intro data + List result = new ArrayList(); + Properties[] prefs = ProductPreferences.getProductPreferences(false); + for (int i=0;i<prefs.length;++i) { + String key = UniversalIntroPlugin.PLUGIN_ID + '/' + VAR_INTRO_DATA; + String dataFile = prefs[i].getProperty(key); + if (dataFile != null) { + String pluginId = ProductPreferences.getPluginId(prefs[i]); + Bundle bundle = Platform.getBundle(pluginId); if (bundle != null) { - String dataFile = resolveVariable(bundle, value); - introData.add(new IntroData(pid, dataFile, false)); + String pid = ProductPreferences.getProductId(prefs[i]); + dataFile = resolveVariable(bundle, dataFile); + result.add(new IntroData(pid, dataFile, false)); } } } + secondaryIntroData = (IntroData[])result.toArray(new IntroData[result.size()]); } private IntroElement[] getContent(String pageId, String groupId) { - ArrayList result = new ArrayList(); - if (introData.size() > 0) { - // TODO getting the active product one only - // Eventually we should consult the data from all the products - IntroData idata = (IntroData) introData.get(0); - PageData pdata = idata.getPage(pageId); - if (pdata != null) { - pdata.addAnchors(result, groupId); - } + List result = new ArrayList(); + List anchors = getAnchors(pageId, groupId); + if (anchors != null) { + result.addAll(anchors); } // Add the fallback anchor IntroElement fallback = new IntroElement("anchor"); //$NON-NLS-1$ @@ -476,6 +496,39 @@ public class UniversalIntroConfigurer extends IntroConfigurer implements return (IntroElement[]) result.toArray(new IntroElement[result.size()]); } + private List getAnchors(String pageId, String groupId) { + List primaryAnchors = null; + if (primaryIntroData != null) { + primaryAnchors = getAnchors(primaryIntroData, pageId, groupId); + } + if (primaryAnchors == null) { + primaryAnchors = Collections.EMPTY_LIST; + } + List secondaryAnchorsList = new ArrayList(); + for (int i=0;i<secondaryIntroData.length;++i) { + IntroData idata = secondaryIntroData[i]; + List anchors = getAnchors(idata, pageId, groupId); + if (anchors != null) { + secondaryAnchorsList.add(anchors); + } + } + List[] secondaryAnchors = (List[])secondaryAnchorsList.toArray(new List[secondaryAnchorsList.size()]); + if (sequenceResolver == null) { + sequenceResolver = new SequenceResolver(); + } + return sequenceResolver.getSequence(primaryAnchors, secondaryAnchors); + } + + private List getAnchors(IntroData data, String pageId, String groupId) { + PageData pdata = data.getPage(pageId); + if (pdata != null) { + List anchors = new ArrayList(); + pdata.addAnchors(anchors, groupId); + return anchors; + } + return null; + } + public String resolvePath(String extensionId, String path) { boolean extensionRelativePath = false; IPath ipath = new Path(path); @@ -488,32 +541,84 @@ public class UniversalIntroConfigurer extends IntroConfigurer implements if (!s2.equals("@")) { //$NON-NLS-1$ extensionRelativePath = true; } - if (introData.size() > 0) { - // TODO getting the active product one only - // Eventually we should consult the data from all the products - IntroData idata = (IntroData) introData.get(0); - PageData pdata = idata.getPage(pageId); - if (pdata != null) { - String resolvedPath = pdata.resolvePath(extensionId); + if (!isHidden(extensionId, pageId)) { + String resolvedPath = resolveExtensionPath(extensionId, pageId); + if (resolvedPath != null) { if (extensionRelativePath) { - // not done - use the resolved extension path - // to complete the source path + // not done - use the resolved extension path to complete the source path IPath p2 = new Path(resolvedPath); IPath p1 = ipath.removeFirstSegments(2); - // remove the last anchor and append the - // relative path from the extension - resolvedPath = p2.removeLastSegments(1).append(p1) - .toString(); + // remove the last anchor and append the relative path from the extension + resolvedPath = p2.removeLastSegments(1).append(p1).toString(); } return resolvedPath; } - } else { - // use fallback anchor return pageId + DEFAULT_CONTENT_PATH; } return null; } + private String resolveExtensionPath(String extensionId, String pageId) { + // does the active product have a preference? + if (primaryIntroData != null) { + PageData pdata = primaryIntroData.getPage(pageId); + if (pdata != null) { + String path = pdata.resolvePath(extensionId); + if (path != null) { + return path; + } + } + } + // if not, do the others have preferences? + PreferenceArbiter arbiter = new PreferenceArbiter(); + for (int i=0;i<secondaryIntroData.length;++i) { + IntroData idata = secondaryIntroData[i]; + PageData pdata = idata.getPage(pageId); + if (pdata != null) { + arbiter.consider(pdata.resolvePath(extensionId)); + } + } + String path = (String)arbiter.getWinner(); + if (path != null) { + return path; + } + // there was no clear winner; fall back to the default + return resolveDefaultPath(pageId); + } + + private String resolveDefaultPath(String pageId) { + // does the active product have a preference? + if (primaryIntroData != null) { + PageData pdata = primaryIntroData.getPage(pageId); + if (pdata != null) { + String path = pdata.resolveDefaultPath(); + if (path != null) { + return path; + } + } + } + // if not, do the others have preferences? + PreferenceArbiter arbiter = new PreferenceArbiter(); + for (int i=0;i<secondaryIntroData.length;++i) { + IntroData idata = secondaryIntroData[i]; + PageData pdata = idata.getPage(pageId); + if (pdata != null) { + arbiter.consider(pdata.resolveDefaultPath()); + } + } + return (String)arbiter.getWinner(); + } + + private boolean isHidden(String extensionId, String pageId) { + if (primaryIntroData != null) { + PageData pdata = primaryIntroData.getPage(pageId); + if (pdata != null) { + return pdata.isHidden(extensionId); + } + } + return false; + } + public void init(IIntroSite site, Map themeProperties) { super.init(site, themeProperties); IConfigurationElement element = CustomizeAction.getPageElement(); diff --git a/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/util/PreferenceArbiter.java b/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/util/PreferenceArbiter.java new file mode 100644 index 000000000..c70b083f3 --- /dev/null +++ b/org.eclipse.ui.intro.universal/src/org/eclipse/ui/internal/intro/universal/util/PreferenceArbiter.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2006 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.intro.universal.util; + +import java.util.HashMap; +import java.util.Map; + +/* + * Accepts a set of Objects that represents each product's preference over some + * matter (e.g. where an item should appear in welcome) and provides a final ruling + * on which Object to use. + */ +public class PreferenceArbiter { + + private Map references; + private Object leader; + + public void consider(Object obj) { + if (obj != null) { + if (references == null) { + references = new HashMap(); + } + int[] count = (int[])references.get(obj); + if (count == null) { + count = new int[] { 0 }; + references.put(obj, count); + } + ++count[0]; + if (obj != leader) { + if (leader == null) { + leader = obj; + } + else if (count[0] > ((int[])references.get(leader))[0]) { + leader = obj; + } + } + } + } + + public Object getWinner() { + return leader; + } +} |