diff options
author | Chris Goldthorpe | 2011-09-21 18:23:06 +0000 |
---|---|---|
committer | Chris Goldthorpe | 2011-09-21 18:23:06 +0000 |
commit | b6e6b5b2dc48bc43b8fdbebae97ab06eb810c038 (patch) | |
tree | 5469e3c746149fae7c82f4c3f70ae8fa5b85f5c7 | |
parent | 1da5474857f78280aa9dd5e70399af518be312f8 (diff) | |
download | eclipse.platform.ua-b6e6b5b2dc48bc43b8fdbebae97ab06eb810c038.tar.gz eclipse.platform.ua-b6e6b5b2dc48bc43b8fdbebae97ab06eb810c038.tar.xz eclipse.platform.ua-b6e6b5b2dc48bc43b8fdbebae97ab06eb810c038.zip |
Bug 353140 - [Help] Handle situation where documentation is not
installed
18 files changed, 752 insertions, 130 deletions
diff --git a/org.eclipse.help.base/src/org/eclipse/help/internal/base/MissingContentManager.java b/org.eclipse.help.base/src/org/eclipse/help/internal/base/MissingContentManager.java new file mode 100644 index 000000000..af5f66d7b --- /dev/null +++ b/org.eclipse.help.base/src/org/eclipse/help/internal/base/MissingContentManager.java @@ -0,0 +1,226 @@ +/*******************************************************************************
+ * Copyright (c) 2011 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.help.internal.base;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.help.internal.HelpPlugin;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * Handle sunresolved toc place holders as well as situations
+ * where remote help is unavailable
+ */
+
+public class MissingContentManager {
+
+ private static final String HELP_PROTOCOL = "help:"; //$NON-NLS-1$
+ private static final String EXTENSION_POINT_ID_TOC = HelpPlugin.PLUGIN_ID + ".toc"; //$NON-NLS-1$
+ private static final String ELEMENT_NAME_PLACEHOLDER = "placeholder"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_NAME_PLUGIN = "plugin"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_NAME_PLACEHOLDER_PAGE = "placeholderPage"; //$NON-NLS-1$
+ public static final String IGNORE_MISSING_PLACEHOLDER_PREFERENCE = "ignorePlaceholders"; //$NON-NLS-1$
+
+ // Hrefs which are processed by org.eclipse.help.internal.webapp.StatusProducer
+ public static final String REMOTE_STATUS_HREF = "NetworkHelpStatus.html"; //$NON-NLS-1$
+ public static final String REMOTE_STATUS_HELP_VIEW_HREF = "NetworkHelpStatusHV.html"; //$NON-NLS-1$
+ public static final String MISSING_TOPIC_HREF = "MissingTopicStatus.html"; //$NON-NLS-1$
+ public static final String MISSING_TOPIC_PATH = "missingTopic/"; //$NON-NLS-1$
+ public static final String MISSING_BOOKS_HREF = "MissingBooks.html"; //$NON-NLS-1$
+ public static final String MISSING_BOOKS_HELP_VIEW_HREF = "MissingBooksHV.html"; //$NON-NLS-1$
+
+ /*
+ * A place holder defines a page to be shown when a documentation page
+ * which matches the specified path not installed
+ */
+ public static class Placeholder implements Comparable {
+ public String path;
+ public String bundle;
+ public String placeholderPage;
+
+ public Placeholder(String path, String bundle, String placeholderPage) {
+ this.path = path;
+ this.bundle = bundle;
+ this.placeholderPage = placeholderPage;
+ }
+
+ public int compareTo(Object arg0) {
+ // Sort in reverse order so more qualified strings appear before
+ // less qualified substrings
+ if (arg0 instanceof Placeholder) {
+ return((Placeholder)arg0).path.compareTo(path);
+ }
+ return 0;
+ }
+ }
+
+ private static MissingContentManager instance;
+ private List placeholders;
+ private Set bundlesToIgnore; // A set of bundles the user does not want to see reference to
+
+ public static MissingContentManager getInstance() {
+ if ( instance == null ) {
+ instance = new MissingContentManager();
+ }
+ return instance;
+ }
+
+ /*
+ * Read the extension registry
+ */
+ private MissingContentManager() {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ placeholders = new ArrayList();
+ bundlesToIgnore = new HashSet();
+ if ( BaseHelpSystem.getMode() == BaseHelpSystem.MODE_INFOCENTER ) {
+ return; // Placeholders are not shown for infocenters
+ }
+ // Read the placeholders from the extension registry
+ IConfigurationElement[] elements = registry
+ .getConfigurationElementsFor(EXTENSION_POINT_ID_TOC);
+ for (int i = 0; i < elements.length; ++i) {
+ IConfigurationElement elem = elements[i];
+ String pluginId = elem.getContributor().getName();
+ if (elem.getName().equals(ELEMENT_NAME_PLACEHOLDER)) {
+ try {
+ String plugin = elem.getAttribute(ATTRIBUTE_NAME_PLUGIN);
+ String path = HELP_PROTOCOL + plugin + '/';
+ String placeholder = elem
+ .getAttribute(ATTRIBUTE_NAME_PLACEHOLDER_PAGE);
+ placeholders.add(new Placeholder(path, plugin, placeholder));
+ } catch (Exception e) {
+ // log and skip
+ String msg = "Exception reading " + ELEMENT_NAME_PLACEHOLDER + " extension in bundle" + pluginId; //$NON-NLS-1$ //$NON-NLS-2$
+ HelpPlugin.logError(msg, e);
+ }
+ }
+ }
+ Collections.sort(placeholders);
+ // Read the preferences to find any ignored placeholders
+ String ignoredBundles = Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, IGNORE_MISSING_PLACEHOLDER_PREFERENCE, "", null); //$NON-NLS-1$
+ if (ignoredBundles.length() > 0) {
+ StringTokenizer tokenizer = new StringTokenizer(ignoredBundles, " ,"); //$NON-NLS-1$
+ while (tokenizer.hasMoreTokens()) {
+ bundlesToIgnore.add(tokenizer.nextToken());
+ }
+ }
+ }
+
+ /**
+ * Called when a page cannot be found
+ * @param path the path of the page that could not be loaded
+ * @return a place holder page if defined, otherwise an error page
+ */
+ public String getPageNotFoundPage(String path, boolean showPlaceholderPage) {
+ for (Iterator iter = placeholders.iterator(); iter.hasNext(); ) {
+ Placeholder placeholder = (Placeholder) iter.next();
+ if (path.startsWith(placeholder.path) && Platform.getBundle(placeholder.bundle) == null) {
+ if ( showPlaceholderPage) {
+ return placeholder.placeholderPage;
+ } else {
+ return "/org.eclipse.help.webapp/" + MISSING_TOPIC_PATH + path.substring(HELP_PROTOCOL.length()); //$NON-NLS-1$
+ }
+ }
+ }
+ return Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, "page_not_found", null, null); //$NON-NLS-1$
+ }
+
+ /**
+ *
+ * @return true if there is an unresolved place holder and this is not an infocenter
+ */
+ public boolean isUnresolvedPlaceholders() {
+ if (BaseHelpSystem.getMode()==BaseHelpSystem.MODE_INFOCENTER) {
+ return false;
+ }
+ Placeholder[] unresolvedPlaceHolders = getUnresolvedPlaceholders();
+ return unresolvedPlaceHolders.length > 0;
+ }
+
+ /**
+ * If any help is missing returns an appropriate page
+ * @return null if no help is unavailable or an appropriate page if
+ * the plug-in that corresponds to a place holder is not available.
+ * The returned page will be in the format /plug-in/path.
+ */
+ public String getHelpMissingPage(boolean isHelpView) {
+ Placeholder[] unresolvedPlaceHolders = getUnresolvedPlaceholders();
+ if (unresolvedPlaceHolders.length == 0) {
+ return null;
+ } else {
+ String suffix = isHelpView ? MISSING_BOOKS_HELP_VIEW_HREF : MISSING_BOOKS_HREF;
+ return "/org.eclipse.help.webapp" + '/'+ suffix; //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Get the page to be shown when some remote help is known to be unavailable
+ */
+ public String getRemoteHelpUnavailablePage(boolean isHelpView) {
+ if ( BaseHelpSystem.getMode()!=BaseHelpSystem.MODE_INFOCENTER ) {
+ String suffix = isHelpView ? REMOTE_STATUS_HELP_VIEW_HREF : REMOTE_STATUS_HREF;
+ return "/org.eclipse.help.webapp/" + suffix; //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ public Placeholder[] getUnresolvedPlaceholders() {
+ List unresolved;
+ unresolved = new ArrayList();
+ for (Iterator iter = placeholders.iterator(); iter.hasNext(); ) {
+ Placeholder ph = (Placeholder) iter.next();
+ String bundle = ph.bundle;
+ if (bundle != null && !bundlesToIgnore.contains(bundle) ) {
+ if (Platform.getBundle(bundle) == null ) {
+ unresolved.add(ph);
+ }
+ }
+ }
+ return (Placeholder[]) unresolved.toArray(new Placeholder[unresolved.size()]);
+ }
+
+ // Modifies the preferences to ignore any bundles that are currently unresolved placeholders
+ public void ignoreAllMissingPlaceholders() {
+ Placeholder[] unresolved = getUnresolvedPlaceholders();
+ String ignoredBundles = Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, IGNORE_MISSING_PLACEHOLDER_PREFERENCE, "", null); //$NON-NLS-1$
+ for ( int i = 0; i < unresolved.length; i++) {
+ String bundle = unresolved[i].bundle;
+ bundlesToIgnore.add(bundle);
+ if (ignoredBundles.length() > 0) {
+ ignoredBundles = ignoredBundles + ',';
+ }
+ ignoredBundles = ignoredBundles + bundle;
+
+ }
+ IScopeContext instanceScope = InstanceScope.INSTANCE;
+ IEclipsePreferences prefs = instanceScope.getNode(HelpBasePlugin.PLUGIN_ID);
+ prefs.put(IGNORE_MISSING_PLACEHOLDER_PREFERENCE, ignoredBundles);
+ try {
+ prefs.flush();
+ } catch (BackingStoreException e) {
+ HelpBasePlugin.logError("Cannot save preferences", e); //$NON-NLS-1$
+ }
+ }
+
+}
diff --git a/org.eclipse.help.ui/plugin.properties b/org.eclipse.help.ui/plugin.properties index 5bbddba35..11b958ea1 100644 --- a/org.eclipse.help.ui/plugin.properties +++ b/org.eclipse.help.ui/plugin.properties @@ -47,6 +47,9 @@ command.closeTray.description = Close the user assistance tray containing contex command.index.description = Show Keyword Index command.index.name = Index + +command.ignoreMissingPlaceholders.description = Sets the help preferences to no longer report a warning about the current set of missing documents. +command.ignoreMissingPlaceholders.name = Do not warn of missing documentation command.openBundleResource.name=Open Resource in Browser command.openBundleResource.description=Opens a bundle resource in the default web browser. diff --git a/org.eclipse.help.ui/plugin.xml b/org.eclipse.help.ui/plugin.xml index be3accd6d..65321d1a7 100644 --- a/org.eclipse.help.ui/plugin.xml +++ b/org.eclipse.help.ui/plugin.xml @@ -149,6 +149,13 @@ id="org.eclipse.help.ui.indexcommand" name="%command.index.name"> </command> + <command + categoryId="org.eclipse.ui.category.help" + defaultHandler="org.eclipse.help.ui.internal.views.IgnoreMissingPlaceholderHandler" + description="%command.ignoreMissingPlaceholders.description" + id="org.eclipse.help.ui.ignoreMissingPlaceholders" + name="%command.ignoreMissingPlaceholders.name"> + </command> </extension> <extension point="org.eclipse.ui.commandImages"> diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/IHelpUIConstants.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/IHelpUIConstants.java index a6f1a5c29..dbeae8518 100644 --- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/IHelpUIConstants.java +++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/IHelpUIConstants.java @@ -73,7 +73,8 @@ public interface IHelpUIConstants { public static final String HV_BROWSER_PAGE = "browser-page"; //$NON-NLS-1$ public static final String HV_RELATED_TOPICS = "related-topics"; //$NON-NLS-1$ public static final String HV_CONTEXT_HELP_PAGE = "context-help-page"; //$NON-NLS-1$ - + public static final String HV_MISSING_CONTENT = "missing-content"; //$NON-NLS-1$ + public static final String HV_INDEX = "index"; //$NON-NLS-1$ public static final String HV_INDEX_TYPEIN = "index-typein"; //$NON-NLS-1$ public static final String HV_INDEX_PAGE = "index-page"; //$NON-NLS-1$ diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/Messages.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/Messages.java index 96ec41590..d366db497 100644 --- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/Messages.java +++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/Messages.java @@ -43,6 +43,7 @@ public final class Messages extends NLS { public static String ReusableHelpPart_bookmarkAction_label; public static String ReusableHelpPart_status; public static String ReusableHelpPart_indexPage_name; + public static String ReusableHelpPart_missingContent; public static String HelpView_defaultText; public static String expression; public static String expression_label; diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/Messages.properties b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/Messages.properties index 027531ba3..2090e1eda 100644 --- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/Messages.properties +++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/Messages.properties @@ -46,6 +46,7 @@ ReusableHelpPart_bookmarkAction_label=&Add Bookmark ReusableHelpPart_internalBrowserTitle=Help ReusableHelpPart_status = {0} - {1} ReusableHelpPart_indexPage_name=Index +ReusableHelpPart_missingContent=Additional help content available HelpView_defaultText=Click on any workbench part to show related help topics. diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/BrowserPart.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/BrowserPart.java index 4be56d97c..f1690bd10 100644 --- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/BrowserPart.java +++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/BrowserPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -17,6 +17,7 @@ import java.util.StringTokenizer; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.help.internal.base.BaseHelpSystem; import org.eclipse.help.internal.base.HelpBasePlugin; @@ -246,7 +247,7 @@ public class BrowserPart extends AbstractFormPart implements IHelpPart { highlightAction = new Action() { public void run() { - InstanceScope instanceScope = new InstanceScope(); + IScopeContext instanceScope = InstanceScope.INSTANCE; IEclipsePreferences prefs = instanceScope.getNode(HelpBasePlugin.PLUGIN_ID); prefs.putBoolean(HIGHLIGHT_ON, highlightAction.isChecked()); if (browser.getUrl().indexOf("resultof")!=-1) browser.execute("setHighlight(" +highlightAction.isChecked()+");"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -409,13 +410,14 @@ public class BrowserPart extends AbstractFormPart implements IHelpPart { private boolean redirectLink(final String url) { if (url.indexOf("/topic/") != -1) { //$NON-NLS-1$ if (url.indexOf("noframes") == -1) { //$NON-NLS-1$ - // char sep = url.lastIndexOf('?') != -1 ? '&' : '?'; - // String newURL = url + sep + "noframes=true"; //$NON-NLS-1$ return true; } } else if (url.indexOf("livehelp/?pluginID=")>0) { //$NON-NLS-1$ processLiveAction(url); return true; + } else if (url.indexOf("helpview:") == 0) { //$NON-NLS-1$ + HelpviewProtocol.handleProtocolCall(url, parent); + return true; } return false; } @@ -482,7 +484,7 @@ public class BrowserPart extends AbstractFormPart implements IHelpPart { private void doMagnify(int percent) { fontScalePercentage += percent; - InstanceScope instanceScope = new InstanceScope(); + IScopeContext instanceScope = InstanceScope.INSTANCE; IEclipsePreferences prefs = instanceScope.getNode(HelpBasePlugin.PLUGIN_ID); prefs.putInt(HELP_VIEW_SCALE, fontScalePercentage); try { diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/HelpviewProtocol.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/HelpviewProtocol.java new file mode 100644 index 000000000..6869af147 --- /dev/null +++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/HelpviewProtocol.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2011 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.help.ui.internal.views; + +import org.eclipse.help.internal.base.MissingContentManager; + +/** + * The helpview: protocol is used as a way to create hyperlinks which perform specific functions within the help view. + */ + +public class HelpviewProtocol { + public static final String HELPVIEW_PROTOCOL = "helpview:"; //$NON-NLS-1$ + public static final String CHECK_REMOTE_STATUS = "checkremote"; //$NON-NLS-1$ + public static final String IGNORE_MISSING_BOOKS = "ignoreMissingBooks"; //$NON-NLS-1$ + + public static void handleProtocolCall(String url, ReusableHelpPart part) { + int index = url.indexOf(HELPVIEW_PROTOCOL); + if (index == -1) { + return; + } + String command = url.substring(index + HELPVIEW_PROTOCOL.length()); + if ( command.equals(CHECK_REMOTE_STATUS) ) { + part.checkRemoteStatus(); + } + if ( command.equals(IGNORE_MISSING_BOOKS)) { + MissingContentManager.getInstance().ignoreAllMissingPlaceholders(); + part.checkPlaceholderStatus(); + } + } +} diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/IgnoreMissingPlaceholderHandler.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/IgnoreMissingPlaceholderHandler.java new file mode 100644 index 000000000..e243632c9 --- /dev/null +++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/IgnoreMissingPlaceholderHandler.java @@ -0,0 +1,27 @@ +/*******************************************************************************
+ * Copyright (c) 2011 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.help.ui.internal.views;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.help.internal.base.MissingContentManager;
+
+
+public class IgnoreMissingPlaceholderHandler extends AbstractHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ MissingContentManager.getInstance().ignoreAllMissingPlaceholders();
+ return null;
+ }
+
+}
diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/MissingContentPart.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/MissingContentPart.java new file mode 100644 index 000000000..de0cc5a16 --- /dev/null +++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/MissingContentPart.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2011 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.help.ui.internal.views; + +import org.eclipse.help.internal.base.MissingContentManager; +import org.eclipse.help.internal.base.remote.RemoteStatusData; +import org.eclipse.help.ui.internal.Messages; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ImageHyperlink; + +public class MissingContentPart extends AbstractFormPart implements IHelpPart { + + private Composite container; + private String id; + private ReusableHelpPart helpPart; + private ImageHyperlink statusLink; + private boolean wasRemoteHelpUnavailable = false; + private boolean wasUnresolvedPlaceholders = false; + + public MissingContentPart(Composite parent, FormToolkit toolkit) { + container = toolkit.createComposite(parent, SWT.NULL); + container.setBackgroundMode(SWT.INHERIT_DEFAULT); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.marginTop = 2; + container.setLayout(layout); + updateStatus(); + } + + public void updateStatus() { + // Only update the controls if the status has changed + boolean isRemoteHelpUnavailable = RemoteStatusData.isAnyRemoteHelpUnavailable(); + if ( isRemoteHelpUnavailable && wasRemoteHelpUnavailable) { + return; // Nothing to do, remote help unavailable message already showing + } + boolean isUnresolvedPlaceholders = MissingContentManager.getInstance().isUnresolvedPlaceholders(); + if ( isRemoteHelpUnavailable == wasRemoteHelpUnavailable && isUnresolvedPlaceholders == wasUnresolvedPlaceholders ) { + return; + } + disposeLink(); + wasRemoteHelpUnavailable = isRemoteHelpUnavailable; + wasUnresolvedPlaceholders = isUnresolvedPlaceholders; + FormToolkit toolkit = new FormToolkit(container.getDisplay()); + if ( isRemoteHelpUnavailable ) { + createHelpMissingLink(container, toolkit, Dialog.DLG_IMG_MESSAGE_WARNING, Messages.remoteHelpUnavailable, + MissingContentManager.getInstance().getRemoteHelpUnavailablePage(true), true); + } else if ( isUnresolvedPlaceholders) { + createHelpMissingLink(container, toolkit, Dialog.DLG_IMG_MESSAGE_INFO, Messages.ReusableHelpPart_missingContent, + MissingContentManager.getInstance().getHelpMissingPage(true), false); + } + toolkit.dispose(); + } + + private void createHelpMissingLink(Composite container, FormToolkit toolkit, String imageKey, String linkText, String linkTarget, boolean isRemoteUnavailableLink) { + final String target = linkTarget; + final boolean isRemote = isRemoteUnavailableLink; + Composite padding = new Composite(container, SWT.NULL); + GridData paddingData = new GridData(); + paddingData.heightHint = 2; + padding.setLayoutData(paddingData); + toolkit.adapt(padding); + Image warningImage = JFaceResources.getImage(imageKey); + statusLink = toolkit.createImageHyperlink(container, SWT.NULL); + statusLink.setText(linkText); + statusLink.setImage(warningImage); + statusLink.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + helpPart.showURL(target); + if ( isRemote ) { + helpPart.checkRemoteStatus(); + } else { + helpPart.checkPlaceholderStatus(); + } + } + }); + GridData statusData = new GridData(GridData.BEGINNING, GridData.CENTER, false, false); + statusLink.setLayoutData(statusData); + } + + private void disposeLink() { + if (statusLink != null) { + statusLink.dispose(); + } + statusLink = null; + } + + public void setSubsequentPage(String subsequentPage) { + + } + + public void init(ReusableHelpPart parent, String id, IMemento memento) { + this.id = id; + this.helpPart = parent; + } + + public void saveState(IMemento memento) { + } + + public Control getControl() { + return container; + } + + public String getId() { + return id; + } + + public void setVisible(boolean visible) { + if (container != null) { + container.setVisible(visible); + } + } + + public boolean hasFocusControl(Control control) { + return false; + } + + public boolean fillContextMenu(IMenuManager manager) { + return false; + } + + public IAction getGlobalAction(String id) { + return null; + } + + public void stop() { + + } + + public void toggleRoleFilter() { + + } + + public void refilter() { + + } + + public void dispose() { + disposeLink(); + } + +} diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/ReusableHelpPart.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/ReusableHelpPart.java index 4d6b1e20e..1951c74c5 100644 --- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/ReusableHelpPart.java +++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/ReusableHelpPart.java @@ -33,6 +33,7 @@ import org.eclipse.help.internal.base.BaseHelpSystem; import org.eclipse.help.internal.base.HelpBasePlugin; import org.eclipse.help.internal.base.HelpEvaluationContext; import org.eclipse.help.internal.base.IHelpBaseConstants; +import org.eclipse.help.internal.base.MissingContentManager; import org.eclipse.help.internal.base.util.LinkUtil; import org.eclipse.help.internal.protocols.HelpURLConnection; import org.eclipse.help.internal.search.federated.IndexerJob; @@ -547,10 +548,11 @@ public class ReusableHelpPart implements IHelpUIConstants, } public void setFocus() { - // Focus on the first part that is not the see also links + // Focus on the first part that is not the see also links or missing content link for (int focusPart = 0; focusPart < partRecs.size(); focusPart++) { PartRec rec = (PartRec) partRecs.get(focusPart); - if ( rec.part.getId() != IHelpUIConstants.HV_SEE_ALSO ) { + String partId = rec.part.getId(); + if ( partId != IHelpUIConstants.HV_SEE_ALSO && partId != IHelpUIConstants.HV_MISSING_CONTENT) { rec.part.setFocus(); return; } @@ -747,6 +749,7 @@ public class ReusableHelpPart implements IHelpUIConstants, IHelpUIConstants.IMAGE_HELP_SEARCH); page.setVerticalSpacing(0); page.addPart(HV_SEE_ALSO, false); + page.addPart(HV_MISSING_CONTENT, false); page.addPart(HV_FSEARCH, false); page.addPart(HV_FSEARCH_RESULT, true); pages.add(page); @@ -758,6 +761,7 @@ public class ReusableHelpPart implements IHelpUIConstants, page.setVerticalSpacing(0); page.setHorizontalMargin(0); page.addPart(HV_SEE_ALSO, false); + page.addPart(HV_MISSING_CONTENT, false); page.addPart(HV_SCOPE_SELECT, false); page.addPart(HV_TOPIC_TREE, true); pages.add(page); @@ -788,6 +792,7 @@ public class ReusableHelpPart implements IHelpUIConstants, page.setVerticalSpacing(0); page.setHorizontalMargin(0); page.addPart(HV_SEE_ALSO, false); + page.addPart(HV_MISSING_CONTENT, false); page.addPart(HV_RELATED_TOPICS, true); pages.add(page); @@ -797,6 +802,7 @@ public class ReusableHelpPart implements IHelpUIConstants, IHelpUIConstants.IMAGE_INDEX); page.setVerticalSpacing(0); page.addPart(HV_SEE_ALSO, false); + page.addPart(HV_MISSING_CONTENT, false); page.addPart(HV_SCOPE_SELECT, false); page.addPart(HV_INDEX_TYPEIN, false); page.addPart(HV_INDEX, true); @@ -1190,6 +1196,8 @@ public class ReusableHelpPart implements IHelpUIConstants, part = new IndexPart(parent, mform.getToolkit(), tbm); } else if (id.equals(HV_INDEX_TYPEIN)) { part = new IndexTypeinPart(parent, mform.getToolkit(), tbm); + } else if (id.equals(HV_MISSING_CONTENT)) { + part = new MissingContentPart(parent, mform.getToolkit()); } if (part != null) { mform.addPart(part); @@ -1723,5 +1731,36 @@ public class ReusableHelpPart implements IHelpUIConstants, } return style; } + + public void checkRemoteStatus() { + clearBrowser(); + showURL("/org.eclipse.help.webapp/" + MissingContentManager.REMOTE_STATUS_HELP_VIEW_HREF); //$NON-NLS-1$ + updateStatusLinks(); + } + + public void checkPlaceholderStatus() { + clearBrowser(); + showURL("/org.eclipse.help.webapp/" + MissingContentManager.MISSING_BOOKS_HELP_VIEW_HREF); //$NON-NLS-1$ + updateStatusLinks(); + + } + + private void clearBrowser() { + IHelpPart part = findPart(HV_BROWSER); + if ( part == null ) { + return; + } + BrowserPart browserPart = (BrowserPart) part; + browserPart.clearBrowser(); + } + + private void updateStatusLinks() { + IHelpPart part = findPart(HV_MISSING_CONTENT); + if ( part == null ) { + return; + } + MissingContentPart mcPart = (MissingContentPart) part; + mcPart.updateStatus(); + } } diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/SearchPart.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/SearchPart.java index 08ad71ac8..acd240910 100644 --- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/SearchPart.java +++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/SearchPart.java @@ -23,7 +23,6 @@ import org.eclipse.core.runtime.jobs.IJobChangeListener; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.help.HelpSystem; import org.eclipse.help.internal.base.BaseHelpSystem; -import org.eclipse.help.internal.base.remote.RemoteStatusData; import org.eclipse.help.internal.search.federated.FederatedSearchEntry; import org.eclipse.help.internal.search.federated.FederatedSearchJob; import org.eclipse.help.internal.search.federated.LocalHelp; @@ -35,10 +34,8 @@ import org.eclipse.help.ui.internal.IHelpUIConstants; import org.eclipse.help.ui.internal.Messages; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.preference.PreferenceManager; -import org.eclipse.jface.resource.JFaceResources; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; @@ -47,7 +44,6 @@ import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; @@ -65,7 +61,6 @@ import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Hyperlink; -import org.eclipse.ui.forms.widgets.ImageHyperlink; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.forms.widgets.TableWrapData; import org.eclipse.ui.forms.widgets.TableWrapLayout; @@ -93,10 +88,6 @@ public class SearchPart extends AbstractFormPart implements IHelpPart, IHelpUICo private static final String HREF_SEARCH_HELP = "/org.eclipse.platform.doc.user/tasks/help_search.htm"; //$NON-NLS-1$ private static boolean SEARCH_HELP_AVAILABLE = false; - - - private ImageHyperlink remoteStatusLink; - private boolean wasHelpUnavailable = false; static { InputStream is = HelpSystem.getHelpContent(HREF_SEARCH_HELP); @@ -268,27 +259,12 @@ public class SearchPart extends AbstractFormPart implements IHelpPart, IHelpUICo createScopeSection(toolkit); - createRemoteStatusLink(toolkit); - // createAlternateQueriesSection(toolkit); toolkit.paintBordersFor(container); jobListener = new JobListener(); Job.getJobManager().addJobChangeListener(jobListener); } - - public boolean isStale() - { - boolean currentAvailability = RemoteStatusData.isAnyRemoteHelpUnavailable(); - - if (wasHelpUnavailable!=currentAvailability) - { - wasHelpUnavailable=currentAvailability; - return true; - } - - return false; - } private void createScopeSection(FormToolkit toolkit) { TableWrapData td; @@ -337,37 +313,6 @@ public class SearchPart extends AbstractFormPart implements IHelpPart, IHelpUICo toolkit.paintBordersFor(detailGroup); } - private void createRemoteStatusLink(FormToolkit toolkit){ - TableWrapData td; - - Image warningImage = JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING); - - remoteStatusLink = toolkit.createImageHyperlink(container, SWT.NULL); - remoteStatusLink.setText(Messages.remoteHelpUnavailable); - remoteStatusLink.setImage(warningImage); - remoteStatusLink.addHyperlinkListener(new HyperlinkAdapter() { - - public void linkActivated(HyperlinkEvent e) { - doRemoteStatus(); - } - }); - - td = new TableWrapData(); - td.colspan = 2; - td.align = TableWrapData.FILL; - remoteStatusLink.setLayoutData(td); - - if (wasHelpUnavailable = RemoteStatusData.isAnyRemoteHelpUnavailable()) - { - remoteStatusLink.setVisible(true); - } - else - { - remoteStatusLink.dispose(); - } - - } - private void createAlternateQueriesSection(FormToolkit toolkit){ TableWrapData td = new TableWrapData(); @@ -706,10 +651,6 @@ public class SearchPart extends AbstractFormPart implements IHelpPart, IHelpUICo updateMasters(set); } - private void doRemoteStatus() { - SearchPart.this.parent.showURL("org.eclipse.help.webapp/SearchNetworkHelpStatus.html",true); //$NON-NLS-1$ - } - private void doChangeScopeSet() { ScopeSetDialog dialog = new ScopeSetDialog(container.getShell(), scopeSetManager, parent .getEngineManager(), false); @@ -790,10 +731,6 @@ public class SearchPart extends AbstractFormPart implements IHelpPart, IHelpUICo doSearch(searchWordCombo.getText()); } - if(RemoteStatusData.isAnyRemoteHelpUnavailable()) - createRemoteStatusLink(toolkit); - else - remoteStatusLink.dispose(); } public String getId() { diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/StatusProducer.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/StatusProducer.java index ff946897d..f75ce6bb1 100644 --- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/StatusProducer.java +++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/StatusProducer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 IBM Corporation and others. + * Copyright (c) 2009, 2011 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 @@ -23,6 +23,7 @@ import java.util.Locale; import org.eclipse.core.runtime.Platform; import org.eclipse.help.IHelpContentProducer; import org.eclipse.help.internal.base.HelpBasePlugin; +import org.eclipse.help.internal.base.MissingContentManager; import org.eclipse.help.internal.base.remote.RemoteStatusData; import org.eclipse.help.internal.protocols.HelpURLStreamHandler; import org.eclipse.help.internal.util.ProductPreferences; @@ -31,12 +32,6 @@ import org.eclipse.help.internal.webapp.data.WebappPreferences; public class StatusProducer implements IHelpContentProducer { - // Remote Status 'page' href - public static final String REMOTE_STATUS_HREF = "NetworkHelpStatus.html"; //$NON-NLS-1$ - // Remote Status from bad topic 'page' href - public static final String MISSING_TOPIC_HREF = "MissingTopicStatus.html"; //$NON-NLS-1$ - // Remote Status from bad topic 'page' href - public static final String SEARCH_REMOTE_STATUS_HREF = "SearchNetworkHelpStatus.html"; //$NON-NLS-1$ // Default TAB size private static final String TAB = " "; //$NON-NLS-1$ // index.jsp @@ -58,9 +53,25 @@ public class StatusProducer implements IHelpContentProducer { // Only accept requests for our pages. Otherwise // return null so Eclipse tries to find the right help - if (!href.equalsIgnoreCase(REMOTE_STATUS_HREF) && - !href.equalsIgnoreCase(MISSING_TOPIC_HREF) && - !href.equalsIgnoreCase(SEARCH_REMOTE_STATUS_HREF)) + + + // If this is called because of unresolved placeholders create a list of + // the placeholders + if (href.equalsIgnoreCase(MissingContentManager.MISSING_BOOKS_HREF)) { + return getMissingBooksPage(locale, false); + } + if (href.equalsIgnoreCase(MissingContentManager.MISSING_BOOKS_HELP_VIEW_HREF)) { + return getMissingBooksPage(locale, true); + } + + if (href.startsWith(MissingContentManager.MISSING_TOPIC_PATH)) { + String topicPath = href.substring(MissingContentManager.MISSING_TOPIC_PATH.length()); + return getMissingTopicPage(topicPath, locale); + } + + if (!href.equalsIgnoreCase(MissingContentManager.REMOTE_STATUS_HREF) && + !href.equalsIgnoreCase(MissingContentManager.MISSING_TOPIC_HREF) && + !href.equalsIgnoreCase(MissingContentManager.REMOTE_STATUS_HELP_VIEW_HREF)) return null; StringBuffer pageBuffer = new StringBuffer(); @@ -72,16 +83,22 @@ public class StatusProducer implements IHelpContentProducer { RemoteStatusData.clearCache(); // Check to see if there are any enabled remote sites. - // If not, return null - default topic not found will display if (remoteSites.isEmpty()) { - return null; + if ( href.equalsIgnoreCase(MissingContentManager.MISSING_TOPIC_HREF) ) { + // Return null - default topic not found will display + return null; + } else { + // The help unavailable page has been refreshed after fixing a network connection, report + // that everything is OK + return getNetworkOKPage(locale); + } } - + // If this is a call from an invalid topic, // check to see if a predefined error page exists // in the preferences - if (href.equalsIgnoreCase(MISSING_TOPIC_HREF)){ + if (href.equalsIgnoreCase(MissingContentManager.MISSING_TOPIC_HREF)){ String errorPage = Platform.getPreferencesService().getString( HelpBasePlugin.PLUGIN_ID, "page_not_found", //$NON-NLS-1$ @@ -106,11 +123,11 @@ public class StatusProducer implements IHelpContentProducer { // Write HTML header and body beginning. - pageBuffer.append(getHtmlHead(locale)); - pageBuffer.append(getBeginHtmlBody()); - + String title = WebappResources.getString("remoteStatusTitle", locale); //$NON-NLS-1$ + pageBuffer.append(getHtmlHead(locale, title)); + pageBuffer.append(getBeginHtmlBody(true)); - + // Check to see if all remote sites failed, // or just a subset boolean allFailed; @@ -127,19 +144,12 @@ public class StatusProducer implements IHelpContentProducer { // Add a close link to top - if (href.equalsIgnoreCase(REMOTE_STATUS_HREF)) + if (href.equalsIgnoreCase(MissingContentManager.REMOTE_STATUS_HREF)) { - WebappPreferences prefs = new WebappPreferences(); - String homepage = "/help/topic"+prefs.getHelpHome(); //$NON-NLS-1$ - - pageBuffer.append(tab(3)+"<div style=\"position:absolute;right:4px;top:4px;\">\n"); //$NON-NLS-1$ - pageBuffer.append(tab(4)+"<table>\n"+tab(5)+"<tr>\n"); //$NON-NLS-1$ //$NON-NLS-2$ - pageBuffer.append(tab(6)+"<td style=\"background-color:white;border-width:1px;border-style:solid;border-color:grey;\">"+makeAnchor(homepage,WebappResources.getString("Close", locale),"style=\"font-size:.8em;\"",false)+"</td>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - pageBuffer.append(tab(5)+"</tr>\n"+tab(4)+"</table>\n"+tab(3)+"</div>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - + addCloseLink(locale, pageBuffer); + } - if (href.equalsIgnoreCase(MISSING_TOPIC_HREF)) + if (href.equalsIgnoreCase(MissingContentManager.MISSING_TOPIC_HREF)) pageBuffer.append(tab(3)+"<p>"+WebappResources.getString("topicUnavailable",locale)+"</p>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ // Write potential causes, based on some or @@ -187,28 +197,148 @@ public class StatusProducer implements IHelpContentProducer { new String[]{getActiveLink(locale)}); pageBuffer.append(tab(3)+activeLink); - - pageBuffer.append(END_BODY_HTML); - - -// String tmp = pluginID+" , "+href; //$NON-NLS-1$ -// System.out.println(tmp); + if (href.equalsIgnoreCase(MissingContentManager.REMOTE_STATUS_HELP_VIEW_HREF)) { + // Add link to retest + pageBuffer.append(tab(3)+"<h2>"+WebappResources.getString("RemoteHelpRetestTitle", locale)+"</h2>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + pageBuffer.append(tab(3)+"<p>\n"); //$NON-NLS-1$ + pageBuffer.append(tab(4)+ "<a href=helpview:checkremote>"+ //$NON-NLS-1$ + WebappResources.getString("RemoteHelpRetestLink", locale) + "</a>\n"); //$NON-NLS-1$ //$NON-NLS-2$ + pageBuffer.append(tab(3)+ "</p>\n"); //$NON-NLS-1$ + + pageBuffer.append(END_BODY_HTML); + } ByteArrayInputStream bais = new ByteArrayInputStream(pageBuffer.toString().getBytes()); - return bais; } + public void addCloseLink(Locale locale, StringBuffer pageBuffer) { + WebappPreferences prefs = new WebappPreferences(); + String homepage = "/help/topic"+prefs.getHelpHome(); //$NON-NLS-1$ + pageBuffer.append(tab(3)+"<div style=\"position:absolute;right:4px;top:4px;\">\n"); //$NON-NLS-1$ + pageBuffer.append(tab(4)+"<table>\n"+tab(5)+"<tr>\n"); //$NON-NLS-1$ //$NON-NLS-2$ + pageBuffer.append(tab(6)+"<td style=\"background-color:white;border-width:1px;border-style:solid;border-color:grey;\">"+makeAnchor(homepage,WebappResources.getString("Close", locale),"style=\"font-size:.8em;\"",false)+"</td>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + pageBuffer.append(tab(5)+"</tr>\n"+tab(4)+"</table>\n"+tab(3)+"</div>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + private InputStream getNetworkOKPage(Locale locale) { + StringBuffer pageBuffer = new StringBuffer(); + // Write HTML header and body beginning. + String title = WebappResources.getString("networkHelpAvailable", locale); //$NON-NLS-1$ + pageBuffer.append(getHtmlHead(locale, title)); + pageBuffer.append(getBeginHtmlBody(false)); + pageBuffer.append(tab(3)+"<h1>"+title+"</h1>\n"); //$NON-NLS-1$ //$NON-NLS-2$ + pageBuffer.append(tab(3) + "<p>\n"); //$NON-NLS-1$ + pageBuffer.append(WebappResources.getString("networkHelpAvailableDetails", locale)); //$NON-NLS-1$ + pageBuffer.append("</p>\n"); //$NON-NLS-1$ + pageBuffer.append(END_BODY_HTML); + ByteArrayInputStream bais = new ByteArrayInputStream(pageBuffer.toString().getBytes()); + return bais; + } + + private InputStream getMissingTopicPage(String topicPath, Locale locale) { + StringBuffer pageBuffer = new StringBuffer(); + // Write HTML header and body beginning. + String title = WebappResources.getString("someBooksUninstalled", locale); //$NON-NLS-1$ + pageBuffer.append(getHtmlHead(locale, title)); + pageBuffer.append(getBeginHtmlBody(false)); + pageBuffer.append(tab(3)+"<h1>"+title+"</h1>\n"); //$NON-NLS-1$ //$NON-NLS-2$ + pageBuffer.append(tab(3) + "<p>\n"); //$NON-NLS-1$ + pageBuffer.append(WebappResources.getString("linkToUninstalledDetails", locale)); //$NON-NLS-1$ + pageBuffer.append("</p>\n"); //$NON-NLS-1$ + pageBuffer.append(tab(3) + "<p>\n"); //$NON-NLS-1$ + String href = "PLUGINS_ROOT/" + MissingContentManager.getInstance().getPageNotFoundPage("help:" + topicPath, true); //$NON-NLS-1$ //$NON-NLS-2$ + pageBuffer.append(tab(4)); + pageBuffer.append("<a href=\"" + href + "\">"); //$NON-NLS-1$ //$NON-NLS-2$ + pageBuffer.append(WebappResources.getString("linkToUninstalledClick", locale)); //$NON-NLS-1$ + pageBuffer.append("</a>\n"); //$NON-NLS-1$ + pageBuffer.append(tab(3) + "</p>\n"); //$NON-NLS-1$ + pageBuffer.append(END_BODY_HTML); + ByteArrayInputStream bais = new ByteArrayInputStream(pageBuffer.toString().getBytes()); + return bais; + } + + /* + * Return the page used to display place holder information about missing books + */ + private InputStream getMissingBooksPage(Locale locale, boolean isHelpView) { + MissingContentManager.Placeholder[] unresolved = MissingContentManager.getInstance().getUnresolvedPlaceholders(); + if (unresolved.length == 0) { + return getNoBooksMissingPage(locale, isHelpView); + } + StringBuffer pageBuffer = new StringBuffer(); + // Write HTML header and body beginning. + String title = WebappResources.getString("someBooksUninstalled", locale); //$NON-NLS-1$ + pageBuffer.append(getHtmlHead(locale, title)); + pageBuffer.append(getBeginHtmlBody(!isHelpView)); + pageBuffer.append(tab(3)+"<h1>"+title+"</h1>\n"); //$NON-NLS-1$ //$NON-NLS-2$ + // Add a close link to top + if (!isHelpView) + { + addCloseLink(locale, pageBuffer); + } + + pageBuffer.append(tab(3) + "<p>"); //$NON-NLS-1$ + pageBuffer.append(WebappResources.getString("installInstructions", locale)); //$NON-NLS-1$ + pageBuffer.append("</p>\n"); //$NON-NLS-1$ + pageBuffer.append(tab(3)+"<ul>\n"); //$NON-NLS-1$ + for (int i = 0; i < unresolved.length; i++ ) { + pageBuffer.append(tab(4) + "<li>\n"); //$NON-NLS-1$ + pageBuffer.append(tab(5) + "<a href = \".."); //$NON-NLS-1$ + pageBuffer.append(unresolved[i].placeholderPage); + pageBuffer.append("\">"); //$NON-NLS-1$ + pageBuffer.append(unresolved[i].bundle); + pageBuffer.append("</a>\n"); //$NON-NLS-1$ + pageBuffer.append(tab(4) + "</li>\n"); //$NON-NLS-1$ + } + pageBuffer.append(tab(3)+ "</ul>\n"); //$NON-NLS-1$ + if (isHelpView) { + pageBuffer.append(tab(3)+"<br/><p>\n"); //$NON-NLS-1$ + pageBuffer.append(tab(4)+ "<a href=helpview:ignoreMissingBooks>"+ //$NON-NLS-1$ + WebappResources.getString("ignoreMissingBooks", locale) + "</a>\n"); //$NON-NLS-1$ //$NON-NLS-2$ + pageBuffer.append(tab(3)+ "</p>\n"); //$NON-NLS-1$ + } else { + pageBuffer.append(tab(3)+"<br/><p>\n"); //$NON-NLS-1$ + //pageBuffer.append("<img src=\"PLUGINS_ROOT/org.eclipse.help/command_link.png\"/>"); //$NON-NLS-1$ + pageBuffer.append("<a class=\"command-link\"" //$NON-NLS-1$ + + " href='javascript:executeCommand(\"org.eclipse.help.ui.ignoreMissingPlaceholders\")'>" //$NON-NLS-1$ + + WebappResources.getString("ignoreMissingBooks", locale)+"</a>"); //$NON-NLS-1$ //$NON-NLS-2$ + pageBuffer.append(tab(3)+ "</p>\n"); //$NON-NLS-1$ + } + pageBuffer.append(END_BODY_HTML); + ByteArrayInputStream bais = new ByteArrayInputStream(pageBuffer.toString().getBytes()); + return bais; + } + + + private InputStream getNoBooksMissingPage(Locale locale, boolean isHelpView) { + StringBuffer pageBuffer = new StringBuffer(); + // Write HTML header and body beginning. + String title = WebappResources.getString("allBooksInstalledTitle", locale); //$NON-NLS-1$ + pageBuffer.append(getHtmlHead(locale, title)); + pageBuffer.append(getBeginHtmlBody(!isHelpView)); + pageBuffer.append(tab(3)+"<h2>"+title+"</h2>\n"); //$NON-NLS-1$ //$NON-NLS-2$ + // Add a close link to top + if (!isHelpView) + { + addCloseLink(locale, pageBuffer); + } + pageBuffer.append(tab(3) + "<p>\n"); //$NON-NLS-1$ + pageBuffer.append(WebappResources.getString("allBooksInstalled", locale)); //$NON-NLS-1$ + pageBuffer.append("</p>\n"); //$NON-NLS-1$ + pageBuffer.append(END_BODY_HTML); + ByteArrayInputStream bais = new ByteArrayInputStream(pageBuffer.toString().getBytes()); + return bais; + } /* * Build the HTML header */ - private String getHtmlHead(Locale locale) + private String getHtmlHead(Locale locale, String title) { return BEGIN_HEAD_HTML + '\n' + tab(2) + "<meta name=\"copyright\" content=\"Copyright (c) IBM Corporation and others 2000, 2009. This page is made available under license. For full details see the LEGAL in the documentation book that contains this page.\" >\n" //$NON-NLS-1$ - + tab(2) + "<title>"+WebappResources.getString("remoteStatusTitle", locale)+"</title>\n" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + tab(2) + "<title>"+ title +"</title>\n" //$NON-NLS-1$ //$NON-NLS-2$ + tab(2) + "<link rel=\"stylesheet\" href=\"PLUGINS_ROOT/org.eclipse.help.base/doc/book.css\" charset=\"utf-8\" type=\"text/css\">\n" //$NON-NLS-1$ + tab(2) + "<script language=\"JavaScript\" src=\"PLUGINS_ROOT/org.eclipse.help/livehelp.js\"> </script>\n" //$NON-NLS-1$ + tab(2) + "<script type=\"text/javascript\" src=\"../../../content/org.eclipse.help/livehelp.js\"></script>\n" //$NON-NLS-1$ @@ -218,7 +348,7 @@ public class StatusProducer implements IHelpContentProducer { /* * Build the beginning of the HTML body */ - private String getBeginHtmlBody() + private String getBeginHtmlBody(boolean addBanner) { String body = tab(1); @@ -226,11 +356,12 @@ public class StatusProducer implements IHelpContentProducer { body += "<body dir=\"rtl\">"; //$NON-NLS-1$ else body += "<body>"; //$NON-NLS-1$ + body += '\n'; + if (addBanner) { + body += tab(2) + "<div id=\"banner\"><img src=\"PLUGINS_ROOT/org.eclipse.help.base/doc/help_banner.jpg\" alt=\"Help banner\" width=\"1600\" height=\"36\"></div>\n"; //$NON-NLS-1$ + } - - return body + '\n' - + tab(2) + "<div id=\"banner\"><img src=\"PLUGINS_ROOT/org.eclipse.help.base/doc/help_banner.jpg\" alt=\"Help banner\" width=\"1600\" height=\"36\"></div>\n" //$NON-NLS-1$ - + tab(2) + "<div id=\"content\">\n"; //$NON-NLS-1$ + return body + tab(2) + "<div id=\"content\">\n"; //$NON-NLS-1$ } /* diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/WebappResources.properties b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/WebappResources.properties index ef9db7c25..a26c1d278 100644 --- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/WebappResources.properties +++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/WebappResources.properties @@ -141,6 +141,10 @@ networkCouldBeDown=Your machine may have lost network connectivity. mayNeedProxy=You may need to configure proxy settings to access a remote server. remotePreferences=To view, edit, and test network information center settings, open {0}. remotePreferencesMenuSelect=Window > Preferences > Help > Content +RemoteHelpRetestTitle=Retest +RemoteHelpRetestLink=Test remote help connections +networkHelpAvailable=Network Help Connected +networkHelpAvailableDetails=All remote help servers are accessible. # Frame Titles ignore=Layout frame: {0} @@ -213,6 +217,15 @@ criterionClosed=Criterion closed criterionOpen=Criterion open Criteria=Criteria +# toc placeholders +someBooksUninstalled=Documentation not installed +installInstructions=Documentation is available but not installed. Click on a link below for information on how to install this documentation. +linkToUninstalledDetails=This help page is in a book that has not been installed. +linkToUninstalledClick=Instructions for installing this book. +ignoreMissingBooks=Do not show again +allBooksInstalledTitle=No Missing Documentation +allBooksInstalled=There is no missing documentation that needs to be installed. + # Validator Servlet cantCreateServlet=Unable to create servlet: {0} diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/LayoutData.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/LayoutData.java index 5b3b7de65..3a33356fe 100644 --- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/LayoutData.java +++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/LayoutData.java @@ -22,9 +22,9 @@ import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.help.internal.HelpPlugin; import org.eclipse.help.internal.base.BaseHelpSystem; +import org.eclipse.help.internal.base.MissingContentManager; import org.eclipse.help.internal.base.remote.RemoteStatusData; import org.eclipse.help.internal.webapp.HelpWebappPlugin; -import org.eclipse.help.internal.webapp.StatusProducer; import org.eclipse.help.webapp.AbstractView; import org.eclipse.osgi.service.localization.BundleLocalization; import org.osgi.framework.Bundle; @@ -111,10 +111,16 @@ public class LayoutData extends RequestData { } String topicHref = request.getParameter("topic"); //$NON-NLS-1$ if (topicHref == null || topicHref.length() == 0) { - if (BaseHelpSystem.getMode()!=BaseHelpSystem.MODE_INFOCENTER && RemoteStatusData.isAnyRemoteHelpUnavailable()) - return "../topic/"+HelpWebappPlugin.PLUGIN_ID+'/'+StatusProducer.REMOTE_STATUS_HREF; //$NON-NLS-1$ - else - return UrlUtil.getHelpURL(preferences.getHelpHome()); + if (BaseHelpSystem.getMode()!=BaseHelpSystem.MODE_INFOCENTER && RemoteStatusData.isAnyRemoteHelpUnavailable()) { + return "../topic/"+HelpWebappPlugin.PLUGIN_ID+'/'+MissingContentManager.REMOTE_STATUS_HREF; //$NON-NLS-1$ + } + if (MissingContentManager.getInstance().isUnresolvedPlaceholders()) { + String helpMissingPage = MissingContentManager.getInstance().getHelpMissingPage(false); + if (helpMissingPage != null) { + return "../topic" + helpMissingPage; //$NON-NLS-1$ + } + } + return UrlUtil.getHelpURL(preferences.getHelpHome()); } else { TocData tocData = new TocData(context, request, response); diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/EclipseConnector.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/EclipseConnector.java index 3c0b70174..a67a4e4c7 100644 --- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/EclipseConnector.java +++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/EclipseConnector.java @@ -28,10 +28,9 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.URIUtil; import org.eclipse.help.internal.base.BaseHelpSystem; -import org.eclipse.help.internal.base.HelpBasePlugin; +import org.eclipse.help.internal.base.MissingContentManager; import org.eclipse.help.internal.base.remote.RemoteHelpInputStream; import org.eclipse.help.internal.base.remote.RemoteStatusData; import org.eclipse.help.internal.protocols.HelpURLConnection; @@ -128,14 +127,13 @@ public class EclipseConnector { if (requiresErrorPage(lowerCaseuRL) && !isRTopicPath) { - String errorPage; - - if (RemoteStatusData.isAnyRemoteHelpUnavailable()) - errorPage = '/'+HelpWebappPlugin.PLUGIN_ID+'/'+StatusProducer.MISSING_TOPIC_HREF; - else // Try to load the error page if defined - errorPage = Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, "page_not_found", null, null); //$NON-NLS-1$ - - if (errorPage != null && errorPage.length() > 0) { + String errorPage = null; + if (RemoteStatusData.isAnyRemoteHelpUnavailable()) { + errorPage = '/'+HelpWebappPlugin.PLUGIN_ID+'/'+ MissingContentManager.MISSING_TOPIC_HREF; + } else if ( MissingContentManager.getInstance().isUnresolvedPlaceholders()) { + errorPage = MissingContentManager.getInstance().getPageNotFoundPage(url, false); + } + if (errorPage != null && errorPage.length() > 0) { con = createConnection(req, resp, "help:" + errorPage); //$NON-NLS-1$ resp.setContentType("text/html"); //$NON-NLS-1$ try { diff --git a/org.eclipse.help/META-INF/MANIFEST.MF b/org.eclipse.help/META-INF/MANIFEST.MF index 0e29f69a9..86ef1faeb 100644 --- a/org.eclipse.help/META-INF/MANIFEST.MF +++ b/org.eclipse.help/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %help_plugin_name Bundle-SymbolicName: org.eclipse.help; singleton:=true -Bundle-Version: 3.5.100.qualifier +Bundle-Version: 3.6.0.qualifier Bundle-Activator: org.eclipse.help.internal.HelpPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/org.eclipse.help/schema/toc.exsd b/org.eclipse.help/schema/toc.exsd index 2c72d2627..e61489964 100644 --- a/org.eclipse.help/schema/toc.exsd +++ b/org.eclipse.help/schema/toc.exsd @@ -36,6 +36,7 @@ point and specify TOC file(s).</li> <element ref="tocProvider"/> <element ref="index"/> <element ref="tocIcon"/> + <element ref="placeholder"/> </choice> <attribute name="point" type="string" use="required"> <annotation> @@ -297,6 +298,32 @@ or not primary and intended to be integrated into another table of contents. </complexType> </element> + <element name="placeholder"> + <annotation> + <documentation> + A placeholder is used for products where the documentation is installed as an additional step. The placeholder specifies a help page which will be presented to the user if help is opened and a documentation bundle is not installed. Typically this help page would contain information about how to install the documentation. + + Each placeholder specifies a bundle or list of bundles and a help page which will be displayed if one or more of the bundles in the list is not installed + </documentation> + </annotation> + <complexType> + <attribute name="plugin" type="string"> + <annotation> + <documentation> + The name of a help plug-in for which this is a placeholder. + </documentation> + </annotation> + </attribute> + <attribute name="placeholderPage" type="string"> + <annotation> + <documentation> + The page to show when the plug-in is not installed. + </documentation> + </annotation> + </attribute> + </complexType> + </element> + <annotation> <appInfo> <meta.section type="examples"/> |