Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Suaridze2020-02-08 16:53:13 +0000
committerAlexander Fedorov2020-02-16 17:48:23 +0000
commit6467b78d26822b22215ab2c87409a9ced3abcaa4 (patch)
tree9f376758faf5f140ccb0a6652e503a4284077037 /org.eclipse.ui.cheatsheets
parent078759650d652ca8952c8ba61e9522dff00156b8 (diff)
downloadeclipse.platform.ua-6467b78d26822b22215ab2c87409a9ced3abcaa4.tar.gz
eclipse.platform.ua-6467b78d26822b22215ab2c87409a9ced3abcaa4.tar.xz
eclipse.platform.ua-6467b78d26822b22215ab2c87409a9ced3abcaa4.zip
Bug 559885 - Hyperlink support in cheat sheet itemI20200217-0600I20200216-1800
description Added support for hyperlinks in cheat sheet item description. Hyperlinks are expressed using <a href="URL">diplay link</a>, where URL is a valid URL to an external web site or an CheatSheet URL that represents an CheatSheat action. All cheat sheet URLs have the following form: http://org.eclipse.ui.cheatsheet/<action_name>?param1=value1&amp;param2=value2 and will be processed by the cheat sheet framework. The following predefined actions are included in the cheat sheet framework: - showView - activates view with given view id - execute - executes the specified command Change-Id: I8b2500e734e45d2b00e93d4795316347a2ff4ccd Signed-off-by: George Suaridze <suag@1c.ru>
Diffstat (limited to 'org.eclipse.ui.cheatsheets')
-rw-r--r--org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.exsd12
-rw-r--r--org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.html13
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.java4
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.properties4
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetParser.java39
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IParserTags.java7
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetHyperlinkActionFactory.java316
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ViewItem.java24
8 files changed, 405 insertions, 14 deletions
diff --git a/org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.exsd b/org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.exsd
index af736e2d6..91a1bdf06 100644
--- a/org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.exsd
+++ b/org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.exsd
@@ -69,7 +69,17 @@ DTD fragments (&lt;a href=&quot;cheatSheetContentFileSpec.exsd&quot;&gt;machine
<documentation>
The &amp;lt;description&amp;gt; element holds the description of a cheat sheet or of
a cheat sheet item. The description consists of text interspersed with &lt;a href=&quot;../../../org.eclipse.platform.doc.isv/guide/forms_controls_text_markup.htm&quot;&gt;form text markup&lt;/a&gt;. The cheat sheet automatically formats and lays out the text to
-make it show up reasonably in the UI. Within the text, balanced &lt;b&gt;&amp;lt;b&amp;gt;&lt;/b&gt;...&lt;b&gt;&amp;lt;/b&amp;gt;&lt;/b&gt;
+make it show up reasonably in the UI. Hyperlinks are expressed using &lt;b&gt;&amp;lt;a href=&quot;URL&quot;&amp;gt;text&amp;lt;/a&amp;gt;&lt;/b&gt;, where URL is a valid URL to an external web site or a CheatSheet URL that represents a CheatSheat action. All cheat sheet URLs have the following form: http://org.eclipse.ui.cheatsheet/&amp;lt;action name&amp;gt;?param1=value1&amp;amp;param2=value2 and will be processed by the cheat sheet framework.
+&lt;br&gt;
+The following predefined actions are included in the cheat sheet framework:
+&lt;p style=&quot;margin-left:15px;&quot;&gt;
+&lt;b&gt;showView&lt;/b&gt; - activates view with given view id&lt;br&gt;
+&lt;i&gt;id&lt;/i&gt; - a view id&lt;br&gt;
+&lt;br&gt;
+&lt;b&gt;execute&lt;/b&gt; - executes the specified command. See the &lt;code&gt;serialize()&lt;/code&gt; method on &lt;code&gt;org.eclipse.core.command.ParameterizedCommand&lt;/code&gt; for details of the command serialization format. Since 3.2.&lt;br&gt;
+&lt;i&gt;command&lt;/i&gt; - a serialized &lt;code&gt;ParameterizedCommand&lt;/code&gt;&lt;br&gt;
+&lt;/p&gt;
+Within the text, balanced &lt;b&gt;&amp;lt;b&amp;gt;&lt;/b&gt;...&lt;b&gt;&amp;lt;/b&amp;gt;&lt;/b&gt;
tags cause the enclosed text to be rendered in a bold font, and the &lt;b&gt;&amp;lt;br/&amp;gt;&lt;/b&gt;
element can be used to force a line break. These are the only formatting tags
supported at this time (however, others may be added in the future). Certain
diff --git a/org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.html b/org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.html
index e396f8f09..cd1de3a1a 100644
--- a/org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.html
+++ b/org.eclipse.ui.cheatsheets/schema/cheatSheetContentFileSpec.html
@@ -44,7 +44,18 @@ The &lt;intro&gt; element is used to define the introductory text to be displaye
<p class="ConfigMarkupElementDesc">
The &lt;description&gt; element holds the description of a cheat sheet or of
a cheat sheet item. The description consists of text interspersed with <a href="../../../org.eclipse.platform.doc.isv/guide/forms_controls_text_markup.htm">form text markup</a>. The cheat sheet automatically formats and lays out the text to
-make it show up reasonably in the UI. Within the text, balanced <b>&lt;b&gt;</b>...<b>&lt;/b&gt;</b>
+make it show up reasonably in the UI.
+Hyperlinks are expressed using <b>&lt;a href="URL"&gt;text&lt;a&gt;</b>, where URL is a valid URL to an external web site or a CheatSheet URL that represents a CheatSheat action. All cheat sheet URLs have the following form: http://org.eclipse.ui.cheatsheet/&lt;action name&gt;?param1=value1&amp;param2=value2 and will be processed by the cheat sheet framework.
+<br>
+The following predefined actions are included in the cheat sheet framework:
+<p style="margin-left:15px;">
+<b>showView</b> - activates view with given view id<br>
+<i>id</i> - a view id<br>
+<br>
+<b>execute</b> - executes the specified command. See the <code>serialize()</code> method on <code>org.eclipse.core.command.ParameterizedCommand</code> for details of the command serialization format. Since 3.2.<br>
+<i>command</i> - a serialized <code>ParameterizedCommand</code><br>
+</p>
+Within the text, balanced <b>&lt;b&gt;</b>...<b>&lt;/b&gt;</b>
tags cause the enclosed text to be rendered in a bold font, and the <b>&lt;br/&gt;</b>
element can be used to force a line break. These are the only formatting tags
supported at this time (however, others may be added in the future). Certain
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.java
index a39476041..3d4a12955 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.java
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * George Suaridze <suag@1c.ru> (1C-Soft LLC) - Bug 559885
*******************************************************************************/
package org.eclipse.ui.internal.cheatsheets;
@@ -27,6 +28,7 @@ public final class Messages extends NLS {
public static String ERROR_WRITING_STATE_FILE;
public static String CHEAT_SHEET_SELECTION_DIALOG_TITLE;
public static String CHEAT_SHEET_SELECTION_DIALOG_MSG;
+ public static String CHEAT_SHEET_UNSUPPORTED_LINK_ACTIVATION_MESSAGE;
public static String COLLAPSE_ALL_BUT_CURRENT_TOOLTIP;
public static String CATEGORY_OTHER;
public static String RESTORE_ALL_TOOLTIP;
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.properties b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.properties
index f03fbe80e..9a55e158a 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.properties
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/Messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2003, 2007 IBM Corporation and others.
+# Copyright (c) 2003, 2020 IBM Corporation and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
#
# Contributors:
# IBM Corporation - initial API and implementation
+# George Suaridze <suag@1c.ru> (1C-Soft LLC) - Bug 559885
###############################################################################
# ----------------------------------------------------------------------
# Properties for org.eclipse.ui.cheatsheets
@@ -61,6 +62,7 @@ RESTART_CHEATSHEET_TOOLTIP = Click to Restart
# ViewItem
HELP_BUTTON_TOOLTIP = Open Related Help
+CHEAT_SHEET_UNSUPPORTED_LINK_ACTIVATION_MESSAGE = URL of this link is: ''{0}''
# CheatSheetViewer
ERROR_RUNNING_ACTION = The action could not be run.
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetParser.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetParser.java
index 18f4bb3f0..acbc55503 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetParser.java
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetParser.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2018 IBM Corporation and others.
+ * Copyright (c) 2002, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * George Suaridze <suag@1c.ru> (1C-Soft LLC) - Bug 559885
*******************************************************************************/
package org.eclipse.ui.internal.cheatsheets.data;
@@ -119,7 +120,7 @@ public class CheatSheetParser implements IStatusContainer {
* }
* </pre>
*
- * Tags that will be ignored {@literal <b>, </b> and <br/>
+ * Tags that will be ignored {@literal <b>, </b>, <a>, </a> and <br/>
* }.
*
* @param text
@@ -137,6 +138,8 @@ public class CheatSheetParser implements IStatusContainer {
// Create the buffer to store the resulting string
StringBuilder result = new StringBuilder(length);
+ boolean hyperlinkContext = false;
+
// Loop for the characters of the original string
for(int i=0; i<length; i++) {
// Grab the next character and determine how to handle it
@@ -152,7 +155,11 @@ public class CheatSheetParser implements IStatusContainer {
else {
tmp = text.substring(i, length).toLowerCase();
}
- if(tmp.startsWith(IParserTags.BOLD_START_TAG) || tmp.startsWith(IParserTags.BOLD_END_TAG) || tmp.startsWith(IParserTags.BREAK_TAG)) {
+ if (hyperlinkContext || tmp.startsWith(IParserTags.HYPERLINK_START_TAG)) {
+ result.append(c);
+ hyperlinkContext = true;
+ } else if (tmp.startsWith(IParserTags.BOLD_START_TAG) || tmp.startsWith(IParserTags.BOLD_END_TAG)
+ || tmp.startsWith(IParserTags.BREAK_TAG)) {
// We have a tag to ignore so just emit the character
result.append(c);
} else {
@@ -171,6 +178,15 @@ public class CheatSheetParser implements IStatusContainer {
} else {
tmp = text.substring(0, i+1).toLowerCase();
}
+ if (tmp.endsWith(IParserTags.HYPERLINK_END_TAG)) {
+ result.append(c);
+ hyperlinkContext = false;
+ break;
+ }
+ if (hyperlinkContext) {
+ result.append(c);
+ break;
+ }
if(tmp.endsWith(IParserTags.BOLD_START_TAG) || tmp.endsWith(IParserTags.BOLD_END_TAG) || tmp.endsWith(IParserTags.BREAK_TAG)) {
// We have a tag to ignore so just emit the character
result.append(c);
@@ -190,7 +206,7 @@ public class CheatSheetParser implements IStatusContainer {
break;
case '"':
// We have a quote so emit the XML escaped counterpart
- result.append(IParserTags.QUOTE);
+ result.append(hyperlinkContext ? c : IParserTags.QUOTE);
break;
case '\t':
// We have a tab, replace with a space
@@ -442,7 +458,7 @@ public class CheatSheetParser implements IStatusContainer {
text.append(nodeValue);
isLeadingTrimRequired = false;
} else if(node.getNodeType() == Node.ELEMENT_NODE) {
- // handle <b></b> and <br/>
+ // handle <b></b>, <br/> and <a></a>
switch (node.getNodeName()) {
case IParserTags.BOLD:
containsMarkup = true;
@@ -456,6 +472,19 @@ public class CheatSheetParser implements IStatusContainer {
text.append(IParserTags.BREAK_TAG);
isLeadingTrimRequired = true;
break;
+ case IParserTags.HYPERLINK:
+ containsMarkup = true;
+ if (node.getAttributes().getNamedItem(IParserTags.HREF) == null) {
+ text.append(NLS.bind(IParserTags.HYPERLINK_PLACEHOLDER, "")); //$NON-NLS-1$
+ } else {
+ String href = node.getAttributes().getNamedItem(IParserTags.HREF).getNodeValue();
+ String link = NLS.bind(IParserTags.HYPERLINK_PLACEHOLDER, href);
+ text.append(link);
+ }
+ text.append(node.getTextContent());
+ text.append(IParserTags.HYPERLINK_END_TAG);
+ isLeadingTrimRequired = false;
+ break;
default:
warnUnknownMarkupElement(startNode, nodeName, node);
break;
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IParserTags.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IParserTags.java
index 0dc27f4e0..46a982a22 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IParserTags.java
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IParserTags.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2015 IBM Corporation and others.
+ * Copyright (c) 2002, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * George Suaridze <suag@1c.ru> (1C-Soft LLC) - Bug 559885
*******************************************************************************/
package org.eclipse.ui.internal.cheatsheets.data;
@@ -47,9 +48,13 @@ public interface IParserTags {
public static final String DESCRIPTION = "description"; //$NON-NLS-1$
public static final String BOLD = "b"; //$NON-NLS-1$
public static final String BREAK = "br"; //$NON-NLS-1$
+ public static final String HYPERLINK = "a"; //$NON-NLS-1$
public static final String BOLD_START_TAG = "<b>"; //$NON-NLS-1$
public static final String BOLD_END_TAG = "</b>"; //$NON-NLS-1$
public static final String BREAK_TAG = "<br/>"; //$NON-NLS-1$
+ public static final String HYPERLINK_START_TAG = "<a"; //$NON-NLS-1$
+ public static final String HYPERLINK_PLACEHOLDER = "<a href=\"{0}\">"; //$NON-NLS-1$
+ public static final String HYPERLINK_END_TAG = "</a>"; //$NON-NLS-1$
public static final String FORM_START_TAG = "<form><p>"; //$NON-NLS-1$
public static final String FORM_END_TAG = "</p></form>"; //$NON-NLS-1$
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetHyperlinkActionFactory.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetHyperlinkActionFactory.java
new file mode 100644
index 000000000..b34be5e08
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetHyperlinkActionFactory.java
@@ -0,0 +1,316 @@
+/*******************************************************************************
+ * Copyright (c) 2020 1C-Soft LLC and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * George Suaridze (1C-Soft LLC) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.text.MessageFormat;
+import java.util.Properties;
+
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.commands.common.CommandException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.cheatsheets.CheatSheetPlugin;
+import org.eclipse.ui.internal.cheatsheets.Messages;
+
+/**
+ * A factory that knows how to create cheatsheet URL actions.
+ * <p>
+ * A cheatsheet URL is a valid http url, with org.eclipse.ui.cheatsheet as a
+ * host.
+ * </p>
+ * <p>
+ * A cheatsheet url instance is created by parsing the url and retrieving the
+ * embedded "command" and parameters. For example, the following urls are valid
+ * cheatsheet urls:
+ * <p>
+ *
+ * <pre>
+ * http://org.eclipse.ui.cheatsheet/showView?id=org.eclipse.pde.runtime.LogView
+ * http://org.eclipse.ui.cheatsheet/execute?command=org.eclipse.ui.newWizard%28newWizardId%3Dorg.eclipse.ui.wizards.new.project%29"
+ * </pre>
+ * <p>
+ * When parsed, the first url has "showView" as a command, and "id" parameter.
+ * While the second "execute" as a command and "command" as parameter with
+ * "newWizardId" as command parameter.
+ * </p>
+ * <p>
+ * For now it supports two commands:
+ * <li>showView - to activate given view by its id</li>
+ * <li>execute - to execute eclipse command</li>
+ */
+public class CheatSheetHyperlinkActionFactory {
+
+ private static final String CHEAT_SHEET_PROTOCOL = "http"; //$NON-NLS-1$
+ private static final String CHEAT_SHEET_HOST_ID = "org.eclipse.ui.cheatsheet"; //$NON-NLS-1$
+
+ private static final String EXECUTE = "execute"; //$NON-NLS-1$
+ private static final String SHOW_VIEW = "showView"; //$NON-NLS-1$
+
+ private static final String KEY_ID = "id"; //$NON-NLS-1$
+ private static final String KEY_COMAND = "command"; //$NON-NLS-1$
+ private static final String KEY_DECODE = "decode"; //$NON-NLS-1$
+
+ private static final String VALUE_TRUE = "true"; //$NON-NLS-1$
+
+ /**
+ * Creates {@link CheatSheetHyperlinkAction} for given url string
+ *
+ * @param urlString
+ * - url string representation, cannot be {@code null}
+ * @return appropriate cheatsheet action {@link CheatSheetHyperlinkAction}
+ */
+ public CheatSheetHyperlinkAction create(String urlString) {
+ if (urlString == null) {
+ return new FallbackAction(urlString);
+ }
+ try {
+ URL url = new URL(urlString);
+ if (isCheatSheetHyperlink(url)) {
+ String action = getPathAsAction(url);
+ Properties parameters = getQueryParameters(url);
+ switch (action) {
+ case EXECUTE:
+ return new CommandAction(getParameter(parameters, KEY_COMAND));
+ case SHOW_VIEW:
+ return new ShowViewAction(getParameter(parameters, KEY_ID));
+ default:
+ CheatSheetPlugin.getPlugin().getLog().error("Unsupported action: " + action, null); //$NON-NLS-1$
+ }
+ return new FallbackAction(urlString);
+ } else if (url.getProtocol() != null) {
+ return new OpenInBrowserAction(url);
+ } else {
+ return new FallbackAction(urlString);
+ }
+ } catch (MalformedURLException e) {
+ CheatSheetPlugin.getPlugin().getLog().error("Malformed URL: " + urlString, e); //$NON-NLS-1$
+ return new FallbackAction(urlString);
+ }
+ }
+
+ private boolean isCheatSheetHyperlink(URL url) {
+ if (!url.getProtocol().equalsIgnoreCase(CHEAT_SHEET_PROTOCOL)) {
+ return false;
+ }
+ if (url.getHost().equalsIgnoreCase(CHEAT_SHEET_HOST_ID)) {
+ return true;
+ }
+ return false;
+ }
+
+ private Properties getQueryParameters(URL url) {
+ Properties properties = new Properties();
+ String query = url.getQuery();
+ if (query == null) {
+ return properties;
+ }
+ String[] params = query.split("&"); //$NON-NLS-1$
+ for (int i = 0; i < params.length; i++) {
+ String[] keyValuePair = params[i].split("="); //$NON-NLS-1$
+ if (keyValuePair.length != 2) {
+ CheatSheetPlugin.getPlugin().getLog()
+ .warn(MessageFormat.format("Ignoring the following Cheatsheet URL parameter: {0}", params[i])); //$NON-NLS-1$
+ continue;
+ }
+
+ String key = urlDecode(keyValuePair[0]);
+ if (key == null) {
+ CheatSheetPlugin.getPlugin().getLog()
+ .warn(MessageFormat.format("Failed to URL decode key: {0}", keyValuePair[0])); //$NON-NLS-1$
+ continue;
+ }
+
+ String value = urlDecode(keyValuePair[1]);
+ if (value == null) {
+ CheatSheetPlugin.getPlugin().getLog()
+ .warn(MessageFormat.format("Failed to URL decode value: {0}", keyValuePair[1])); //$NON-NLS-1$
+ continue;
+ }
+
+ properties.setProperty(key, value);
+ }
+ return properties;
+ }
+
+ private String urlDecode(String encodedURL) {
+ int len = encodedURL.length();
+ ByteArrayOutputStream os = new ByteArrayOutputStream(len);
+
+ for (int i = 0; i < len;) {
+ switch (encodedURL.charAt(i)) {
+ case '%':
+ if (len >= i + 3) {
+ os.write(Integer.parseInt(encodedURL.substring(i + 1, i + 3), 16));
+ }
+ i += 3;
+ break;
+ case '+': // exception from standard
+ os.write(' ');
+ i++;
+ break;
+ default:
+ os.write(encodedURL.charAt(i++));
+ break;
+ }
+ }
+ return new String(os.toByteArray(), StandardCharsets.UTF_8);
+ }
+
+ private String getPathAsAction(URL url) {
+ String action = url.getPath();
+ if (action != null) {
+ action = action.substring(1);
+ }
+ return action;
+ }
+
+ private String getParameter(Properties parameters, String parameterId) {
+ String value = parameters.getProperty(parameterId);
+ String decode = parameters.getProperty(KEY_DECODE);
+
+ if (value != null) {
+ try {
+ if (decode != null && decode.equalsIgnoreCase(VALUE_TRUE)) {
+ return decode(value, "UTF-8"); //$NON-NLS-1$
+ }
+ return value;
+ } catch (Exception e) {
+ CheatSheetPlugin.getPlugin().getLog().error("Failed to decode URL: " + parameterId, e); //$NON-NLS-1$
+ }
+ }
+ return value;
+ }
+
+ private String decode(String s, String enc) throws UnsupportedEncodingException {
+ try {
+ return URLDecoder.decode(s, enc);
+ } catch (Exception ex) {
+ return s;
+ }
+ }
+
+ public static abstract class CheatSheetHyperlinkAction {
+
+ /**
+ * Executes action.
+ */
+ public final void execute() {
+ Display display = Display.getDefault();
+ BusyIndicator.showWhile(display, () -> {
+ doExecute(display);
+ });
+
+ }
+
+ protected abstract void doExecute(Display display);
+ }
+
+ private static class FallbackAction extends CheatSheetHyperlinkAction {
+
+ private final String url;
+
+ public FallbackAction(String url) {
+ this.url = url;
+ }
+
+ @Override
+ public void doExecute(Display display) {
+ MessageDialog.openInformation(display.getActiveShell(),
+ null,
+ MessageFormat.format(Messages.CHEAT_SHEET_UNSUPPORTED_LINK_ACTIVATION_MESSAGE, url));
+ }
+ }
+
+ private static class OpenInBrowserAction extends CheatSheetHyperlinkAction {
+
+ private final URL url;
+
+ public OpenInBrowserAction(URL url) {
+ this.url = url;
+ }
+
+ @Override
+ public void doExecute(Display display) {
+ try {
+ IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
+ support.getExternalBrowser().openURL(url);
+ } catch (PartInitException e) {
+ CheatSheetPlugin.getPlugin().getLog().error("Cheatsheet failed to get Browser support.", e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ private static class ShowViewAction extends CheatSheetHyperlinkAction {
+
+ private final String viewId;
+
+ public ShowViewAction(String viewId) {
+ this.viewId = viewId;
+ }
+
+ @Override
+ protected void doExecute(Display display) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
+ if (activeWorkbenchWindow != null) {
+ try {
+ activeWorkbenchWindow.getActivePage().showView(viewId, null, IWorkbenchPage.VIEW_ACTIVATE);
+ } catch (PartInitException e) {
+ CheatSheetPlugin.getPlugin().getLog().error("Error while activating view: " + viewId, e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ private static class CommandAction extends CheatSheetHyperlinkAction {
+
+ private final String command;
+
+ public CommandAction(String command) {
+ this.command = command;
+ }
+
+ @Override
+ protected void doExecute(Display display) {
+ ICommandService commandService = PlatformUI.getWorkbench().getService(ICommandService.class);
+ IHandlerService handlerService = PlatformUI.getWorkbench().getService(IHandlerService.class);
+ if (commandService == null || handlerService == null) {
+ CheatSheetPlugin.getPlugin().getLog().error(
+ "Could not get ICommandService or IHandlerService while trying to execute: " + command, null); //$NON-NLS-1$
+ return;
+ }
+ try {
+ ParameterizedCommand pCommand = commandService.deserialize(command);
+ handlerService.executeCommand(pCommand, null);
+ } catch (CommandException e) {
+ CheatSheetPlugin.getPlugin().getLog().error("Could not execute command: " + command, e); //$NON-NLS-1$
+ }
+ }
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ViewItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ViewItem.java
index bc98a0ca2..d0de8758b 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ViewItem.java
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ViewItem.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2019 IBM Corporation and others.
+ * Copyright (c) 2002, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -11,6 +11,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Asma Smaoui - CEA LIST - https://bugs.eclipse.org/bugs/show_bug.cgi?id=517379
+ * George Suaridze <suag@1c.ru> (1C-Soft LLC) - Bug 559885
*******************************************************************************/
package org.eclipse.ui.internal.cheatsheets.views;
@@ -54,6 +55,7 @@ import org.eclipse.ui.internal.cheatsheets.ICheatSheetResource;
import org.eclipse.ui.internal.cheatsheets.Messages;
import org.eclipse.ui.internal.cheatsheets.data.IParserTags;
import org.eclipse.ui.internal.cheatsheets.data.Item;
+import org.eclipse.ui.internal.cheatsheets.views.CheatSheetHyperlinkActionFactory.CheatSheetHyperlinkAction;
public abstract class ViewItem {
@@ -199,24 +201,38 @@ public abstract class ViewItem {
@Override
public void widgetSelected(SelectionEvent e) {
Action copyAction = viewer.getCopyAction();
- if (copyAction!=null)
+ if (copyAction != null) {
copyAction.setEnabled(bodyText.canCopy());
+ }
}
});
bodyText.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
Action copyAction = viewer.getCopyAction();
- if (copyAction!=null)
+ if (copyAction != null) {
copyAction.setEnabled(bodyText.canCopy());
+ }
}
@Override
public void focusLost(FocusEvent e) {
Action copyAction = viewer.getCopyAction();
- if (copyAction!=null)
+ if (copyAction != null) {
copyAction.setEnabled(false);
+ }
+ }
+ });
+
+ bodyText.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(HyperlinkEvent event) {
+ String url = (String) event.getHref();
+ CheatSheetHyperlinkActionFactory actionFactory = new CheatSheetHyperlinkActionFactory();
+ CheatSheetHyperlinkAction cheatSheetHyperlink = actionFactory.create(url);
+ cheatSheetHyperlink.execute();
}
});
+
// bodyText = toolkit.createLabel(bodyWrapperComposite, item.getDescription(), SWT.WRAP);
bodyText.setText(item.getDescription(), item.getDescription().startsWith(IParserTags.FORM_START_TAG), false);

Back to the top