Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlparsons2004-03-08 16:52:24 -0500
committerlparsons2004-03-08 16:52:24 -0500
commit724e690df07a50a5ebc98aa46be05c367a61daa6 (patch)
treeb5bc283735acf7a8328035340e33bce4fd2397ac /org.eclipse.ui.cheatsheets
parent447edb015c8f02afaf92c56711f8b85196ae2acb (diff)
downloadeclipse.platform.ua-724e690df07a50a5ebc98aa46be05c367a61daa6.tar.gz
eclipse.platform.ua-724e690df07a50a5ebc98aa46be05c367a61daa6.tar.xz
eclipse.platform.ua-724e690df07a50a5ebc98aa46be05c367a61daa6.zip
Intial version
Diffstat (limited to 'org.eclipse.ui.cheatsheets')
-rw-r--r--org.eclipse.ui.cheatsheets/.classpath7
-rw-r--r--org.eclipse.ui.cheatsheets/.cvsignore1
-rw-r--r--org.eclipse.ui.cheatsheets/.project38
-rw-r--r--org.eclipse.ui.cheatsheets/about.html30
-rw-r--r--org.eclipse.ui.cheatsheets/build.properties7
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/collapse_all.gifbin0 -> 127 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/collapse_expand_all.gifbin0 -> 124 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/complete_task.gifbin0 -> 167 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/expand_all.gifbin0 -> 112 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/icon_legend.gifbin0 -> 173 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/linkto_help.gifbin0 -> 242 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/restart_cheatsheet.gifbin0 -> 179 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/restart_task.gifbin0 -> 124 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/skip_task.gifbin0 -> 132 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/start_cheatsheet.gifbin0 -> 178 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/clcl16/start_task.gifbin0 -> 112 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/cview16/cheatsheet_view.gifbin0 -> 173 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/collapse_all.gifbin0 -> 85 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/collapse_expand_all.gifbin0 -> 83 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/complete_task.gifbin0 -> 76 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/expand_all.gifbin0 -> 79 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/icon_legend.gifbin0 -> 104 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/linkto_help.gifbin0 -> 82 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/restart_cheatsheet.gifbin0 -> 84 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/restart_task.gifbin0 -> 74 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/skip_task.gifbin0 -> 80 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/start_cheatsheet.gifbin0 -> 81 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/dlcl16/start_task.gifbin0 -> 74 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/collapse_all.gifbin0 -> 123 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/collapse_expand_all.gifbin0 -> 171 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/complete_task.gifbin0 -> 216 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/expand_all.gifbin0 -> 110 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/icon_legend.gifbin0 -> 136 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/linkto_help.gifbin0 -> 242 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/restart_cheatsheet.gifbin0 -> 249 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/restart_task.gifbin0 -> 211 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/skip_task.gifbin0 -> 222 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/start_cheatsheet.gifbin0 -> 247 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/elcl16/start_task.gifbin0 -> 147 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/eview16/cheatsheet_view.gifbin0 -> 266 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/obj16/collapse_state.gifbin0 -> 91 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/obj16/complete_status.gifbin0 -> 100 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/obj16/expand_state.gifbin0 -> 90 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/icons/full/obj16/skip_status.gifbin0 -> 85 bytes
-rw-r--r--org.eclipse.ui.cheatsheets/plugin.properties54
-rw-r--r--org.eclipse.ui.cheatsheets/plugin.xml44
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IAbstractItem.java29
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetAction.java35
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetItemExtensionElement.java80
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetManager.java93
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IItem.java79
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IItemWithSubItems.java84
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ISubItem.java41
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/LaunchCheatSheetAction.java108
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/OpenCheatSheetFromHelpAction.java49
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetEvent.java38
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetItemEvent.java52
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetItemListener.java62
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetListener.java18
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetViewEvent.java37
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetViewListener.java58
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/package.html40
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/package.html36
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/CheatSheetHistory.java131
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/CheatSheetPlugin.java359
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/ICheatSheetResource.java86
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetCategoryBasedSelectionAction.java68
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetMenu.java328
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetSelectionAction.java64
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/AbstractItem.java26
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ActionItem.java79
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetDomParser.java509
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetSaveHelper.java264
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetXMLSaveHelper.java420
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/Content.java90
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ContentItem.java109
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ContentItemWithSubItems.java191
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IContainsContent.java62
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IParserTags.java50
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/SubContentItem.java28
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java382
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetSelectionDialog.java182
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetCollectionElement.java177
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetCollectionSorter.java56
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetElement.java144
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetListenerElement.java80
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetRegistryReader.java529
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/RegistryReader.java159
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/Sorter.java72
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/Button.java292
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetEvent.java17
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetExpandRestoreAction.java33
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetItemEvent.java73
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetManager.java273
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetView.java1543
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetViewEvent.java43
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CoreItem.java431
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHack.java175
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHackPartListener.java527
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHackPerspectiveListener.java211
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/IntroItem.java114
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/NoopAction.java41
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/SubItemCompositeHolder.java69
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleButton.java104
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleImage.java71
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleableControl.java251
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ViewItem.java731
-rw-r--r--org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/WizardReturnCodeHack.java50
108 files changed, 10814 insertions, 0 deletions
diff --git a/org.eclipse.ui.cheatsheets/.classpath b/org.eclipse.ui.cheatsheets/.classpath
new file mode 100644
index 000000000..065ac06e1
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.ui.cheatsheets/.cvsignore b/org.eclipse.ui.cheatsheets/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/org.eclipse.ui.cheatsheets/.project b/org.eclipse.ui.cheatsheets/.project
new file mode 100644
index 000000000..34425bbfb
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/.project
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.ui.cheatsheets</name>
+ <comment></comment>
+ <projects>
+ <project>org.apache.xerces</project>
+ <project>org.eclipse.core.resources</project>
+ <project>org.eclipse.core.runtime.compatibility</project>
+ <project>org.eclipse.help</project>
+ <project>org.eclipse.jface.text</project>
+ <project>org.eclipse.ui</project>
+ <project>org.eclipse.ui.editors</project>
+ <project>org.eclipse.ui.ide</project>
+ <project>org.eclipse.ui.views</project>
+ <project>org.eclipse.ui.workbench.texteditor</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.ui.cheatsheets/about.html b/org.eclipse.ui.cheatsheets/about.html
new file mode 100644
index 000000000..9db411aab
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/about.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>20th June, 2002</p>
+<h3>License</h3>
+<p>Eclipse.org makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Common Public License Version 1.0 (&quot;CPL&quot;). A copy of the CPL is available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+For purposes of the CPL, &quot;Program&quot; will mean the Content.</p>
+
+<h3>Contributions</h3>
+
+<p>If this Content is licensed to you under the terms and conditions of the CPL, any Contributions, as defined in the CPL, uploaded, submitted, or otherwise
+made available to Eclipse.org, members of Eclipse.org and/or the host of Eclipse.org web site, by you that relate to such
+Content are provided under the terms and conditions of the CPL and can be made available to others under the terms of the CPL.</p>
+
+<p>If this Content is licensed to you under license terms and conditions other than the CPL (&quot;Other License&quot;), any modifications, enhancements and/or
+other code and/or documentation (&quot;Modifications&quot;) uploaded, submitted, or otherwise made available to Eclipse.org, members of Eclipse.org and/or the
+host of Eclipse.org, by you that relate to such Content are provided under terms and conditions of the Other License and can be made available
+to others under the terms of the Other License. In addition, with regard to Modifications for which you are the copyright holder, you are also
+providing the Modifications under the terms and conditions of the CPL and such Modifications can be made available to others under the terms of
+the CPL.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.ui.cheatsheets/build.properties b/org.eclipse.ui.cheatsheets/build.properties
new file mode 100644
index 000000000..7a2571d92
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/build.properties
@@ -0,0 +1,7 @@
+bin.includes = plugin.properties,\
+ icons/,\
+ *.jar,\
+ plugin.xml,\
+ about.html
+source.cheatsheets.jar = src/
+src.includes = about.html \ No newline at end of file
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/collapse_all.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/collapse_all.gif
new file mode 100644
index 000000000..55ac571a4
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/collapse_all.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/collapse_expand_all.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/collapse_expand_all.gif
new file mode 100644
index 000000000..ba84ad9f6
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/collapse_expand_all.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/complete_task.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/complete_task.gif
new file mode 100644
index 000000000..534c62a12
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/complete_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/expand_all.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/expand_all.gif
new file mode 100644
index 000000000..17b8f0e4b
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/expand_all.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/icon_legend.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/icon_legend.gif
new file mode 100644
index 000000000..3a1413b0a
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/icon_legend.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/linkto_help.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/linkto_help.gif
new file mode 100644
index 000000000..3b5a0f2d5
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/linkto_help.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/restart_cheatsheet.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/restart_cheatsheet.gif
new file mode 100644
index 000000000..ad8502c76
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/restart_cheatsheet.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/restart_task.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/restart_task.gif
new file mode 100644
index 000000000..2451c5d36
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/restart_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/skip_task.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/skip_task.gif
new file mode 100644
index 000000000..c5720e197
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/skip_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/start_cheatsheet.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/start_cheatsheet.gif
new file mode 100644
index 000000000..8ca3ae184
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/start_cheatsheet.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/clcl16/start_task.gif b/org.eclipse.ui.cheatsheets/icons/full/clcl16/start_task.gif
new file mode 100644
index 000000000..75e0e71fc
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/clcl16/start_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/cview16/cheatsheet_view.gif b/org.eclipse.ui.cheatsheets/icons/full/cview16/cheatsheet_view.gif
new file mode 100644
index 000000000..4923ba5dd
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/cview16/cheatsheet_view.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/collapse_all.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/collapse_all.gif
new file mode 100644
index 000000000..c42f719da
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/collapse_all.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/collapse_expand_all.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/collapse_expand_all.gif
new file mode 100644
index 000000000..a905b19b4
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/collapse_expand_all.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/complete_task.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/complete_task.gif
new file mode 100644
index 000000000..ab0e87ff7
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/complete_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/expand_all.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/expand_all.gif
new file mode 100644
index 000000000..c03bc19ce
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/expand_all.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/icon_legend.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/icon_legend.gif
new file mode 100644
index 000000000..5dd1466d3
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/icon_legend.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/linkto_help.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/linkto_help.gif
new file mode 100644
index 000000000..62044e2d7
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/linkto_help.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/restart_cheatsheet.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/restart_cheatsheet.gif
new file mode 100644
index 000000000..604c8f531
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/restart_cheatsheet.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/restart_task.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/restart_task.gif
new file mode 100644
index 000000000..043450e05
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/restart_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/skip_task.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/skip_task.gif
new file mode 100644
index 000000000..103bd5cb8
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/skip_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/start_cheatsheet.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/start_cheatsheet.gif
new file mode 100644
index 000000000..7ece404b8
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/start_cheatsheet.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/dlcl16/start_task.gif b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/start_task.gif
new file mode 100644
index 000000000..8a9c9cbf8
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/dlcl16/start_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/collapse_all.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/collapse_all.gif
new file mode 100644
index 000000000..1a49bddf0
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/collapse_all.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/collapse_expand_all.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/collapse_expand_all.gif
new file mode 100644
index 000000000..27f3fe0fd
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/collapse_expand_all.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/complete_task.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/complete_task.gif
new file mode 100644
index 000000000..930184b35
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/complete_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/expand_all.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/expand_all.gif
new file mode 100644
index 000000000..9f99673da
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/expand_all.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/icon_legend.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/icon_legend.gif
new file mode 100644
index 000000000..914f463e4
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/icon_legend.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/linkto_help.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/linkto_help.gif
new file mode 100644
index 000000000..3b5a0f2d5
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/linkto_help.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/restart_cheatsheet.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/restart_cheatsheet.gif
new file mode 100644
index 000000000..7549854b3
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/restart_cheatsheet.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/restart_task.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/restart_task.gif
new file mode 100644
index 000000000..306c20df4
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/restart_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/skip_task.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/skip_task.gif
new file mode 100644
index 000000000..6f0ba1e8f
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/skip_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/start_cheatsheet.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/start_cheatsheet.gif
new file mode 100644
index 000000000..4a1cfba53
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/start_cheatsheet.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/elcl16/start_task.gif b/org.eclipse.ui.cheatsheets/icons/full/elcl16/start_task.gif
new file mode 100644
index 000000000..c9ef69504
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/elcl16/start_task.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/eview16/cheatsheet_view.gif b/org.eclipse.ui.cheatsheets/icons/full/eview16/cheatsheet_view.gif
new file mode 100644
index 000000000..260d2e26b
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/eview16/cheatsheet_view.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/obj16/collapse_state.gif b/org.eclipse.ui.cheatsheets/icons/full/obj16/collapse_state.gif
new file mode 100644
index 000000000..41ab5707b
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/obj16/collapse_state.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/obj16/complete_status.gif b/org.eclipse.ui.cheatsheets/icons/full/obj16/complete_status.gif
new file mode 100644
index 000000000..1d9c323e9
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/obj16/complete_status.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/obj16/expand_state.gif b/org.eclipse.ui.cheatsheets/icons/full/obj16/expand_state.gif
new file mode 100644
index 000000000..e38d016fb
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/obj16/expand_state.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/icons/full/obj16/skip_status.gif b/org.eclipse.ui.cheatsheets/icons/full/obj16/skip_status.gif
new file mode 100644
index 000000000..0fc38173e
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/icons/full/obj16/skip_status.gif
Binary files differ
diff --git a/org.eclipse.ui.cheatsheets/plugin.properties b/org.eclipse.ui.cheatsheets/plugin.properties
new file mode 100644
index 000000000..b7f3ac544
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/plugin.properties
@@ -0,0 +1,54 @@
+# ----------------------------------------------------------------------
+# Properties for org.eclipse.ui.cheatsheets
+#
+# Entries are of the form CONSTANT=string
+# ----------------------------------------------------------------------
+
+CHEAT_SHEET_SELECTION_DIALOG_TITLE = Cheat Sheet Selection
+CHEAT_SHEET_SELECTION_DIALOG_MSG = Select the cheat sheet to open
+
+COLLAPSE_ALL_BUT_CURRENT_TOOLTIP = Collapse all items but current
+RESTORE_ALL_TOOLTIP = Expand to previous expansion states
+
+CHEAT_SHEET_OTHER_MENU = Other...
+
+PLUGIN_NAME = Cheat Sheets Plugin
+CHEAT_SHEETS = Cheat Sheets
+FASTVIEW_ONLY_ERROR = Internal Error
+FASTVIEW_ONLY_ERROR_MESSAGE = Could not instantiate the Cheat Sheets view:\n
+FASTVIEW_DISABLED_FOR_CHEAT_SHEET = Disabled for Cheat Sheets
+
+PERFORM_TASK_TOOLTIP = Click to perform
+SKIP_TASK_TOOLTIP = Click to skip
+COMPLETE_TASK_TOOLTIP = Click to complete
+START_CHEATSHEET_TOOLTIP = Click to begin
+RESTART_CHEATSHEET_TOOLTIP = Click to restart
+RESTART_TASK_TOOLTIP = Click to redo
+
+VIEW_READFILE_ACCESSEXCEPTION = Error in CheatSheetView.readFile: An exception occurred when trying to access the cheat sheet file
+
+ERROR_OPENING_FILE_TITLE = Error opening file
+ERROR_OPENING_FILE = Could not open the cheat sheet content file
+ERROR_OPENING_FILE_IN_PARSER = Cheat sheet content file not found by parser
+ERROR_SAX_PARSING = Cheat sheet content file could not be parsed
+ERROR_RUNNING_ACTION = Action could not be run
+ERROR_FINDING_PLUGIN_FOR_ACTION = The specified action could not be run because the plugin specified could not be located.
+ERROR_LOADING_CLASS_FOR_ACTION = The specified action could not be run because the specified class could not be loaded.
+ERROR_CREATING_CLASS_FOR_ACTION = The specified action could not be run because an instance of the specified class could not be created.
+ERROR_PARSING_ITEMS = There was an error while attempting to parse the items in the cheat sheet content file.
+ERROR_LOADING_CHEATSHEET_CONTENT = Error loading cheat sheet content.
+ERROR_PAGE_MESSAGE = An error occurred loading the cheat sheet content file. Contact the cheat sheet provider for assistance.
+
+CHEAT_SHEET_INTRO_TITLE = Introduction
+
+ERROR_READING_STATE_FILE = Unable to read state information.
+ERROR_WRITING_STATE_FILE = Unable to store state information.
+
+LAUNCH_SHEET_ERROR = Error loading the cheat sheet view
+CHEAT_SHEET_ERROR_OPENING = Error opening cheat sheet
+
+CHEAT_SHEET_OTHER_CATEGORY = Other
+HELP_BUTTON_TOOLTIP = Open related help
+
+LESS_THAN_2_SUBITEMS = Less than 2 sub items found for the next item. This is not allowed. Contact the cheat sheet provider for assistance.
+
diff --git a/org.eclipse.ui.cheatsheets/plugin.xml b/org.eclipse.ui.cheatsheets/plugin.xml
new file mode 100644
index 000000000..3b1fa4dee
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/plugin.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+ id="org.eclipse.ui.cheatsheets"
+ name="%PLUGIN_NAME"
+ version="3.0"
+ provider-name="IBM"
+ class="org.eclipse.ui.internal.cheatsheets.CheatSheetPlugin">
+
+ <runtime>
+ <library name="cheatsheets.jar">
+ <export name="*"/>
+ </library>
+ </runtime>
+ <requires>
+ <import plugin="org.eclipse.ui"/>
+ <import plugin="org.eclipse.help"/>
+ <import plugin="org.eclipse.core.runtime.compatibility"/>
+ </requires>
+
+
+ <extension-point id="cheatSheetContent" name="CheatSheetContent"/>
+ <extension-point id="cheatSheetItemExtension" name="CheatSheetItemExtension"/>
+
+ <extension
+ point="org.eclipse.ui.views">
+ <category
+ name="Cheat Sheets"
+ id="org.eclipse.ui.cheatsheets.cheatsheetCategory">
+ </category>
+ <view
+ name="%CHEAT_SHEETS"
+ icon="icons/full/cview16/cheatsheet_view.gif"
+ category="org.eclipse.ui.cheatsheets.cheatsheetCategory"
+ fastViewWidthRatio="0.5"
+ class="org.eclipse.ui.internal.cheatsheets.views.CheatSheetView"
+ id="org.eclipse.ui.cheatsheets.views.CheatSheetView">
+ </view>
+ </extension>
+ <extension
+ point="org.eclipse.ui.startup">
+ </extension>
+
+</plugin>
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IAbstractItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IAbstractItem.java
new file mode 100644
index 000000000..ee91e892c
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IAbstractItem.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets;
+
+/**
+ * <p>Implementations of IAbstractItem are returned from the ICheatSheetManager
+ * on a call to ICheatSheetManager.getItem(String itemID).</p>
+ *
+ * <p>These implementations can be checked to see if they implement IItem or
+ * IItemWithSubItems, and can be casted appropriately.</p>
+ *
+ *<p>If an IItem representing a step in a cheat sheet needs to be converted to an
+ * IItemWithSubItems that represents a step in the cheat sheet with sub steps,
+ * the IAbstractItem is passed to the ICheatSheetManager to convert it.</p>
+ */
+
+public interface IAbstractItem {
+ /**
+ * This method returns the id of the item.
+ * Items are recognized by their id.
+ * @return the id of the item
+ */
+ public String getID();
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetAction.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetAction.java
new file mode 100644
index 000000000..beca245ec
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetAction.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets;
+
+/**
+ * <p>This interface should be implemented by action classes used by the
+ * cheat sheet view, however it is not mandatory. If action classes implement this
+ * interface, parameters that have been set to be passed to this action
+ * by the cheat sheet are passed when the action is run. Furthermore, if this interface
+ * is implemented, a handle to the implementation of ICheatSheetManager is passed
+ * while running the action.</p>
+ * <p>The action that implements this interface is specified as the class for the class="com.org.xyz.XYZ" portion of the
+ * &lt;item&gt; tag for the cheat sheet content file to be run as the action for a step in the cheat sheet.
+ * </p>
+ */
+public interface ICheatSheetAction {
+
+ /**
+ * This method will be called when the action is run.
+ * Implementors of this method need not do anything with the
+ * parameters, however, this provides the CheatSheetManager object
+ * access, as well as accomodation for retrieving parameters set in the
+ * cheat sheet content file, or added dynamically during the cheat sheet's
+ * lifetime.
+ * @param params an array of strings
+ * @param csm the ICheatSheetManager used to access the items
+ */
+ public void run(String [] params, ICheatSheetManager csm);
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetItemExtensionElement.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetItemExtensionElement.java
new file mode 100644
index 000000000..228c73bee
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetItemExtensionElement.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Composite;
+import org.w3c.dom.Node;
+
+/**
+ * <p>This interface is used for extending steps in the cheat sheet.
+ * Each cheat sheet has a set of steps, and each of these steps potentially has a
+ * help link. The help link is displayed in the top right hand corner of the step in the
+ * cheat sheet. The cheatSheetItemExtension extension point may be used to add
+ * graphical items to an item to the left of the help icon for the step. </p>
+ *
+ *<p> To add graphical elements to the left of the help icon, the extension cheatSheetItemExtension is used.
+ * An extra attribute tag is added to the "item" element in the cheat sheet content file. This attribute's
+ * name corresponds to the itemAttribute name specified in the cheatSheetItemExtension.
+ * The class name in the extension must specify a class that implements ICheatSheetItemExtensionElement.</p>
+ *
+ *<p> When the cheat sheet content file is initially read, if an attribute is found for an Item element that is not known
+ * by the cheat sheets framework, the name of the attribute is checked against the itemAttribute name in
+ * all cheatSheetItemExtension extensions. If the attribute matches the name specified in an extension,
+ * an instance of the class specified in the extension is created. The attribute specified in the cheat sheet content
+ * file that is unknown to the cheat sheets framework is then passed to the instance of ICheatSheetItemExtensionElement
+ * using the handleAttribute(Node) method. It is up to the instance of ICheatSheetItemExtensionElement to handle
+ * parsing and storing of the attribute data from the cheat sheet content file.</p>
+ *
+ *<p> When the attribute has been handled by the created instance of the interface,
+ * the cheat sheet continues to load. At the moment when the cheat sheet framework begins to generate the
+ * graphical components for the steps in the cheat sheet, the createControl method is called on the
+ * ICheatSheetItemExtensionElement and the implementation of this interface may add graphical components to the
+ * Composite that is passed to it. </p>
+ *
+ */
+public interface ICheatSheetItemExtensionElement {
+
+ /**
+ * this method is called by the cheat sheet framework when the step is being grahically
+ * generated. Extra graphical elements may be added to this composite here and will be
+ * displayed to the left of the help icon for the step containing the unknown attribute in it's item
+ * element of the cheat sheet content file. The developer must set the background of their graphics
+ * to the color of the cheat sheet passed to them.
+ * @param c the composite to add graphical compontents to
+ * @param color the color to set the backgrount of the graphical component to to make it look integrated
+ */
+ public void createControl(Composite c, Color color);
+ /**
+ * This method is called by the cheat sheet framework when an attribute is found for an item element in the
+ * cheat sheet content file that the framework is unaware of, and hence does not know how to handle it.
+ * It is only called if the name of the attribute found matches the itemAttribute specified in the cheatSheetItemExtension
+ * extension. If it matches, an instance of the class specified in the extension implementing this
+ * ICheatSheetItemExtensionElement interface is created and this method is called with a Node
+ * containing the attribute from the cheat sheet content file.
+ * @param n is a node containing the attribute parsed from the cheat sheet content file. The attribute name
+ * matches the itemAttribute specified in the cheatSheetItemExtension
+ */
+ public void handleAttribute(Node n);
+ /**
+ * This method sets the name of the attribute to match if an unknown attribute name is found in the item
+ * tag of the cheat sheet content file during parsing.
+ * @param name the name of the attribute to match if an unknown attribute is found
+ */
+ public void setAttributeName(String name);
+ /**
+ * This method returns the name of the attribute to match in the cheat sheet content file.
+ * If an unknown attribute appears in the cheat sheet item tag, the name of that attribute will
+ * be compared to all the objects implementing ICheatSheetItemExtensionElement registered in the
+ * cheatsheetItemExtension extension points. If the attribute name matches, that object will handle the parsing
+ * of the attribute by a call to handleAttribute(Node n).
+ * @return the name of the attribute to match in the cheat sheet content file
+ */
+ public String getAttributeName();
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetManager.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetManager.java
new file mode 100644
index 000000000..519b38507
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ICheatSheetManager.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets;
+
+import java.util.Map;
+
+
+/**
+ *<p> While a cheat sheet is running, an implementation of ICheatSheetManager is passed to actions
+ * launched by the cheat sheet that implement ICheatSheetAction. A handle to an instance of an
+ * ICheatSheetManager is also available to in the events received by implementors of ICheatSheetViewListener
+ * and ICheatSheetItemListener. The implementaion of ICheatSheetManager is specific to each cheat sheet
+ * available to the user. It's data is reset when the cheat sheet is restarted and it's data is maintained until the cheat sheet
+ * is either re-started or completed. Each cheat sheet that is opened has a unique implementation of ICheatSheetManager.
+ * Data may be stored and retrieved from the implementation of ICheatSheetManager during the lifetime of a cheat sheet.
+ * The lifetime of a cheat sheet is from the moment the introductory item is kicked off until the cheat sheet is either completed or
+ * re-started. The implementation received by cheat sheet actions and listeners may also be used to access and
+ * change information for all of the steps and sub steps in the cheat sheet that are marked as being dynamic in the cheat sheet
+ * content file. </p>
+ *
+ * <p>The ICheatSheetManager interface provides access to the data representation of the steps
+ * in the cheat sheet view. Each step in the cheat sheet view is represented by an IItem.
+ * If a step in the view has sub items, this step is represented by an IItemWithSubItems.
+ * Both IItem and IItemWithSubItems have fields that can be changed.
+ * IItems and IItemWithSubItems can only be changed if the item in the cheat sheet content file
+ * is marked as a "dynamic" item, then that action can be changed on the fly. </p>
+ *
+ *<p> This ICheatSheetManager interface allows users to get a handle to any of the IItems or IItemWithSubItems
+ * in the running cheat sheet. It also allows the changing of a regular IItem into an IItemWithSubItems
+ * if a regular cheat sheet step needs to be changed into a step with sub steps.</p>
+ *
+ */
+public interface ICheatSheetManager {
+
+ /**
+ * This method returns the id of the current cheat sheet that is open.
+ * @return the id of the current cheat sheet
+ */
+ public String getCheatSheetID();
+ /**
+ * This method returns an IAbstractItem representing a step in the cheat sheet that corresponds to the specified id.
+ * The returned IAbstractItem could be either an IItem or an IItemWithSubItems and can be checked and cast to one of
+ * those interfaces for data access and manipulation.
+ * @param id the id of the item you want to access
+ * @return IAbstractItem, the item you want to access. <code>null</code> if there is no item with that id
+ */
+ public IAbstractItem getItem(String id);
+ /**
+ * This method adds string data to be stored by the ICheatSheetManager using the specified key.
+ * Any data added is persisted accross cheat sheet sessions.
+ * Data is stored until the cheat sheet is completed or restarted. Any data previously stored
+ * using the key specified will be replaced.
+ * @param key the key to store the data against
+ * @param data string data to be stored
+ */
+ public void addData(String key, String data);
+ /**
+ * This method returns data that has been stored with the specified key.
+ * @param key the key the data was stored against
+ * @return the string data that was stored against the key. Null if non existant key
+ */
+ public String getData(String key);
+ /**
+ * This method allows you to access a map of all all the data that has been stored in the
+ * ICheatSheetManager.
+ * @return a map of the data stored
+ */
+ public Map getData();
+
+ /**
+ * This method attempts to remove the data stored with the given key from the ICheatSheetManager.
+ * @param key the key that you want to remove the data for
+ * @return true if the data with the given key is removed, false if it was not or if the key is not found
+ */
+ public boolean removeData(String key);
+
+ /**
+ * This method allows you to convert the dynamic IItem that was returned from the call to getItem
+ * to an IItemWithSubItems. You only need to do this if there was no sub items specified
+ * for this item in the cheat sheet content xml file and you want to change it from a regular cheat sheet step
+ * to a step with sub steps. The item must be specified as dynamic in the cheat sheet content file.
+ * @param ai the abstract item from a call to getItem
+ * @return the IItem converted to an IItemWithSubItems so that you may add sub items to it. <code>null</code> if the argument cannot be converted
+ */
+// TODO: Need a way to convert it way as well!
+ public IItemWithSubItems convertToIItemWithSubItems(IAbstractItem ai);
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IItem.java
new file mode 100644
index 000000000..2c783c977
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IItem.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets;
+
+/**
+ * <p>Interface that represents a step with no sub steps in the cheat sheets view.
+ * An IItem can be retrieved from the <code>ICheatSheetManager</code> by calling getItem with the
+ * id of the step in the cheat sheet. You may use the methods from this interface
+ * to change and manipulate the buttons displayed for this step in the cheat sheet,
+ * as well as change/set the action class and plugin id for the action that will be run by the
+ * "click to perform" button. You may also manipulate or add string parameters that will
+ * be passed to the action for this step in the cheat sheet. To convert this step to allow the addition of sub steps
+ * to it in the cheat sheet, see <code>IItemWithSubItems</code> and <code>ICheatSheetManager</code>.</p>
+ *
+ *<p> Note: You may only use these methods to change the step if it has been marked as
+ * "dynamic" in the cheat sheet content file.</p>
+ */
+public interface IItem extends IAbstractItem {
+
+ /**
+ * This method returns the class specified to be run when the "click to perform" button is pressed for this item.
+ * @return the class name to be run for the item
+ */
+ public String getActionClass();
+ /**
+ * This method returns a comma separated string that represents the buttons displayed for this item in the cheat sheet.
+ * the code possibilities are :<li> 0 : perform action</li>
+ * <li>1 : Skip this task</li>
+ * <li>2 : click when done</li></p>
+ * <p>An example string to pass would be "0,1,2". When using this in the cheat sheet content file,
+ * the full attribute for the item would be this: actionphrase="0,1,2".</p>
+ * @return a comma separated string of button possibilities
+ */
+ public String getButtonCodes();
+ /**
+ * This method returns the string id of the plugin that contains the action class to be run.
+ * @return the id of the plugin that has the action class
+ */
+ public String getActionPluginID();
+ /**
+ * This method returns an array of parameters specified to be passed to the action class
+ * when it is run in the cheat sheet.
+ * @return an array of string parameters that are passed to the action class when it is run
+ */
+ public String[] getActionParams();
+ /**
+ * This method allows you to specify the class to be run when the perform button is pressed for this
+ * item in the cheat sheet.
+ * @param classname the class to be run by the item in the cheat sheet
+ */
+ public void setActionClass(String classname);
+ /**
+ * <p>This method accepts a comma separated string of the valid button codes,
+ * the code possibilities are : <li>0 : perform action</li>
+ * <li>1 : Skip this task</li>
+ * <li>2 : click when done</li>
+ * An example string to pass would be "0,1,2". When using this in the cheat sheet content file,
+ * the full attribute for the item would be this: actionphrase="0,1,2".</p>
+ * @param codes the comma separated string of codes
+ */
+ public void setButtonCodes(String codes);
+ /**
+ * This method allows to set the plugin id of the action to be run by this item in the cheat sheet.
+ * @param pluginId the id of the plugin containing the action class specified for this item
+ */
+ public void setActionPluginID(String pluginId);
+ /**
+ * This method allows you to set the string parameters to be passed to the action class on running it
+ * in the cheat sheet.
+ * @param params an array of strings that is passed to the action class on running the action
+ */
+ public void setActionParams(String[] params);
+
+} \ No newline at end of file
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IItemWithSubItems.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IItemWithSubItems.java
new file mode 100644
index 000000000..8e3a10893
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/IItemWithSubItems.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets;
+
+/**
+ *<p>This interface allows access to read and change information on a step that has sub steps in the cheat sheet.
+ *An IItemWithSubItems represents a step in the cheat sheet that has sub steps.
+ *An IItemWithSubItems is received from a call to getItem on ICheatSheetManager if the id passed
+ *to the getItem method matches the id of a step in the cheat sheet that has sub steps.</p>
+ *
+ *<p>In order to change or manipulate data on an <code>IItemWithSubItems</code> or an <code>IItem</code>
+ *it must be declared as being dynamic in the cheat sheet content file.
+ *If there is a step in the cheat sheet that does not have sub items but you want to add sub items to it,
+ *you must first get a handle to the IItem for that step using getItem on ICheatSheetManager. After you have
+ *the IItem representing the step you want to have sub items, you must call convertToIItemWithSubItems
+ *on ICheatSheetManager with this IItem. This IItem will be replaced by an IItemWithSubItems, and the cheat sheet
+ *will display any sub items added to it when that step is activated in the cheat sheet.
+ *You will have an IItemWithSubItems returned that can have ISubItems added to it, which will turn the
+ *step in the cheat sheet into a step with sub steps.</p>
+ *
+ * <p>Note: You may only use these methods to change the step if it has been marked as
+ * "dynamic" in the cheat sheet content file.</p>
+ */
+
+public interface IItemWithSubItems extends IAbstractItem {
+
+ /**
+ * This method allows to set the sub items that will be shown for this item in the cheat sheet.
+ * @param subitems an array of ISubItem's
+ * @throws IllegalArgumentException if the array is not an array of ISubItem's
+ */
+ public void addSubItems(ISubItem[] subitems) throws IllegalArgumentException; //Include the sub item id that could not be added.
+ /**
+ * This method adds a sub item to this item in the cheat sheet.
+ * @param sub the ISubItem to add.
+ * @return true if it was added, false if it was not added
+ * @throws IllegalArgumentException if the sub item passed is not an ISubItem
+ */
+ public boolean addSubItem(ISubItem sub) throws IllegalArgumentException;
+ /**
+ * This method is similar to addSubItem(ISubItem) but you may specify the index you want
+ * to add it to the list of sub items to be shown in the cheat sheet for this item.
+ * @param sub the ISubItem to add
+ * @param index the index where the ISubItem will be placed or inserted
+ * @return true if it was added, false if not
+ * @throws IllegalArgumentException if the sub item passed is not an ISubItem
+ * @throws IndexOutOfBoundsException if the index specified is out of bounds
+ */
+ public boolean addSubItem(ISubItem sub, int index) throws IllegalArgumentException, IndexOutOfBoundsException;
+/**
+ * This method returns an array of the sub items specified for this item in the cheat sheet.
+ * @return an array of the ISubItems
+ */
+ public ISubItem[] getSubItems();
+ /**
+ * This method returns the sub item for this item from the specified index in the list of sub items for this item.
+ * @param index of the sub item to retrieve
+ * @return the ISubItem
+ * @throws IndexOutOfBoundsException if the sub item at the index does not exist
+ */
+ public ISubItem getSubItem(int index) throws IndexOutOfBoundsException;
+ /**
+ * This method removes the ISubItem specified from the list of sub items to show for this item in the cheat sheet.
+ * @param item the ISubItem to remove.
+ * @return true if removed, false if it either does not exist or could not be removed
+ */
+ public boolean removeSubItem(ISubItem item);
+ /**
+ * This method removes the ISubItem at the specified index from the list of sub items to show for this item in the cheat sheet.
+ * @param index of the sub item to remove
+ * @return true if removed, false if not
+ * @throws IndexOutOfBoundsException if the index is out of bounds
+ */
+ public boolean removeSubItem(int index) throws IndexOutOfBoundsException;
+ /**
+ * This method removes all of the sub items for this item.
+ */
+ public void removeSubItems();
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ISubItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ISubItem.java
new file mode 100644
index 000000000..c0c365e57
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/ISubItem.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets;
+
+/**
+ * <p>An ISubItem represents a sub step of a step in the cheat sheet that has sub steps.
+ * A step in the cheat sheet that contains sub steps is represented by an IItemWithSubItems.
+ * By calling getItem on ICheatSheetManager and passing the id of a step in the cheat sheet
+ * with sub steps, you get an IAbstractItem that may be casted to an IItemWithSubItems. </p>
+ *
+ * <p>This IItemWithSubItems can be used to access info about the sub steps for that step in the cheat sheet.
+ * ISubItem can be implemented to add sub steps to a step in the cheat sheet.</p>
+ *
+ * <p>Each sub step in the cheat sheet has a label, as well as the same buttons and actions that a retular
+ * step in the cheat sheet (represented by IItem) has.</p>
+ *
+ */
+public interface ISubItem extends IItem {
+
+ /**
+ * This method sets the label that will be shown for the sub item.
+ * @param label the label to be shown
+ */
+ public void setLabel(String label);
+ /**
+ * This method returns the label to be shown for the sub item.
+ * @return the label
+ */
+ public String getLabel();
+ /**
+ * This method sets the id of this sub item. This id is used to access this sub item
+ * later and must be unique from the id of the other sub items added to the same base item.
+ * @param id the unique id to assign to this sub item
+ */
+ public void setID(String id);
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/LaunchCheatSheetAction.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/LaunchCheatSheetAction.java
new file mode 100644
index 000000000..0a59f2112
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/LaunchCheatSheetAction.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.*;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.registry.*;
+import org.eclipse.ui.internal.cheatsheets.views.CheatSheetView;
+
+/**
+ * <p>This action class can be used to launch a cheat sheet in the cheat sheets view.
+ * A cheat sheet may be launched using it's id, or by passing a URL of the cheat sheet content file
+ * location.</p>
+ */
+public class LaunchCheatSheetAction extends Action {
+ CheatSheetElement element;
+ URL csURL;
+
+
+ public LaunchCheatSheetAction(CheatSheetElement element) {
+ this.element = element;
+ }
+
+ /**
+ * Constructor. The id of passed to this constructor must match the id
+ * of a cheat sheet specified in a client's implementation of the cheatsheetContent extension point.
+ * @param id the id of the cheat sheet to launch
+ */
+ public LaunchCheatSheetAction(String id) {
+ this.element = CheatSheetRegistryReader.getInstance().findCheatSheet(id);
+ }
+
+ /**
+ * This constructor can be used to launch a cheat sheet that is not specified by a plugin
+ * implementing the cheatsheetContent extension point.
+ * @param url the url of the cheat sheet content file location.
+ * @param name the name to give this cheat sheet.
+ * @param id the unique id to assign this cheat sheet.
+ */
+ public LaunchCheatSheetAction(URL url, String name, String id){
+ csURL = url;
+ if(name == null)
+ name = ""; //$NON-NLS-1$
+ element = new CheatSheetElement(name);
+ if(id == null)
+ id = ""; //$NON-NLS-1$
+ element.setID(id);
+
+ element.setContentFile(url.toString());
+ }
+
+ /**
+ * Method called when this action is run.
+ * This action will try to launch the cheat sheets view and populate it with the content
+ * specified either in the URL or the content file specified in the cheatsheetContent extension point
+ * for the cheat sheet with the id passed to this action.
+ */
+ public void run() {
+
+ if (element == null) {
+ return;
+ }
+
+ IWorkbench myworkbench = CheatSheetPlugin.getPlugin().getWorkbench();
+ IWorkbenchWindow window = myworkbench.getActiveWorkbenchWindow();
+
+ IWorkbenchPage page = window.getActivePage();
+ WorkbenchPage realpage = (WorkbenchPage) page;
+
+ CheatSheetView newview = (CheatSheetView) page.findView(ICheatSheetResource.CHEAT_SHEET_VIEW_ID);
+ if (newview != null) {
+ newview.setContent(element);
+ page.bringToTop(newview);
+ } else {
+ try {
+//TODO: Port problem, update the following to open the view correctly.
+// IViewReference viewref = realpage.getViewFactory().createView(ICheatSheetResource.CHEAT_SHEET_VIEW_ID);
+// CheatSheetView view = (CheatSheetView) viewref.getPart(true);
+ CheatSheetView view = (CheatSheetView)realpage.showView(ICheatSheetResource.CHEAT_SHEET_VIEW_ID);
+// IViewReference viewref = realpage.findViewReference(ICheatSheetResource.CHEAT_SHEET_VIEW_ID);
+// realpage.addFastView(viewref);
+ page.activate(view);
+ view.setContent(element);
+ } catch (PartInitException pie) {
+ String message = CheatSheetPlugin.getResourceString(ICheatSheetResource.LAUNCH_SHEET_ERROR);
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, message, pie);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ org.eclipse.jface.dialogs.ErrorDialog.openError(new Shell(), CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEET_ERROR_OPENING), null, pie.getStatus());
+ return;
+ }
+ }
+
+ // Update most recently used cheat sheets list.
+ CheatSheetPlugin.getPlugin().getCheatSheetHistory().add(element);
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/OpenCheatSheetFromHelpAction.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/OpenCheatSheetFromHelpAction.java
new file mode 100644
index 000000000..6be049273
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/OpenCheatSheetFromHelpAction.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets;
+
+import org.eclipse.help.ILiveHelpAction;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * <p>This action class can be used to launch a cheat sheet from the eclipse help system
+ * using a live help link. To use this action, the initialization string must correspond to the id of a
+ * cheat sheet that has been declared using the cheatsheetContent extension point.
+ * See ILiveHelpAction for further details on how to run an action from eclipse help pages. </p>
+ */
+public class OpenCheatSheetFromHelpAction implements ILiveHelpAction {
+ private String cheatsheetID;
+
+ /**
+ * Constructor for OpenCheatSheetFromHelpAction.
+ */
+ public OpenCheatSheetFromHelpAction() {
+ super();
+ }
+
+ /**
+ * This method is called by the eclipse framework. The initialization string must be the id of a
+ * registered cheat sheet in order for the action to work.
+ * @see org.eclipse.help.ILiveHelpAction#setInitializationString(String)
+ */
+ public void setInitializationString(String data) {
+ cheatsheetID = data;
+ }
+
+ /**
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+ // Active help does not run on the UI thread, so we must use syncExec
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ new LaunchCheatSheetAction(cheatsheetID).run(); //$NON-NLS-1$
+ }
+ });
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetEvent.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetEvent.java
new file mode 100644
index 000000000..2a311b708
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetEvent.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets.events;
+
+import org.eclipse.ui.cheatsheets.ICheatSheetManager;
+
+/**
+ * <p>This is the interface for a cheat sheet event. Cheat sheet item and view events
+ * are fired by the cheat sheets view to any registered listener classes implementing
+ * either ICheatSheetItemListener or ICheatSheetViewListener interfaces. The event
+ * type may be accessed, as well as the id of the cheat sheet that was open when the
+ * event was fired. A handle to the ICheatSheetManager is available from cheat sheet events.</p>
+ */
+public interface ICheatSheetEvent {
+
+ /**
+ * This method returns an integer that corresponds to an event type.
+ * See ICheatSheetviewEvent and ICheatSheetItemEvent for the integer codes of event types.
+ * @return the event code
+ */
+ public int getCheatSheetEventType();
+ /**
+ * This method returns the id of the cheat sheet that generated the event.
+ * @return the id of the cheat sheet that fired the event
+ */
+ public String getCheatSheetID();
+ /**
+ * This method returns a handle to the implementation of ICheatSheetManager.
+ * @return a reference to the ICheatSheetManager
+ */
+ public ICheatSheetManager getCheatSheetManager();
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetItemEvent.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetItemEvent.java
new file mode 100644
index 000000000..f9c455ce1
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetItemEvent.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets.events;
+
+/**
+ * ICheatSheetItemEvent is the type of object that is received by a registered ICheatSheetItemListener.
+ * The information in this type of object can be used to determine what item or sub item an event was
+ * fired from.
+ */
+public interface ICheatSheetItemEvent extends ICheatSheetEvent {
+ /**
+ * an event type notifying of an item having been activated.
+ */
+ public static final int ITEM_ACTIVATED = 0;
+ /**
+ * an event type notifying of an item or sub item that had an action class run.
+ */
+ public static final int ITEM_PERFORMED = 1;
+ /**
+ * an event type notifying of an item or sub item having been skipped.
+ */
+ public static final int ITEM_SKIPPED = 2;
+ /**
+ * an event type notifying of an item or sub item having been completed.
+ */
+ public static final int ITEM_COMPLETED = 3;
+ /**
+ * an event type notifying of an item having been deactivated.
+ */
+
+ public static final int ITEM_DEACTIVATED = 4;
+
+ /**
+ * This method returns the id of the sub item associated with this event.
+ * If there is no sub item associated with this item event, then this method will return null.
+ * @return the id of the sub item associated with this event. Null if no sub item is associated and it is just an item
+ * event.
+ */
+ public String getCheatSheetSubItemID();
+ /**
+ * This method returns the id of the item that is associated with this item event. If it is a sub item event,
+ * it will return the id of the item that contains the sub item that had an event fired.
+ * @return the id of the item associated with this item event.
+ */
+ public String getCheatSheetItemID();
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetItemListener.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetItemListener.java
new file mode 100644
index 000000000..20a0027a4
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetItemListener.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets.events;
+
+
+/**
+ * <p>This interface should be implemented if you need to be notified of item events for the cheat sheets.
+ * Sample item events that are fired include the performing of an action for an item and the notification when an item
+ * becomes the active item that is highlited in the cheat sheets view. Items are identified by their id's as specified in the
+ * cheat sheet content file describing the steps in the cheat sheet. A listener that implements this ICheatSheetItemListener
+ * must register itself using the cheat sheet extension point. Here is a sample of a view listener extension point implementation:<br>
+ *&lt;extension point="org.eclipse.ui.cheatsheets.cheatSheetContent"&gt;<br>
+ * &lt;cheatSheetListener<br>
+* id="org.xyz.com.ItemListener"<br>
+* targetCheatSheetId="org.xyz.com.cheatSheetId"<br>
+* class="org.xyz.com.ItemListener"<br>
+* classPluginId="org.xyz.com.Plugin"&gt;<br>
+* &lt;/cheatSheetListener&gt; <br>
+* &lt;/extension&gt; <br>
+ * </p>
+ */
+
+public interface ICheatSheetItemListener extends ICheatSheetListener {
+
+ /**
+ * This method is triggered when the view has an item that becomes the active item in the view.
+ * When an item becomes the active item it is the step that is highlighted in the view.
+ * @param e the item activated event fired
+ */
+ public void itemActivated(ICheatSheetItemEvent e);
+ /**
+ * This method is triggered when an item has it's action called and the action completes.
+ * If the action for an item spawns a wizard, the item will only be completed if the wizard is finished, not cancelled.
+ * @param e the item performed event fired
+ */
+ public void itemPerformed(ICheatSheetItemEvent e);
+ /**
+ * This method is triggered after an item in the cheat sheet that has it's skip button pushed
+ * and it is marked as skipped.
+ * @param e the item skipped event fired
+ */
+ public void itemSkipped(ICheatSheetItemEvent e);
+ /**
+ * This method is triggered when an item is marked as completed in the view either by having it's
+ * action class called and completed, or by pressing the click when done button.
+ * @param e the item completed event fired
+ */
+ public void itemCompleted(ICheatSheetItemEvent e);
+ /**
+ * This method is called after an item is no longer the active item.
+ * This method is notified when an item is either completed or was skipped and
+ * the next step in the cheat sheet becomes the active step.
+ * @param e the item deactivated event fired
+ */
+ public void itemDeactivated(ICheatSheetItemEvent e);
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetListener.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetListener.java
new file mode 100644
index 000000000..8cda8af71
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetListener.java
@@ -0,0 +1,18 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets.events;
+
+/**
+ * <p>Base interface in place for future use.</p>
+ * <p>Listener classes that implement the ICheatSheetItemListener or ICheatSheetViewListener interfaces
+ * must be registered in the plugin.xml file of the implementing plugin using the cheatsheetContent extension
+ * point with a listener tag. See <code>ICheatSheetViewListener</code> and <code>ICheatSheetItemListener</code>.</p>
+ */
+public interface ICheatSheetListener {
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetViewEvent.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetViewEvent.java
new file mode 100644
index 000000000..ac2639624
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetViewEvent.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets.events;
+
+/**
+ * ICheatSheetViewEvent is an interface for view events. View events are fired
+ * by the cheat sheets view when certain item actions occur in the view.
+ * For example, events are fired whenever the cheat sheets view is opened or closed.
+ * Listeners implementing ICheatSheetViewListener are notified of these events.
+ */
+public interface ICheatSheetViewEvent extends ICheatSheetEvent {
+ /**
+ * an event type notifying that the cheat sheets view was opened.
+ */
+ public static final int CHEATSHEET_OPENED = 0;
+ /**
+ * an event type notifying that the cheat sheets view was closed.
+ */
+ public static final int CHEATSHEET_CLOSED = 1;
+ /**
+ * an event type notifying that the cheat sheet was started.
+ */
+ public static final int CHEATSHEET_STARTED = 2;
+ /**
+ * an event type notifying that the cheat sheet was restarted.
+ */
+ public static final int CHEATSHEET_RESTARTED = 3;
+ /**
+ * an event type notifying that the cheat sheet has reached the end and all items were either completed or skipped.
+ */
+ public static final int CHEATSHEET_END_REACHED = 4;
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetViewListener.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetViewListener.java
new file mode 100644
index 000000000..d0e017afa
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/ICheatSheetViewListener.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.cheatsheets.events;
+
+/**
+ * <p>This interface should be implemented if you need to be notified of view events for the cheat sheets view.
+ * Sample view events that are fired include the opening and closing events of the view. A listener that implements this
+ * ICheatSheetViewListener must register itself using the cheat sheet extension point. Here is a sample of a view
+ * listener extension point implementation: <br>
+ *&lt;extension point="org.eclipse.ui.cheatsheets.cheatSheetContent"&gt;<br>
+ * &lt;cheatSheetListener<br>
+* id="org.xyz.com.Listener"<br>
+* targetCheatSheetId="org.xyz.com.cheatSheetId"<br>
+* class="org.xyz.com.Listener"<br>
+* classPluginId="org.xyz.com.Plugin"&gt;<br>
+* &lt;/cheatSheetListener&gt;<br>
+* &lt;extension&gt; <br>
+ * </p>
+ */
+public interface ICheatSheetViewListener extends ICheatSheetListener {
+
+ /**
+ * This method is triggered when a cheat sheet is selected and the cheat sheets view is opened.
+ * @param e the cheat sheet view opened event fired
+ */
+ public void cheatSheetOpened(ICheatSheetViewEvent e);
+ /**
+ * This method is triggered when the cheat sheet view is closed.
+ * @param e the cheat sheet view closed event fired
+ */
+ public void cheatSheetClosed(ICheatSheetViewEvent e);
+ /**
+ * This method is called when a cheat sheet is started by the intro item's button having been pushed.
+ * @param e the cheat sheet started event
+ *
+ */
+ public void cheatSheetStarted(ICheatSheetViewEvent e);
+ /**
+ * This method is triggered when the cheat sheet has been started and the intro item is
+ * clicked again. The cheat sheet is restarted when the intro is clicked after the cheat sheet
+ * has already been started.
+ * @param e the cheat sheet restarted event fired
+ */
+ public void cheatSheetRestarted(ICheatSheetViewEvent e);
+ /**
+ * This method is triggered when the cheat sheet is finished. The sheet may still be open,
+ * but the last specified item has been either marked as completed or skipped.
+ * @param e the cheat sheet end reached event fired
+ */
+ public void cheatSheetEndReached(ICheatSheetViewEvent e);
+
+}
+ \ No newline at end of file
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/package.html b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/package.html
new file mode 100644
index 000000000..5cea659c3
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/events/package.html
@@ -0,0 +1,40 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides support for listeners that are notified of cheat sheet events.
+<h2>
+Package Specification</h2>
+This package specifies the API for cheat sheet listeners. Classes that implement the ICheatSheetItemListener and
+ICheatSheetViewListener interfaces can be notified of cheat sheet item and view events as they occur. Sample view events
+that are fired to these listeners include view opening and closing events, and sample item events are item skipped and item completion events.
+Classes that implement at least one of these interfaces must be registered using the cheatsheetContent extension point
+with a listener tag in the Client's plugin.xml file. Listeners used will be notified of events from the cheat sheets view as
+they occur, and can access the ICheatSheetManager implementation from the event received. Events are received
+by these listeners in the form of an implementation of ICheatSheetItemEvent or ICheatSheetViewEvent.
+These event objects will contain information about the event and provide a handle to the implementation of ICheatSheetManager
+for the cheat sheet..
+<p>
+Here is a sample snippet from a plugin.xml file that registers the com.org.xyz.ItemListener class that implements
+ICheatSheetItemListener to listen for item events from the cheat sheet with the id com.org.xyz.cheatsheet.
+The com.org.xyz.ItemListener class resides in the plugin with id com.org.xyz.plugin.
+</p>
+<p>
+&lt;extension point="org.eclipse.ui.cheatsheets.cheatSheetContent"&gt;<br>
+&nbsp;&nbsp;&nbsp;&lt;cheatSheetListener<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id="org.eclipse.xyz.cheatsheet.listener"<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;targetCheatSheetId="com.org.xyz.cheatsheet"<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class="com.org.xyz.ItemListener"<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;classPluginId="com.org.xyz.plugin"&gt;<br>
+ &nbsp;&nbsp;&nbsp;&lt;/cheatSheetListener&gt;<br>
+&lt;/extension&gt<br>
+</p>
+</p>
+Clients writing plug-ins that want to be notified of cheat sheet item and view events to integrate their code with their cheat sheets will be interested in the types provided by this package.
+Useful api's for tracking user progress through cheat sheets and view open and closing events.
+</p>
+</body>
+</html>
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/package.html b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/package.html
new file mode 100644
index 000000000..17323a3eb
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/cheatsheets/package.html
@@ -0,0 +1,36 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides support for plug-ins to dynamically change cheat sheet content and track cheat sheet data, also provides actions to launch the cheat sheets view.
+<h2>
+Package Specification</h2>
+This package specifies the API related to modifying and manipulating the contents of a cheat sheet.
+This includes adding and removing sub items from a cheat sheet, changing actions launched by an item or sub item,
+delayed setting the action to be run by an item or a sub item, changing the buttons available to a user
+for an item or sub item in the cheat sheet, and so on.
+<p>This package has several useful interfaces such as ICheatSheetManager,
+which allows the storage and retrieval of information related to a particular cheat sheet.
+Each cheat sheet that is opened has an implementation of ICheatSheetManager that manages data associated
+with the cheat sheet. Data may be stored and retrieved from the implementation of ICheatSheetManager, and
+any data stored in it is persisted for the cheat sheet until it is either completed or restarted. Using the ICheatSheetManager
+you can modify step information for a cheat sheet on the fly. Furthermore, you can add and remove sub steps for a cheat sheet
+step.
+</p><p> You can get a handle to the ICheatSheetManager either by using actions for your cheat sheet steps that implement
+ICheatSheetAction interface, or by registering listeners using ICheatSheetItemListener or ICheatSheetViewListener interfaces.
+Actions that implement ICheatSheetAction get a handle to the ICheatSheetManager when the action is run.
+The listeners that are registered using the cheatsheetContent extension point with a listener tag receive a handle to the
+implementaion of the ICheatSheetManager for the active cheat sheet from the event objects it receives.
+</p>
+<p>There are two action classes available
+in this package that may be helpful for launching the cheat sheets view. One to launch the view using a regular action,
+and one to launch the cheat sheets view from the help contents.
+</p>
+<p>
+Clients writing plug-ins that integrate cheat sheet steps with their plugin code will be interested in the types provided by this package.
+</p>
+</body>
+</html>
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/CheatSheetHistory.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/CheatSheetHistory.java
new file mode 100644
index 000000000..10d45e429
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/CheatSheetHistory.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets;
+
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.ui.*;
+
+import org.eclipse.ui.internal.cheatsheets.registry.*;
+
+/**
+ * This is used to store the most recently used (MRU) list
+ * of cheatsheet for the entire workbench.
+ */
+public class CheatSheetHistory {
+
+ private static final int DEFAULT_DEPTH = 5;
+
+ private ArrayList history;
+ private CheatSheetRegistryReader reg;
+ private ListenerList listeners = new ListenerList();
+
+ public CheatSheetHistory(CheatSheetRegistryReader reg) {
+ this.history = new ArrayList(DEFAULT_DEPTH);
+ this.reg = reg;
+ }
+
+ public void addListener(IPropertyListener l) {
+ listeners.add(l);
+ }
+
+ public void removeListener(IPropertyListener l) {
+ listeners.remove(l);
+ }
+
+ private void fireChange() {
+ Object[] array = listeners.getListeners();
+ for (int i = 0; i < array.length; i++) {
+ IPropertyListener element = (IPropertyListener)array[i];
+ element.propertyChanged(this, 0);
+ }
+ }
+
+ public IStatus restoreState(IMemento memento) {
+ IMemento [] children = memento.getChildren("element"); //$NON-NLS-1$
+ for (int i = 0; i < children.length && i < DEFAULT_DEPTH; i++) {
+ CheatSheetElement element =
+ reg.findCheatSheet(children[i].getID());
+ if (element != null)
+ history.add(element);
+ }
+ return new Status(IStatus.OK,ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID,0,"",null); //$NON-NLS-1$
+ }
+
+ public IStatus saveState(IMemento memento) {
+ Iterator iter = history.iterator();
+ while (iter.hasNext()) {
+ CheatSheetElement element = (CheatSheetElement)iter.next();
+ memento.createChild("element", element.getID()); //$NON-NLS-1$
+ }
+ return new Status(IStatus.OK,ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID,0,"",null); //$NON-NLS-1$
+ }
+
+ public void add(String id) {
+ CheatSheetElement element = reg.findCheatSheet(id);
+ if (element != null)
+ add(element);
+ }
+
+ public void add(CheatSheetElement element) {
+ // Avoid duplicates
+ if (history.contains(element))
+ return;
+
+ // If the shortcut list will be too long, remove oldest ones
+ int size = history.size();
+ int preferredSize = DEFAULT_DEPTH;
+ while (size >= preferredSize) {
+ size--;
+ history.remove(size);
+ }
+
+ // Insert at top as most recent
+ history.add(0, element);
+ fireChange();
+ }
+
+ public void refreshFromRegistry() {
+ boolean change = false;
+
+ Iterator iter = history.iterator();
+ while (iter.hasNext()) {
+ CheatSheetElement element = (CheatSheetElement)iter.next();
+ if (reg.findCheatSheet(element.getID()) == null) {
+ iter.remove();
+ change = true;
+ }
+ }
+
+ if (change)
+ fireChange();
+ }
+
+ /**
+ * Copy the requested number of items from the history into
+ * the destination list at the given index.
+ *
+ * @param dest destination list to contain the items
+ * @param destStart index in destination list to start copying items at
+ * @param count number of items to copy from history
+ * @return the number of items actually copied
+ */
+ public int copyItems(List dest, int destStart, int count) {
+ int itemCount = count;
+ if (itemCount > history.size())
+ itemCount = history.size();
+
+ for (int i = 0; i < itemCount; i++)
+ dest.add(destStart + i, history.get(i));
+
+ return itemCount;
+ }
+}
+
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/CheatSheetPlugin.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/CheatSheetPlugin.java
new file mode 100644
index 000000000..ffa4d6c99
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/CheatSheetPlugin.java
@@ -0,0 +1,359 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets;
+
+import java.io.*;
+import java.text.MessageFormat;
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.ui.*;
+import org.eclipse.ui.cheatsheets.events.ICheatSheetListener;
+import org.eclipse.ui.internal.WorkbenchWindow;
+import org.eclipse.ui.internal.cheatsheets.actions.CheatSheetMenu;
+import org.eclipse.ui.internal.cheatsheets.registry.*;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class for cheat sheets.
+ */
+
+public class CheatSheetPlugin extends AbstractUIPlugin implements IStartup, ICheatSheetResource {
+
+ //The shared instance of this plugin.
+ private static CheatSheetPlugin plugin;
+
+ //Resource bundle.
+ private ResourceBundle resourceBundle;
+ private CheatSheetHistory history;
+ private ArrayList cheatsheetListeners;
+
+ private static final String DEFAULT_CHEATSHEET_STATE_FILENAME = "cheatsheet.xml"; //$NON-NLS-1$
+ private static final String MEMENTO_TAG_CHEATSHEET = "cheatsheet"; //$NON-NLS-1$
+ private static final String MEMENTO_TAG_VERSION = "version"; //$NON-NLS-1$
+ private static final String VERSION_STRING[] = { "0.0", "5.0.0" }; //$NON-NLS-1$ //$NON-NLS-2$
+ private static final String MEMENTO_TAG_CHEATSHEET_HISTORY = "cheatsheetHistory"; //$NON-NLS-1$
+
+/*
+ public CheatSheetPlugin() {
+ System.out.println("Here"); //$NON-NLS-1$
+ }
+
+*/
+
+ /**
+ * The constructor.
+ */
+ public CheatSheetPlugin(IPluginDescriptor descriptor) {
+ super(descriptor);
+ plugin = this;
+
+ //we have this in the code, but resourceBundle is never used.
+ //we are leaving it in for the future in case it is needed.
+ try {
+ resourceBundle = ResourceBundle.getBundle(ICheatSheetResource.CHEAT_SHEET_RESOURCE_ID);
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+
+ }
+
+ /**
+ * Adds the Cheat Sheet menu items to the help menu of the list of workbench windows.
+ *
+ * @param windows the workbench windows that need to have there help menu updated
+ */
+ private void addCheatSheetMenu(IWorkbenchWindow[] windows) {
+ if (windows == null) {
+ return;
+ }
+
+ CheatSheetCollectionElement collection = (CheatSheetCollectionElement) CheatSheetRegistryReader.getInstance().getCheatSheets();
+ if (collection.getCheatSheets().length <= 0 && collection.getChildren().length <= 0) {
+ return;
+ }
+
+ cheatsheetListeners = CheatSheetRegistryReader.getInstance().getCheatsheetListenerElements();
+
+ WindowLoop : for (int windowCount = 0; windowCount < windows.length; ++windowCount) {
+
+ MenuManager cheatmanager = new MenuManager(getResourceString(ICheatSheetResource.CHEAT_SHEETS), ICheatSheetResource.CHEAT_SHEET_MENU_ID);
+
+ WorkbenchWindow realwindow = (WorkbenchWindow) windows[windowCount];
+ IMenuManager menubar = realwindow.getMenuBarManager();
+ IContributionItem[] myitems = menubar.getItems();
+
+ for (int i = 0; i < myitems.length; i++) {
+ //System.out.println("The id of the item is: "+myitems[i].getId());
+ if (myitems[i].getId() != null && myitems[i].getId().equals(IWorkbenchActionConstants.M_HELP)) {
+ IContributionItem helpitem = myitems[i];
+ IContributionItem cheatsheetMenu = ((IMenuManager) helpitem).find(ICheatSheetResource.CHEAT_SHEET_MENU_ID);
+ if (cheatsheetMenu == null) {
+ ((IMenuManager) helpitem).insertBefore(IWorkbenchActionConstants.HELP_START, cheatmanager);
+ } else {
+ break WindowLoop;
+ }
+ break;
+ }
+ }
+
+ CheatSheetMenu cheatsheetMenuMenuItem = new CheatSheetMenu();
+ cheatmanager.add(cheatsheetMenuMenuItem);
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.IStartup#earlyStartup()
+ */
+ public void earlyStartup() {
+ //get a handle to the help menu in the workbench. It is a MenuManager type.
+ final IWorkbench mybench = getPlugin().getWorkbench();
+
+ IWorkbenchWindow[] windows = mybench.getWorkbenchWindows();
+ addCheatSheetMenu(windows);
+
+ mybench.addWindowListener(new IWindowListener() {
+ public void windowActivated(IWorkbenchWindow window) {
+ }
+ public void windowDeactivated(IWorkbenchWindow window) {
+ }
+ public void windowClosed(IWorkbenchWindow window) {
+ }
+ public void windowOpened(IWorkbenchWindow window) {
+ IWorkbenchWindow[] openedWindow = { mybench.getActiveWorkbenchWindow()};
+ addCheatSheetMenu(openedWindow);
+ }
+ });
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle,
+ * or 'key' if not found.
+ */
+ public static String getResourceString(String key) {
+ try {
+ if(plugin != null) {
+ return plugin.getDescriptor().getResourceString(key);
+ }
+ } catch (MissingResourceException e) {
+ }
+ return key;
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static CheatSheetPlugin getPlugin() {
+ return plugin;
+ }
+
+ /**
+ * Returns the formatted message for the given key in
+ * the resource bundle.
+ *
+ * @param key the resource name
+ * @param args the message arguments
+ * @return the string
+ */
+ public static String formatResourceString(String key, Object[] args) {
+ return MessageFormat.format(getResourceString(key), args);
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+
+ /**
+ * Returns the CheatSheetHistory,
+ */
+ public CheatSheetHistory getCheatSheetHistory() {
+ if (history == null) {
+ history = new CheatSheetHistory(CheatSheetRegistryReader.getInstance());
+ restoreCheatSheetHistory();
+ }
+ return history;
+ }
+
+ /**
+ * Answer the workbench state file.
+ */
+ private File getCheatSheetStateFile() {
+ IPath path = CheatSheetPlugin.getPlugin().getStateLocation();
+ path = path.append(DEFAULT_CHEATSHEET_STATE_FILENAME);
+ return path.toFile();
+ }
+
+ /**
+ * Restores the state of the previously saved cheatsheet history
+ */
+ private void restoreCheatSheetHistory() {
+ Platform.run(new SafeRunnable() { //$NON-NLS-1$
+ public void run() {
+ InputStreamReader reader = null;
+
+ try {
+ // Read the cheatsheet state file.
+ final File stateFile = getCheatSheetStateFile();
+
+ FileInputStream input = new FileInputStream(stateFile);
+ reader = new InputStreamReader(input, "utf-8"); //$NON-NLS-1$
+ IMemento memento = XMLMemento.createReadRoot(reader);
+
+ IMemento childMem = memento.getChild(MEMENTO_TAG_CHEATSHEET_HISTORY);
+ if (childMem != null) {
+ history.restoreState(childMem);
+ }
+ } catch (FileNotFoundException e) {
+ // Do nothing, the file will not exist the first time the workbench in used.
+ } catch (Exception e) {
+ String message = getResourceString(ICheatSheetResource.ERROR_READING_STATE_FILE);
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, message, e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ } finally {
+ try {
+ if (reader != null)
+ reader.close();
+ } catch (IOException e) {
+ // Not much to do, just catch the exception and keep going.
+ String message = getResourceString(ICheatSheetResource.ERROR_READING_STATE_FILE);
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, message, e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ }
+ }
+ }
+ public void handleException(Throwable e) {
+ String message = getResourceString(ICheatSheetResource.ERROR_READING_STATE_FILE);
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, message, e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ }
+ });
+ }
+
+ /**
+ * Saves the current cheatsheet history so it can be restored later on
+ */
+ private void saveCheatSheetHistory() {
+ Platform.run(new SafeRunnable() {
+ public void run() {
+ XMLMemento memento = XMLMemento.createWriteRoot(MEMENTO_TAG_CHEATSHEET);
+
+ // Save the version number.
+ memento.putString(MEMENTO_TAG_VERSION, VERSION_STRING[1]);
+
+ // Save perspective history.
+ getCheatSheetHistory().saveState(memento.createChild(MEMENTO_TAG_CHEATSHEET_HISTORY)); //$NON-NLS-1$
+
+ // Save the IMemento to a file.
+ File stateFile = getCheatSheetStateFile();
+ OutputStreamWriter writer = null;
+ try {
+ FileOutputStream stream = new FileOutputStream(stateFile);
+ writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$
+ memento.save(writer);
+ } catch (IOException e) {
+ stateFile.delete();
+ String message = getResourceString(ICheatSheetResource.ERROR_WRITING_STATE_FILE);
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, message, e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ } finally {
+ try {
+ if (writer != null)
+ writer.close();
+ } catch (IOException e) {
+ String message = getResourceString(ICheatSheetResource.ERROR_WRITING_STATE_FILE);
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, message, e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ }
+ }
+ }
+ public void handleException(Throwable e) {
+ String message = getResourceString(ICheatSheetResource.ERROR_WRITING_STATE_FILE);
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, message, e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ }
+ });
+ }
+
+ /**
+ * @see org.eclipse.core.runtime.Plugin#startup()
+ */
+ public void startup() throws CoreException {
+ // initialize the MRU history
+ getCheatSheetHistory();
+ }
+
+ /**
+ * @see org.eclipse.core.runtime.Plugin#shutdown()
+ */
+ public void shutdown() throws CoreException {
+ // save the MRU history
+ saveCheatSheetHistory();
+ }
+
+ private Class loadClass(String className, String classPluginId) {
+ IPluginDescriptor desc = Platform.getPluginRegistry().getPluginDescriptor(classPluginId);
+ if (desc == null) {
+ return null;
+ }
+ Class aClass = null;
+ try {
+ aClass = desc.getPluginClassLoader().loadClass(className);
+ } catch (Exception e) {
+ return null;
+ }
+ return aClass;
+ }
+
+ public ArrayList getListenerObjects(String id) {
+ if (cheatsheetListeners == null)
+ return null;
+
+ ArrayList returnList = null;
+ for (int i = 0; i < cheatsheetListeners.size(); i++) {
+ CheatSheetListenerElement el = (CheatSheetListenerElement) cheatsheetListeners.get(i);
+ if (el.getTargetCheatsheetID().equals(id)) {
+ if (returnList == null)
+ returnList = new ArrayList(20);
+ Class c = loadClass(el.getListenerClass(), el.getListenerClassPluginID());
+ if (c != null) {
+ try {
+ ICheatSheetListener l = (ICheatSheetListener) c.newInstance();
+ returnList.add(l);
+ } catch (Exception e) {
+ //return VIEWITEM_DONOT_ADVANCE;
+ }
+ }
+ }
+ }
+ return returnList;
+ }
+ /* (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+
+ plugin = this;
+ startup();
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ shutdown();
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/ICheatSheetResource.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/ICheatSheetResource.java
new file mode 100644
index 000000000..d632d2a6b
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/ICheatSheetResource.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets;
+
+public interface ICheatSheetResource {
+
+
+ //
+ // ID used through out the cheatsheets:
+ // plugin, menu, view
+ //
+ public static final String CHEAT_SHEET_PLUGIN_ID = "org.eclipse.ui.cheatsheets"; //$NON-NLS-1$
+ public static final String CHEAT_SHEET_MENU_ID = "org.eclipse.ui.cheatsheets.menu"; //$NON-NLS-1$
+ public static final String CHEAT_SHEET_VIEW_ID = "org.eclipse.ui.cheatsheets.views.CheatSheetView"; //$NON-NLS-1$
+ public static final String CHEAT_SHEET_RESOURCE_ID = "org.eclipse.ui.internal.cheatsheets.CheatsheetPluginResources"; //$NON-NLS-1$
+
+ // cheatsheet state data file
+ public static final String CHEAT_SHEET_SAVE_FILE="cheatsheet.dat"; //$NON-NLS-1$
+
+ // cheatsheet help page
+ public static final String CHEAT_SHEET_HELP_PAGE="/org.eclipse.ui.cheatsheets.doc/tasks/tcheatst.htm";//$NON-NLS-1$
+
+ // Memento info
+ public static final String URL_MEMENTO = "contentURLMemento"; //$NON-NLS-1$
+ public static final String URL_ID = "contentURL"; //$NON-NLS-1$
+
+
+
+
+ //
+ // Constants used to retrieve strings from the cheatsheet resource bundle.
+ //
+ public static final String CHEAT_SHEET_SELECTION_DIALOG_TITLE = "%CHEAT_SHEET_SELECTION_DIALOG_TITLE"; //$NON-NLS-1$
+ public static final String CHEAT_SHEET_SELECTION_DIALOG_MSG = "%CHEAT_SHEET_SELECTION_DIALOG_MSG"; //$NON-NLS-1$
+
+ public static final String COLLAPSE_ALL_BUT_CURRENT_TOOLTIP = "%COLLAPSE_ALL_BUT_CURRENT_TOOLTIP"; //$NON-NLS-1$
+ public static final String RESTORE_ALL_TOOLTIP = "%RESTORE_ALL_TOOLTIP"; //$NON-NLS-1$
+
+ public static final String CHEAT_SHEET_OTHER_MENU = "%CHEAT_SHEET_OTHER_MENU"; //$NON-NLS-1$
+
+ public static final String CHEAT_SHEETS = "%CHEAT_SHEETS"; //$NON-NLS-1$
+ public static final String FASTVIEW_ONLY_ERROR = "FASTVIEW_ONLY_ERROR"; //$NON-NLS-1$
+ public static final String FASTVIEW_ONLY_ERROR_MESSAGE = "FASTVIEW_ONLY_ERROR_MESSAGE"; //$NON-NLS-1$
+ public static final String FASTVIEW_DISABLED_FOR_CHEAT_SHEET = "FASTVIEW_DISABLED_FOR_CHEAT_SHEET"; //$NON-NLS-1$
+
+ public static final String PERFORM_TASK_TOOLTIP = "%PERFORM_TASK_TOOLTIP"; //$NON-NLS-1$
+ public static final String SKIP_TASK_TOOLTIP = "%SKIP_TASK_TOOLTIP"; //$NON-NLS-1$
+ public static final String COMPLETE_TASK_TOOLTIP = "%COMPLETE_TASK_TOOLTIP"; //$NON-NLS-1$
+ public static final String START_CHEATSHEET_TOOLTIP = "%START_CHEATSHEET_TOOLTIP"; //$NON-NLS-1$
+ public static final String RESTART_CHEATSHEET_TOOLTIP = "%RESTART_CHEATSHEET_TOOLTIP"; //$NON-NLS-1$
+ public static final String RESTART_TASK_TOOLTIP = "%RESTART_TASK_TOOLTIP"; //$NON-NLS-1$
+
+ public static final String VIEW_READFILE_ACCESSEXCEPTION = "%VIEW_READFILE_ACCESSEXCEPTION"; //$NON-NLS-1$
+
+ public static final String ERROR_OPENING_FILE_TITLE = "%ERROR_OPENING_FILE_TITLE"; //$NON-NLS-1$
+ public static final String ERROR_OPENING_FILE = "%ERROR_OPENING_FILE"; //$NON-NLS-1$
+ public static final String ERROR_PARSING_ITEMS = "%ERROR_PARSING_ITEMS"; //$NON-NLS-1$
+ public static final String ERROR_OPENING_FILE_IN_PARSER = "%ERROR_OPENING_FILE_IN_PARSER"; //$NON-NLS-1$
+ public static final String ERROR_SAX_PARSING = "%ERROR_SAX_PARSING"; //$NON-NLS-1$
+ public static final String CHEAT_SHEET_INTRO_TITLE = "%CHEAT_SHEET_INTRO_TITLE"; //$NON-NLS-1$
+
+ public static final String ERROR_READING_STATE_FILE = "ERROR_READING_STATE_FILE"; //$NON-NLS-1$
+ public static final String ERROR_WRITING_STATE_FILE = "ERROR_WRITING_STATE_FILE"; //$NON-NLS-1$
+
+ public static final String ERROR_RUNNING_ACTION = "%ERROR_RUNNING_ACTION"; //$NON-NLS-1$
+ public static final String ERROR_FINDING_PLUGIN_FOR_ACTION = "%ERROR_FINDING_PLUGIN_FOR_ACTION"; //$NON-NLS-1$
+ public static final String ERROR_LOADING_CLASS_FOR_ACTION = "%ERROR_LOADING_CLASS_FOR_ACTION"; //$NON-NLS-1$
+ public static final String ERROR_CREATING_CLASS_FOR_ACTION = "%ERROR_CREATING_CLASS_FOR_ACTION"; //$NON-NLS-1$
+ public static final String ERROR_LOADING_CHEATSHEET_CONTENT = "%ERROR_LOADING_CHEATSHEET_CONTENT"; //$NON-NLS-1$
+ public static final String ERROR_PAGE_MESSAGE ="%ERROR_PAGE_MESSAGE"; //$NON-NLS-1$
+
+ public static final String LAUNCH_SHEET_ERROR = "%LAUNCH_SHEET_ERROR"; //$NON-NLS-1$
+ public static final String CHEAT_SHEET_ERROR_OPENING = "%CHEAT_SHEET_ERROR_OPENING"; //$NON-NLS-1$
+
+ public static final String CHEAT_SHEET_OTHER_CATEGORY = "%CHEAT_SHEET_OTHER_CATEGORY"; //$NON-NLS-1$
+
+ public static final String HELP_BUTTON_TOOLTIP = "%HELP_BUTTON_TOOLTIP";//$NON-NLS-1$
+ public static final String LESS_THAN_2_SUBITEMS = "%LESS_THAN_2_SUBITEMS";//$NON-NLS-1$
+
+}
+
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetCategoryBasedSelectionAction.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetCategoryBasedSelectionAction.java
new file mode 100644
index 000000000..b24acacb5
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetCategoryBasedSelectionAction.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.window.Window;
+import org.eclipse.ui.PlatformUI;
+
+import org.eclipse.ui.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.dialogs.CheatSheetCategoryBasedSelectionDialog;
+import org.eclipse.ui.internal.cheatsheets.registry.*;
+
+/**
+ * Action to programmatically open the CheatSheet selection dialog.
+ *
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ */
+public class CheatSheetCategoryBasedSelectionAction extends Action {
+
+ /**
+ * Create a new <code>CheatSheetSelectionAction</code> action.
+ */
+ public CheatSheetCategoryBasedSelectionAction() {
+ }
+
+ /**
+ * Constructor for CheatSheetSelectionAction.
+ * @param text
+ */
+ public CheatSheetCategoryBasedSelectionAction(String text) {
+ super(text);
+ }
+
+ /**
+ * Constructor for CheatSheetSelectionAction.
+ * @param text
+ * @param image
+ */
+ public CheatSheetCategoryBasedSelectionAction(String text, ImageDescriptor image) {
+ super(text, image);
+ }
+
+ /**
+ * @see Action#run()
+ */
+ public void run() {
+ CheatSheetCollectionElement cheatSheets = (CheatSheetCollectionElement)CheatSheetRegistryReader.getInstance().getCheatSheets();
+
+ CheatSheetCategoryBasedSelectionDialog dialog = new CheatSheetCategoryBasedSelectionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), cheatSheets);
+
+ if(dialog.open() != Window.OK || dialog.getResult().length != 1)
+ return;
+
+ CheatSheetElement result = (CheatSheetElement)dialog.getResult()[0];
+
+ new LaunchCheatSheetAction(result).run(); //$NON-NLS-1$
+ }
+}
+
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetMenu.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetMenu.java
new file mode 100644
index 000000000..4a4371004
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetMenu.java
@@ -0,0 +1,328 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.actions;
+
+import java.text.Collator;
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+
+import org.eclipse.ui.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.registry.*;
+import org.eclipse.ui.internal.cheatsheets.views.CheatSheetView;
+
+/**
+ * A menu for cheatsheet selection.
+ * <p>
+ * A <code>CheatSheetMenu</code> is used to populate a menu with
+ * cheatsheet items. If the user selects one of these items
+ * an action is performed to launch the selected cheatsheet.
+ * </p><p>
+ * The visible cheatsheet items within the menu are dynamic and reflect the
+ * available set. The available set consists of a limited combination of
+ * the most recently used cheatsheet list and the currently available
+ * cheatsheet.
+ * </p>
+ */
+public class CheatSheetMenu extends ContributionItem {
+ private static final int MAX_CHEATSHEET_ITEMS = 5;
+ private static CheatSheetRegistryReader reg;
+
+ private boolean showActive = false;
+
+ private Comparator comparator = new Comparator() {
+ private Collator collator = Collator.getInstance();
+
+ public int compare(Object ob1, Object ob2) {
+ CheatSheetElement d1 = (CheatSheetElement) ob1;
+ CheatSheetElement d2 = (CheatSheetElement) ob2;
+ return collator.compare(d1.getLabel(null), d2.getLabel(null));
+ }
+ };
+
+ private static Hashtable imageCache = new Hashtable(7);
+
+ /**
+ * Constructs a new instance of <code>CheatSheetMenu</code>.
+ */
+ public CheatSheetMenu() {
+ super("LaunchCheatSheetMenu"); //$NON-NLS-1$
+
+ if (reg == null)
+ reg = CheatSheetRegistryReader.getInstance();
+
+ showActive(true);
+ }
+
+ /* (non-Javadoc)
+ * Creates a menu item for a cheatsheet.
+ */
+ private void createMenuItem(Menu menu, int index, final CheatSheetElement element, boolean bCheck) {
+
+ MenuItem mi = new MenuItem(menu, bCheck ? SWT.RADIO : SWT.PUSH, index);
+ mi.setText(element.getLabel(null));
+ Image image = getImage(element);
+ if (image != null) {
+ mi.setImage(image);
+ }
+ mi.setSelection(bCheck);
+ mi.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ run(element, e);
+ }
+ });
+ }
+
+ /* (non-Javadoc)
+ * Creates a menu item for "Other...".
+ */
+ private void createOtherItem(Menu menu, int index) {
+ MenuItem mi = new MenuItem(menu, SWT.PUSH, index);
+ mi.setText(CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEET_OTHER_MENU));
+ mi.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ runOther(e);
+ }
+ });
+ }
+
+ /* (non-Javadoc)
+ * Fills the menu with cheatsheet items.
+ */
+ public void fill(Menu menu, int index) {
+ // Get the checked cheatsheet.
+ String checkID = null;
+ if (showActive) {
+ checkID = getActiveCheatSheetID();
+ }
+
+ // Collect and sort cheatsheet items.
+ ArrayList cheatsheets = getCheatSheetItems();
+ Collections.sort(cheatsheets, comparator);
+
+ // Add cheatsheet shortcuts
+ for (int i = 0; i < cheatsheets.size(); i++) {
+ CheatSheetElement element = (CheatSheetElement) cheatsheets.get(i);
+ createMenuItem(menu, index++, element, element.getID().equals(checkID));
+ }
+
+ // Add others item..
+ if (cheatsheets.size() > 0) {
+ new MenuItem(menu, SWT.SEPARATOR, index++);
+ }
+ createOtherItem(menu, index);
+ }
+
+ /**
+ * Method getActiveCheatSheetID returns the id of the active
+ * cheatsheet or null.
+ *
+ * @return String
+ */
+ private String getActiveCheatSheetID() {
+ //get the active cheatsheet view, if opened
+ IWorkbenchPage page = getActiveWorkbenchPage();
+
+ if( page != null ) {
+ CheatSheetView view = (CheatSheetView) page.findView(ICheatSheetResource.CHEAT_SHEET_VIEW_ID);
+ if (view != null) {
+ CheatSheetElement content = view.getContent();
+ if (content != null) {
+ return content.getID();
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Method getActiveWorkbenchPage returns the active
+ * workbench page or null.
+ *
+ * @return IWorkbenchPage
+ */
+ private IWorkbenchPage getActiveWorkbenchPage() {
+ IWorkbench myworkbench = CheatSheetPlugin.getPlugin().getWorkbench();
+ IWorkbenchWindow window = myworkbench.getActiveWorkbenchWindow();
+
+ //get the active cheatsheet view, if opened
+ return window.getActivePage();
+ }
+
+ /**
+ * Returns the available list of cheatsheets to display
+ * in the menu.
+ * <p>
+ * By default, the list contains the most recently used cheatsheets
+ * and then random cheatsheets until there are 5 present in the list.
+ * </p><p>
+ * Care should be taken to keep this list to a minimum (7 +/- 2 items
+ * is a good guideline to follow).
+ * </p>
+ *
+ * @return an <code>ArrayList<code> of cheatsheet items <code>CheatSheetElement</code>
+ */
+ protected ArrayList getCheatSheetItems() {
+ ArrayList list = new ArrayList(MAX_CHEATSHEET_ITEMS);
+ int emptySlots = MAX_CHEATSHEET_ITEMS;
+
+ // Add cheatsheets from MRU list
+ if (emptySlots > 0) {
+ ArrayList mru = new ArrayList(MAX_CHEATSHEET_ITEMS);
+ int count = getCheatSheetMru(mru, 0, MAX_CHEATSHEET_ITEMS);
+ for (int i = 0; i < count && emptySlots > 0; i++) {
+ if (!list.contains(mru.get(i))) {
+ list.add(mru.get(i));
+ emptySlots--;
+ }
+ }
+ }
+
+ // Add random cheatsheets until the list is filled.
+ CheatSheetCollectionElement cheatSheetsCollection = (CheatSheetCollectionElement)reg.getCheatSheets();
+ emptySlots = addCheatSheets(list, cheatSheetsCollection, emptySlots);
+
+ return list;
+ }
+
+ /**
+ * Method addCheatSheets fills a list with cheatsheet elements until there
+ * are no more empty slots.
+ *
+ * @param list - the list to file
+ * @param cheatSheetsCollection - the collection to get the elements from
+ * @param emptySlots - number of empty slots remaining
+ * @return int - number of empty slots remaining
+ */
+ private int addCheatSheets(ArrayList list, CheatSheetCollectionElement cheatSheetsCollection, int emptySlots) {
+ Object[] cheatSheets = cheatSheetsCollection.getCheatSheets();
+ for (int i = 0; i < cheatSheets.length && emptySlots > 0; i++) {
+ if (!list.contains(cheatSheets[i])) {
+ list.add(cheatSheets[i]);
+ emptySlots--;
+ }
+ }
+
+ Object[] cheatSheetsFromCollection = cheatSheetsCollection.getChildren();
+ for (int nX = 0; nX < cheatSheetsFromCollection.length && emptySlots > 0; nX++) {
+ CheatSheetCollectionElement collection = (CheatSheetCollectionElement) cheatSheetsFromCollection[nX];
+ emptySlots = addCheatSheets(list, collection, emptySlots);
+ }
+
+ return emptySlots;
+ }
+
+ /* (non-Javadoc)
+ * Gets the most recently used (MRU) shortcut cheatsheets
+ * (<code>CheatSheetElement</code> items)
+ * <p>
+ * The list is formed from the global cheatsheet history.
+ * </p>
+ * @param dest destination list to contain the items
+ * @param destStart index in destination list to start copying items at
+ * @param count number of items to copy from history
+ * @return the number of items actually copied
+ */
+ private int getCheatSheetMru(List dest, int destStart, int count) {
+ CheatSheetHistory history = CheatSheetPlugin.getPlugin().getCheatSheetHistory();
+ return history.copyItems(dest, destStart, count);
+ }
+
+ /**
+ * Returns an image to show for the corresponding cheatsheet descriptor.
+ *
+ * @param element the cheatsheet element
+ * @return the image or null
+ */
+ private Image getImage(CheatSheetElement element) {
+ ImageDescriptor imageDesc = element.getImageDescriptor();
+
+ if (imageDesc == null) {
+ return null;
+ }
+
+ Image image = (Image) imageCache.get(imageDesc);
+ if (image == null) {
+ image = imageDesc.createImage();
+ imageCache.put(imageDesc, image);
+ }
+ return image;
+ }
+
+
+ /**
+ * Returns whether the menu item representing the active cheatsheet
+ * will have a check mark.
+ *
+ * @return <code>true</code> if a check mark is shown, <code>false</code> otherwise
+ */
+ protected boolean getShowActive() {
+ return showActive;
+ }
+
+ /* (non-Javadoc)
+ * Returns whether this menu is dynamic.
+ */
+ public boolean isDynamic() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.IContributionItem#isVisible()
+ */
+ public boolean isVisible() {
+ return getActiveWorkbenchPage() != null;
+ }
+
+ /**
+ * Runs an action to launch the cheatsheet.
+ *
+ * @param element the selected cheatsheet
+ */
+ protected void run(CheatSheetElement element) {
+ new LaunchCheatSheetAction(element).run(); //$NON-NLS-1$
+ }
+
+ /**
+ * Runs an action to launch the cheatsheet.
+ *
+ * @param element the selected cheatsheet
+ * @param event SelectionEvent - the event send along with the selection callback
+ */
+ protected void run(CheatSheetElement element, SelectionEvent event) {
+ //Do a run without the event by default
+ run(element);
+ }
+
+ /* (non-Javadoc)
+ * Show the "other" dialog, select a cheatsheet, and launch it. Pass on the selection
+ * event should the meny need it.
+ */
+ private void runOther(SelectionEvent event) {
+ new CheatSheetCategoryBasedSelectionAction().run();
+ }
+
+ /**
+ * Sets the showActive flag. If <code>showActive == true</code> then the
+ * active cheatsheet is hilighted with a check mark.
+ *
+ * @param the new showActive flag
+ */
+ protected void showActive(boolean b) {
+ showActive = b;
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetSelectionAction.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetSelectionAction.java
new file mode 100644
index 000000000..4cf39f947
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/actions/CheatSheetSelectionAction.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.window.Window;
+import org.eclipse.ui.PlatformUI;
+
+import org.eclipse.ui.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.dialogs.CheatSheetSelectionDialog;
+import org.eclipse.ui.internal.cheatsheets.registry.CheatSheetElement;
+
+/**
+ * Action to programmatically open the CheatSheet selection dialog.
+ *
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ */
+public class CheatSheetSelectionAction extends Action {
+
+ /**
+ * Create a new <code>CheatSheetSelectionAction</code> action.
+ */
+ public CheatSheetSelectionAction() {
+ }
+
+ /**
+ * Constructor for CheatSheetSelectionAction.
+ * @param text
+ */
+ public CheatSheetSelectionAction(String text) {
+ super(text);
+ }
+
+ /**
+ * Constructor for CheatSheetSelectionAction.
+ * @param text
+ * @param image
+ */
+ public CheatSheetSelectionAction(String text, ImageDescriptor image) {
+ super(text, image);
+ }
+
+ /**
+ * @see Action#run()
+ */
+ public void run() {
+ CheatSheetSelectionDialog dialog = new CheatSheetSelectionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+
+ if(dialog.open() != Window.OK || dialog.getResult().length != 1)
+ return;
+
+ new LaunchCheatSheetAction((CheatSheetElement)dialog.getResult()[0]).run(); //$NON-NLS-1$
+ }
+}
+
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/AbstractItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/AbstractItem.java
new file mode 100644
index 000000000..33adae54f
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/AbstractItem.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+public abstract class AbstractItem {
+
+ protected String id;
+
+ public AbstractItem() {
+ super();
+ }
+
+ public void setID(String id){
+ this.id = id;
+ }
+
+ public String getID(){
+ return id;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ActionItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ActionItem.java
new file mode 100644
index 000000000..cd7425183
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ActionItem.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+import org.eclipse.ui.cheatsheets.IItem;
+
+public abstract class ActionItem extends AbstractItem implements IItem {
+ private String buttonCodes;
+ private String actionClass;
+ private String actionPluginID;
+ private String[] actionParams;
+
+ public ActionItem() {
+ super();
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItem#getActionClass()
+ */
+ public String getActionClass() {
+ return (actionClass!=null)?actionClass:null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItem#getActionParams()
+ */
+ public String[] getActionParams() {
+ return (actionParams!=null)?actionParams:null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItem#getActionPluginID()
+ */
+ public String getActionPluginID() {
+ return (actionPluginID!=null)?actionPluginID:null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItem#getButtonCodes()
+ */
+ public String getButtonCodes() {
+ return (buttonCodes!=null)?buttonCodes:null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItem#setActionClass(java.lang.String)
+ */
+ public void setActionClass(String aclass) {
+ this.actionClass = aclass;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItem#setActionParams(java.lang.String[])
+ */
+ public void setActionParams(String[] params) {
+ this.actionParams = params;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItem#setActionPluginID(java.lang.String)
+ */
+ public void setActionPluginID(String pluginId) {
+ this.actionPluginID = pluginId;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItem#setButtonCodes(java.lang.String)
+ */
+ public void setButtonCodes(String codes) {
+ this.buttonCodes = codes;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetDomParser.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetDomParser.java
new file mode 100644
index 000000000..f47635e4c
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetDomParser.java
@@ -0,0 +1,509 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+
+import javax.xml.parsers.*;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.swt.widgets.Shell;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.registry.CheatSheetRegistryReader;
+import org.eclipse.ui.cheatsheets.ICheatSheetItemExtensionElement;
+import org.eclipse.ui.cheatsheets.ISubItem;
+
+/**
+ * Parser for the cheatsheet content files.
+ *
+ * Construct an intance of the CheatSheetDomParser.
+ * Call <code>parse()</code>.
+ * Then get the content items by calling
+ * <code>getIntroItem()</code> and <code>getItemsList()</code>.
+ * The title of the cheatsheet can be retrieved by calling
+ * <code>getTitle()</code>.
+ *
+ */
+public class CheatSheetDomParser {
+ private float csversion;
+ private DocumentBuilder documentBuilder;
+ private ArrayList idChecker;
+ private ContentItem introItem;
+ private ArrayList items;
+ private Document myDocument;
+ private InputSource mysource;
+ private ArrayList subIDChecker;
+ private String title;
+ private URL url;
+ private ArrayList itemExtensionContainerList;
+
+ /**
+ * ConvertJava constructor comment.
+ */
+ public CheatSheetDomParser(URL url) {
+ super();
+ this.url = url;
+ try {
+ documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ items = new ArrayList();
+ subIDChecker = new ArrayList();
+ }
+
+ private boolean checkThisID(String idToCheck) {
+ if (idChecker.contains(idToCheck))
+ return true;
+ return false;
+ }
+
+ private String formatBodyString(String bodyString) {
+ int hasNewLine = 0;
+ int hasTab = 0;
+ int hasRetLine = 0;
+
+ hasNewLine = bodyString.indexOf("\n"); //$NON-NLS-1$
+ if (hasNewLine != -1)
+ bodyString = bodyString.replace('\n', ' ');
+
+ hasRetLine = bodyString.indexOf("\r"); //$NON-NLS-1$
+ if (hasRetLine != -1)
+ bodyString = bodyString.replace('\r', ' ');
+
+ hasTab = bodyString.indexOf("\t"); //$NON-NLS-1$
+ if (hasTab != -1)
+ bodyString = bodyString.replace('\t', ' ');
+
+ //now take out double/tripple/etc. spaces.
+ char last = 'x';
+ char current = 'x';
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < bodyString.length(); i++) {
+ current = bodyString.charAt(i);
+
+ if (current != ' ')
+ sb.append(current);
+ else {
+ if (last != ' ')
+ sb.append(current);
+ }
+ last = current;
+ }
+
+ return sb.toString();
+ }
+
+ public float getCsversion() {
+ return (csversion != 0.0) ? csversion : 1.0f;
+ }
+
+ /**
+ * Returns the intro item.
+ */
+ public ContentItem getIntroItem() {
+ return introItem;
+ }
+
+ /**
+ * Returns the items.
+ */
+ public ArrayList getItems() {
+ return items;
+ }
+
+ private ArrayList getParamList(NamedNodeMap nnm) {
+ // System.out.println("Parsing parameters for actions");
+ ArrayList params = new ArrayList();
+
+ try {
+ String param = "param"; //$NON-NLS-1$
+ for (int j = 0; param != null; j++) {
+ String actionparam = nnm.getNamedItem(IParserTags.ACTIONPARAM + j).getNodeValue();
+ // System.out.println("Action parameter found: " + actionparam);
+ param = actionparam;
+ if (param != null)
+ params.add(param);
+ }
+ } catch (Exception e) {
+ }
+
+ return params;
+ }
+
+ /**
+ * Gets the title.
+ * @return Returns a String
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ public boolean parse() {
+ InputStream is = null;
+
+ try {
+ is = url.openStream();
+
+ if (is != null) {
+ mysource = new InputSource(is);
+ }
+ } catch (Exception e) {
+ //Need to log exception here.
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_OPENING_FILE), e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ org.eclipse.jface.dialogs.ErrorDialog.openError(new Shell(), CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_OPENING_FILE), null, status);
+ return false;
+ }
+
+ try {
+ if(documentBuilder == null) {
+ throw new Exception("Exception");
+ }
+ myDocument = documentBuilder.parse(mysource);
+ } catch (IOException e) {
+ //Need to log exception here.
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_OPENING_FILE_IN_PARSER), e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ return false;
+ } catch (SAXParseException spe) {
+ //Need to log exception here.
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_SAX_PARSING), spe);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ return false;
+ } catch (SAXException se) {
+ //Need to log exception here.
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_SAX_PARSING), se);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ return false;
+ } catch (Exception se) {
+ //TODO: Needs to update the error message
+ //Need to log exception here.
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_SAX_PARSING), se);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ return false;
+ } finally {
+ try {
+ is.close();
+ } catch (Exception e) {
+ }
+ }
+
+ // If the document passed is null return a null tree and update the status
+ if (myDocument != null) {
+
+ Node rootnode = myDocument.getDocumentElement();
+ NamedNodeMap rootatts = rootnode.getAttributes();
+ setTitle(rootatts.getNamedItem(IParserTags.TITLE).getNodeValue());
+
+ //Must be in a try catch here, the named item may not be there if old cs version of xml.
+ String fversion = null;
+ try {
+ fversion = rootatts.getNamedItem(IParserTags.VERSION).getNodeValue();
+ } catch (Exception e) {
+ }
+
+ if (fversion != null) {
+ try {
+ csversion = Float.parseFloat(fversion);
+ } catch (Exception e) {
+ }
+ }
+
+ // Version Stuff, reads version number here.
+ // String printString = (fversion != null) ? "Version Number Found: " + fversion : "No Version Number";
+ // System.out.println(printString);
+
+ //Get the Intro item.
+ NodeList introlist = myDocument.getElementsByTagName(IParserTags.INTRO);
+ Node introelement = introlist.item(0);
+ NamedNodeMap mymap = introelement.getAttributes();
+ String introTitle = null;
+ String introHref = null;
+
+ introTitle = CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEET_INTRO_TITLE);
+ try {
+ introHref = mymap.getNamedItem(IParserTags.HREF).getNodeValue();
+ } catch (Exception e) {
+ }
+
+ String introtext = introelement.getFirstChild().getNodeValue();
+ // comment out for defect 25997 undo text formatting.introtext = formatBodyString(introtext);
+ //introtext = formatBodyString(introtext);
+ introItem = new ContentItem(introTitle, introtext, introHref);
+
+ //Get the items.
+ NodeList itemList = myDocument.getElementsByTagName(IParserTags.ITEM);
+ //parse the items. assemble CheatSheetItem objects.
+ items = parseItems(itemList);
+
+ if (items == null) {
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_PARSING_ITEMS), null);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ org.eclipse.jface.dialogs.ErrorDialog.openError(new Shell(), CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_OPENING_FILE_TITLE), CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_PARSING_ITEMS), status);
+ return false;
+ }
+
+ return true;
+ } else {
+ //System.err.println("Null document");
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_OPENING_FILE), null);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+
+ org.eclipse.jface.dialogs.ErrorDialog.openError(new Shell(), CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_OPENING_FILE_TITLE), CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_OPENING_FILE), status);
+ return false;
+ }
+
+ }
+
+ private ArrayList parseItems(NodeList itemList) {
+ CheatSheetRegistryReader reader = CheatSheetRegistryReader.getInstance();
+ itemExtensionContainerList = reader.readItemExtensions();
+
+ ArrayList localList = new ArrayList();
+ Vector counterslist = new Vector();
+ idChecker = new ArrayList();
+ counterslist.addElement(new Integer(0));
+
+ for (int i = 0; i < itemList.getLength(); i++) {
+ //get the item node.
+ Node itemnode = itemList.item(i);
+ NodeList itemchildren = itemnode.getChildNodes();
+
+ String actionPhrase = null;
+ String title = null;
+ String actionPid = null;
+ String actionClass = null;
+ String topicHref = null;
+ boolean dynamic = false;
+ String itemID = null;
+ boolean hasID = false;
+
+ StringBuffer bodyText = new StringBuffer();
+
+ // System.out.println("Checking for sub items.");
+ NodeList subItems = itemnode.getChildNodes();
+ ArrayList subItemArrayList = null;
+ ArrayList l = null;
+
+ //Gather sub items and add them to the sub item array list. this will be parsed later.
+ for (int m = 0; m < subItems.getLength(); m++) {
+ Node n = subItems.item(m);
+ if (n.getNodeName().equals(IParserTags.SUBITEM)) {
+ if (subItemArrayList == null)
+ subItemArrayList = new ArrayList(10);
+ subItemArrayList.add(n);
+ }
+ }
+
+ ArrayList itemExtensionElements = new ArrayList();
+
+ NamedNodeMap itematts = itemnode.getAttributes();
+ if (itematts != null) {
+ for (int x = 0; x < itematts.getLength(); x++) {
+ Node item = itematts.item(x);
+ String attName = item.getNodeName();
+ if (item == null || attName == null)
+ continue;
+
+ if (attName.equals(IParserTags.TITLE)) {
+ title = item.getNodeValue();
+ } else if (attName.equals(IParserTags.ID)) {
+ itemID = item.getNodeValue();
+ if (itemID != null) {
+ hasID = true;
+ if (checkThisID(itemID))
+ return null;
+ } else {
+ return null;
+ }
+ } else if (attName.equals(IParserTags.DYNAMIC)) {
+ String dynamicString = item.getNodeValue();
+ if (dynamicString != null)
+ if (dynamicString.equals("true")) { //$NON-NLS-1$
+ dynamic = true;
+ } else if (dynamicString.equals("false")) { //$NON-NLS-1$
+ dynamic = false;
+ } else {
+ dynamic = false;
+ }
+ } else if (attName.equals(IParserTags.PLUGINID)) {
+ actionPid = item.getNodeValue();
+ } else if (attName.equals(IParserTags.CLASS)) {
+ actionClass = item.getNodeValue();
+ } else if (attName.equals(IParserTags.HREF)) {
+ topicHref = item.getNodeValue();
+ } else if (attName.equals(IParserTags.ACTIONPHRASE)) {
+ actionPhrase = item.getNodeValue();
+ } else {
+ ICheatSheetItemExtensionElement[] ie = handleUnknownItemAttribute(item);
+ if (ie != null)
+ itemExtensionElements.add(ie);
+ }
+ }
+ //Set the action parameters if there are any.
+ l = getParamList(itematts);
+ }
+
+ //Get the text for the description here. Assemble a string, then remove new line chars.
+ for (int j = 0; j < itemchildren.getLength(); j++) {
+ Node child = itemchildren.item(j);
+ if (child.getNodeValue() != null && child.getNodeType() == Node.TEXT_NODE) {
+ bodyText.append(child.getNodeValue());
+ }
+ }
+
+ //remove the new line and form feed chars here.
+ //comment out for defect 25997 String bodyString = formatBodyString(bodyText.toString());
+ //String bodyString = formatBodyString(bodyText.toString());
+ String bodyString = bodyText.toString();
+
+ //Create the cheatsheetitem and fill it with data.
+ if (subItemArrayList == null) {
+ ContentItem itemtoadd = new ContentItem();
+ itemtoadd.setActionPluginID(actionPid);
+ itemtoadd.setActionClass(actionClass);
+ itemtoadd.setHref(topicHref);
+ itemtoadd.setTitle(title);
+ itemtoadd.setActionParams((String[]) l.toArray(new String[l.size()]));
+ itemtoadd.setButtonCodes(actionPhrase);
+ itemtoadd.setText(bodyString);
+ itemtoadd.setIsDynamic(dynamic);
+ itemtoadd.setID(itemID);
+ if (itemExtensionElements != null)
+ itemtoadd.setItemExtensions(itemExtensionElements);
+
+ //Add the item to the list of items to build the view from.
+ localList.add(itemtoadd);
+ } else {
+ ContentItemWithSubItems itemtoadd = new ContentItemWithSubItems();
+ itemtoadd.setHref(topicHref);
+ itemtoadd.setTitle(title);
+ itemtoadd.setText(bodyString);
+ itemtoadd.setIsDynamic(dynamic);
+ itemtoadd.setID(itemID);
+ //Parse the sub items for this item and add it to the sub item list.
+ ArrayList subs = parseSubItems(subItemArrayList);
+ if (subs == null || subs.size() <=1 )
+ return null;
+ itemtoadd.addSubItems((ISubItem[]) subs.toArray(new ISubItem[subs.size()]));
+
+ if (itemExtensionElements != null)
+ itemtoadd.setItemExtensions(itemExtensionElements);
+
+ //Add the item to the list of items to build the view from.
+ localList.add(itemtoadd);
+ }
+ idChecker.add(itemID);
+ }
+ return localList;
+ }
+
+ private ICheatSheetItemExtensionElement[] handleUnknownItemAttribute(Node item) {
+ ArrayList al = new ArrayList();
+ if (itemExtensionContainerList == null)
+ return null;
+
+ for (int i = 0; i < itemExtensionContainerList.size(); i++) {
+ ICheatSheetItemExtensionElement itemElement = (ICheatSheetItemExtensionElement) itemExtensionContainerList.get(i);
+ String itemExtensionAtt = itemElement.getAttributeName();
+
+ if (itemExtensionAtt.equals(item.getNodeName())) {
+ itemElement.handleAttribute(item);
+ al.add(itemElement);
+ }
+ }
+
+ return (ICheatSheetItemExtensionElement[])al.toArray(new ICheatSheetItemExtensionElement[al.size()]);
+ }
+
+ //Returns an array list full of SubContentItems.
+ private ArrayList parseSubItems(ArrayList sil) {
+ // System.out.println("Parsing sub items.");
+ if (sil == null || sil.size() == 0)
+ return null;
+ ArrayList subItemList = new ArrayList(10);
+
+ String label = null;
+ String actionPid = null;
+ String actionClass = null;
+ String actionNums = null;
+ ArrayList actionParamList = null;
+ String subItemID = null;
+
+ for (int i = 0; i < sil.size(); i++) {
+ Node n = (Node) sil.get(i);
+ NamedNodeMap nnm = n.getAttributes();
+ try {
+ subItemID = nnm.getNamedItem(IParserTags.ID).getNodeValue();
+ if (subItemID == null) {
+ return null;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ try {
+ label = nnm.getNamedItem(IParserTags.LABEL).getNodeValue();
+ if (label == null)
+ return null;
+ } catch (Exception e) {
+ return null;
+ }
+ try {
+ actionNums = nnm.getNamedItem(IParserTags.ACTIONPHRASE).getNodeValue();
+ if (actionNums == null)
+ return null;
+ } catch (Exception e) {
+ return null;
+ }
+ try {
+ actionPid = nnm.getNamedItem(IParserTags.PLUGINID).getNodeValue();
+ } catch (Exception e) {
+ actionPid = null;
+ }
+ try {
+ actionClass = nnm.getNamedItem(IParserTags.CLASS).getNodeValue();
+ } catch (Exception e) {
+ actionClass = null;
+ }
+ try {
+ actionParamList = getParamList(nnm);
+ } catch (Exception e) {
+ actionParamList = null;
+ }
+ SubContentItem sub = new SubContentItem();
+ sub.setID(subItemID);
+ sub.setLabel(label);
+ // sub.setSuperItem(superItem);
+ sub.setActionPluginID(actionPid);
+ sub.setActionClass(actionClass);
+ sub.setButtonCodes(actionNums);
+ sub.setActionParams((String[]) actionParamList.toArray(new String[actionParamList.size()]));
+ subItemList.add(sub);
+
+ } //end iterate through sub item node list.
+
+ return subItemList;
+ }
+
+ /**
+ * Sets the title.
+ * @param title The title to set
+ */
+ private void setTitle(String title) {
+ this.title = title;
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetSaveHelper.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetSaveHelper.java
new file mode 100644
index 000000000..6b7bc2ae9
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetSaveHelper.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.views.*;
+
+public class CheatSheetSaveHelper {
+ protected Hashtable stateHash = new Hashtable();
+ protected Vector stateVector = new Vector();
+ private CheatSheetXMLSaveHelper xmlsh;
+ /**
+ * Constructor for CheatSheetSaveHelper.
+ */
+ public CheatSheetSaveHelper() {
+ super();
+ loadDATStates();
+ }
+
+ private Properties createProperties(URL urlKey, int stateNum, ViewItem[] myitems, boolean buttonIsDown, ArrayList expandRestoreStates, String csID) {
+ Properties props = new Properties();
+ Hashtable subcompletedTable = new Hashtable(10);
+ Hashtable subskippedTable = new Hashtable(10);
+
+ int buttonState = 0;
+ if (buttonIsDown)
+ buttonState = 1;
+
+ props.put(IParserTags.CHEATSHEETID, csID);
+ props.put(IParserTags.URL, urlKey.toString()); //$NON-NLS-1$
+ props.put(IParserTags.CURRENT, Integer.toString(stateNum)); //$NON-NLS-1$
+ ArrayList mylist = new ArrayList();
+ ArrayList elist = new ArrayList();
+
+ if (expandRestoreStates == null)
+ expandRestoreStates = new ArrayList();
+
+ //Assemble lists of expanded items and completed items.
+ for (int i = 0; i < myitems.length; i++) {
+ ViewItem item = myitems[i];
+ if (item.isCompleted()) {
+ mylist.add(Integer.toString(i));
+ }
+ if (item.isExpanded()) {
+ elist.add(Integer.toString(i));
+ }
+
+ if (item instanceof CoreItem) {
+ CoreItem withsubs = (CoreItem) item;
+ ArrayList compList = withsubs.getListOfSubItemCompositeHolders();
+ if (compList != null) {
+ StringBuffer skippedsubItems = new StringBuffer();
+ StringBuffer completedsubItems = new StringBuffer();
+ for (int j = 0; j < compList.size(); j++) {
+ SubItemCompositeHolder sch = (SubItemCompositeHolder) compList.get(j);
+ if (sch.isCompleted())
+ completedsubItems.append(Integer.toString(j) + ","); //$NON-NLS-1$
+ if (sch.isSkipped())
+ skippedsubItems.append(Integer.toString(j) + ","); //$NON-NLS-1$
+ }
+ if (completedsubItems.toString().length() > 0) {
+ String csi = completedsubItems.toString();
+ if (csi.endsWith(",")) //$NON-NLS-1$
+ csi = csi.substring(0, csi.length() - 1);
+ subcompletedTable.put(Integer.toString(i), csi);
+
+ }
+ if (skippedsubItems.toString().length() > 0) {
+ String csi = skippedsubItems.toString();
+ if (csi.endsWith(",")) //$NON-NLS-1$
+ csi = csi.substring(0, csi.length() - 1);
+ subskippedTable.put(Integer.toString(i), csi);
+ }
+ }
+ }
+ }
+
+ //put expanded item list, completed list, button state
+ props.put(IParserTags.COMPLETED, mylist); //$NON-NLS-1$
+ props.put(IParserTags.EXPANDED, elist); //$NON-NLS-1$
+ props.put(IParserTags.EXPANDRESTORE, expandRestoreStates); //$NON-NLS-1$
+ props.put(IParserTags.BUTTON, Integer.toString(buttonState)); //$NON-NLS-1$
+ if (subcompletedTable != null)
+ props.put(IParserTags.SUBITEMCOMPLETED, subcompletedTable); //$NON-NLS-1$
+ if (subskippedTable != null)
+ props.put(IParserTags.SUBITEMSKIPPED, subskippedTable); //$NON-NLS-1$
+
+ return props;
+ }
+
+ public Properties getSavedStateProperties(URL urlToCheck, float version) {
+ Properties datData = null;
+ Properties xmlData = null;
+
+ //Step 1: Check stateVector for url. (Check for v1 saved data)
+ datData = v1DataExists(urlToCheck.toString());
+ removeState(urlToCheck.toString());
+ saveStates();
+
+ //Step 2: Check for xml file with data for that url. (V2 saved data)
+ if (xmlsh == null)
+ xmlsh = new CheatSheetXMLSaveHelper();
+ xmlData = xmlsh.loadState(urlToCheck);
+
+ if (xmlData != null & datData != null) {
+ return xmlData;
+ } else if (xmlData != null) {
+ return xmlData;
+ } else if (datData != null) {
+ return datData;
+ } else
+ return null;
+ }
+
+ private void loadDATStates() {
+ //Get a handle to the save location for the cheatsheet plugin.
+ IPath savePath = Platform.getPluginStateLocation(CheatSheetPlugin.getPlugin());
+ Path filePath = new Path(savePath.append(ICheatSheetResource.CHEAT_SHEET_SAVE_FILE).toOSString());
+
+ FileReader reader = null;
+ BufferedReader mybuf = null;
+
+ //Open a file handle.
+ try {
+
+ reader = new FileReader(filePath.toFile());
+ mybuf = new BufferedReader(reader);
+
+ String line = mybuf.readLine();
+ while (line != null) {
+ StringTokenizer st = new StringTokenizer(line, ";"); //$NON-NLS-1$
+ String url = st.nextToken();
+ String itemnum = st.nextToken();
+ Properties myprop = new Properties();
+ myprop.put(IParserTags.URL, url); //non nls //$NON-NLS-1$
+ myprop.put(IParserTags.CURRENT, itemnum); //non nls //$NON-NLS-1$
+ ArrayList completedNumStrings = new ArrayList();
+ ArrayList expandedNumStrings = new ArrayList();
+ ArrayList expandRestore = new ArrayList();
+ while (st.hasMoreTokens()) {
+ String mytoken = st.nextToken();
+ if (mytoken.startsWith("c")) { //$NON-NLS-1$
+ completedNumStrings.add(mytoken.substring(1, mytoken.length()));
+ } else if (mytoken.startsWith("e")) { //$NON-NLS-1$
+ expandedNumStrings.add(mytoken.substring(1, mytoken.length()));
+ } else if (mytoken.startsWith("b")) { //$NON-NLS-1$
+ myprop.put(IParserTags.BUTTON, mytoken.substring(1, mytoken.length())); //$NON-NLS-1$
+ } else if (mytoken.startsWith("h")) { //$NON-NLS-1$
+ expandRestore.add(mytoken.substring(1, mytoken.length()));
+ }
+ }
+ myprop.put(IParserTags.COMPLETED, completedNumStrings); //$NON-NLS-1$
+ myprop.put(IParserTags.EXPANDED, expandedNumStrings); //$NON-NLS-1$
+ myprop.put(IParserTags.EXPANDRESTORE, expandRestore); //$NON-NLS-1$
+ stateVector.addElement(myprop);
+ line = mybuf.readLine();
+ }
+ reader.close();
+ mybuf.close();
+
+ } catch (FileNotFoundException fnfe) {
+ } catch (IOException ioe) {
+ }
+ }
+
+ public void removeState(String myurl) {
+ int index = -1;
+ for (int i = 0; i < stateVector.size(); i++) {
+ Properties myprop = (Properties) stateVector.elementAt(i);
+ String urlstring = (String) myprop.get(IParserTags.URL); //non nls //$NON-NLS-1$
+ if (urlstring.equals(myurl))
+ index = i;
+ }
+ if (index > -1) {
+ stateVector.removeElementAt(index);
+ }
+ }
+
+ private void saveStates() {
+
+ IPath savePath = Platform.getPluginStateLocation(CheatSheetPlugin.getPlugin());
+ Path filePath = new Path(savePath.append(ICheatSheetResource.CHEAT_SHEET_SAVE_FILE).toOSString());
+
+ FileWriter mywriter = null;
+
+ try {
+ mywriter = new FileWriter(filePath.toFile());
+
+ for (int i = 0; i < stateVector.size(); i++) {
+ Properties myprop = (Properties) stateVector.elementAt(i);
+
+ String urlstring = (String) myprop.get(IParserTags.URL); //non nls //$NON-NLS-1$
+ String number = (String) myprop.get(IParserTags.CURRENT); //non nls //$NON-NLS-1$
+ ArrayList mylist = (ArrayList) myprop.get(IParserTags.COMPLETED); //$NON-NLS-1$
+ ArrayList elist = (ArrayList) myprop.get(IParserTags.EXPANDED); //$NON-NLS-1$
+ ArrayList eRlist = (ArrayList) myprop.get(IParserTags.EXPANDRESTORE); //$NON-NLS-1$
+ StringBuffer writeString = new StringBuffer();
+ writeString.append(urlstring);
+ writeString.append(";"); //$NON-NLS-1$
+ writeString.append(number);
+ writeString.append(";"); //$NON-NLS-1$
+
+ for (int j = 0; j < mylist.size(); j++) {
+ writeString.append("c"); //$NON-NLS-1$
+ writeString.append((String) mylist.get(j));
+ writeString.append(";"); //$NON-NLS-1$
+ }
+ for (int j = 0; j < elist.size(); j++) {
+ writeString.append("e"); //$NON-NLS-1$
+ writeString.append((String) elist.get(j));
+ writeString.append(";"); //$NON-NLS-1$
+ }
+ for (int j = 0; j < eRlist.size(); j++) {
+ writeString.append("h"); //$NON-NLS-1$
+ writeString.append((String) eRlist.get(j));
+ writeString.append(";"); //$NON-NLS-1$
+ }
+
+ String newstring = (String) myprop.get(IParserTags.BUTTON); //$NON-NLS-1$
+ writeString.append("b"); //$NON-NLS-1$
+ writeString.append(newstring);
+ writeString.append(";"); //$NON-NLS-1$
+
+ writeString.append("\n"); //$NON-NLS-1$
+ mywriter.write(writeString.toString());
+
+ mywriter.close();
+ } //End else if version !>= 2.0
+ } catch (Exception e) {
+ }
+ }
+
+ public void saveThisState(URL urlKey, int stateNum, ViewItem[] myitems, boolean buttonIsDown, ArrayList expandRestoreStates, String csID, CheatSheetManager csm) {
+ Properties prop = createProperties(urlKey, stateNum, myitems, buttonIsDown, expandRestoreStates, csID);
+ saveXMLState(prop, csm, myitems);
+ }
+
+ private void saveXMLState(Properties props, CheatSheetManager csm, ViewItem[] items) {
+ if (xmlsh == null)
+ xmlsh = new CheatSheetXMLSaveHelper();
+ xmlsh.saveStates(props, csm, items);
+ }
+
+ private Properties v1DataExists(String urlToCheck) {
+ duck : for (int i = 0; i < stateVector.size(); i++) {
+ Properties myprop = (Properties) stateVector.elementAt(i);
+ String urlstring = (String) myprop.get(IParserTags.URL); //non nls //$NON-NLS-1$
+ if (urlstring.equals(urlToCheck))
+ return myprop;
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetXMLSaveHelper.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetXMLSaveHelper.java
new file mode 100644
index 000000000..7112849f7
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetXMLSaveHelper.java
@@ -0,0 +1,420 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import javax.xml.parsers.*;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.transform.*;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+//import org.apache.xerces.dom.DocumentImpl;
+//import org.apache.xerces.parsers.DOMParser;
+//import org.apache.xml.serialize.*;
+import org.eclipse.core.runtime.*;
+import org.w3c.dom.*;
+import org.xml.sax.InputSource;
+
+import org.eclipse.ui.internal.cheatsheets.CheatSheetPlugin;
+import org.eclipse.ui.cheatsheets.ISubItem;
+import org.eclipse.ui.internal.cheatsheets.views.*;
+
+public class CheatSheetXMLSaveHelper {
+
+ //Get the path to the cheatsheet folder in the .metadata folder of workspace.
+ private IPath savePath;
+
+ public CheatSheetXMLSaveHelper() {
+ super();
+ savePath = Platform.getPluginStateLocation(CheatSheetPlugin.getPlugin());
+ }
+
+// //For unit testing only.
+// public static void main(String args[]) {
+// CheatSheetXMLSaveHelper xmlsh = new CheatSheetXMLSaveHelper();
+// URL url = null;
+// try {
+// url = new URL("file:D:/eclipse2.1/eclipse/workspace/org.eclipse.ui.cheatsheets.sample/testCheatSheet.xml");
+// } catch (MalformedURLException mue) {
+// }
+// Document doc = xmlsh.readXMLFile(url);
+//
+// }
+
+ /*package*/ Properties loadState(URL urlOfContent) {
+ Properties returnProps = null;
+ Hashtable subskipped = null;
+ Hashtable subcompleted = null;
+
+ String urlstring = urlOfContent.toString();
+ String fileNameToLoad = urlstring.substring(urlstring.lastIndexOf("/"), urlstring.length()); //$NON-NLS-1$
+ // System.out.println("File name to load: " + fileNameToLoad);
+ Path filePath = new Path(savePath.append(fileNameToLoad).toOSString()); //$NON-NLS-1$
+ // System.out.println("Reading from this file: " + filePath);
+ Document doc = null;
+
+ try {
+ URL readURL = filePath.toFile().toURL();
+ doc = readXMLFile(readURL);
+ } catch (MalformedURLException mue) {
+ System.err.println("Could not create url of xml file to read in"); //$NON-NLS-1$
+ return null;
+ }
+
+ if (doc != null) {
+ //Parse stuff from document here.
+ Hashtable ht = null;
+ Node rootnode = doc.getDocumentElement();
+ NamedNodeMap rootatts = rootnode.getAttributes();
+
+ String number = getAttributeWithName(doc.getElementsByTagName(IParserTags.CURRENT).item(0).getAttributes(), IParserTags.ITEM);
+ String currentID = getAttributeWithName(doc.getElementsByTagName(IParserTags.CHEATSHEETID).item(0).getAttributes(), IParserTags.ID);
+ String url = getAttributeWithName(rootatts, IParserTags.URL);
+ ArrayList completeList = getMultipleAttributesWithSameName(doc.getElementsByTagName(IParserTags.COMPLETED), IParserTags.ITEM);
+ ArrayList expandedList = getMultipleAttributesWithSameName(doc.getElementsByTagName(IParserTags.EXPANDED), IParserTags.ITEM);
+ ArrayList expandRestoreList = getMultipleAttributesWithSameName(doc.getElementsByTagName(IParserTags.EXPANDRESTORE), IParserTags.ITEM);
+ String buttonState = getAttributeWithName(doc.getElementsByTagName(IParserTags.BUTTON).item(0).getAttributes(), IParserTags.BUTTONSTATE);
+
+ NodeList nl = doc.getElementsByTagName(IParserTags.SUBITEMCOMPLETED);
+ if (nl != null)
+ subcompleted = new Hashtable(10);
+ for (int i = 0; i < nl.getLength(); i++) {
+ String item = getAttributeWithName(nl.item(i).getAttributes(), IParserTags.ITEM);
+ String subItems = getAttributeWithName(nl.item(i).getAttributes(), IParserTags.SUBITEM);
+ subcompleted.put(item, subItems);
+ } //end for nl
+
+ NodeList snl = doc.getElementsByTagName(IParserTags.SUBITEMSKIPPED);
+ if (snl != null) {
+ subskipped = new Hashtable(10);
+ for (int i = 0; i < snl.getLength(); i++) {
+ String item = getAttributeWithName(snl.item(i).getAttributes(), IParserTags.ITEM);
+ String subItems = getAttributeWithName(snl.item(i).getAttributes(), IParserTags.SUBITEM);
+ subskipped.put(item, subItems);
+ } //end for nl
+ }
+//TODO: Need to fix/handle null data or keys more gracefully!
+ NodeList csmDatanl = doc.getElementsByTagName(IParserTags.MANAGERDATA);
+ if (csmDatanl != null) {
+ ht = new Hashtable(30);
+ for (int i = 0; i < csmDatanl.getLength(); i++) {
+ String key = getAttributeWithName(csmDatanl.item(i).getAttributes(), IParserTags.MANAGERDATAKEY);
+ String data = csmDatanl.item(i).getFirstChild().getNodeValue();
+ ht.put(key, data);
+ }
+ }
+
+ //Parse out the saved steps and sub steps that are dynamic.
+ ArrayList dynamicItemDataList = null;
+ NodeList dynamicNL = doc.getElementsByTagName(IParserTags.DYNAMICDATA);
+ if (dynamicNL != null) {
+ dynamicItemDataList = new ArrayList(30);
+ for (int i = 0; i < dynamicNL.getLength(); i++) {
+ String itemid = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.ITEM);
+ String buttonCodes = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.ACTIONPHRASE);
+ String aclass = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.CLASS);
+ String actionpid = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.PLUGINID);
+ ArrayList actionParams = getParamList(dynamicNL.item(i).getAttributes());
+
+ Properties p = new Properties();
+ p.put(IParserTags.ITEM, itemid);
+ p.put(IParserTags.ACTIONPHRASE, buttonCodes);
+ p.put(IParserTags.CLASS, aclass);
+ p.put(IParserTags.PLUGINID, actionpid);
+ p.put(IParserTags.ACTIONPARAM, actionParams.toArray(new String[actionParams.size()]));
+ dynamicItemDataList.add(p);
+ }
+ }
+
+ //Parse out the saved steps and sub steps that are dynamic.
+ ArrayList dynamicSubItemDataList = null;
+ dynamicNL = doc.getElementsByTagName(IParserTags.DYNAMICSUBITEMDATA);
+ if (dynamicNL != null) {
+ dynamicSubItemDataList = new ArrayList(30);
+ for (int i = 0; i < dynamicNL.getLength(); i++) {
+ String itemid = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.ITEM);
+ String subitemid = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.SUBITEM);
+ String buttonCodes = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.ACTIONPHRASE);
+ String aclass = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.CLASS);
+ String actionpid = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.PLUGINID);
+ String subItemLabel = getAttributeWithName(dynamicNL.item(i).getAttributes(), IParserTags.SUBITEMLABEL);
+ ArrayList actionParams = getParamList(dynamicNL.item(i).getAttributes());
+
+ Properties p = new Properties();
+ p.put(IParserTags.ITEM, itemid);
+ p.put(IParserTags.SUBITEM, subitemid);
+ p.put(IParserTags.ACTIONPHRASE, buttonCodes);
+ p.put(IParserTags.CLASS, aclass);
+ p.put(IParserTags.PLUGINID, actionpid);
+ p.put(IParserTags.SUBITEMLABEL, subItemLabel);
+ p.put(IParserTags.ACTIONPARAM, actionParams.toArray(new String[actionParams.size()]));
+ dynamicSubItemDataList.add(p);
+ }
+ }
+
+ // System.out.println("URL in xml state file read by xml helper is:" + url);
+ returnProps = new Properties();
+ returnProps.put(IParserTags.CHEATSHEETID, currentID);
+ returnProps.put(IParserTags.CURRENT, number);
+ returnProps.put(IParserTags.URL, url);
+ returnProps.put(IParserTags.COMPLETED, completeList);
+ returnProps.put(IParserTags.EXPANDED, expandedList);
+ returnProps.put(IParserTags.EXPANDRESTORE, expandRestoreList);
+ returnProps.put(IParserTags.BUTTON, buttonState);
+ returnProps.put(IParserTags.SUBITEMCOMPLETED, subcompleted);
+ returnProps.put(IParserTags.SUBITEMSKIPPED, subskipped);
+ returnProps.put(IParserTags.MANAGERDATA, ht);
+ returnProps.put(IParserTags.DYNAMICDATA, dynamicItemDataList);
+ returnProps.put(IParserTags.DYNAMICSUBITEMDATA, dynamicSubItemDataList);
+ }
+ return returnProps;
+ }
+
+ private ArrayList getParamList(NamedNodeMap nnm) {
+ ArrayList params = new ArrayList();
+
+ try {
+ String param = "param"; //$NON-NLS-1$
+ for (int j = 0; param != null; j++) {
+ String actionparam = nnm.getNamedItem(IParserTags.ACTIONPARAM + j).getNodeValue();
+ param = actionparam;
+ if (param != null)
+ params.add(param);
+ }
+ } catch (Exception e) {
+ }
+
+ return params;
+ }
+
+ /**
+ * Method parses attribute from named node map. Returns value as string.
+ */
+ private String getAttributeWithName(NamedNodeMap map, String name) {
+ try {
+ return map.getNamedItem(name).getNodeValue();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ /**
+ * Method parses all elements in nodelist, attempts to pull out same attribute from each.
+ * attributes are put into an array list in order they occur in node list elements.
+ */
+ private ArrayList getMultipleAttributesWithSameName(NodeList nl, String name) {
+ ArrayList returnList = new ArrayList();
+ for (int i = 0; i < nl.getLength(); i++) {
+ String value = nl.item(i).getAttributes().getNamedItem(name).getNodeValue();
+ if (value != null)
+ returnList.add(value);
+ }
+ return returnList;
+ }
+
+ //Attempts to read an xml file from the provided url. Returns a Dom Document object if parses ok,
+ //returns null if the parse or read fails.
+ private Document readXMLFile(URL url) {
+ InputStream is = null;
+ InputSource mysource = null;
+
+ try {
+ is = url.openStream();
+ if (is != null) {
+ mysource = new InputSource(is);
+ }
+ } catch (Exception e) {
+ return null;
+ }
+
+ if (mysource == null)
+ return null;
+
+ try {
+ DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ return documentBuilder.parse(mysource);
+ } catch (Exception e) {
+ } finally {
+ try {
+ if (is != null)
+ is.close();
+ } catch (IOException ioe) {
+ }
+ }
+
+ return null;
+ }
+
+ /*package*/ void saveStates(Properties saveProperties, CheatSheetManager csm, ViewItem[] items) {
+
+ try {
+ DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+
+ Document doc = documentBuilder.newDocument();
+
+ Properties myprop = saveProperties;
+ String csID = (String) myprop.get(IParserTags.CHEATSHEETID); //$NON-NLS-1$
+ String urlstring = (String) myprop.get(IParserTags.URL); //non nls //$NON-NLS-1$
+ String number = (String) myprop.get(IParserTags.CURRENT); //non nls //$NON-NLS-1$
+
+ // String urlstringWithoutFile = urlstring.substring(0, urlstring.lastIndexOf("/"));
+ // String pluginID = urlstringWithoutFile.substring(urlstringWithoutFile.lastIndexOf("/"), urlstringWithoutFile.length());
+
+ String fileNameToSave = urlstring.substring(urlstring.lastIndexOf("/"), urlstring.length()); //$NON-NLS-1$
+
+ // System.out.println("File name: " + fileNameToSave);
+ Path filePath = new Path(savePath.append(fileNameToSave).toOSString()); //$NON-NLS-1$
+ // System.out.println("Writing to this file: " + filePath);
+
+ ArrayList completedList = (ArrayList) myprop.get(IParserTags.COMPLETED); //$NON-NLS-1$
+ ArrayList expandedList = (ArrayList) myprop.get(IParserTags.EXPANDED); //$NON-NLS-1$
+ ArrayList expandRestoreList = (ArrayList) myprop.get(IParserTags.EXPANDRESTORE); //$NON-NLS-1$
+ Hashtable subcompletedTable = (Hashtable) myprop.get(IParserTags.SUBITEMCOMPLETED); //$NON-NLS-1$
+ Hashtable subskippedTable = (Hashtable) myprop.get(IParserTags.SUBITEMSKIPPED); //$NON-NLS-1$
+
+ //Create the root element for the document now:
+ Element root = doc.createElement(IParserTags.CHEATSHEET);
+ root.setAttribute(IParserTags.URL, urlstring);
+ doc.appendChild(root);
+
+ Element idEl = doc.createElement(IParserTags.CHEATSHEETID);
+ idEl.setAttribute(IParserTags.ID, csID);
+ root.appendChild(idEl);
+
+ //create current element.
+ Element cEl = doc.createElement(IParserTags.CURRENT);
+ cEl.setAttribute(IParserTags.ITEM, number);
+ root.appendChild(cEl);
+
+ for (int j = 0; j < completedList.size(); j++) {
+ Element compEl = doc.createElement(IParserTags.COMPLETED);
+ compEl.setAttribute(IParserTags.ITEM, (String) completedList.get(j));
+ root.appendChild(compEl);
+ }
+ for (int j = 0; j < expandedList.size(); j++) {
+ Element expandEl = doc.createElement(IParserTags.EXPANDED);
+ expandEl.setAttribute(IParserTags.ITEM, (String) expandedList.get(j));
+ root.appendChild(expandEl);
+ }
+ for (int j = 0; j < expandRestoreList.size(); j++) {
+ Element eRel = doc.createElement(IParserTags.EXPANDRESTORE);
+ eRel.setAttribute(IParserTags.ITEM, (String) expandRestoreList.get(j));
+ root.appendChild(eRel);
+ }
+ if (subcompletedTable != null) {
+ Enumeration enum = subcompletedTable.keys();
+ while (enum.hasMoreElements()) {
+ String itemNum = (String) enum.nextElement();
+ String subItemNum = (String) subcompletedTable.get(itemNum);
+ if (itemNum == null || subItemNum == null)
+ continue;
+ Element eRel = doc.createElement(IParserTags.SUBITEMCOMPLETED);
+ eRel.setAttribute(IParserTags.ITEM, itemNum);
+ eRel.setAttribute(IParserTags.SUBITEM, subItemNum);
+ root.appendChild(eRel);
+ }
+ }
+ if (subskippedTable != null) {
+ Enumeration enum = subskippedTable.keys();
+ while (enum.hasMoreElements()) {
+ String itemNum = (String) enum.nextElement();
+ String subItemNum = (String) subskippedTable.get(itemNum);
+ if (itemNum == null || subItemNum == null)
+ continue;
+ Element eRel = doc.createElement(IParserTags.SUBITEMSKIPPED);
+ eRel.setAttribute(IParserTags.ITEM, itemNum);
+ eRel.setAttribute(IParserTags.SUBITEM, subItemNum);
+ root.appendChild(eRel);
+ }
+ }
+ Element bel = doc.createElement(IParserTags.BUTTON);
+ bel.setAttribute(IParserTags.BUTTONSTATE, (String) myprop.get(IParserTags.BUTTON)); //$NON-NLS-1$
+ root.appendChild(bel);
+
+ //Store cheatsheet data here.
+ Hashtable managerData = (Hashtable)csm.getData();
+ if (managerData != null) {
+ Enumeration e = managerData.keys();
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ String data = (String) managerData.get(key);
+ Element csmDataTag = doc.createElement(IParserTags.MANAGERDATA);
+ csmDataTag.setAttribute(IParserTags.MANAGERDATAKEY, key); //$NON-NLS-1$
+ Text t = doc.createTextNode(data);
+ csmDataTag.appendChild(t);
+ root.appendChild(csmDataTag);
+ }
+ }
+
+ //Store dynamic single step data here.
+ for (int i = 0; i < items.length; i++) {
+ ViewItem item = items[i];
+ IContainsContent c = item.getContentItem();
+ if (c.isDynamic()) {
+ if (c instanceof ContentItem) {
+ ContentItem ci = (ContentItem) c;
+ Element dynamicTag = doc.createElement(IParserTags.DYNAMICDATA);
+ dynamicTag.setAttribute(IParserTags.ITEM, ci.getID());
+ dynamicTag.setAttribute(IParserTags.ACTIONPHRASE, ci.getButtonCodes());
+ dynamicTag.setAttribute(IParserTags.CLASS, ci.getActionClass());
+ dynamicTag.setAttribute(IParserTags.PLUGINID, ci.getActionPluginID());
+ String[] params = ci.getActionParams();
+ for (int j = 0; j < params.length; j++)
+ dynamicTag.setAttribute(IParserTags.ACTIONPARAM + j, params[j]);
+ root.appendChild(dynamicTag);
+ } else if (c instanceof ContentItemWithSubItems) {
+ ContentItemWithSubItems ciws = (ContentItemWithSubItems) c;
+ String itemid = ciws.getID();
+ ISubItem[] subs = ciws.getSubItems();
+ if (subs != null)
+ for (int j = 0; j < subs.length; j++) {
+ ISubItem s = subs[j];
+ String subitemid = s.getID();
+ Element dynamicTag = doc.createElement(IParserTags.DYNAMICSUBITEMDATA);
+ dynamicTag.setAttribute(IParserTags.ITEM, itemid);
+ dynamicTag.setAttribute(IParserTags.SUBITEM, subitemid);
+ dynamicTag.setAttribute(IParserTags.ACTIONPHRASE, s.getButtonCodes());
+ dynamicTag.setAttribute(IParserTags.CLASS, s.getActionClass());
+ dynamicTag.setAttribute(IParserTags.PLUGINID, s.getActionPluginID());
+ dynamicTag.setAttribute(IParserTags.SUBITEMLABEL, s.getLabel());
+ String[] params = s.getActionParams();
+ if(params != null)
+ for (int k = 0; k < params.length; k++)
+ dynamicTag.setAttribute(IParserTags.ACTIONPARAM + k, params[k]);
+ root.appendChild(dynamicTag);
+ }
+ }
+ }
+ }
+
+ StreamResult streamResult = new StreamResult(filePath.toFile());
+
+ DOMSource domSource = new DOMSource(doc);
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+ transformer.transform(domSource, streamResult);
+
+// OutputFormat format = new OutputFormat(doc);
+// FileWriter fw = new FileWriter(filePath.toOSString());
+// PrintWriter pw = new PrintWriter(fw);
+// XMLSerializer serial = new XMLSerializer(pw, format);
+// serial.serialize(doc.getDocumentElement());
+//
+// pw.close();
+// fw.close();
+ } catch (Exception e) {
+ }
+ finally {
+
+ }
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/Content.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/Content.java
new file mode 100644
index 000000000..9298ac32a
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/Content.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+import java.util.ArrayList;
+
+public class Content {
+ private String title;
+ private String href;
+ private String text;
+ private boolean dynamic;
+ private ArrayList itemExtensions;
+
+ /**
+ *
+ */
+ public Content() {
+ super();
+ }
+
+ /**
+ * @return
+ */
+ public boolean isDynamic() {
+ return dynamic;
+ }
+
+ /**
+ * @return
+ */
+ public String getHref() {
+ return href;
+ }
+
+ /**
+ * @return
+ */
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * @return
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * @param b
+ */
+ public void setDynamic(boolean b) {
+ dynamic = b;
+ }
+
+ /**
+ * @param string
+ */
+ public void setHref(String string) {
+ href = string;
+ }
+
+ /**
+ * @param string
+ */
+ public void setText(String string) {
+ text = string;
+ }
+
+ /**
+ * @param string
+ */
+ public void setTitle(String string) {
+ title = string;
+ }
+
+ public void setItemExtensions(ArrayList exts){
+ this.itemExtensions = exts;
+ }
+
+ public ArrayList getItemExtensions(){
+ return itemExtensions;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ContentItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ContentItem.java
new file mode 100644
index 000000000..d0b038cb6
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ContentItem.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+import java.util.ArrayList;
+
+public class ContentItem extends ActionItem implements IContainsContent {
+ private Content content;
+
+ /**
+ * Constructor for ContentItem.
+ */
+ public ContentItem() {
+ super();
+ content = new Content();
+ }
+
+ public ContentItem(String title, String description, String href){
+ super();
+ content = new Content();
+ content.setText(description);
+ content.setTitle(title);
+ content.setHref(href);
+ }
+
+ /**
+ * Returns the helpLink.
+ * @return String
+ */
+ public String getHref() {
+ return content.getHref();
+ }
+
+ /**
+ * Returns the text.
+ * @return String
+ */
+ public String getText() {
+ return content.getText();
+ }
+
+ /**
+ * Returns the title.
+ * @return String
+ */
+ public String getTitle() {
+ return content.getTitle();
+ }
+
+ /**
+ * Sets the helpLink.
+ * @param helpLink The helpLink to set
+ */
+ public void setHref(String helpLink) {
+ content.setHref(helpLink);
+ }
+
+ /**
+ * Sets the text.
+ * @param text The text to set
+ */
+ public void setText(String text) {
+ content.setText(text);
+ }
+
+ /**
+ * Sets the title.
+ * @param title The title to set
+ */
+ public void setTitle(String title) {
+ content.setTitle(title);
+ }
+
+ public boolean isDynamic() {
+ return content.isDynamic();
+ }
+
+ public void setIsDynamic(boolean b) {
+ content.setDynamic(b);
+ }
+
+ public void setContent(Content c){
+ this.content = c;
+ }
+
+ public Content getContent(){
+ return this.content;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.internal.cheatsheets.data.IContainsContent#getItemExtensions()
+ */
+ public ArrayList getItemExtensions() {
+ return content.getItemExtensions();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.internal.cheatsheets.data.IContainsContent#setItemExtensions(java.util.ArrayList)
+ */
+ public void setItemExtensions(ArrayList itemExtensions) {
+ content.setItemExtensions(itemExtensions);
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ContentItemWithSubItems.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ContentItemWithSubItems.java
new file mode 100644
index 000000000..c1fd69249
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ContentItemWithSubItems.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+import java.util.*;
+
+import org.eclipse.ui.cheatsheets.*;
+
+public class ContentItemWithSubItems extends AbstractItem implements IContainsContent, IItemWithSubItems {
+ private Content content;
+
+ private ArrayList subItems;
+
+ /**
+ *
+ */
+ public ContentItemWithSubItems() {
+ super();
+ content = new Content();
+ subItems = new ArrayList(10);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItemWithSubItems#addSubItem(org.eclipse.ui.cheatsheets.ISubItem)
+ */
+ public boolean addSubItem(ISubItem sub) {
+ if(isDuplicateId(sub.getID()))
+ return false;
+ if(subItems == null)
+ subItems = new ArrayList(20);
+ subItems.add(sub);
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItemWithSubItems#addSubItem(org.eclipse.ui.cheatsheets.ISubItem, int)
+ */
+ public boolean addSubItem(ISubItem sub, int index) throws IndexOutOfBoundsException {
+ if(isDuplicateId(sub.getID()))
+ return false;
+ subItems.add(index, sub);
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItemWithSubItems#addSubItems(org.eclipse.ui.cheatsheets.ISubItem[])
+ */
+ public void addSubItems(ISubItem[] subitems) {
+ if (subitems == null)
+ this.subItems = null;
+ else
+ this.subItems = new ArrayList(Arrays.asList(subitems));
+ }
+
+ public Content getContent() {
+ return this.content;
+ }
+
+ /**
+ * Returns the helpLink.
+ * @return String
+ */
+ public String getHref() {
+ return content.getHref();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItemWithSubItems#getSubItem(int)
+ */
+ public ISubItem getSubItem(int index) throws IndexOutOfBoundsException {
+ return (ISubItem) subItems.get(index);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItemWithSubItems#getSubItems()
+ */
+ public ISubItem[] getSubItems() {
+ if(subItems == null)
+ return null;
+ return (ISubItem[]) subItems.toArray(new ISubItem[subItems.size()]);
+ }
+
+ /**
+ * Returns the text.
+ * @return String
+ */
+ public String getText() {
+ return content.getText();
+ }
+
+ /**
+ * Returns the title.
+ * @return String
+ */
+ public String getTitle() {
+ return content.getTitle();
+ }
+
+ private boolean isDuplicateId(String id){
+ if(subItems!=null)
+ for(int i=0; i<subItems.size(); i++){
+ ISubItem isi = (ISubItem)subItems.get(i);
+ if(isi.getID().equals(id))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isDynamic() {
+ return content.isDynamic();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItemWithSubItems#removeSubItem(int)
+ */
+ public boolean removeSubItem(int index) throws IndexOutOfBoundsException {
+ subItems.remove(index);
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItemWithSubItems#removeSubItem(org.eclipse.ui.cheatsheets.ISubItem)
+ */
+ public boolean removeSubItem(ISubItem item) {
+ int index = subItems.indexOf(item);
+ if (index != -1) {
+ subItems.remove(index);
+ return true;
+ } else
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.IItemWithSubItems#removeSubItems()
+ */
+ public void removeSubItems() {
+ subItems = new ArrayList();
+ }
+
+ public void setContent(Content c) {
+ this.content = c;
+ }
+
+ /**
+ * Sets the helpLink.
+ * @param helpLink The helpLink to set
+ */
+ public void setHref(String helpLink) {
+ content.setHref(helpLink);
+ }
+
+ public void setIsDynamic(boolean b) {
+ content.setDynamic(b);
+ }
+
+ /**
+ * Sets the text.
+ * @param text The text to set
+ */
+ public void setText(String text) {
+ content.setText(text);
+ }
+
+ /**
+ * Sets the title.
+ * @param title The title to set
+ */
+ public void setTitle(String title) {
+ content.setTitle(title);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.internal.cheatsheets.data.IContainsContent#getItemExtensions()
+ */
+ public ArrayList getItemExtensions() {
+ return content.getItemExtensions();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.internal.cheatsheets.data.IContainsContent#setItemExtensions(java.util.ArrayList)
+ */
+ public void setItemExtensions(ArrayList itemExtensions) {
+ content.setItemExtensions(itemExtensions);
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IContainsContent.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IContainsContent.java
new file mode 100644
index 000000000..f0fd7b4a9
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IContainsContent.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+import java.util.ArrayList;
+
+public interface IContainsContent {
+
+ /**
+ * Returns the helpLink.
+ * @return String
+ */
+ public String getHref();
+
+ /**
+ * Returns the text.
+ * @return String
+ */
+ public String getText();
+
+ /**
+ * Returns the title.
+ * @return String
+ */
+ public String getTitle();
+
+ /**
+ * Sets the helpLink.
+ * @param helpLink The helpLink to set
+ */
+ public void setHref(String helpLink);
+
+ /**
+ * Sets the text.
+ * @param text The text to set
+ */
+ public void setText(String text);
+
+ /**
+ * Sets the title.
+ * @param title The title to set
+ */
+ public void setTitle(String title);
+
+ public boolean isDynamic();
+
+ public void setIsDynamic(boolean b);
+
+ public void setContent(Content c);
+
+ public Content getContent();
+
+ public void setItemExtensions(ArrayList itemExtensions);
+
+ public ArrayList getItemExtensions();
+
+}
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
new file mode 100644
index 000000000..0a8dfd30f
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/IParserTags.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+/**
+ * Interface containing the constants used by the cheatsheet parser
+ * to identify the tags used in the cheatsheet file.
+ */
+public interface IParserTags {
+ public static final String copyright = "Licensed Material - Property of IBM <<PART NUMBER - 5724-D15>> (C) Copyright IBM Corp. 2003 - All Rights Reserved. US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.".intern(); //$NON-NLS-1$
+ public static final String TITLE = "title"; //$NON-NLS-1$
+ public static final String INTRO = "intro"; //$NON-NLS-1$
+ public static final String HREF = "href"; //$NON-NLS-1$
+ public static final String ITEM = "item"; //$NON-NLS-1$
+ public static final String SUBITEM = "subitem"; //$NON-NLS-1$
+ public static final String SUPERITEM = "superitem"; //$NON-NLS-1$
+ public static final String LABEL = "label"; //$NON-NLS-1$
+ public static final String PLUGINID = "pluginId"; //$NON-NLS-1$
+ public static final String CHEATSHEETID = "cheatsheetID"; //$NON-NLS-1$
+ public static final String CHEATSHEET = "Cheatsheet"; //$NON-NLS-1$
+ public static final String CLASS = "class"; //$NON-NLS-1$
+ public static final String ACTIONPHRASE = "actionphrase"; //$NON-NLS-1$
+ public static final String ACTIONPARAM = "actionparam"; //$NON-NLS-1$
+ public static final String ACTION = "action"; //$NON-NLS-1$
+ public static final String VERSION = "version";//$NON-NLS-1$
+ public static final String ID = "id";//$NON-NLS-1$
+ public static final String DYNAMIC = "dynamic";//$NON-NLS-1$
+ public static final String CHEATSHEETMANAGER = "CheatsheetManager";//$NON-NLS-1$
+ public static final String MANAGERDATA = "CSMData";//$NON-NLS-1$
+ public static final String MANAGERDATAKEY = "key"; //$NON-NLS-1$
+ public static final String DYNAMICDATA = "dynamicData"; //$NON-NLS-1$
+ public static final String DYNAMICSUBITEMDATA = "dynamicSubItemData"; //$NON-NLS-1$
+ public static final String SUBITEMLABEL ="subitemlabel"; //$NON-NLS-1$
+
+ public static final String COMPLETED ="completed"; //$NON-NLS-1$
+ public static final String SUBITEMCOMPLETED ="subitemcompleted"; //$NON-NLS-1$
+ public static final String SUBITEMSKIPPED ="subitemskipped"; //$NON-NLS-1$
+ public static final String CURRENT = "current"; //$NON-NLS-1$
+ public static final String EXPANDED = "expanded"; //$NON-NLS-1$
+ public static final String EXPANDRESTORE = "expandRestore"; //$NON-NLS-1$
+ public static final String BUTTON = "button"; //$NON-NLS-1$
+ public static final String BUTTONSTATE = "buttonstate"; //$NON-NLS-1$
+ public static final String URL = "url"; //$NON-NLS-1$
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/SubContentItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/SubContentItem.java
new file mode 100644
index 000000000..a46f2ccdc
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/SubContentItem.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.data;
+
+import org.eclipse.ui.cheatsheets.ISubItem;
+
+public class SubContentItem extends ActionItem implements ISubItem {
+
+ private String label;
+
+ public SubContentItem() {
+ super();
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String string) {
+ label = string;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java
new file mode 100644
index 000000000..60cc73a25
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java
@@ -0,0 +1,382 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.dialogs;
+
+
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.model.*;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.registry.*;
+
+/**
+ * Dialog to allow the user to select a cheat sheet from a list.
+ */
+public class CheatSheetCategoryBasedSelectionDialog extends SelectionDialog implements ISelectionChangedListener {
+ private IDialogSettings settings;
+ private CheatSheetCollectionElement cheatsheetCategories;
+ private CheatSheetElement currentSelection;
+ private TreeViewer categoryTreeViewer;
+ private TableViewer cheatsheetSelectionViewer;
+ private final static int SIZING_CATEGORY_LIST_HEIGHT = 150;
+ private final static int SIZING_CATEGORY_LIST_WIDTH = 180;
+ private final static int SIZING_CHEATSHEET_LIST_HEIGHT = 150;
+ private final static int SIZING_CHEATSHEET_LIST_WIDTH = 350;
+ private boolean okButtonState;
+
+ // id constants
+ private final static String STORE_SELECTED_CATEGORY_ID =
+ "CheatSheetCategoryBasedSelectionDialog.STORE_SELECTED_CATEGORY_ID"; //$NON-NLS-1$
+ private final static String STORE_EXPANDED_CATEGORIES_ID =
+ "CheatSheetCategoryBasedSelectionDialog.STORE_EXPANDED_CATEGORIES_ID"; //$NON-NLS-1$
+ private final static String STORE_SELECTED_CHEATSHEET_ID =
+ "CheatSheetCategoryBasedSelectionDialog.STORE_SELECTED_CHEATSHEET_ID"; //$NON-NLS-1$
+
+ /**
+ * Creates an instance of this dialog to display
+ * the a list of cheat sheets.
+ *
+ * @param shell the parent shell
+ */
+ public CheatSheetCategoryBasedSelectionDialog(Shell shell, CheatSheetCollectionElement cheatsheetCategories) {
+ super(shell);
+
+ this.cheatsheetCategories = cheatsheetCategories;
+
+ setTitle(CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEET_SELECTION_DIALOG_TITLE));
+ setMessage(CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEET_SELECTION_DIALOG_MSG));
+
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Window.
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ // WorkbenchHelp.setHelp(newShell, IHelpContextIds.WELCOME_PAGE_SELECTION_DIALOG);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Dialog.
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+
+ enableOKButton(okButtonState);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Dialog.
+ */
+ protected Control createDialogArea(Composite parent) {
+ IDialogSettings workbenchSettings = CheatSheetPlugin.getPlugin().getDialogSettings();
+ IDialogSettings dialogSettings = workbenchSettings.getSection("CheatSheetCategoryBasedSelectionDialog");//$NON-NLS-1$
+ if(dialogSettings==null)
+ dialogSettings = workbenchSettings.addNewSection("CheatSheetCategoryBasedSelectionDialog");//$NON-NLS-1$
+
+ setDialogSettings(dialogSettings);
+
+ // top level group
+ Composite outerContainer = (Composite) super.createDialogArea(parent);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ outerContainer.setLayout(layout);
+ outerContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // Create label
+ createMessageArea(outerContainer);
+
+ // category tree pane...create SWT tree directly to
+ // get single selection mode instead of multi selection.
+ Tree tree = new Tree(outerContainer, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+ categoryTreeViewer = new TreeViewer(tree);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.widthHint = SIZING_CATEGORY_LIST_WIDTH;
+ data.heightHint = SIZING_CATEGORY_LIST_HEIGHT;
+ categoryTreeViewer.getTree().setLayoutData(data);
+ categoryTreeViewer.setContentProvider(new BaseWorkbenchContentProvider());
+ categoryTreeViewer.setLabelProvider(new WorkbenchLabelProvider());
+ categoryTreeViewer.setSorter(CheatSheetCollectionSorter.INSTANCE);
+ categoryTreeViewer.addSelectionChangedListener(this);
+ categoryTreeViewer.setInput(cheatsheetCategories);
+
+ // cheatsheet actions pane...create SWT table directly to
+ // get single selection mode instead of multi selection.
+ Table table = new Table(outerContainer, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+ cheatsheetSelectionViewer = new TableViewer(table);
+ data = new GridData(GridData.FILL_BOTH);
+ data.widthHint = SIZING_CHEATSHEET_LIST_WIDTH;
+ data.heightHint = SIZING_CHEATSHEET_LIST_HEIGHT;
+ cheatsheetSelectionViewer.getTable().setLayoutData(data);
+ cheatsheetSelectionViewer.setContentProvider(getCheatSheetProvider());
+ cheatsheetSelectionViewer.setLabelProvider(new WorkbenchLabelProvider());
+ cheatsheetSelectionViewer.addSelectionChangedListener(this);
+
+ // Add double-click listener
+ cheatsheetSelectionViewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ okPressed();
+ }
+ });
+
+ restoreWidgetValues();
+
+ if (!categoryTreeViewer.getSelection().isEmpty())
+ // we only set focus if a selection was restored
+ categoryTreeViewer.getTree().setFocus();
+
+ return outerContainer;
+ }
+
+ /**
+ * @see org.eclipse.ui.dialogs.SelectionDialog#createMessageArea(Composite)
+ */
+ protected Label createMessageArea(Composite composite) {
+ Label label = new Label(composite,SWT.NONE);
+ label.setText(getMessage());
+
+ GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
+ gridData.horizontalSpan = 2;
+ label.setLayoutData(gridData);
+
+ return label;
+ }
+
+ /**
+ * Method enableOKButton enables/diables the OK button for the dialog
+ * and saves the state, allowing the enabling/disabling to occur even if
+ * the button has not been created yet.
+ *
+ * @param value
+ */
+ private void enableOKButton(boolean value) {
+ Button button = getButton(IDialogConstants.OK_ID);
+
+ okButtonState = value;
+ if( button != null ) {
+ button.setEnabled(value);
+ }
+ }
+
+ /**
+ * Expands the cheatsheet categories in this page's category viewer that were
+ * expanded last time this page was used. If a category that was previously
+ * expanded no longer exists then it is ignored.
+ */
+ protected void expandPreviouslyExpandedCategories() {
+ String[] expandedCategoryPaths = settings.getArray(STORE_EXPANDED_CATEGORIES_ID);
+ List categoriesToExpand = new ArrayList(expandedCategoryPaths.length);
+
+ for (int i = 0; i < expandedCategoryPaths.length; i++){
+ CheatSheetCollectionElement category =
+ cheatsheetCategories.findChildCollection(
+ new Path(expandedCategoryPaths[i]));
+ if (category != null) // ie.- it still exists
+ categoriesToExpand.add(category);
+ }
+
+ if (!categoriesToExpand.isEmpty())
+ categoryTreeViewer.setExpandedElements(categoriesToExpand.toArray());
+ }
+
+ /**
+ * Returns the content provider for this page.
+ */
+ protected IContentProvider getCheatSheetProvider() {
+ //want to get the cheatsheets of the collection element
+ return new BaseWorkbenchContentProvider() {
+ public Object[] getChildren(Object o) {
+ if (o instanceof CheatSheetCollectionElement) {
+ return ((CheatSheetCollectionElement)o).getCheatSheets();
+ }
+ return new Object[0];
+ }
+ };
+ }
+
+ /**
+ * Returns the single selected object contained in the passed selectionEvent,
+ * or <code>null</code> if the selectionEvent contains either 0 or 2+ selected
+ * objects.
+ */
+ protected Object getSingleSelection(IStructuredSelection selection) {
+ return selection.size() == 1 ? selection.getFirstElement() : null;
+ }
+
+ /**
+ * Handle the (de)selection of cheatsheet element(s)
+ *
+ * @param selectionEvent SelectionChangedEvent
+ */
+ private void handleCategorySelection(SelectionChangedEvent selectionEvent) {
+ Object currentSelection = cheatsheetSelectionViewer.getInput();
+ Object selectedCategory =
+ getSingleSelection((IStructuredSelection)selectionEvent.getSelection());
+ if (currentSelection != selectedCategory) {
+ cheatsheetSelectionViewer.setInput(selectedCategory);
+
+ enableOKButton(false);
+ }
+ }
+
+ /**
+ * Handle the (de)selection of cheatsheet element(s)
+ *
+ * @param selectionEvent SelectionChangedEvent
+ */
+ private void handleCheatSheetSelection(SelectionChangedEvent selectionEvent) {
+ currentSelection = (CheatSheetElement)getSingleSelection((IStructuredSelection)selectionEvent.getSelection());
+
+ if( currentSelection != null ) {
+ enableOKButton(true);
+ }
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Dialog.
+ */
+ protected void okPressed() {
+ if( currentSelection != null ) {
+ ArrayList result = new ArrayList(1);
+ result.add(currentSelection);
+ setResult(result);
+ } else {
+ return;
+ }
+
+ //save our selection state
+ saveWidgetValues();
+
+ super.okPressed();
+ }
+
+ /**
+ * Set self's widgets to the values that they held last time this page was open
+ *
+ */
+ protected void restoreWidgetValues() {
+ String[] expandedCategoryPaths = settings.getArray(STORE_EXPANDED_CATEGORIES_ID);
+ if (expandedCategoryPaths == null)
+ return; // no stored values
+
+ expandPreviouslyExpandedCategories();
+ selectPreviouslySelectedCategoryAndCheatSheet();
+ }
+
+ /**
+ * Store the current values of self's widgets so that they can
+ * be restored in the next instance of self
+ *
+ */
+ public void saveWidgetValues() {
+ storeExpandedCategories();
+ storeSelectedCategoryAndCheatSheet();
+ }
+
+ /**
+ * The user selected either new cheatsheet category(s) or cheatsheet element(s).
+ * Proceed accordingly.
+ *
+ * @param newSelection ISelection
+ */
+ public void selectionChanged(SelectionChangedEvent selectionEvent) {
+ if (selectionEvent.getSelectionProvider().equals(categoryTreeViewer))
+ handleCategorySelection(selectionEvent);
+ else
+ handleCheatSheetSelection(selectionEvent);
+ }
+
+ /**
+ * Selects the cheatsheet category and cheatsheet in this page that were selected
+ * last time this page was used. If a category or cheatsheet that was previously
+ * selected no longer exists then it is ignored.
+ */
+ protected void selectPreviouslySelectedCategoryAndCheatSheet() {
+ String categoryId = settings.get(STORE_SELECTED_CATEGORY_ID);
+ if (categoryId == null)
+ return;
+ CheatSheetCollectionElement category =
+ cheatsheetCategories.findChildCollection(new Path(categoryId));
+ if (category == null)
+ return; // category no longer exists, or has moved
+
+ StructuredSelection selection = new StructuredSelection(category);
+ categoryTreeViewer.setSelection(selection);
+ selectionChanged(new SelectionChangedEvent(categoryTreeViewer,selection));
+
+ String cheatsheetId = settings.get(STORE_SELECTED_CHEATSHEET_ID);
+ if (cheatsheetId == null)
+ return;
+ CheatSheetElement cheatsheet = category.findCheatSheet(cheatsheetId,false);
+ if (cheatsheet == null)
+ return; // cheatsheet no longer exists, or has moved
+
+ selection = new StructuredSelection(cheatsheet);
+ cheatsheetSelectionViewer.setSelection(selection);
+ selectionChanged(new SelectionChangedEvent(cheatsheetSelectionViewer,selection));
+ }
+
+ /**
+ * Set the dialog store to use for widget value storage and retrieval
+ *
+ * @param settings IDialogSettings
+ */
+ public void setDialogSettings(IDialogSettings settings) {
+ this.settings = settings;
+ }
+
+ /**
+ * Stores the collection of currently-expanded categories in this page's dialog store,
+ * in order to recreate this page's state in the next instance of this page.
+ */
+ protected void storeExpandedCategories() {
+ Object[] expandedElements = categoryTreeViewer.getExpandedElements();
+ String[] expandedElementPaths = new String[expandedElements.length];
+ for (int i = 0; i < expandedElements.length; ++i) {
+ expandedElementPaths[i] =
+ ((CheatSheetCollectionElement)expandedElements[i]).getPath().toString();
+ }
+ settings.put(
+ STORE_EXPANDED_CATEGORIES_ID,
+ expandedElementPaths);
+ }
+
+ /**
+ * Stores the currently-selected category and cheatsheet in this page's dialog store,
+ * in order to recreate this page's state in the next instance of this page.
+ */
+ protected void storeSelectedCategoryAndCheatSheet() {
+ CheatSheetCollectionElement selectedCategory = (CheatSheetCollectionElement)
+ getSingleSelection((IStructuredSelection)categoryTreeViewer.getSelection());
+
+ if (selectedCategory != null) {
+ settings.put(
+ STORE_SELECTED_CATEGORY_ID,
+ selectedCategory.getPath().toString());
+ }
+
+ CheatSheetElement selectedCheatSheet = (CheatSheetElement)
+ getSingleSelection((IStructuredSelection)cheatsheetSelectionViewer.getSelection());
+
+ if (selectedCheatSheet != null) {
+ settings.put(
+ STORE_SELECTED_CHEATSHEET_ID,
+ selectedCheatSheet.getID());
+ }
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetSelectionDialog.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetSelectionDialog.java
new file mode 100644
index 000000000..27b2e09fd
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetSelectionDialog.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.dialogs;
+
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.registry.*;
+
+/**
+ * Dialog to allow the user to select a cheat sheet from a list.
+ */
+public class CheatSheetSelectionDialog extends SelectionDialog {
+ /**
+ * The SimpleListContentProvider is a class designed to return a static list of items
+ * when queried for use in simple list dialogs.
+ */
+ public class SimpleListContentProvider implements IStructuredContentProvider{
+
+ //The elements to display
+ private Object[] elements;
+
+ /**
+ * SimpleListContentProvider constructor comment.
+ */
+ public SimpleListContentProvider() {
+ super();
+ }
+ /**
+ * Do nothing when disposing,
+ */
+ public void dispose() {}
+ /**
+ * Returns the elements to display in the viewer. The inputElement is ignored for this
+ * provider.
+ */
+ public Object[] getElements(Object inputElement) {
+ return this.elements;
+ }
+ /**
+ * Required method from IStructuredContentProvider. The input is assumed to not change
+ * for the SimpleListContentViewer so do nothing here.
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
+ /**
+ * Set the elements to display.
+ * @param items Object[]
+ */
+ public void setElements(Object[] items) {
+
+ this.elements = items;
+ }
+ }
+
+ /**
+ * List width in characters.
+ */
+ private final static int LIST_WIDTH = 60;
+ /**
+ * List height in characters.
+ */
+ private final static int LIST_HEIGHT = 10;
+ /**
+ * List to display the resolutions.
+ */
+ private ListViewer listViewer;
+
+ /**
+ * Creates an instance of this dialog to display
+ * the a list of cheat sheets.
+ *
+ * @param shell the parent shell
+ */
+ public CheatSheetSelectionDialog(Shell shell) {
+ super(shell);
+
+ setTitle(CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEET_SELECTION_DIALOG_TITLE));
+ setMessage(CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEET_SELECTION_DIALOG_MSG));
+
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ }
+
+ private void addCheatSheets(ArrayList list, CheatSheetCollectionElement cheatSheetsCollection) {
+ Object[] cheatSheets = cheatSheetsCollection.getCheatSheets();
+ for (int i = 0; i < cheatSheets.length; i++) {
+ if (!list.contains(cheatSheets[i])) {
+ list.add(cheatSheets[i]);
+ }
+ }
+
+ Object[] cheatSheetsFromCollection = cheatSheetsCollection.getChildren();
+ for (int nX = 0; nX < cheatSheetsFromCollection.length; nX++) {
+ CheatSheetCollectionElement collection = (CheatSheetCollectionElement) cheatSheetsFromCollection[nX];
+ addCheatSheets(list, collection);
+ }
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Window.
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ // WorkbenchHelp.setHelp(newShell, IHelpContextIds.WELCOME_PAGE_SELECTION_DIALOG);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Dialog.
+ */
+ protected Control createDialogArea(Composite parent) {
+ ArrayList list = new ArrayList(10);
+ CheatSheetCollectionElement cheatSheetsCollection = (CheatSheetCollectionElement)CheatSheetRegistryReader.getInstance().getCheatSheets();
+ addCheatSheets(list, cheatSheetsCollection);
+
+ Composite composite = (Composite) super.createDialogArea(parent);
+
+ // Create label
+ createMessageArea(composite);
+ // Create list viewer
+ listViewer = new ListViewer(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.heightHint = convertHeightInCharsToPixels(LIST_HEIGHT);
+ data.widthHint = convertWidthInCharsToPixels(LIST_WIDTH);
+ listViewer.getList().setLayoutData(data);
+ // Set the label provider
+ listViewer.setLabelProvider(new LabelProvider() {
+ public String getText(Object element) {
+ // Return the features's label.
+ return element == null ? "" : ((CheatSheetElement) element).getLabel(null); //$NON-NLS-1$
+ }
+ });
+
+ // Set the content provider
+ SimpleListContentProvider cp = new SimpleListContentProvider();
+ cp.setElements(list.toArray());
+ listViewer.setContentProvider(cp);
+ listViewer.setInput(new Object()); // it is ignored but must be non-null
+
+ // Set the initial selection
+ if (getInitialElementSelections() != null)
+ listViewer.setSelection(new StructuredSelection(getInitialElementSelections()), true);
+
+ // Add a selection change listener
+ listViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ // Update OK button enablement
+ getOkButton().setEnabled(!event.getSelection().isEmpty());
+ }
+ });
+
+ // Add double-click listener
+ listViewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ okPressed();
+ }
+ });
+ return composite;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Dialog.
+ */
+ protected void okPressed() {
+ IStructuredSelection selection = (IStructuredSelection) listViewer.getSelection();
+ setResult(selection.toList());
+
+ super.okPressed();
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetCollectionElement.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetCollectionElement.java
new file mode 100644
index 000000000..1388f5f0d
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetCollectionElement.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.registry;
+
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.ui.model.AdaptableList;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+/**
+ * Instances of this class are a collection of CheatSheetCollectionElements,
+ * thereby facilitating the definition of tree structures composed of
+ * these elements. Instances also store a list of cheatsheets.
+ */
+public class CheatSheetCollectionElement extends AdaptableList {
+ private String id;
+ private String name;
+ private CheatSheetCollectionElement parent;
+ private AdaptableList cheatsheets = new AdaptableList();
+
+ /**
+ * Creates a new <code>CheatSheetCollectionElement</code>. Parent can be null.
+ *
+ * @param name java.lang.String
+ */
+ public CheatSheetCollectionElement(String id, String name, CheatSheetCollectionElement parent) {
+ this.name = name;
+ this.id = id;
+ this.parent = parent;
+ }
+
+ /**
+ * Adds a cheatsheet collection to this collection.
+ */
+ public AdaptableList add(IAdaptable a) {
+ if (a instanceof CheatSheetElement) {
+ cheatsheets.add(a);
+ } else {
+ super.add(a);
+ }
+ return this;
+ }
+
+ /**
+ * Returns the cheatsheet collection child object corresponding to the
+ * passed path (relative to this object), or <code>null</code> if
+ * such an object could not be found.
+ *
+ * @param searchPath org.eclipse.core.runtime.IPath
+ * @return CheatSheetCollectionElement
+ */
+ public CheatSheetCollectionElement findChildCollection(IPath searchPath) {
+ Object[] children = getChildren(null);
+ String searchString = searchPath.segment(0);
+ for (int i = 0; i < children.length; ++i) {
+ CheatSheetCollectionElement currentCategory = (CheatSheetCollectionElement) children[i];
+ if (currentCategory.getLabel(null).equals(searchString)) {
+ if (searchPath.segmentCount() == 1)
+ return currentCategory;
+
+ return currentCategory.findChildCollection(searchPath.removeFirstSegments(1));
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns this collection's associated cheatsheet object corresponding to the
+ * passed id, or <code>null</code> if such an object could not be found.
+ */
+ public CheatSheetElement findCheatSheet(String searchId, boolean recursive) {
+ Object[] cheatsheets = getCheatSheets();
+ for (int i = 0; i < cheatsheets.length; ++i) {
+ CheatSheetElement currentCheatSheet = (CheatSheetElement) cheatsheets[i];
+ if (currentCheatSheet.getID().equals(searchId))
+ return currentCheatSheet;
+ }
+ if (!recursive)
+ return null;
+ for (Iterator iterator = children.iterator(); iterator.hasNext();) {
+ CheatSheetCollectionElement child = (CheatSheetCollectionElement) iterator.next();
+ CheatSheetElement result = child.findCheatSheet(searchId, true);
+ if (result != null)
+ return result;
+ }
+ return null;
+ }
+
+ /**
+ * Returns an object which is an instance of the given class
+ * associated with this object. Returns <code>null</code> if
+ * no such object can be found.
+ */
+ public Object getAdapter(Class adapter) {
+ if (adapter == IWorkbenchAdapter.class) {
+ return this;
+ }
+ return Platform.getAdapterManager().getAdapter(this, adapter);
+ }
+
+ /**
+ * Returns the unique ID of this element.
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the label for this collection.
+ */
+ public String getLabel(Object o) {
+ return name;
+ }
+
+ /**
+ * Returns the logical parent of the given object in its tree.
+ */
+ public Object getParent(Object o) {
+ return parent;
+ }
+
+ /**
+ * Returns a path representing this collection's ancestor chain.
+ */
+ public IPath getPath() {
+ if (parent == null)
+ return new Path(""); //$NON-NLS-1$
+
+ return parent.getPath().append(name);
+ }
+
+ /**
+ * Returns this collection element's associated collection of cheatsheets.
+ */
+ public Object[] getCheatSheets() {
+ return cheatsheets.getChildren();
+ }
+
+ /**
+ * Returns true if this element has no children and no cheatsheets.
+ */
+ public boolean isEmpty() {
+ return size() == 0 && cheatsheets.size() == 0;
+ }
+
+ /**
+ * Sets this collection's unique id.
+ */
+ public void setId(java.lang.String newId) {
+ id = newId;
+ }
+
+ /**
+ * Sets the collection of cheatsheets associated with this collection element.
+ */
+ public void setCheatSheets(AdaptableList value) {
+ cheatsheets = value;
+ }
+
+ /**
+ * For debugging purposes.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer("CheatSheetCollection, "); //$NON-NLS-1$
+ buf.append(children.size());
+ buf.append(" children, "); //$NON-NLS-1$
+ buf.append(cheatsheets.size());
+ buf.append(" cheatsheets"); //$NON-NLS-1$
+ return buf.toString();
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetCollectionSorter.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetCollectionSorter.java
new file mode 100644
index 000000000..b20edc3d1
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetCollectionSorter.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.registry;
+
+import java.text.Collator;
+
+import org.eclipse.jface.viewers.*;
+
+/**
+ * A Viewer element sorter that sorts Elements by their name attribute.
+ * Note that capitalization differences are not considered by this
+ * sorter, so a < B < c.
+ */
+public class CheatSheetCollectionSorter extends ViewerSorter {
+ public final static CheatSheetCollectionSorter INSTANCE = new CheatSheetCollectionSorter();
+ private Collator collator = Collator.getInstance();
+
+ /**
+ * Creates an instance of <code>NewWizardCollectionSorter</code>. Since this
+ * is a stateless sorter, it is only accessible as a singleton; the private
+ * visibility of this constructor ensures this.
+ */
+ private CheatSheetCollectionSorter() {
+ super();
+ }
+
+ /**
+ * The 'compare' method of the sort operation.
+ *
+ * @return the value <code>0</code> if the argument o1 is equal to o2;
+ * a value less than <code>0</code> if o1 is less than o2;
+ * and a value greater than <code>0</code> if o1 is greater than o2.
+ */
+ public int compare(Viewer viewer, Object o1, Object o2) {
+ String name1 = ((CheatSheetCollectionElement) o1).getLabel(o1);
+ String name2 = ((CheatSheetCollectionElement) o2).getLabel(o2);
+
+ if (name1.equals(name2))
+ return 0;
+
+ return collator.compare(name1, name2);
+ }
+
+ /**
+ * Return true if this sorter is affected by a property
+ * change of propertyName on the specified element.
+ */
+ public boolean isSorterProperty(Object object, String propertyId) {
+ return propertyId.equals(IBasicPropertyConstants.P_TEXT);
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetElement.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetElement.java
new file mode 100644
index 000000000..e7e6467d6
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetElement.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.registry;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.model.WorkbenchAdapter;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+
+/**
+ * Instances represent registered cheatsheets.
+ */
+public class CheatSheetElement extends WorkbenchAdapter implements IAdaptable {
+ private String contentFile;
+ private String id;
+ private String name;
+ private ImageDescriptor imageDescriptor;
+ private String description;
+ private IConfigurationElement configurationElement;
+
+ /**
+ * Create a new instance of this class
+ *
+ * @param name java.lang.String
+ */
+ public CheatSheetElement(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns an object which is an instance of the given class
+ * associated with this object. Returns <code>null</code> if
+ * no such object can be found.
+ */
+ public Object getAdapter(Class adapter) {
+ if (adapter == IWorkbenchAdapter.class) {
+ return this;
+ }
+ return Platform.getAdapterManager().getAdapter(this, adapter);
+ }
+
+ /**
+ *
+ * @return IConfigurationElement
+ */
+ public IConfigurationElement getConfigurationElement() {
+ return configurationElement;
+ }
+
+ /**
+ * Answer the contentFile parameter of this element
+ *
+ * @return java.lang.String
+ */
+ public String getContentFile() {
+ return contentFile;
+ }
+
+ /**
+ * Answer the description parameter of this element
+ *
+ * @return java.lang.String
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Answer the id as specified in the extension.
+ *
+ * @return java.lang.String
+ */
+ public String getID() {
+ return id;
+ }
+
+ /**
+ * Answer the icon of this element.
+ */
+ public ImageDescriptor getImageDescriptor() {
+ return imageDescriptor;
+ }
+
+ /**
+ * Returns the name of this cheatsheet element.
+ */
+ public ImageDescriptor getImageDescriptor(Object element) {
+ return imageDescriptor;
+ }
+
+ /**
+ * Returns the name of this cheatsheet element.
+ */
+ public String getLabel(Object element) {
+ return name;
+ }
+
+ /**
+ *
+ * @param newConfigurationElement IConfigurationElement
+ */
+ public void setConfigurationElement(IConfigurationElement newConfigurationElement) {
+ configurationElement = newConfigurationElement;
+ }
+
+ /**
+ * Set the contentFile parameter of this element
+ *
+ * @param value java.lang.String
+ */
+ public void setContentFile(String value) {
+ contentFile = value;
+ }
+
+ /**
+ * Set the description parameter of this element
+ *
+ * @param value java.lang.String
+ */
+ public void setDescription(String value) {
+ description = value;
+ }
+
+ /**
+ * Set the id parameter of this element
+ *
+ * @param value java.lang.String
+ */
+ public void setID(String value) {
+ id = value;
+ }
+
+ /**
+ * Set the icon of this element.
+ */
+ public void setImageDescriptor(ImageDescriptor value) {
+ imageDescriptor = value;
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetListenerElement.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetListenerElement.java
new file mode 100644
index 000000000..11b83e26f
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetListenerElement.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.registry;
+
+public class CheatSheetListenerElement {
+ private String listenerClassPluginID;
+ private String listenerID;
+ private String listenerClass;
+ private String targetCheatsheetID;
+
+ /*package*/ CheatSheetListenerElement(String listenerID, String listenerClass, String classPluginId, String targetID) {
+ super();
+ this.listenerID = listenerID;
+ this.listenerClass = listenerClass;
+ this.targetCheatsheetID = targetID;
+ this.listenerClassPluginID = classPluginId;
+ }
+
+ /**
+ * @return
+ */
+ public String getListenerClass() {
+ return listenerClass;
+ }
+
+ /**
+ * @return
+ */
+ public String getListenerID() {
+ return listenerID;
+ }
+
+ /**
+ * @return
+ */
+ public String getTargetCheatsheetID() {
+ return targetCheatsheetID;
+ }
+
+ /**
+ * @param string
+ */
+ public void setListenerClass(String string) {
+ listenerClass = string;
+ }
+
+ /**
+ * @param string
+ */
+ public void setListenerID(String string) {
+ listenerID = string;
+ }
+
+ /**
+ * @param string
+ */
+ public void setTargetCheatsheetID(String string) {
+ targetCheatsheetID = string;
+ }
+
+ /**
+ * @return
+ */
+ public String getListenerClassPluginID() {
+ return listenerClassPluginID;
+ }
+
+ /**
+ * @param string
+ */
+ public void setListenerClassPluginID(String string) {
+ listenerClassPluginID = string;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetRegistryReader.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetRegistryReader.java
new file mode 100644
index 000000000..af8f0c62e
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/CheatSheetRegistryReader.java
@@ -0,0 +1,529 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.registry;
+
+import java.text.Collator;
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.ui.cheatsheets.ICheatSheetItemExtensionElement;
+import org.eclipse.ui.model.AdaptableList;
+import org.eclipse.ui.internal.registry.Category;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+
+/**
+ * Instances access the registry that is provided at creation time
+ * in order to determine the contained CheatSheet Contents
+ */
+public class CheatSheetRegistryReader extends RegistryReader {
+
+ private class CategoryNode {
+ private Category category;
+ private String path;
+ public CategoryNode(Category cat) {
+ category = cat;
+ path = ""; //$NON-NLS-1$
+ String[] categoryPath = category.getParentPath();
+ if (categoryPath != null) {
+ for (int nX = 0; nX < categoryPath.length; nX++) {
+ path += categoryPath[nX] + '/'; //$NON-NLS-1$
+ }
+ }
+ path += cat.getId();
+ }
+ public Category getCategory() {
+ return category;
+ }
+ public String getPath() {
+ return path;
+ }
+ }
+ private final static String ATT_CATEGORY = "category"; //$NON-NLS-1$
+ public final static String ATT_CONTENTFILE = "contentFile"; //$NON-NLS-1$
+ protected final static String ATT_ICON = "icon"; //$NON-NLS-1$
+ protected final static String ATT_ID = "id"; //$NON-NLS-1$
+ protected final static String ATT_LISTENERCLASS = "class"; //$NON-NLS-1$
+ protected final static String ATT_NAME = "name"; //$NON-NLS-1$
+ protected final static String ATT_PLUGINCLASSID = "classPluginId"; //$NON-NLS-1$
+ protected final static String ATT_CLASS = "class"; //$NON-NLS-1$
+ protected final static String ATT_TARGETCHEATSHEETID = "targetCheatSheetId"; //$NON-NLS-1$
+ private final static String CATEGORY_SEPARATOR = "/"; //$NON-NLS-1$
+ private final static String ATT_ITEM_ATTRIBUTE = "itemAttribute"; //$NON-NLS-1$
+ private static CheatSheetRegistryReader instance;
+ private final static String TAG_CATEGORY = "category"; //$NON-NLS-1$
+
+ // constants
+ protected final static String TAG_CHEATSHEET = "cheatSheet"; //$NON-NLS-1$
+ protected final static String TAG_CHEATSHEET_LISTENER = "cheatSheetListener"; //$NON-NLS-1$
+ protected final static String TAG_ITEM_EXTENSION = "itemExtension"; //$NON-NLS-1$
+ protected final static String trueString = "TRUE"; //$NON-NLS-1$
+ private final static String UNCATEGORIZED_CHEATSHEET_CATEGORY = "org.eclipse.ui.Other"; //$NON-NLS-1$
+ private final static String UNCATEGORIZED_CHEATSHEET_CATEGORY_LABEL = CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEET_OTHER_CATEGORY);
+
+ /**
+ * Returns a list of cheatsheets, project and not.
+ *
+ * The return value for this method is cached since computing its value
+ * requires non-trivial work.
+ */
+ public static CheatSheetRegistryReader getInstance() {
+ if (instance == null)
+ instance = new CheatSheetRegistryReader();
+
+ return instance;
+ }
+ protected ArrayList cheatsheetListeners;
+ protected ArrayList cheatsheetItemExtensions;
+
+ protected AdaptableList cheatsheets;
+ private ArrayList deferCategories = null;
+
+ // private boolean shouldPrune = true;
+ private ArrayList deferCheatSheets = null;
+ private final String pluginListenerPoint = "cheatSheetListener"; //$NON-NLS-1$
+ private final String pluginPoint = "cheatSheetContent"; //$NON-NLS-1$
+ private final String csItemExtension = "cheatSheetItemExtension"; //$NON-NLS-1$
+
+ /**
+ * Create an instance of this class.
+ */
+ private CheatSheetRegistryReader() {
+ }
+
+ /**
+ * Adds new cheatsheet to the provided collection. Override to
+ * provide more logic.
+ * <p>
+ * This implementation uses a defering strategy. For more info see
+ * <code>readCheatSheets</code>.
+ * </p>
+ */
+ protected void addNewElementToResult(CheatSheetElement element, IConfigurationElement config, AdaptableList result) {
+ deferCheatSheet(element);
+ }
+
+ /**
+ * Returns a new CheatSheetElement configured according to the parameters
+ * contained in the passed Registry.
+ *
+ * May answer null if there was not enough information in the Extension to create
+ * an adequate cheatsheet
+ */
+ protected CheatSheetElement createCheatSheetElement(IConfigurationElement element) {
+ // CheatSheetElements must have a name attribute
+ String nameString = element.getAttribute(ATT_NAME);
+ if (nameString == null) {
+ logMissingAttribute(element, ATT_NAME);
+ return null;
+ }
+ CheatSheetElement result = new CheatSheetElement(nameString);
+ if (initializeCheatSheet(result, element))
+ return result; // ie.- initialization was successful
+
+ return null;
+ }
+
+ /**
+ * Create and answer a new CheatSheetCollectionElement, configured as a
+ * child of <code>parent</code>
+ *
+ * @return org.eclipse.ui.internal.model.CheatSheetCollectionElement
+ * @param parent org.eclipse.ui.internal.model.CheatSheetCollectionElement
+ * @param childName java.lang.String
+ */
+ protected CheatSheetCollectionElement createCollectionElement(CheatSheetCollectionElement parent, String id, String label) {
+ CheatSheetCollectionElement newElement = new CheatSheetCollectionElement(id, label, parent);
+
+ parent.add(newElement);
+ return newElement;
+ }
+
+ /**
+ * Creates empty element collection. Overrider to fill
+ * initial elements, if needed.
+ */
+ protected AdaptableList createEmptyCheatSheetCollection() {
+ return new CheatSheetCollectionElement("root", "root", null); //$NON-NLS-2$//$NON-NLS-1$
+ }
+
+ private void createListenerElement(IConfigurationElement element) {
+ String listenerID = element.getAttribute(ATT_ID);
+ String targetCheatsheetID = element.getAttribute(ATT_TARGETCHEATSHEETID);
+ String className = element.getAttribute(ATT_LISTENERCLASS);
+ String listenerClassPluginID = element.getAttribute(ATT_PLUGINCLASSID);
+ if(listenerClassPluginID==null)
+ listenerClassPluginID = element.getDeclaringExtension().getDeclaringPluginDescriptor().getUniqueIdentifier();
+ if (listenerID == null || targetCheatsheetID == null || className == null || listenerClassPluginID == null)
+ return;
+ CheatSheetListenerElement listenerElement = new CheatSheetListenerElement(listenerID, className, listenerClassPluginID, targetCheatsheetID);
+ if (cheatsheetListeners == null)
+ cheatsheetListeners = new ArrayList(20);
+ cheatsheetListeners.add(listenerElement);
+ }
+
+ /**
+ * Stores a category element for deferred addition.
+ */
+ private void deferCategory(IConfigurationElement config) {
+ // Create category.
+ Category category = null;
+ try {
+ category = new Category(config);
+ } catch (CoreException e) {
+ CheatSheetPlugin.getPlugin().getLog().log(e.getStatus());
+ return;
+ }
+
+ // Defer for later processing.
+ if (deferCategories == null)
+ deferCategories = new ArrayList(20);
+ deferCategories.add(category);
+ }
+
+ /**
+ * Stores a cheatsheet element for deferred addition.
+ */
+ private void deferCheatSheet(CheatSheetElement element) {
+ if (deferCheatSheets == null)
+ deferCheatSheets = new ArrayList(50);
+ deferCheatSheets.add(element);
+ }
+
+ /**
+ * Returns the first cheatsheet
+ * with a given id.
+ */
+ public CheatSheetElement findCheatSheet(String id) {
+ Object[] cheatsheets = getCheatSheets().getChildren();
+ for (int nX = 0; nX < cheatsheets.length; nX++) {
+ CheatSheetCollectionElement collection = (CheatSheetCollectionElement) cheatsheets[nX];
+ CheatSheetElement element = collection.findCheatSheet(id, true);
+ if (element != null)
+ return element;
+ }
+ return null;
+ }
+
+ /**
+ * Finishes the addition of categories. The categories are sorted and
+ * added in a root to depth traversal.
+ */
+ private void finishCategories() {
+ // If no categories just return.
+ if (deferCategories == null)
+ return;
+
+ // Sort categories by flattened name.
+ CategoryNode[] flatArray = new CategoryNode[deferCategories.size()];
+ for (int i = 0; i < deferCategories.size(); i++) {
+ flatArray[i] = new CategoryNode((Category) deferCategories.get(i));
+ }
+ Sorter sorter = new Sorter() {
+ private Collator collator = Collator.getInstance();
+
+ public boolean compare(Object o1, Object o2) {
+ String s1 = ((CategoryNode) o1).getPath();
+ String s2 = ((CategoryNode) o2).getPath();
+ return collator.compare(s2, s1) > 0;
+ }
+ };
+ Object[] sortedCategories = sorter.sort(flatArray);
+
+ // Add each category.
+ for (int nX = 0; nX < sortedCategories.length; nX++) {
+ Category cat = ((CategoryNode) sortedCategories[nX]).getCategory();
+ finishCategory(cat);
+ }
+
+ // Cleanup.
+ deferCategories = null;
+ }
+
+ /**
+ * Save new category definition.
+ */
+ private void finishCategory(Category category) {
+ CheatSheetCollectionElement currentResult = (CheatSheetCollectionElement) cheatsheets;
+
+ String[] categoryPath = category.getParentPath();
+ CheatSheetCollectionElement parent = currentResult; // ie.- root
+
+ // Traverse down into parent category.
+ if (categoryPath != null) {
+ for (int i = 0; i < categoryPath.length; i++) {
+ CheatSheetCollectionElement tempElement = getChildWithID(parent, categoryPath[i]);
+ if (tempElement == null) {
+ // The parent category is invalid. By returning here the
+ // category will be dropped and any cheatsheet within the category
+ // will be added to the "Other" category.
+ return;
+ } else
+ parent = tempElement;
+ }
+ }
+
+ // If another category already exists with the same id ignore this one.
+ Object test = getChildWithID(parent, category.getId());
+ if (test != null)
+ return;
+
+ if (parent != null)
+ createCollectionElement(parent, category.getId(), category.getLabel());
+ }
+
+ /**
+ * Insert the passed cheatsheet element into the cheatsheet collection appropriately
+ * based upon its defining extension's CATEGORY tag value
+ *
+ * @param element CheatSheetElement
+ * @param extension
+ * @param currentResult CheatSheetCollectionElement
+ */
+ private void finishCheatSheet(CheatSheetElement element, IConfigurationElement config, AdaptableList result) {
+ CheatSheetCollectionElement currentResult = (CheatSheetCollectionElement) result;
+ StringTokenizer familyTokenizer = new StringTokenizer(getCategoryStringFor(config), CATEGORY_SEPARATOR);
+
+ // use the period-separated sections of the current CheatSheet's category
+ // to traverse through the NamedSolution "tree" that was previously created
+ CheatSheetCollectionElement currentCollectionElement = currentResult; // ie.- root
+ boolean moveToOther = false;
+
+ while (familyTokenizer.hasMoreElements()) {
+ CheatSheetCollectionElement tempCollectionElement = getChildWithID(currentCollectionElement, familyTokenizer.nextToken());
+
+ if (tempCollectionElement == null) { // can't find the path; bump it to uncategorized
+ moveToOther = true;
+ break;
+ } else
+ currentCollectionElement = tempCollectionElement;
+ }
+
+ if (moveToOther)
+ moveElementToUncategorizedCategory(currentResult, element);
+ else
+ currentCollectionElement.add(element);
+ }
+
+ /**
+ * Finishes the addition of cheatsheets. The cheatsheets are processed and categorized.
+ */
+ private void finishCheatSheets() {
+ if (deferCheatSheets != null) {
+ Iterator iter = deferCheatSheets.iterator();
+ while (iter.hasNext()) {
+ CheatSheetElement cheatsheet = (CheatSheetElement) iter.next();
+ IConfigurationElement config = cheatsheet.getConfigurationElement();
+ finishCheatSheet(cheatsheet, config, cheatsheets);
+ }
+ deferCheatSheets = null;
+ }
+ }
+
+ /**
+ * Return the appropriate category (tree location) for this CheatSheet.
+ * If a category is not specified then return a default one.
+ */
+ protected String getCategoryStringFor(IConfigurationElement config) {
+ String result = config.getAttribute(ATT_CATEGORY);
+ if (result == null)
+ result = UNCATEGORIZED_CHEATSHEET_CATEGORY;
+
+ return result;
+ }
+
+ public ArrayList getCheatsheetListenerElements() {
+ return cheatsheetListeners;
+ }
+
+ /**
+ * Returns a list of cheatsheets, project and not.
+ *
+ * The return value for this method is cached since computing its value
+ * requires non-trivial work.
+ */
+ public AdaptableList getCheatSheets() {
+ if (cheatsheets == null)
+ readCheatSheets();
+ return cheatsheets;
+ }
+
+ /**
+ * Go through the children of the passed parent and answer the child
+ * with the passed name. If no such child is found then return null.
+ *
+ * @return org.eclipse.ui.internal.model.CheatSheetCollectionElement
+ * @param parent org.eclipse.ui.internal.model.CheatSheetCollectionElement
+ * @param childName java.lang.String
+ */
+ protected CheatSheetCollectionElement getChildWithID(CheatSheetCollectionElement parent, String id) {
+ Object[] children = parent.getChildren();
+ for (int i = 0; i < children.length; ++i) {
+ CheatSheetCollectionElement currentChild = (CheatSheetCollectionElement) children[i];
+ if (currentChild.getId().equals(id))
+ return currentChild;
+ }
+ return null;
+ }
+
+ /**
+ * Initialize the passed element's properties based on the contents of
+ * the passed registry. Answer a boolean indicating whether the element
+ * was able to be adequately initialized.
+ *
+ * @return boolean
+ * @param element CheatSheetElement
+ * @param extension Extension
+ */
+ protected boolean initializeCheatSheet(CheatSheetElement element, IConfigurationElement config) {
+ element.setID(config.getAttribute(ATT_ID));
+ element.setDescription(getDescription(config));
+
+ // apply CONTENTFILE and ICON properties
+ element.setConfigurationElement(config);
+//TODO: Port problem, need to fix.
+// String iconName = config.getAttribute(ATT_ICON);
+// if (iconName != null) {
+// IExtension extension = config.getDeclaringExtension();
+// element.setImageDescriptor(WorkbenchImages.getImageDescriptorFromExtension(extension, iconName));
+// }
+
+ String contentFile = config.getAttribute(ATT_CONTENTFILE);
+ if (contentFile != null) {
+ element.setContentFile(contentFile);
+ }
+
+ // ensure that a contentfile was specified
+ if (element.getConfigurationElement() == null) {
+ logMissingAttribute(config, ATT_CONTENTFILE);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Moves given element to "Other" category, previously creating one if missing.
+ */
+ protected void moveElementToUncategorizedCategory(CheatSheetCollectionElement root, CheatSheetElement element) {
+ CheatSheetCollectionElement otherCategory = getChildWithID(root, UNCATEGORIZED_CHEATSHEET_CATEGORY);
+
+ if (otherCategory == null)
+ otherCategory = createCollectionElement(root, UNCATEGORIZED_CHEATSHEET_CATEGORY, UNCATEGORIZED_CHEATSHEET_CATEGORY_LABEL);
+
+ otherCategory.add(element);
+ }
+
+ /**
+ * Removes the empty categories from a cheatsheet collection.
+ */
+ private void pruneEmptyCategories(CheatSheetCollectionElement parent) {
+ Object[] children = parent.getChildren();
+ for (int nX = 0; nX < children.length; nX++) {
+ CheatSheetCollectionElement child = (CheatSheetCollectionElement) children[nX];
+ pruneEmptyCategories(child);
+ // if (child.isEmpty() && shouldPrune)
+ // parent.remove(child);
+ }
+ }
+
+ /**
+ * Reads the cheatsheets in a registry.
+ * <p>
+ * This implementation uses a defering strategy. All of the elements
+ * (categories, cheatsheets) are read. The categories are created as the read occurs.
+ * The cheatsheets are just stored for later addition after the read completes.
+ * This ensures that cheatsheet categorization is performed after all categories
+ * have been read.
+ * </p>
+ */
+ protected void readCheatSheets() {
+ IPluginRegistry pregistry = Platform.getPluginRegistry();
+
+ if (cheatsheets == null) {
+ cheatsheets = createEmptyCheatSheetCollection();
+ readRegistry(pregistry, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, pluginPoint);
+ }
+
+ finishCategories();
+ finishCheatSheets();
+
+ if (cheatsheets != null) {
+ CheatSheetCollectionElement parent = (CheatSheetCollectionElement) cheatsheets;
+ pruneEmptyCategories(parent);
+ }
+
+ //Now read the cheatsheet listeners here from the plugin registry.
+ readRegistry(pregistry, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, pluginListenerPoint);
+
+ }
+
+ public ArrayList readItemExtensions() {
+ cheatsheetItemExtensions = new ArrayList();
+
+ IPluginRegistry pregistry = Platform.getPluginRegistry();
+ //Now read the cheat sheet extensions.
+ readRegistry(pregistry, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, csItemExtension);
+
+ return cheatsheetItemExtensions;
+ }
+
+ private void createItemExtensionElement(IConfigurationElement element) {
+ String className = element.getAttribute(ATT_CLASS);
+ String itemAttribute = element.getAttribute(ATT_ITEM_ATTRIBUTE);
+ if (className == null || itemAttribute == null)
+ return;
+
+ Class extClass = null;
+ ICheatSheetItemExtensionElement extElement = null;
+ IPluginDescriptor desc = element.getDeclaringExtension().getDeclaringPluginDescriptor();
+
+ try {
+ extClass = desc.getPluginClassLoader().loadClass(className);
+ } catch (Exception e) {
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_LOADING_CLASS_FOR_ACTION), e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ }
+ try {
+ if (extClass != null)
+ extElement = (ICheatSheetItemExtensionElement) extClass.newInstance();
+ } catch (Exception e) {
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_CREATING_CLASS_FOR_ACTION), e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ }
+
+ if(extElement != null){
+ extElement.setAttributeName(itemAttribute);
+ cheatsheetItemExtensions.add(extElement);
+ }
+
+ }
+
+ /**
+ * Implement this method to read element attributes.
+ */
+ protected boolean readElement(IConfigurationElement element) {
+ if (element.getName().equals(TAG_CATEGORY)) {
+ deferCategory(element);
+ return true;
+ } else if (element.getName().equals(TAG_CHEATSHEET_LISTENER)) {
+ createListenerElement(element);
+ return true;
+ } else if (element.getName().equals(TAG_ITEM_EXTENSION)) {
+ createItemExtensionElement(element);
+ return true;
+ } else {
+ if (!element.getName().equals(TAG_CHEATSHEET))
+ return false;
+
+ CheatSheetElement cheatsheet = createCheatSheetElement(element);
+ if (cheatsheet != null)
+ addNewElementToResult(cheatsheet, element, cheatsheets);
+ return true;
+ }
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/RegistryReader.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/RegistryReader.java
new file mode 100644
index 000000000..efd353e32
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/RegistryReader.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.registry;
+
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+
+/**
+ * Template implementation of a registry reader that creates objects
+ * representing registry contents. Typically, an extension
+ * contains one element, but this reader handles multiple
+ * elements per extension.
+ *
+ * To start reading the extensions from the registry for an
+ * extension point, call the method <code>readRegistry</code>.
+ *
+ * To read children of an IConfigurationElement, call the
+ * method <code>readElementChildren</code> from your implementation
+ * of the method <code>readElement</code>, as it will not be
+ * done by default.
+ */
+public abstract class RegistryReader {
+ protected static final String TAG_DESCRIPTION = "description"; //$NON-NLS-1$
+
+ /**
+ * The constructor.
+ */
+ /*package*/ RegistryReader() {
+ }
+
+ /**
+ * This method extracts description as a subelement of
+ * the given element.
+ * @return description string if defined, or empty string
+ * if not.
+ */
+ /*package*/ String getDescription(IConfigurationElement config) {
+ IConfigurationElement[] children = config.getChildren(TAG_DESCRIPTION);
+ if (children.length >= 1) {
+ return children[0].getValue();
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Logs the error in the workbench log using the provided
+ * text and the information in the configuration element.
+ */
+ private void logError(IConfigurationElement element, String text) {
+ IExtension extension = element.getDeclaringExtension();
+ IPluginDescriptor descriptor = extension.getDeclaringPluginDescriptor();
+ StringBuffer buf = new StringBuffer();
+ buf.append("Plugin " + descriptor.getUniqueIdentifier() + ", extension " + extension.getExtensionPointUniqueIdentifier()); //$NON-NLS-2$//$NON-NLS-1$
+ buf.append("\n" + text); //$NON-NLS-1$
+
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, buf.toString(), null);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ }
+
+ /**
+ * Logs a very common registry error when a required attribute is missing.
+ */
+ /*package*/ void logMissingAttribute(IConfigurationElement element, String attributeName) {
+ logError(element, "Required attribute '" + attributeName + "' not defined"); //$NON-NLS-2$//$NON-NLS-1$
+ }
+
+ /**
+ * Logs a registry error when the configuration element is unknown.
+ */
+ private void logUnknownElement(IConfigurationElement element) {
+ logError(element, "Unknown extension tag found: " + element.getName()); //$NON-NLS-1$
+ }
+
+ /**
+ * Apply a reproducable order to the list of extensions
+ * provided, such that the order will not change as
+ * extensions are added or removed.
+ */
+ private IExtension[] orderExtensions(IExtension[] extensions) {
+ // By default, the order is based on plugin id sorted
+ // in ascending order. The order for a plugin providing
+ // more than one extension for an extension point is
+ // dependent in the order listed in the XML file.
+ Sorter sorter = new Sorter() {
+ public boolean compare(Object extension1, Object extension2) {
+ String s1 = ((IExtension) extension1).getDeclaringPluginDescriptor().getUniqueIdentifier().toUpperCase();
+ String s2 = ((IExtension) extension2).getDeclaringPluginDescriptor().getUniqueIdentifier().toUpperCase();
+ //Return true if elementTwo is 'greater than' elementOne
+ return s2.compareTo(s1) > 0;
+ }
+ };
+
+ Object[] sorted = sorter.sort(extensions);
+ IExtension[] sortedExtension = new IExtension[sorted.length];
+ System.arraycopy(sorted, 0, sortedExtension, 0, sorted.length);
+ return sortedExtension;
+ }
+
+ /**
+ * Implement this method to read element's attributes.
+ * If children should also be read, then implementor
+ * is responsible for calling <code>readElementChildren</code>.
+ * Implementor is also responsible for logging missing
+ * attributes.
+ *
+ * @return true if element was recognized, false if not.
+ */
+ /*package*/ abstract boolean readElement(IConfigurationElement element);
+
+ /**
+ * Read the element's children. This is called by
+ * the subclass' readElement method when it wants
+ * to read the children of the element.
+ */
+ /*package*/ void readElementChildren(IConfigurationElement element) {
+ readElements(element.getChildren());
+ }
+
+ /**
+ * Read each element one at a time by calling the
+ * subclass implementation of <code>readElement</code>.
+ *
+ * Logs an error if the element was not recognized.
+ */
+ private void readElements(IConfigurationElement[] elements) {
+ for (int i = 0; i < elements.length; i++) {
+ if (!readElement(elements[i]))
+ logUnknownElement(elements[i]);
+ }
+ }
+
+ /**
+ * Read one extension by looping through its
+ * configuration elements.
+ */
+ private void readExtension(IExtension extension) {
+ readElements(extension.getConfigurationElements());
+ }
+
+ /**
+ * Start the registry reading process using the
+ * supplied plugin ID and extension point.
+ */
+ /*package*/ void readRegistry(IPluginRegistry registry, String pluginId, String extensionPoint) {
+ IExtensionPoint point = registry.getExtensionPoint(pluginId, extensionPoint);
+ if (point != null) {
+ IExtension[] extensions = point.getExtensions();
+ extensions = orderExtensions(extensions);
+ for (int i = 0; i < extensions.length; i++)
+ readExtension(extensions[i]);
+ }
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/Sorter.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/Sorter.java
new file mode 100644
index 000000000..124369c85
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/registry/Sorter.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.registry;
+
+/**
+ * The SortOperation takes a collection of objects and returns
+ * a sorted collection of these objects. Concrete instances of this
+ * class provide the criteria for the sorting of the objects based on
+ * the type of the objects.
+ */
+public abstract class Sorter {
+ /**
+ * Returns true if elementTwo is 'greater than' elementOne
+ * This is the 'ordering' method of the sort operation.
+ * Each subclass overides this method with the particular
+ * implementation of the 'greater than' concept for the
+ * objects being sorted.
+ */
+ /*package*/ abstract boolean compare(Object elementOne, Object elementTwo);
+
+ /**
+ * Sort the objects in sorted collection and return that collection.
+ */
+ private Object[] quickSort(Object[] sortedCollection, int left, int right) {
+ int originalLeft = left;
+ int originalRight = right;
+ Object mid = sortedCollection[(left + right) / 2];
+
+ do {
+ while (compare(sortedCollection[left], mid))
+ left++;
+ while (compare(mid, sortedCollection[right]))
+ right--;
+ if (left <= right) {
+ Object tmp = sortedCollection[left];
+ sortedCollection[left] = sortedCollection[right];
+ sortedCollection[right] = tmp;
+ left++;
+ right--;
+ }
+ }
+ while (left <= right);
+
+ if (originalLeft < right)
+ sortedCollection = quickSort(sortedCollection, originalLeft, right);
+ if (left < originalRight)
+ sortedCollection = quickSort(sortedCollection, left, originalRight);
+
+ return sortedCollection;
+ }
+
+ /**
+ * Return a new sorted collection from this unsorted collection.
+ * Sort using quick sort.
+ */
+ /*package*/ Object[] sort(Object[] unSortedCollection) {
+ int size = unSortedCollection.length;
+ Object[] sortedCollection = new Object[size];
+
+ //copy the array so can return a new sorted collection
+ System.arraycopy(unSortedCollection, 0, sortedCollection, 0, size);
+ if (size > 1)
+ quickSort(sortedCollection, 0, size - 1);
+
+ return sortedCollection;
+ }
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/Button.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/Button.java
new file mode 100644
index 000000000..010f3414d
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/Button.java
@@ -0,0 +1,292 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.accessibility.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+public class Button extends Canvas {
+ protected static final int MARGIN_HEIGHT = 2;
+ protected static final int MARGIN_WIDTH = 2;
+ protected String fAccessibleDescription;
+ protected String fAccessibleName;
+ protected boolean fHasFocus;
+ protected Image fImage;
+ protected Rectangle fImageSize;
+ protected boolean fSelection;
+ protected int fToggleImageHeight;
+ protected int fToggleImageWidth;
+
+ public Button(Composite parent, int style, Image newImage) {
+ super(parent, style);
+ initAccessible();
+
+ fImage = newImage;
+
+ addPaintListener(new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ paint(e);
+ }
+ });
+ addMouseListener(new MouseAdapter () {
+ public void mouseDown(MouseEvent e) {
+ notifyListeners(SWT.Selection);
+ }
+ });
+ addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (e.character == '\r' || e.character == ' ') {
+ // Activation
+ notifyListeners(SWT.Selection);
+ }
+ }
+ });
+ addListener(SWT.Traverse, new Listener () {
+ public void handleEvent(Event e) {
+ if (e.detail != SWT.TRAVERSE_RETURN)
+ e.doit = true;
+ }
+ });
+ addFocusListener(new FocusListener() {
+ public void focusGained(FocusEvent e) {
+ if (!fHasFocus) {
+ fHasFocus=true;
+ redraw();
+ }
+ }
+ public void focusLost(FocusEvent e) {
+ if (fHasFocus) {
+ fHasFocus=false;
+ redraw();
+ }
+ }
+ });
+
+ addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ fSelection = !fSelection;
+ redraw();
+ }
+ });
+
+// addMouseTrackListener(new MouseTrackAdapter() {
+// public void mouseEnter(MouseEvent e) {
+// hover = true;
+// if (activeCursor!=null)
+// setCursor(activeCursor);
+// redraw();
+// }
+// public void mouseExit(MouseEvent e) {
+// hover = false;
+// if (activeCursor!=null)
+// setCursor(null);
+// redraw();
+// }
+// });
+
+ calculateDimensions();
+ }
+
+ /*package*/ void addSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) return;
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ }
+
+ private void calculateDimensions() {
+ fImageSize = fImage.getBounds();
+ fToggleImageWidth = fImageSize.width + MARGIN_WIDTH*2;
+ fToggleImageHeight = fImageSize.height + MARGIN_HEIGHT*2;
+ }
+
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ return new Point(fToggleImageWidth, fToggleImageWidth);
+ }
+ /**
+ * Returns the fAccessibleDescription.
+ * @return String
+ */
+ public String getFAccessibleDescription() {
+ return fAccessibleDescription;
+ }
+
+ /**
+ * Returns the fAccessibleName.
+ * @return String
+ */
+ public String getFAccessibleName() {
+ return fAccessibleName;
+ }
+
+ public Image getImage(){
+ return fImage;
+ }
+
+ public boolean getSelection() {
+ return fSelection;
+ }
+
+ private void initAccessible() {
+ getAccessible().addAccessibleListener(new AccessibleAdapter() {
+
+ public void getDescription(AccessibleEvent e) {
+ if(fAccessibleDescription!=null)
+ e.result = fAccessibleDescription;
+ }
+
+ public void getName(AccessibleEvent e) {
+ if(fAccessibleName != null)
+ e.result = fAccessibleName;
+ }
+ });
+
+ getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() {
+
+ public void getChildCount(AccessibleControlEvent e) {
+ e.detail = 0;
+ }
+
+ public void getLocation(AccessibleControlEvent e) {
+ Rectangle location = getBounds();
+ Point pt = toDisplay(new Point(location.x, location.y));
+ e.x = pt.x;
+ e.y = pt.y;
+ e.width = location.width;
+ e.height = location.height;
+ }
+
+ public void getRole(AccessibleControlEvent e) {
+ e.detail = ACC.ROLE_PUSHBUTTON;
+ }
+
+ public void getState(AccessibleControlEvent e) {
+// e.detail = fSelection ? ACC.STATE_SELECTED : ACC.STATE_SELECTABLE;
+ }
+
+ });
+ }
+
+ protected void notifyListeners(int eventType) {
+ Event event = new Event();
+ event.type = eventType;
+ event.widget = this;
+ notifyListeners(eventType, event);
+ }
+
+ /*
+ * @see SelectableControl#paint(GC)
+ */
+ protected void paint(GC gc) {
+
+// if (hover && activeColor!=null)
+// gc.setBackground(activeColor);
+// else if (decorationColor!=null)
+// gc.setBackground(decorationColor);
+// else
+// gc.setBackground(getForeground());
+
+ // Find point to center image
+ Point size = getSize();
+ int x = (size.x - fImageSize.width)/2;
+ int y = (size.y - fImageSize.height)/2;
+
+ gc.drawImage(fImage, 0, 0, fImageSize.width, fImageSize.height, x, y, fImageSize.width, fImageSize.height);
+// gc.setBackground(getBackground());
+ }
+
+// public void setDecorationColor(Color decorationColor) {
+// this.decorationColor = decorationColor;
+// }
+//
+// public Color getDecorationColor() {
+// return decorationColor;
+// }
+//
+// public void setActiveDecorationColor(Color activeColor) {
+// this.activeColor = activeColor;
+// }
+//
+// public void removeSelectionListener(SelectionListener listener) {
+// checkWidget ();
+// if (listener == null) return;
+// removeListener (SWT.Selection, listener);
+// }
+//
+// public void setActiveCursor(Cursor activeCursor) {
+// this.activeCursor = activeCursor;
+// }
+//
+// public Color getActiveDecorationColor() {
+// return activeColor;
+// }
+
+// public Point computeSize(int wHint, int hHint, boolean changed) {
+// int width, height;
+//
+// if (wHint!=SWT.DEFAULT) width = wHint;
+// else
+// width = WIDTH + 2*marginWidth;
+// if (hHint!=SWT.DEFAULT) height = hHint;
+// else height = HEIGHT + 2*marginHeight;
+// return new Point(width, height);
+// }
+
+ protected void paint(PaintEvent e) {
+ GC gc = e.gc;
+ Point size = getSize();
+ gc.setFont(getFont());
+ paint(gc);
+ if (fHasFocus) {
+ gc.setForeground(getForeground());
+ gc.drawFocus(0, 0, size.x, size.y);
+ }
+ }
+
+ /**
+ * Sets the fAccessibleDescription.
+ * @param fAccessibleDescription The fAccessibleDescription to set
+ */
+ public void setFAccessibleDescription(String fAccessibleDescription) {
+ this.fAccessibleDescription = fAccessibleDescription;
+ }
+
+ /**
+ * Sets the fAccessibleName.
+ * @param fAccessibleName The fAccessibleName to set
+ */
+ public void setFAccessibleName(String fAccessibleName) {
+ this.fAccessibleName = fAccessibleName;
+ }
+
+ public void setImage(Image myimage){
+ if( fImage != myimage ) {
+ fImage = myimage;
+ calculateDimensions();
+ }
+ }
+
+ public void setSelection(boolean selection) {
+ this.fSelection = selection;
+ }
+
+ protected int [] translate(int [] data, int x, int y) {
+ int [] target = new int [data.length];
+ for (int i=0; i<data.length; i+=2) {
+ target[i] = data[i]+ x;
+ }
+ for (int i=1; i<data.length; i+=2) {
+ target[i] = data[i]+y;
+ }
+ return target;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetEvent.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetEvent.java
new file mode 100644
index 000000000..aa1ce9733
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetEvent.java
@@ -0,0 +1,17 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.cheatsheets.ICheatSheetManager;
+
+public class CheatSheetEvent extends Event {
+ int fCheatsheetEventType;
+ String fCheatsheetID;
+ ICheatSheetManager csm;
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetExpandRestoreAction.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetExpandRestoreAction.java
new file mode 100644
index 000000000..c06a2fc52
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetExpandRestoreAction.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+
+import org.eclipse.jface.action.Action;
+
+/**
+ * Action used to enable / disable method filter properties
+ */
+public class CheatSheetExpandRestoreAction extends Action {
+ private CheatSheetView theview;
+
+ public CheatSheetExpandRestoreAction(String title, boolean initValue, CheatSheetView theview) {
+ super(title);
+ this.theview = theview;
+
+ setChecked(initValue);
+ }
+
+ /*
+ * @see Action#actionPerformed
+ */
+ public void run() {
+ theview.toggleExpandRestore();
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetItemEvent.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetItemEvent.java
new file mode 100644
index 000000000..3bada9c72
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetItemEvent.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import org.eclipse.ui.cheatsheets.ICheatSheetManager;
+import org.eclipse.ui.cheatsheets.events.ICheatSheetItemEvent;
+
+public class CheatSheetItemEvent extends CheatSheetEvent implements ICheatSheetItemEvent {
+
+ String fCheatsheetItemID;
+ String fCheatsheetSubItemID;
+
+ /**
+ *
+ */
+ public CheatSheetItemEvent() {
+ super();
+ }
+
+ /**
+ * create new event.
+ * subItemID can be null if it is not an event from a sub item.
+ */
+ public CheatSheetItemEvent(int eventType, String id, String itemid, String subItemID, ICheatSheetManager csm) {
+ super();
+ this.fCheatsheetEventType = eventType;
+ this.fCheatsheetID = id;
+ this.fCheatsheetItemID = itemid;
+ this.fCheatsheetSubItemID = subItemID;
+ this.csm = csm;
+ }
+
+ /**
+ * @return
+ */
+ public int getCheatSheetEventType() {
+ return fCheatsheetEventType;
+ }
+
+ /**
+ * @return
+ */
+ public String getCheatSheetID() {
+ return fCheatsheetID;
+ }
+
+ /**
+ * @return
+ */
+ public String getCheatSheetItemID() {
+ return fCheatsheetItemID;
+ }
+
+ /**
+ * @return
+ */
+ public String getCheatSheetSubItemID() {
+ return fCheatsheetSubItemID;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.events.ICheatSheetEvent#getCheatsheetManager()
+ */
+ public ICheatSheetManager getCheatSheetManager() {
+ return csm;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetManager.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetManager.java
new file mode 100644
index 000000000..62616c24b
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetManager.java
@@ -0,0 +1,273 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.util.*;
+
+import org.eclipse.ui.internal.cheatsheets.CheatSheetPlugin;
+import org.eclipse.ui.internal.cheatsheets.data.*;
+import org.eclipse.ui.cheatsheets.*;
+import org.eclipse.ui.cheatsheets.events.*;
+
+/**
+ * Cheat sheet manager class. Manages cheat sheet data,
+ * enables access to model for adding/modifying steps and sub steps
+ * on the cheat sheet "on the fly".
+ */
+public class CheatSheetManager implements ICheatSheetManager {
+
+ private String cheatsheetID;
+ private Hashtable listenerMap = new Hashtable(20);
+ private Hashtable itemListenerMap = new Hashtable(20);
+ private Hashtable viewListenerMap = new Hashtable(20);
+ private Hashtable dataTable = null;
+ private CheatSheetView csview;
+
+ //Package protected: We don't want anyone else creating instances of this class.
+ CheatSheetManager(String id, CheatSheetView csv) {
+ csview = csv;
+ cheatsheetID = id;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.ICheatSheetManager#getCheatSheetID()
+ */
+ public String getCheatSheetID() {
+ return cheatsheetID;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.ICheatSheetManager#getItemWithID(java.lang.String)
+ */
+ public IAbstractItem getItem(String id) {
+ try {
+ //Check to see if that item with that id is dynamic.
+ //If it is not dynamic, return null for it cannot be modified.
+ ArrayList contentItems = csview.getListOfContentItems();
+ for (int i = 0; i < contentItems.size(); i++) {
+ IAbstractItem contentItem = (IAbstractItem) contentItems.get(i);
+ if (contentItem.getID().equals(id)) {
+ //return contentItem;
+ if (contentItem instanceof IContainsContent) {
+ IContainsContent cc = (IContainsContent) contentItem;
+ if (cc.isDynamic())
+ return contentItem;
+ }
+ return null;
+ }
+
+ }
+ return null;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public IItemWithSubItems convertToIItemWithSubItems(IAbstractItem ai) {
+ if (ai instanceof IItemWithSubItems)
+ return (IItemWithSubItems)ai;
+ if (!(ai instanceof IItem))
+ return null;
+ String id = ai.getID();
+ ArrayList contentItems = csview.getListOfContentItems();
+ for (int i = 0; i < contentItems.size(); i++) {
+ IAbstractItem contentItem = (IAbstractItem) contentItems.get(i);
+ if (contentItem.getID().equals(id)) {
+ ContentItemWithSubItems itemws = convertThisIItem((IItem) contentItem);
+ //replace item in list with new item.
+ contentItems.set(i, itemws);
+ //replace coreItem's contentItem with our new one.
+ ViewItem[] va = csview.getViewItemArray();
+ for(int j=0; j<va.length; j++){
+ if(va[j].contentItem == contentItem)
+ va[j].contentItem = itemws;
+ }
+
+ return itemws;
+ }
+ }
+ return null;
+ }
+
+ private ContentItemWithSubItems convertThisIItem(IItem item) {
+ if (!(item instanceof ContentItem))
+ return null;
+ else {
+ ContentItem cc = (ContentItem) item;
+ ContentItemWithSubItems itemws = new ContentItemWithSubItems();
+ itemws.setContent(cc.getContent());
+ itemws.setID(cc.getID());
+ return itemws;
+ }
+ }
+
+ private void fillListenerMaps(String cheatsheetID) {
+ ArrayList newList = CheatSheetPlugin.getPlugin().getListenerObjects(cheatsheetID);
+ if (newList != null) {
+ listenerMap.put(cheatsheetID, newList);
+ ArrayList itemList = new ArrayList(20);
+ ArrayList viewList = new ArrayList(20);
+ for (int i = 0; i < newList.size(); i++) {
+ ICheatSheetListener c = (ICheatSheetListener) newList.get(i);
+ if (c instanceof ICheatSheetItemListener)
+ itemList.add(c);
+ if (c instanceof ICheatSheetViewListener)
+ viewList.add(newList.get(i));
+ }
+ if (itemList.size() > 0)
+ itemListenerMap.put(cheatsheetID, itemList);
+ if (viewList.size() > 0)
+ viewListenerMap.put(cheatsheetID, viewList);
+ }
+
+ }
+
+ //Package protected: We don't want anyone else firing events but the view.
+ //this method will be called by the c.s. view when events occur.
+ void fireEvent(ICheatSheetEvent e) {
+ // System.out.println("Inside Manager Fire Event!");
+ String cheatsheetID = e.getCheatSheetID();
+ if (cheatsheetID == null)
+ return;
+
+ //First check to see if we have the listener classes for this cheatsheet id.
+ ArrayList list = (ArrayList) listenerMap.get(cheatsheetID);
+ if (list == null)
+ fillListenerMaps(cheatsheetID);
+
+ if (e instanceof CheatSheetViewEvent)
+ notifyViewListeners((CheatSheetViewEvent) e, cheatsheetID);
+ else if (e instanceof CheatSheetItemEvent)
+ notifyItemListeners((CheatSheetItemEvent) e, cheatsheetID);
+ }
+
+ /**
+ * Notifies all Item listeners registered of events.
+ */
+ private void notifyItemListeners(CheatSheetItemEvent e, String cheatsheetID) {
+ ArrayList listeners = (ArrayList) itemListenerMap.get(cheatsheetID);
+ if (listeners == null)
+ return;
+
+ switch (e.getCheatSheetEventType()) {
+ case ICheatSheetItemEvent.ITEM_ACTIVATED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetItemListener) listeners.get(i)).itemActivated(e);
+ }
+ break;
+ case ICheatSheetItemEvent.ITEM_COMPLETED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetItemListener) listeners.get(i)).itemCompleted(e);
+ }
+ break;
+ case ICheatSheetItemEvent.ITEM_DEACTIVATED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetItemListener) listeners.get(i)).itemDeactivated(e);
+ }
+ break;
+ case ICheatSheetItemEvent.ITEM_PERFORMED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetItemListener) listeners.get(i)).itemPerformed(e);
+ }
+ break;
+ case ICheatSheetItemEvent.ITEM_SKIPPED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetItemListener) listeners.get(i)).itemSkipped(e);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Notifies all View listeners registered of events.
+ */
+ private void notifyViewListeners(CheatSheetViewEvent e, String cheatsheetID) {
+ // System.out.println("Inside manager notifyViewListeners!");
+ ArrayList listeners = (ArrayList) viewListenerMap.get(cheatsheetID);
+ if (listeners == null)
+ return;
+
+ switch (e.getCheatSheetEventType()) {
+ case ICheatSheetViewEvent.CHEATSHEET_OPENED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetViewListener) listeners.get(i)).cheatSheetOpened(e);
+ }
+ break;
+ case ICheatSheetViewEvent.CHEATSHEET_CLOSED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetViewListener) listeners.get(i)).cheatSheetClosed(e);
+ }
+ break;
+ case ICheatSheetViewEvent.CHEATSHEET_END_REACHED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetViewListener) listeners.get(i)).cheatSheetEndReached(e);
+ }
+ break;
+ case ICheatSheetViewEvent.CHEATSHEET_RESTARTED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetViewListener) listeners.get(i)).cheatSheetRestarted(e);
+ }
+ break;
+ case ICheatSheetViewEvent.CHEATSHEET_STARTED :
+ for (int i = 0; i < listeners.size(); i++) {
+ ((ICheatSheetViewListener) listeners.get(i)).cheatSheetStarted(e);
+ }
+ break;
+ }
+ }
+
+ /**
+ * adds string data to manager data hashtable.
+ * Stores only keyed string data.
+ */
+ public void addData(String key, String data) {
+ if(key == null || data == null)
+ return;
+ if (dataTable == null)
+ dataTable = new Hashtable(30);
+ dataTable.put(key, data);
+ return;
+ }
+
+ public String getData(String key) {
+ if (dataTable == null)
+ return null;
+ return (String) dataTable.get(key);
+ }
+
+ /**
+ * returns the hashtable with all manager data stored.
+ */
+ public Map getData() {
+ return (Map)dataTable;
+ }
+
+ /*package*/ void setData(Hashtable ht) {
+ dataTable = ht;
+ }
+
+ /**
+ * Removes data from manager data storage hashtable stored with key passed as argument.
+ * returns true if data is removed from manager data storage hashtable.
+ * returns false if no data with the key passed is stored.
+ */
+ public boolean removeData(String key) {
+ if (dataTable == null)
+ return false;
+ else if (dataTable.remove(key) != null)
+ return true;
+ return false;
+ }
+
+ /*PACKAGE*/ boolean removeAllData(){
+ dataTable = new Hashtable(30);
+ return true;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetView.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetView.java
new file mode 100644
index 000000000..48e5ed37a
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetView.java
@@ -0,0 +1,1543 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.net.*;
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.resource.*;
+import org.eclipse.jface.util.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.help.WorkbenchHelp;
+import org.eclipse.ui.internal.IHelpContextIds;
+import org.eclipse.ui.part.ViewPart;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.actions.CheatSheetMenu;
+import org.eclipse.ui.internal.cheatsheets.data.*;
+import org.eclipse.ui.cheatsheets.*;
+import org.eclipse.ui.cheatsheets.events.*;
+import org.eclipse.ui.internal.cheatsheets.registry.CheatSheetElement;
+
+/**
+ * View for displaying a cheatsheet.
+ * Cheatsheet content is plugged into the workspace using the following
+ * extension point:
+ * <extension point="org.eclipse.ui.cheatsheets.cheatSheetContent">
+ * <category
+ * name="Cheat Sheet Category"
+ * id="org.eclipse.ui.cheatsheets.cheatSheetsCat">
+ * </category>
+ * <cheatSheet
+ * name="Sample cheat Sheet"
+ * category="org.eclipse.ui.cheatsheets.cheatSheetsCat"
+ * id="org.eclipse.ui.cheatsheets.samples.sampleSheet"
+ * contentFile="testCheatSheet.xml">
+ * <description>
+ * This is the description of the open cheat sheet.
+ * </description>
+ * </cheatSheet>
+ *</extension>
+ *
+ */
+
+public class CheatSheetView extends ViewPart {
+
+ private final static int HORZ_SCROLL_INCREMENT = 20;
+ private final static int VERT_SCROLL_INCREMENT = 20;
+ private boolean actionBarContributed = false;
+
+ //booleans
+ private boolean allCollapsed = false;
+
+ //Colors
+ private Color backgroundColor;
+ private final RGB bottomRGB = new RGB(249, 247, 251);
+ private Cursor busyCursor;
+ private Composite cheatSheetComposite;
+ private int cheatsheetMinimumWidth;
+ private Color[] colorArray;
+
+ //CS Elements
+ private CheatSheetElement contentElement;
+ private URL contentURL;
+ private float csversion = 1.0f;
+
+ private String currentID;
+
+ //ITEMS
+ private ViewItem currentItem;
+
+ //Numba's
+ private int currentItemNum;
+ private Color darkGrey;
+ private final RGB darkGreyRGB = new RGB(160, 192, 208);
+
+ //Lists
+ private ArrayList expandRestoreList = new ArrayList();
+ private boolean hascontent = false;
+ private CheatSheetExpandRestoreAction hideFields;
+ private final RGB HIGHLIGHT_RGB = new RGB(230, 230, 230);
+
+ //Composites
+ private Composite infoArea;
+ private boolean isStarted = false;
+ private Color lightGrey;
+ private ArrayList listOfContentItems;
+ private CheatSheetManager manager;
+
+ private IMemento memento;
+ private final RGB midRGB = new RGB(234, 234, 252);
+ private ViewItem nextItem;
+ private Composite parent;
+ private CheatSheetDomParser parser;
+
+ private Properties savedProps = null;
+ private CheatSheetSaveHelper saveHelper;
+ private ScrolledComposite scrolledComposite;
+ private final RGB topRGB = new RGB(217, 217, 252);
+ private ArrayList viewItemList = new ArrayList();
+
+ /**
+ * The constructor.
+ */
+ public CheatSheetView() {
+ setTitle(CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEETS));
+ currentItemNum = -1;
+ saveHelper = new CheatSheetSaveHelper();
+ }
+
+ /*package*/ void advanceIntroItem() {
+ expandRestoreList = new ArrayList();
+ hideFields.setChecked(false);
+ allCollapsed = false;
+ hideFields.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.COLLAPSE_ALL_BUT_CURRENT_TOOLTIP));
+
+ clearBackgrounds(getViewItemArray());
+ clearIcons(getViewItemArray());
+ collapseAllButtons(getViewItemArray());
+ if(isStarted)
+ killDynamicData(getViewItemArray());
+
+ currentItemNum = 1;
+
+ for (int i = 0; i < viewItemList.size(); i++) {
+ ViewItem vitem = (ViewItem) viewItemList.get(i);
+ if (vitem instanceof CoreItem) {
+ CoreItem c = (CoreItem) vitem;
+ ArrayList l = c.getListOfSubItemCompositeHolders();
+ if (l != null)
+ for (int j = 0; j < l.size(); j++) {
+ ((SubItemCompositeHolder) l.get(j)).setSkipped(false);
+ ((SubItemCompositeHolder) l.get(j)).setCompleted(false);
+ }
+ }
+ }
+
+
+ if (isStarted)
+ fireManagerViewEvent(ICheatSheetViewEvent.CHEATSHEET_RESTARTED);
+ else
+ fireManagerViewEvent(ICheatSheetViewEvent.CHEATSHEET_STARTED);
+
+ isStarted = true;
+ IntroItem introItem = (IntroItem) viewItemList.get(0);
+ introItem.setAsNormalCollapsed();
+ introItem.setComplete();
+ introItem.setRestartImage();
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_DEACTIVATED, introItem);
+
+ ViewItem nextItem = (ViewItem) viewItemList.get(1);
+ if (nextItem.contentItem.isDynamic()) {
+ ((CoreItem) nextItem).handleLazyButtons();
+ }
+ nextItem.setAsCurrentActiveItem();
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, nextItem);
+ collapseAllButCurrent(false);
+
+ saveHelper.removeState(contentURL.toString());
+ saveCurrentSheet();
+
+
+ }
+
+ /*package*/ void advanceItem(Button mylabel, boolean markAsCompleted) {
+ currentItem = (ViewItem) mylabel.getData();
+ int index = getIndexOfItem(currentItem);
+
+ if (index < currentItemNum) {
+ ViewItem vi = getViewItemAtIndex(currentItemNum);
+ vi.setAsNormalNonCollapsed();
+ }
+ if (currentItem != null) {
+ //set that item to it's original color.
+ currentItem.setAsNormalCollapsed();
+ //set that item as complete.
+ if (markAsCompleted) {
+ currentItem.setComplete();
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_COMPLETED, currentItem);
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_DEACTIVATED, currentItem);
+ } else {
+ currentItem.setSkipped();
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_SKIPPED, currentItem);
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_DEACTIVATED, currentItem);
+ }
+ }
+ if (index < viewItemList.size()) {
+ nextItem = (ViewItem) viewItemList.get(index);
+ currentItemNum = index;
+ if (nextItem != null) {
+ //Handle lazy button instantiation here.
+ if (nextItem.contentItem.isDynamic()) {
+ ((CoreItem) nextItem).handleLazyButtons();
+ }
+ nextItem.setAsCurrentActiveItem();
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, nextItem);
+ currentItem = nextItem;
+ }
+ updateScrolledComposite();
+ scrollIfNeeded();
+ } else if (index == viewItemList.size()) {
+ saveCurrentSheet();
+ getViewItemArray()[0].setExpanded();
+ fireManagerViewEvent(ICheatSheetViewEvent.CHEATSHEET_END_REACHED);
+ }
+
+ saveCurrentSheet();
+ scrolledComposite.layout(true);
+ infoArea.layout(true);
+ layoutMyItems();
+ }
+
+ /*package*/ void advanceSubItem(Button mylabel, boolean markAsCompleted, int subItemIndex) {
+ // System.out.println("Advancing a sub item!! Item Number: " + subItemIndex);
+ String subItemID = null;
+ Label l = null;
+ ArrayList list = null;
+ SubItemCompositeHolder sich = null;
+ CoreItem ciws = null;
+
+ currentItem = (ViewItem) mylabel.getData();
+
+ if (currentItem instanceof CoreItem)
+ ciws = (CoreItem) currentItem;
+
+ if (ciws != null) {
+ IContainsContent ci = ((ViewItem) ciws).contentItem;
+ if (ci instanceof ContentItemWithSubItems)
+ subItemID = ((IItemWithSubItems) ci).getSubItem(subItemIndex).getID();
+ list = ciws.getListOfSubItemCompositeHolders();
+ sich = (SubItemCompositeHolder) list.get(subItemIndex);
+ l = sich.getIconLabel();
+ }
+
+ if (l != null) {
+ if (markAsCompleted) {
+ l.setImage(((ViewItem) ciws).getCompleteImage());
+ sich.setCompleted(true);
+ sich.setSkipped(false);
+ fireManagerSubItemEvent(ICheatSheetItemEvent.ITEM_COMPLETED, ciws, subItemID);
+ } else {
+ l.setImage(((ViewItem) ciws).getSkipImage());
+ sich.setSkipped(true);
+ sich.setCompleted(false);
+ fireManagerSubItemEvent(ICheatSheetItemEvent.ITEM_SKIPPED, ciws, subItemID);
+ }
+ }
+
+ boolean allAttempted = checkAllAttempted(list);
+ boolean anySkipped = checkContainsSkipped(list);
+
+ if (allAttempted && !anySkipped) {
+ advanceItem(mylabel, true);
+ return;
+ } else if (allAttempted && anySkipped) {
+ advanceItem(mylabel, false);
+ return;
+ }
+
+ updateScrolledComposite();
+ scrollIfNeeded();
+ saveCurrentSheet();
+ scrolledComposite.layout(true);
+ infoArea.layout(true);
+ layoutMyItems();
+ }
+
+ private void callDisposeOnViewElements() {
+
+ ViewItem[] myitems = getViewItemArray();
+ for (int i = 0; i < myitems.length; i++) {
+ myitems[i].dispose();
+ }
+
+ if (infoArea != null)
+ infoArea.dispose();
+
+ if (scrolledComposite != null)
+ scrolledComposite.dispose();
+
+ if (cheatSheetComposite != null)
+ cheatSheetComposite.dispose();
+
+ }
+
+ private boolean checkAllAttempted(ArrayList list) {
+ for (int i = 0; i < list.size(); i++) {
+ SubItemCompositeHolder s = (SubItemCompositeHolder) list.get(i);
+ if (s.isCompleted() || s.isSkipped()) {
+ continue;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean checkContainsSkipped(ArrayList list) {
+ for (int i = 0; i < list.size(); i++) {
+ SubItemCompositeHolder s = (SubItemCompositeHolder) list.get(i);
+ if (s.isSkipped()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void checkDynamicModel() {
+ Properties props = saveHelper.getSavedStateProperties(contentURL, csversion);
+ if (props == null)
+ return;
+
+ savedProps = props;
+
+ ArrayList dynamicItemDataList = (ArrayList) props.get(IParserTags.DYNAMICDATA);
+ ArrayList dynamicSubItemDataList = (ArrayList) props.get(IParserTags.DYNAMICSUBITEMDATA);
+
+ if (dynamicItemDataList != null)
+ for (int i = 0; i < dynamicItemDataList.size(); i++) {
+ Properties p = (Properties) dynamicItemDataList.get(i);
+ String itemid = (String) p.get(IParserTags.ITEM);
+ String buttonCodes = (String) p.get(IParserTags.ACTIONPHRASE);
+ String aclass = (String) p.get(IParserTags.CLASS);
+ String actionpid = (String) p.get(IParserTags.PLUGINID);
+ String[] actionParams = (String[]) p.get(IParserTags.ACTIONPARAM);
+ IAbstractItem abItem = getItemWithID(itemid);
+ if (abItem == null) {
+ continue;
+ } else {
+ if (abItem instanceof ContentItem) {
+ ContentItem c = (ContentItem) abItem;
+ if (c.isDynamic()) {
+ c.setActionClass(aclass);
+ c.setActionPluginID(actionpid);
+ c.setActionParams(actionParams);
+ c.setButtonCodes(buttonCodes);
+ }
+ }
+ }
+ }
+
+ //Re-Set the dynamic item sub item data if there was any stored.
+ if (dynamicSubItemDataList != null)
+ for (int i = 0; i < dynamicSubItemDataList.size(); i++) {
+ Properties p = (Properties) dynamicSubItemDataList.get(i);
+ String itemid = (String) p.get(IParserTags.ITEM);
+ String subitemid = (String) p.get(IParserTags.SUBITEM);
+ String buttonCodes = (String) p.get(IParserTags.ACTIONPHRASE);
+ String aclass = (String) p.get(IParserTags.CLASS);
+ String actionpid = (String) p.get(IParserTags.PLUGINID);
+ String sublabel = (String) p.get(IParserTags.SUBITEMLABEL);
+ String[] actionParams = (String[]) p.get(IParserTags.ACTIONPARAM);
+ IAbstractItem abItem = getItemWithID(itemid);
+ if (abItem == null) {
+ continue;
+ } else {
+ if (abItem instanceof ContentItem) {
+ ContentItem c = (ContentItem) abItem;
+ if (c.isDynamic()) {
+ ContentItemWithSubItems ciws = convertThisIItem(c);
+ replaceThisContentItem(c, ciws);
+ ISubItem subItem = createASubItem(subitemid, buttonCodes, actionpid, aclass, actionParams, sublabel);
+ ciws.addSubItem(subItem);
+ }
+ } else if (abItem instanceof ContentItemWithSubItems) {
+ boolean handled = false;
+ ContentItemWithSubItems c = (ContentItemWithSubItems) abItem;
+ if (c.isDynamic()) {
+ ISubItem[] subs = c.getSubItems();
+ sublabel : for (int j = 0; j < subs.length; j++) {
+ ISubItem s = subs[j];
+ if (s.getID().equals(subitemid)) {
+ s.setActionClass(aclass);
+ s.setActionPluginID(actionpid);
+ s.setActionParams(actionParams);
+ s.setButtonCodes(buttonCodes);
+ s.setLabel(sublabel);
+ handled = true;
+ break sublabel;
+ }
+ }
+ if (!handled) {
+ ISubItem subItem = createASubItem(subitemid, buttonCodes, actionpid, aclass, actionParams, sublabel);
+ c.addSubItem(subItem);
+ handled = true;
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ private void checkSavedState() {
+ Properties props = null;
+ if (savedProps == null) {
+ props = saveHelper.getSavedStateProperties(contentURL, csversion);
+ } else {
+ props = savedProps;
+ }
+ manager = new CheatSheetManager(currentID, this);
+ if (props == null) {
+ getViewItemArray()[0].setAsCurrentActiveItem();
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, getViewItemArray()[0]);
+ return;
+ }
+
+ boolean buttonIsDown = (Integer.parseInt((String) props.get(IParserTags.BUTTON)) == 0) ? false : true;
+ int itemNum = Integer.parseInt((String) props.get(IParserTags.CURRENT));
+ ArrayList completedStatesList = (ArrayList) props.get(IParserTags.COMPLETED);
+ ArrayList expandedStatesList = (ArrayList) props.get(IParserTags.EXPANDED);
+ expandRestoreList = (ArrayList) props.get(IParserTags.EXPANDRESTORE);
+ String cid = (String) props.get(IParserTags.CHEATSHEETID);
+ Hashtable completedSubItems = (Hashtable) props.get(IParserTags.SUBITEMCOMPLETED);
+ Hashtable skippedSubItems = (Hashtable) props.get(IParserTags.SUBITEMSKIPPED);
+ Hashtable csmData = (Hashtable) props.get(IParserTags.MANAGERDATA);
+
+ ArrayList completedSubItemsItemList = new ArrayList();
+ ArrayList skippedSubItemsItemList = new ArrayList();
+
+ Enumeration e = completedSubItems.keys();
+ while (e.hasMoreElements())
+ completedSubItemsItemList.add(e.nextElement());
+
+ Enumeration e2 = skippedSubItems.keys();
+ while (e2.hasMoreElements())
+ skippedSubItemsItemList.add(e2.nextElement());
+
+ if (cid != null)
+ currentID = cid;
+
+ manager.setData(csmData);
+
+ if (itemNum >= 0) {
+ clearBackgrounds(getViewItemArray());
+ currentItemNum = itemNum;
+
+ currentItem = (ViewItem) viewItemList.get(itemNum);
+
+ for (int i = 0; i < viewItemList.size(); i++) {
+
+ ViewItem item = (ViewItem) viewItemList.get(i);
+ if (i > 0 && ((CoreItem) item).contentItem.isDynamic() && i <= currentItemNum)
+ ((CoreItem) item).handleLazyButtons();
+
+ if (completedStatesList.contains(Integer.toString(i))) {
+ item.setComplete();
+ item.setRestartImage();
+ } else {
+ if (i < currentItemNum) {
+ item.setSkipped();
+ }
+ }
+ if (expandedStatesList.contains(Integer.toString(i))) {
+ if (i <= currentItemNum) {
+ item.setButtonsExpanded();
+ } else {
+ item.setButtonsCollapsed();
+ }
+ item.setExpanded();
+ } else {
+ item.setCollapsed();
+ if (i > currentItemNum) {
+ item.setButtonsCollapsed();
+ } else {
+ item.setButtonsExpanded();
+ }
+ }
+ if (expandRestoreList.contains(Integer.toString(i))) {
+ item.setCollapsed();
+ }
+ if (completedSubItemsItemList.contains(Integer.toString(i))) {
+ String subItemNumbers = (String) completedSubItems.get(Integer.toString(i));
+ StringTokenizer st = new StringTokenizer(subItemNumbers, ","); //$NON-NLS-1$
+ if (item instanceof CoreItem) {
+ CoreItem coreitemws = (CoreItem) item;
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ ((SubItemCompositeHolder) coreitemws.getListOfSubItemCompositeHolders().get(Integer.parseInt(token))).setCompleted(true);
+ ((SubItemCompositeHolder) coreitemws.getListOfSubItemCompositeHolders().get(Integer.parseInt(token))).getIconLabel().setImage((item).getCompleteImage());
+ ArrayList l = coreitemws.getListOfSubItemCompositeHolders();
+ SubItemCompositeHolder s = (SubItemCompositeHolder) l.get(Integer.parseInt(token));
+ if (s != null) {
+ s.getStartButton().setImage(coreitemws.restartImage);
+ s.getStartButton().redraw();
+ }
+
+ }
+ }
+ }
+ if (skippedSubItemsItemList.contains(Integer.toString(i))) {
+ String subItemNumbers = (String) skippedSubItems.get(Integer.toString(i));
+ StringTokenizer st = new StringTokenizer(subItemNumbers, ","); //$NON-NLS-1$
+ if (item instanceof CoreItem) {
+ CoreItem coreitemws = (CoreItem) item;
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ ((SubItemCompositeHolder) coreitemws.getListOfSubItemCompositeHolders().get(Integer.parseInt(token))).setSkipped(true);
+ ((SubItemCompositeHolder) coreitemws.getListOfSubItemCompositeHolders().get(Integer.parseInt(token))).getIconLabel().setImage((item).getSkipImage());
+ }
+ }
+ }
+ }
+ if (buttonIsDown) {
+ allCollapsed = true;
+ hideFields.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.RESTORE_ALL_TOOLTIP));
+ saveCurrentSheet();
+ hideFields.setChecked(true);
+ }
+ currentItem.setAsCurrentActiveItem();
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, currentItem);
+ } else {
+ getViewItemArray()[0].setAsCurrentActiveItem();
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, getViewItemArray()[0]);
+ }
+
+ updateScrolledComposite();
+ scrollIfNeeded();
+ savedProps = null;
+ }
+
+ private void clearBackgrounds(ViewItem[] myview) {
+ for (int i = 0; i < myview.length; i++) {
+ myview[i].setOriginalColor();
+ myview[i].unboldTitle();
+ }
+ }
+
+ private void clearIcons(ViewItem[] myview) {
+ for (int i = 0; i < myview.length; i++) {
+ if (myview[i].isCompleted() || myview[i].expanded || myview[i].isSkipped())
+ if (i > 0)
+ ((CoreItem) myview[i]).setIncomplete();
+ else
+ myview[i].setIncomplete();
+ }
+ }
+
+ private void collapseAllButCurrent(boolean fromAction) {
+ expandRestoreList = new ArrayList();
+ ViewItem[] items = getViewItemArray();
+ try {
+ for (int i = items.length - 1; i >= 0; i--) {
+
+ if (i != currentItemNum && items[i].expanded) {
+ items[i].setCollapsed();
+ if (fromAction)
+ expandRestoreList.add(Integer.toString(i));
+ }
+
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ private void collapseAllButtons(ViewItem[] myview) {
+ for (int i = 1; i < myview.length; i++) {
+ myview[i].setButtonsCollapsed();
+ }
+ }
+
+ private void contributeToActionBars() {
+ //here you have to assemble the same list as the list added to the help menu bar.
+ //so an external class should do it so it can be shared with something that
+ //both these classes can use. I will call it CheatSheetActionGetter.
+ // System.out.println("Inside of contribute to action bars!!!!");
+
+ IActionBars bars = getViewSite().getActionBars();
+ IMenuManager menuManager = bars.getMenuManager();
+ IToolBarManager tbmanager = bars.getToolBarManager();
+
+ // fields
+ IPluginDescriptor mydesc = CheatSheetPlugin.getPlugin().getDescriptor();
+ String skipfileName = "icons/full/elcl16/collapse_expand_all.gif"; //$NON-NLS-1$
+ URL skipurl = mydesc.find(new Path(skipfileName));
+ ImageDescriptor skipTask = ImageDescriptor.createFromURL(skipurl);
+
+ hideFields = new CheatSheetExpandRestoreAction(CheatSheetPlugin.getResourceString(ICheatSheetResource.COLLAPSE_ALL_BUT_CURRENT_TOOLTIP), false, this);
+ hideFields.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.COLLAPSE_ALL_BUT_CURRENT_TOOLTIP));
+ hideFields.setImageDescriptor(skipTask);
+ tbmanager.add(hideFields);
+
+ CheatSheetMenu cheatsheetMenuMenuItem = new CheatSheetMenu();
+ menuManager.add(cheatsheetMenuMenuItem);
+ }
+
+ private ContentItemWithSubItems convertThisIItem(IItem item) {
+ if (!(item instanceof ContentItem))
+ return null;
+ else {
+ ContentItem cc = (ContentItem) item;
+ ContentItemWithSubItems itemws = new ContentItemWithSubItems();
+ itemws.setContent(cc.getContent());
+ itemws.setID(cc.getID());
+ return itemws;
+ }
+ }
+
+ private ISubItem createASubItem(String subid, String actionCodes, String actionPID, String actionClass, String[] params, String label) {
+ SubContentItem subItem = new SubContentItem();
+ subItem.setActionClass(actionClass);
+ subItem.setButtonCodes(actionCodes);
+ subItem.setActionParams(params);
+ subItem.setLabel(label);
+ subItem.setActionPluginID(actionPID);
+ subItem.setID(subid);
+ return subItem;
+ }
+
+ private void createErrorPageInfoArea(Composite parent) {
+ Composite sampleComposite = null;
+ // Create the title area which will contain
+ // a title, message, and image.
+ scrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ scrolledComposite.setLayoutData(gridData);
+
+ //This infoArea composite is the composite for the items.
+ //It is owned by the scrolled composite which in turn is owned
+ //by the cheatSheetComposite.
+ infoArea = new Composite(scrolledComposite, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ layout.marginHeight = 9;
+ layout.marginWidth = 7;
+ layout.verticalSpacing = 3;
+ infoArea.setLayout(layout);
+ gridData = new GridData(GridData.FILL_HORIZONTAL);
+ infoArea.setLayoutData(gridData);
+ infoArea.setBackground(backgroundColor);
+
+ String errorString = CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_PAGE_MESSAGE);
+//"An error occurred loading the cheat sheet content file. Contact the cheat sheet provider for assistance.";
+
+ StyledText st = new StyledText(infoArea, SWT.WRAP | SWT.READ_ONLY | SWT.NULL);
+ st.setText(errorString);
+
+ GridData bgridData = new GridData();
+ bgridData.verticalAlignment = GridData.BEGINNING;
+ bgridData.horizontalAlignment = GridData.FILL;
+ bgridData.grabExcessHorizontalSpace = true;
+ st.setLayoutData(bgridData);
+ st.setEnabled(false);
+
+
+ // Adjust the scrollbar increments
+ if (sampleComposite == null) {
+ scrolledComposite.getHorizontalBar().setIncrement(HORZ_SCROLL_INCREMENT);
+ scrolledComposite.getVerticalBar().setIncrement(VERT_SCROLL_INCREMENT);
+ } else {
+ GC gc = new GC(sampleComposite);
+ int width = gc.getFontMetrics().getAverageCharWidth();
+ gc.dispose();
+ scrolledComposite.getHorizontalBar().setIncrement(width);
+ scrolledComposite.getVerticalBar().setIncrement(sampleComposite.getLocation().y);
+ }
+
+ // Point newTitleSize = infoArea.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ int workbenchWindowWidth = this.getSite().getWorkbenchWindow().getShell().getBounds().width;
+ cheatsheetMinimumWidth = (workbenchWindowWidth >> 2);
+
+ final int minWidth = cheatsheetMinimumWidth;
+ // from the computeSize(SWT.DEFAULT, SWT.DEFAULT) of all the
+ // children in infoArea excluding the wrapped styled text
+ // There is no easy way to do this.
+ final boolean[] inresize = new boolean[1];
+ // flag to stop unneccesary recursion
+ infoArea.addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ if (inresize[0])
+ return;
+ inresize[0] = true;
+ // Refresh problems are fixed if the following is runs twice
+ for (int i = 0; i < 2; ++i) {
+ // required because of bugzilla report 4579
+ infoArea.layout(true);
+ // required because you want to change the height that the
+ // scrollbar will scroll over when the width changes.
+ int width = infoArea.getClientArea().width;
+ Point p = infoArea.computeSize(width, SWT.DEFAULT);
+ scrolledComposite.setMinSize(minWidth, p.y);
+ inresize[0] = false;
+ }
+ }
+ });
+
+ scrolledComposite.setExpandHorizontal(true);
+ scrolledComposite.setExpandVertical(true);
+ Point p = infoArea.computeSize(minWidth, SWT.DEFAULT);
+ infoArea.setSize(p.x, p.y);
+
+ scrolledComposite.setMinWidth(minWidth);
+ scrolledComposite.setMinHeight(p.y);
+ //bug 20094
+
+ scrolledComposite.setContent(infoArea);
+ hascontent = true;
+
+ }
+
+ /**
+ * Creates the cheatsheet's title areawhich will consists
+ * of a title and image.
+ *
+ * @param parent the SWT parent for the title area composite
+ */
+ private void createErrorPageTitleArea(Composite parent) {
+ String errorTitle = CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_LOADING_CHEATSHEET_CONTENT);
+ //String errorTitle = "Error loading cheat sheet content";
+
+ // Message label
+ final CLabel messageLabel = new CLabel(parent, SWT.NONE);
+ messageLabel.setBackground(colorArray, new int[] { 50, 100 });
+
+ messageLabel.setText(errorTitle);
+ messageLabel.setFont(JFaceResources.getHeaderFont());
+ GridData ldata = new GridData(GridData.FILL_HORIZONTAL);
+ ldata.grabExcessHorizontalSpace = true;
+ messageLabel.setLayoutData(ldata);
+
+ final IPropertyChangeListener fontListener = new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ if (JFaceResources.HEADER_FONT.equals(event.getProperty())) {
+ messageLabel.setFont(JFaceResources.getHeaderFont());
+ }
+ }
+ };
+
+ messageLabel.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent event) {
+ JFaceResources.getFontRegistry().removeListener(fontListener);
+ }
+ });
+
+ JFaceResources.getFontRegistry().addListener(fontListener);
+
+ GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+ messageLabel.setLayoutData(gridData);
+ }
+
+ /**
+ * Creates the main composite area of the view.
+ *
+ * @param parent the SWT parent for the title area composite
+ * @return the created info area composite
+ */
+ private void createInfoArea(Composite parent) {
+ Composite sampleComposite = null;
+ // Create the title area which will contain
+ // a title, message, and image.
+ scrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ scrolledComposite.setLayoutData(gridData);
+
+ //This infoArea composite is the composite for the items.
+ //It is owned by the scrolled composite which in turn is owned
+ //by the cheatSheetComposite.
+ infoArea = new Composite(scrolledComposite, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ layout.marginHeight = 9;
+ layout.marginWidth = 7;
+ layout.verticalSpacing = 3;
+ infoArea.setLayout(layout);
+ gridData = new GridData(GridData.FILL_HORIZONTAL);
+ infoArea.setLayoutData(gridData);
+ infoArea.setBackground(backgroundColor);
+
+ IntroItem myintro = new IntroItem(infoArea, parser.getIntroItem(), darkGrey, this);
+ sampleComposite = myintro.getMainItemComposite();
+
+ myintro.setItemColor(myintro.lightGrey);
+ myintro.boldTitle();
+ viewItemList.add(myintro);
+
+ //Get the content info from the parser. This makes up all items except the intro item.
+ ArrayList items = parser.getItems();
+ listOfContentItems = items;
+ int switcher = 0;
+
+ for (int i = 0; i < items.size(); i++) {
+ if (switcher == 0) {
+ if (items.get(i) instanceof ContentItemWithSubItems) {
+ CoreItem ciws = new CoreItem(infoArea, (ContentItemWithSubItems) items.get(i), backgroundColor, this);
+ viewItemList.add(ciws);
+ } else {
+ CoreItem mycore = new CoreItem(infoArea, (ContentItem) items.get(i), backgroundColor, this);
+ viewItemList.add(mycore);
+ }
+ switcher = 1;
+ } else {
+ if (items.get(i) instanceof ContentItemWithSubItems) {
+ CoreItem ciws = new CoreItem(infoArea, (ContentItemWithSubItems) items.get(i), lightGrey, this);
+ viewItemList.add(ciws);
+ } else {
+ CoreItem mycore = new CoreItem(infoArea, (ContentItem) items.get(i), lightGrey, this);
+ viewItemList.add(mycore);
+ }
+ switcher = 0;
+ }
+ }
+
+ // Adjust the scrollbar increments
+ if (sampleComposite == null) {
+ scrolledComposite.getHorizontalBar().setIncrement(HORZ_SCROLL_INCREMENT);
+ scrolledComposite.getVerticalBar().setIncrement(VERT_SCROLL_INCREMENT);
+ } else {
+ GC gc = new GC(sampleComposite);
+ int width = gc.getFontMetrics().getAverageCharWidth();
+ gc.dispose();
+ scrolledComposite.getHorizontalBar().setIncrement(width);
+ scrolledComposite.getVerticalBar().setIncrement(sampleComposite.getLocation().y);
+ }
+
+ // Point newTitleSize = infoArea.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ int workbenchWindowWidth = this.getSite().getWorkbenchWindow().getShell().getBounds().width;
+ cheatsheetMinimumWidth = (workbenchWindowWidth >> 2);
+
+ final int minWidth = cheatsheetMinimumWidth;
+ // from the computeSize(SWT.DEFAULT, SWT.DEFAULT) of all the
+ // children in infoArea excluding the wrapped styled text
+ // There is no easy way to do this.
+ final boolean[] inresize = new boolean[1];
+ // flag to stop unneccesary recursion
+ infoArea.addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ if (inresize[0])
+ return;
+ inresize[0] = true;
+ // Refresh problems are fixed if the following is runs twice
+ for (int i = 0; i < 2; ++i) {
+ // required because of bugzilla report 4579
+ infoArea.layout(true);
+ // required because you want to change the height that the
+ // scrollbar will scroll over when the width changes.
+ int width = infoArea.getClientArea().width;
+ Point p = infoArea.computeSize(width, SWT.DEFAULT);
+ scrolledComposite.setMinSize(minWidth, p.y);
+ inresize[0] = false;
+ }
+ }
+ });
+
+ scrolledComposite.setExpandHorizontal(true);
+ scrolledComposite.setExpandVertical(true);
+ Point p = infoArea.computeSize(minWidth, SWT.DEFAULT);
+ infoArea.setSize(p.x, p.y);
+
+ scrolledComposite.setMinWidth(minWidth);
+ scrolledComposite.setMinHeight(p.y);
+ //bug 20094
+
+ scrolledComposite.setContent(infoArea);
+ hascontent = true;
+ }
+
+ /**
+ * Creates the SWT controls for this workbench part.
+ * <p>
+ * Clients should not call this method (the workbench calls this method at
+ * appropriate times).
+ * </p>
+ * <p>
+ * For implementors this is a multi-step process:
+ * <ol>
+ * <li>Create one or more controls within the parent.</li>
+ * <li>Set the parent layout as needed.</li>
+ * <li>Register any global actions with the <code>IActionService</code>.</li>
+ * <li>Register any popup menus with the <code>IActionService</code>.</li>
+ * <li>Register a selection provider with the <code>ISelectionService</code>
+ * (optional). </li>
+ * </ol>
+ * </p>
+ *
+ * @param parent the parent control
+ */
+ public void createPartControl(Composite parent) {
+ this.parent = parent;
+ busyCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT);
+ Display display = parent.getDisplay();
+ lightGrey = new Color(display, HIGHLIGHT_RGB);
+ darkGrey = new Color(display, darkGreyRGB);
+ colorArray = new Color[] { new Color(display, topRGB), new Color(display, midRGB), new Color(display, bottomRGB)};
+ // Get the background color for the cheatsheet controls
+ backgroundColor = JFaceColors.getBannerBackground(display);
+
+//TODO: Port problem!
+// FastViewHack.enableFollowingFastViewOnly(this);
+
+ if (!actionBarContributed) {
+ contributeToActionBars();
+ actionBarContributed = true;
+ }
+ if (memento != null) {
+ restoreState(memento);
+ initCheatSheetView();
+ }
+ }
+
+ /**
+ * Creates the cheatsheet's title areawhich will consists
+ * of a title and image.
+ *
+ * @param parent the SWT parent for the title area composite
+ */
+ private void createTitleArea(Composite parent) {
+ // Message label
+ final CLabel messageLabel = new CLabel(parent, SWT.NONE);
+ messageLabel.setBackground(colorArray, new int[] { 50, 100 });
+
+ messageLabel.setText(getBannerTitle());
+ messageLabel.setFont(JFaceResources.getHeaderFont());
+ GridData ldata = new GridData(GridData.FILL_HORIZONTAL);
+ ldata.grabExcessHorizontalSpace = true;
+ messageLabel.setLayoutData(ldata);
+
+ final IPropertyChangeListener fontListener = new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ if (JFaceResources.HEADER_FONT.equals(event.getProperty())) {
+ messageLabel.setFont(JFaceResources.getHeaderFont());
+ }
+ }
+ };
+
+ messageLabel.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent event) {
+ JFaceResources.getFontRegistry().removeListener(fontListener);
+ }
+ });
+
+ JFaceResources.getFontRegistry().addListener(fontListener);
+
+ GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+ messageLabel.setLayoutData(gridData);
+
+ // Point titleSize = messageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ // Point newTitleSize = infoArea.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ // if(newTitleSize == null){
+ //
+ // }else{
+ //
+ // }
+ // cheatsheetMinimumWidth = titleSize.x;
+ // cheatsheetMinimumWidth = newTitleSize.x;
+ }
+
+ /**
+ * @see org.eclipse.ui.IWorkbenchPart#dispose()
+ */
+ public void dispose() {
+ fireManagerViewEvent(ICheatSheetViewEvent.CHEATSHEET_CLOSED);
+
+ super.dispose();
+
+ saveCurrentSheet();
+
+ callDisposeOnViewElements();
+
+ if (busyCursor != null)
+ busyCursor.dispose();
+
+ if (parent != null)
+ parent.dispose();
+
+ if (lightGrey != null)
+ lightGrey.dispose();
+
+ if (darkGrey != null)
+ darkGrey.dispose();
+
+ for (int i = 0; i < colorArray.length; i++) {
+ if (colorArray[i] != null)
+ colorArray[i].dispose();
+ }
+ }
+
+ private void fireManagerItemEvent(int eventType, ViewItem currentItem) {
+ String mid = null;
+ String subid = null;
+ if (currentItem.contentItem instanceof ContentItem)
+ mid = ((ContentItem) currentItem.contentItem).getID();
+ else if (currentItem.contentItem instanceof ContentItemWithSubItems) {
+ mid = ((ContentItemWithSubItems) currentItem.contentItem).getID();
+ }
+ getCheatsheetManager().fireEvent(new CheatSheetItemEvent(eventType, currentID, mid, subid, getCheatsheetManager()));
+ }
+
+ private void fireManagerSubItemEvent(int eventType, ViewItem currentItem, String subItemID) {
+ String mid = null;
+ String subid = subItemID;
+ if (currentItem.contentItem instanceof ContentItem)
+ mid = ((ContentItem) currentItem.contentItem).getID();
+ else if (currentItem.contentItem instanceof ContentItemWithSubItems) {
+ mid = ((ContentItemWithSubItems) currentItem.contentItem).getID();
+ }
+ if (contentElement != null && currentID != null)
+ getCheatsheetManager().fireEvent(new CheatSheetItemEvent(eventType, currentID, mid, subid, getCheatsheetManager()));
+ }
+
+ private void fireManagerViewEvent(int eventType) {
+ getCheatsheetManager().fireEvent(new CheatSheetViewEvent(eventType, currentID, getCheatsheetManager()));
+ }
+
+ /**
+ * Returns the title obtained from the parser
+ */
+ private String getBannerTitle() {
+ if (parser.getTitle() == null)
+ return ""; //$NON-NLS-1$
+ return parser.getTitle();
+ }
+
+ private CheatSheetManager getCheatsheetManager() {
+ if (manager == null) {
+ manager = new CheatSheetManager(currentID, this);
+ }
+ return manager;
+ }
+
+ /**
+ * Returns the current content.
+ *
+ * @return CheatSheetElement
+ */
+ public CheatSheetElement getContent() {
+ return contentElement;
+ }
+
+ /**
+ * @return
+ */
+ public float getCsversion() {
+ return csversion;
+ }
+
+ /**
+ * Returns the hascontent.
+ * true if the cheatsheet has content loaded and displayed.
+ * @return boolean
+ */
+ private boolean getHasContent() {
+ return hascontent;
+ }
+
+ private int getIndexOfItem(ViewItem item) {
+ duckbreak : for (int i = 1; i < viewItemList.size(); i++) {
+ if (currentItem == viewItemList.get(i)) {
+ int index = i + 1;
+ return index;
+ }
+ }
+ return 0;
+ }
+
+ private IAbstractItem getItemWithID(String id) {
+ try {
+ //Check to see if that item with that id is dynamic.
+ //If it is not dynamic, return null for it cannot be modified.
+ ArrayList contentItems = parser.getItems();
+ for (int i = 0; i < contentItems.size(); i++) {
+ IAbstractItem contentItem = (IAbstractItem) contentItems.get(i);
+ if (contentItem.getID().equals(id)) {
+ //return contentItem;
+ if (contentItem instanceof IContainsContent) {
+ IContainsContent cc = (IContainsContent) contentItem;
+ if (cc.isDynamic())
+ return contentItem;
+ }
+ return null;
+ }
+
+ }
+ return null;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * @return
+ */
+ /*package*/ ArrayList getListOfContentItems() {
+ return listOfContentItems;
+ }
+
+ /*package*/ ViewItem[] getViewItemArray() {
+ return (ViewItem[]) viewItemList.toArray(new ViewItem[viewItemList.size()]);
+ }
+
+ private ViewItem getViewItemAtIndex(int index) {
+ return (ViewItem) viewItemList.get(index);
+ }
+
+ /* (non-Javadoc)
+ * Initializes this view with the given view site. A memento is passed to
+ * the view which contains a snapshot of the views state from a previous
+ * session. Where possible, the view should try to recreate that state
+ * within the part controls.
+ * <p>
+ * This implementation will ignore the memento and initialize the view in
+ * a fresh state. Subclasses may override the implementation to perform any
+ * state restoration as needed.
+ */
+ public void init(IViewSite site, IMemento memento) throws PartInitException {
+ init(site);
+ this.memento = memento;
+ }
+
+ private void initCheatSheetView() {
+
+ //Re-initialize list to store items collapsed by expand/restore action on c.s. toolbar.
+ expandRestoreList = new ArrayList();
+
+ // re set that action to turned off.
+ hideFields.setChecked(false);
+ allCollapsed = false;
+ hideFields.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.COLLAPSE_ALL_BUT_CURRENT_TOOLTIP));
+
+ //reset current item to be null; next item too.
+ currentItem = null;
+ nextItem = null;
+
+ currentItemNum = -1;
+ viewItemList = new ArrayList();
+
+ // read our contents;
+ // add checker here in case file could not be parsed. No file parsed, no composite should
+ // be created.
+ boolean parsedOK = readFile();
+ if(!parsedOK){
+// Exception thrown during parsing.
+// Something is wrong with the Cheat sheet content file at the xml level.
+
+ //System.out.println("PARSER ERROR THROWN.");
+ cheatSheetComposite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ layout.numColumns = 1;
+ cheatSheetComposite.setLayout(layout);
+ cheatSheetComposite.setBackground(backgroundColor);
+ createErrorPageTitleArea(cheatSheetComposite);
+ createErrorPageInfoArea(cheatSheetComposite);
+ parent.layout(true);
+ return;
+ }
+
+ cheatSheetComposite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ layout.numColumns = 1;
+ cheatSheetComposite.setLayout(layout);
+ cheatSheetComposite.setBackground(backgroundColor);
+
+ WorkbenchHelp.setHelp(cheatSheetComposite, IHelpContextIds.WELCOME_EDITOR);
+
+ checkDynamicModel();
+
+ createTitleArea(cheatSheetComposite);
+ createInfoArea(cheatSheetComposite);
+
+ checkSavedState();
+
+ fireManagerViewEvent(ICheatSheetViewEvent.CHEATSHEET_OPENED);
+
+ parent.layout(true);
+
+ if (currentItem != null)
+ currentItem.getExpandToggle().setFocus();
+
+ // System.out.println("Firing open event!");
+ scrolledComposite.layout(true);
+ infoArea.layout(true);
+ layoutMyItems();
+ }
+
+ private void killDynamicData(ViewItem[] myitems){
+// getCheatsheetManager().removeAllData();
+ manager = new CheatSheetManager(currentID, this);
+
+ for (int i=0; i<myitems.length; i++){
+ if(myitems[i].contentItem.isDynamic()){
+ ((CoreItem)myitems[i]).setButtonsHandled(false);
+ if(myitems[i].contentItem instanceof ContentItemWithSubItems)
+ ((ContentItemWithSubItems)myitems[i].contentItem).addSubItems(null);
+ }
+
+ }
+ }
+
+ /*package*/ void layout(){
+ infoArea.layout(true);
+ }
+
+ private void layoutMyItems() {
+ ViewItem[] items = getViewItemArray();
+ for (int i = 0; i < items.length; i++) {
+ items[i].getCheckAndMainItemComposite().layout(true);
+ }
+ }
+
+ /**
+ * Read the contents of the welcome page
+ */
+ private boolean readFile() {
+ parser = new CheatSheetDomParser(contentURL);
+ boolean retBool = parser.parse();
+ csversion = parser.getCsversion();
+ return retBool;
+ }
+
+ private boolean replaceThisContentItem(ContentItem ci, ContentItemWithSubItems ciws) {
+ ArrayList list = parser.getItems();
+ for (int i = 0; i < list.size(); i++) {
+ IAbstractItem oci = (IAbstractItem) list.get(i);
+ if (oci.getID().equals(ci.getID())) {
+ list.set(i, ciws);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void restoreExpandStates() {
+ ViewItem[] items = getViewItemArray();
+ try {
+ for (int i = 0; i < expandRestoreList.size(); i++) {
+ int index = Integer.parseInt(((String) expandRestoreList.get(i)));
+ if (!items[index].expanded) {
+ items[index].setExpanded();
+ }
+ }
+ expandRestoreList = null;
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * Restore the view state
+ */
+ private void restoreState(IMemento memento) {
+ IMemento contentMemento = memento.getChild(ICheatSheetResource.URL_MEMENTO);
+ if (contentMemento == null) {
+
+ } else {
+
+ try {
+ URL fileURL = new URL(contentMemento.getString(ICheatSheetResource.URL_ID));
+ contentURL = fileURL;
+ } catch (MalformedURLException mue) {
+ }
+ }
+ }
+
+ /*package*/ void runPerformAction(Button mylabel) {
+ CoreItem mycore = null;
+ mylabel.setCursor(busyCursor);
+ currentItem = (ViewItem) mylabel.getData();
+ mycore = (CoreItem) currentItem;
+
+ try {
+ if (mycore != null) {
+ if ((mycore.runAction(getCheatsheetManager()) == ViewItem.VIEWITEM_ADVANCE)){// && !(mycore.isCompleted())) {
+ fireManagerItemEvent(ICheatSheetItemEvent.ITEM_PERFORMED, currentItem);
+ mycore.setRestartImage();
+ //set that item as complete.
+ advanceItem(mylabel, true);
+ saveCurrentSheet();
+ }
+ }
+ } catch (RuntimeException e) {
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_RUNNING_ACTION), e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ org.eclipse.jface.dialogs.ErrorDialog.openError(new Shell(), CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_RUNNING_ACTION), null, status);
+
+ } finally {
+ mylabel.setCursor(null);
+ }
+ }
+
+ /*package*/ void runSubItemPerformAction(Button mylabel, int subItemIndex) {
+ currentItem = (ViewItem) mylabel.getData();
+
+ // CoreItem c = null;
+ CoreItem ciws = null;
+
+ if (currentItem instanceof CoreItem)
+ ciws = (CoreItem) currentItem;
+
+ try {
+ if (ciws != null) {
+ if (ciws.contentItem instanceof ContentItemWithSubItems) {
+ ContentItemWithSubItems contentWithSubs = (ContentItemWithSubItems) ciws.contentItem;
+ ISubItem isi = contentWithSubs.getSubItem(subItemIndex);
+ String[] params = isi.getActionParams();
+ if ((ciws.runAction(isi.getActionPluginID(), isi.getActionClass(), params, getCheatsheetManager()) == ViewItem.VIEWITEM_ADVANCE)) {
+ //set that item as complete.
+ ArrayList l = ciws.getListOfSubItemCompositeHolders();
+ SubItemCompositeHolder s = (SubItemCompositeHolder) l.get(subItemIndex);
+ if (s != null) {
+ s.getStartButton().setImage(ciws.restartImage);
+ s.getStartButton().redraw();
+ }
+ advanceSubItem(mylabel, true, subItemIndex);
+ saveCurrentSheet();
+ }
+ }
+ }
+ } catch (RuntimeException e) {
+ } finally {
+ mylabel.setCursor(null);
+ }
+ }
+
+ /*package*/ void saveCurrentSheet() {
+ if(currentID != null)
+ saveHelper.saveThisState(contentURL, currentItemNum, getViewItemArray(), allCollapsed, expandRestoreList, currentID, getCheatsheetManager());
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IViewPart.
+ */
+ public void saveState(IMemento memento) {
+ //System.out.println("Saving the state of the cheat Sheet view!!!");
+ if (contentURL != null) {
+ IMemento contentMemento = memento.createChild(ICheatSheetResource.URL_MEMENTO);
+ contentMemento.putString(ICheatSheetResource.URL_ID, contentURL.toString());
+ //System.out.println("The memento got the string.");
+ //System.out.println("Here is teh memento String saved: "+contentMemento.getString("contentURL"));
+ //Get the plugin save location:
+ // IPath savePath = Platform.getPluginStateLocation(CheatSheetPlugin.getPlugin());
+ saveCurrentSheet();
+ }
+ }
+
+ /**
+ * Scroll the our contents to keep the current entry on the screen. Should be
+ * called each time currentEntry is changed.
+ */
+ /*package*/ void scrollIfNeeded() {
+ // System.out.println("Scrolling if needed!!!");
+ // First thing, decide on our target widget - for an InfoAreaEntry, this will
+ // be its composite, for a closing item, it will be the StyledText. Doesn't matter,
+ // so long as it's whatever widget has 'infoArea' as a parent.
+ Composite targetComposite = null;
+ //if(currentItemNum>0 && currentItem == null) {
+ // We are at the end, our target widget is the closing text
+ // targetComposite = closingText;
+ //} else
+ if (nextItem != null) {
+ targetComposite = nextItem.getCheckAndMainItemComposite();
+ } else if (currentItem != null) {
+ targetComposite = currentItem.getCheckAndMainItemComposite();
+ }
+ // System.out.println("The target composite beginning "+targetComposite);
+ if (targetComposite == null) {
+ // System.out.println("The target composite was null!!!");
+ return;
+ }
+ // In an effort to make everything more readable, we will extract out all the
+ // values of relevance into seperate variables, and alias all the relevant composites
+
+ // Composite infoArea = targetComposite.getParent();
+ // System.out.println("The info area is "+infoArea);
+
+ // ScrolledComposite scrolledComposite = (ScrolledComposite) infoArea.getParent();
+ // System.out.println("The sc is "+scrolledComposite);
+
+ // The scrollbar will need to be updated as well. We use its increment because it's
+ // probably better than some arbitrary number
+ // System.out.println("Getting vertical bar");
+ ScrollBar vBar = scrolledComposite.getVerticalBar();
+ int increment = (vBar.getIncrement()) * 4;
+ // int increment = (vBar.getIncrement());
+ // When scrolling, the situation is that infoArea is *larger* than scrolledComposite,
+ // which encloses it. Thus the viewable area of infoArea is a question of how far off
+ // the top of scrolledComposite it begins, and how much of it scrolledComposite can display.
+ int topOfInfoArea = infoArea.getBounds().y;
+ int bottomOfInfoArea = infoArea.getBounds().height;
+ int firstPixelViewable = -topOfInfoArea;
+ int lastPixelViewable = scrolledComposite.getSize().y + firstPixelViewable;
+ int firstPixelOfTarget = targetComposite.getLocation().y;
+ // int geoffPixelofTarget = targetComposite.getBounds().y;
+ // int otherPixelofTarget = targetComposite.get
+
+ int lastPixelOfTarget = firstPixelOfTarget + targetComposite.getSize().y;
+ // If target is on screen already, don't do anything
+ if ((firstPixelOfTarget >= firstPixelViewable) && (lastPixelOfTarget <= lastPixelViewable)) {
+ // System.out.println("Doing nothing!!!");
+ return;
+ }
+
+ // System.out.println("CHECK 1");
+
+ int totalinc = 0;
+ int myint = infoArea.getBounds().y;
+ // Whether we're scrolling up or down, the principle is the same, get the top of the
+ // current entry to within 'increment' pixels of the top of the viewable area.
+ //UPDATED: 05/31/2002 : keeps track of the increment until it has figured out the
+ //scroll value. Then the target area is redrawn. The result is no flicker,
+ //just one refresh redrawn. NICE.
+
+ scrolledComposite.setVisible(false);
+
+ if (firstPixelOfTarget < firstPixelViewable) {
+ while (firstPixelOfTarget < firstPixelViewable) {
+ // We are scrolling up, target is above viewable
+ // Don't scroll past top though
+ // System.err.println("Scrolling UP");
+ if (topOfInfoArea >= firstPixelViewable)
+ break;
+ vBar.setSelection(vBar.getSelection() - increment);
+ totalinc -= increment;
+ myint += increment;
+ // Update relevant indices
+ topOfInfoArea = myint;
+ firstPixelViewable = -topOfInfoArea;
+ lastPixelViewable = scrolledComposite.getSize().y + firstPixelViewable;
+ }
+ infoArea.setLocation(infoArea.getLocation().x, infoArea.getLocation().y - totalinc);
+ } else if (firstPixelOfTarget > (firstPixelViewable + increment)) {
+ while (firstPixelOfTarget > (firstPixelViewable + increment)) {
+ // System.err.println("Scrolling Down");
+ // We are scrolling down, target is below viewable.
+ // Don't scroll past bottom though
+ if (bottomOfInfoArea <= lastPixelViewable)
+ break;
+ vBar.setSelection(vBar.getSelection() + increment + 5);
+ totalinc += increment;
+ myint -= increment;
+ // Update relevant indices
+ topOfInfoArea = myint;
+ firstPixelViewable = -topOfInfoArea;
+ lastPixelViewable = scrolledComposite.getSize().y + firstPixelViewable;
+ }
+ infoArea.setLocation(infoArea.getLocation().x, infoArea.getLocation().y - totalinc);
+ }
+ // System.out.println("Total increment to incrememt = "+totalinc);
+ //Set the info area location last.
+ scrolledComposite.setVisible(true);
+ scrolledComposite.layout(true);
+ infoArea.layout(true);
+
+ }
+
+ public void setContent(CheatSheetElement element) {
+
+ if (contentURL != null)
+ saveCurrentSheet();
+
+ if (element == null)
+ return;
+
+ // Cleanup previous contents
+ if (getHasContent()) {
+ callDisposeOnViewElements();
+ }
+
+ // Set the current content to new content
+ this.contentElement = element;
+ currentID = element.getID();
+
+ // System.out.println("The cheatsheet id loaded is: " + currentID); //$NON-NLS-1$
+
+ IPluginDescriptor desc = null;
+ if(element != null)
+ try{
+ desc = element.getConfigurationElement().getDeclaringExtension().getDeclaringPluginDescriptor();
+ }catch(Exception e){}
+
+ if(desc != null)
+ this.contentURL = desc.find(new Path("$nl$").append(element.getContentFile())); //$NON-NLS-1$
+
+ if (contentURL == null) {
+ URL checker;
+ try {
+ checker = new URL(element.getContentFile());
+ if (checker.getProtocol().equals("http")) { //$NON-NLS-1$
+ this.contentURL = checker;
+ }
+ } catch (MalformedURLException mue) {
+ }
+ }
+
+ // Initialize the view with the new contents
+ if (parent != null) {
+ initCheatSheetView();
+ }
+ }
+
+ /**
+ * Passing the focus request to the viewer's control.
+ */
+ public void setFocus() {
+ //need this to have view refreshed and redrawn nicely.
+ if (infoArea != null && !infoArea.isDisposed())
+ infoArea.setFocus();
+ //need this to have current item selected. (Assumes that when you reactivate the view you will work with current item.)
+ if (currentItem != null)
+ currentItem.getExpandToggle().setFocus();
+ }
+
+
+ /*package*/ void toggleExpandRestore() {
+ if (allCollapsed) {
+ restoreExpandStates();
+ allCollapsed = false;
+ hideFields.setToolTipText(CheatSheetPlugin.getResourceString(CheatSheetPlugin.getResourceString(ICheatSheetResource.COLLAPSE_ALL_BUT_CURRENT_TOOLTIP)));
+ saveCurrentSheet();
+ } else {
+ collapseAllButCurrent(true);
+ allCollapsed = true;
+ hideFields.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.RESTORE_ALL_TOOLTIP));
+ saveCurrentSheet();
+ }
+
+ }
+
+ /*package*/ void updateScrolledComposite() {
+ ScrolledComposite sc = scrolledComposite;
+ Point newSize = infoArea.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ infoArea.setSize(newSize);
+ sc.setMinSize(newSize);
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetViewEvent.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetViewEvent.java
new file mode 100644
index 000000000..c025b1fb4
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetViewEvent.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import org.eclipse.ui.cheatsheets.ICheatSheetManager;
+import org.eclipse.ui.cheatsheets.events.ICheatSheetViewEvent;
+
+public class CheatSheetViewEvent extends CheatSheetEvent implements ICheatSheetViewEvent {
+
+ public CheatSheetViewEvent(int eventType, String id, ICheatSheetManager csm) {
+ super();
+ this.csm = csm;
+ this.fCheatsheetEventType = eventType;
+ this.fCheatsheetID = id;
+ }
+
+ /**
+ * @return
+ */
+ public int getCheatSheetEventType() {
+ return fCheatsheetEventType;
+ }
+
+ /**
+ * @return
+ */
+ public String getCheatSheetID() {
+ return fCheatsheetID;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.cheatsheets.events.ICheatSheetEvent#getCheatSheetManager()
+ */
+ public ICheatSheetManager getCheatSheetManager() {
+ return csm;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CoreItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CoreItem.java
new file mode 100644
index 000000000..b83a71c16
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CoreItem.java
@@ -0,0 +1,431 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.net.URL;
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.data.*;
+import org.eclipse.ui.cheatsheets.ISubItem;
+
+public class CoreItem extends ViewItem {
+ protected Composite bodyWrapperComposite;
+ protected boolean buttonsHandled = false;
+ protected boolean complete;
+ protected Button completeButton;
+ protected Image completeImage;
+ private ArrayList listOfSubItemCompositeHolders;
+ protected Image restartImage;
+ protected boolean skip;
+ protected Button skipButton;
+ protected Image skipImage;
+ protected boolean start;
+ protected Button startButton;
+ protected Image startImage;
+
+
+ /**
+ * Constructor for CoreItem.
+ * @param parent
+ * @param contentItem
+ */
+ public CoreItem(Composite parent, IContainsContent contentItem, Color itemColor, CheatSheetView theview) {
+ super(parent, contentItem, itemColor, theview);
+ }
+
+ /**
+ * @see org.eclipse.ui.internal.cheatsheets.views.ViewItem#disposeOfStuff()
+ */
+ public void dispose() {
+ super.dispose();
+
+ if (startImage != null)
+ startImage.dispose();
+ if (skipImage != null)
+ skipImage.dispose();
+ if (completeImage != null)
+ completeImage.dispose();
+ if (restartImage != null)
+ restartImage.dispose();
+ }
+
+ private int[] getActionCodeArray(String actionPhrase) {
+ int[] actionCodes = { -1, -1, -1 };
+ StringTokenizer mytoken = new StringTokenizer(actionPhrase, ","); //$NON-NLS-1$
+
+ for (int j = 0; j < 3; j++) {
+ if (mytoken.hasMoreTokens()) {
+ String mytokenstring = mytoken.nextToken();
+ //System.out.println("Token"+mytokenstring);
+ try {
+ actionCodes[j] = Integer.parseInt(mytokenstring);
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ return actionCodes;
+ }
+
+ public ArrayList getListOfSubItemCompositeHolders() {
+ return listOfSubItemCompositeHolders;
+ }
+
+ /**
+ * @see org.eclipse.ui.internal.cheatsheets.data.ViewItem#handleButtons(Composite)
+ */
+ /*package*/ void handleButtons(Composite bodyWrapperComposite) {
+ if (contentItem instanceof ContentItemWithSubItems) {
+ try{
+ handleSubButtons(bodyWrapperComposite);
+ }catch(Exception e){
+ //Need to log exception here.
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.LESS_THAN_2_SUBITEMS), e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ org.eclipse.jface.dialogs.ErrorDialog.openError(new Shell(), CheatSheetPlugin.getResourceString(ICheatSheetResource.LESS_THAN_2_SUBITEMS), null, status);
+ }
+ return;
+ }
+
+ if (buttonsHandled)
+ return;
+
+ buttonComposite = new Composite(bodyWrapperComposite, SWT.NONE);
+ GridLayout buttonlayout = new GridLayout(4, false);
+ buttonlayout.marginHeight = 2;
+ buttonlayout.marginWidth = 2;
+ buttonlayout.verticalSpacing = 2;
+
+ GridData buttonData = new GridData(GridData.FILL_HORIZONTAL);
+ buttonData.grabExcessHorizontalSpace = true;
+
+ buttonComposite.setLayout(buttonlayout);
+ buttonComposite.setLayoutData(buttonData);
+ buttonComposite.setBackground(itemColor);
+ Label filllabel = new Label(buttonComposite, SWT.NULL);
+ filllabel.setBackground(itemColor);
+ GridData filldata = new GridData();
+ filldata.widthHint = 16;
+ filllabel.setLayoutData(filldata);
+
+
+ start = false;
+ complete = false;
+ skip = false;
+ int[] actionCodes = null;
+
+ //Get the action codes to display buttons for.
+
+ actionCodes = getActionCodeArray(((ContentItem) contentItem).getButtonCodes());
+
+
+
+
+ //Add the icons in order. Check each one when you add it.
+ for (int i = 0; i < actionCodes.length; i++) {
+ if (actionCodes[i] == 0) {
+ //perform
+ start = true;
+ } else if (actionCodes[i] == 1) {
+ //continue/skip
+ skip = true;
+ } else if (actionCodes[i] == 2) {
+ //done
+ complete = true;
+ }
+ }
+
+ if (start) {
+ startButton = new Button(buttonComposite, SWT.NULL, startImage);
+ startButton.setData(this);
+ startButton.setBackground(itemColor);
+ startButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.PERFORM_TASK_TOOLTIP));
+ startButton.setFAccessibleDescription(bodyText.getText());
+ startButton.setFAccessibleName(startButton.getToolTipText());
+
+ startButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ theview.runPerformAction(startButton);
+ }
+ });
+ }
+ if (skip) {
+ skipButton = new Button(buttonComposite, SWT.NULL, skipImage);
+ skipButton.setData(this);
+ skipButton.setBackground(itemColor);
+ skipButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.SKIP_TASK_TOOLTIP));
+ skipButton.setFAccessibleName(skipButton.getToolTipText());
+ skipButton.setFAccessibleDescription(bodyText.getText());
+
+ skipButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ theview.advanceItem(skipButton, false);
+ }
+ });
+ }
+ if (complete) {
+ completeButton = new Button(buttonComposite, SWT.NULL, completeImage);
+ completeButton.setData(this);
+ completeButton.setBackground(itemColor);
+ completeButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.COMPLETE_TASK_TOOLTIP));
+ completeButton.setFAccessibleName(completeButton.getToolTipText());
+ completeButton.setFAccessibleDescription(bodyText.getText());
+
+ completeButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ theview.advanceItem(completeButton, true);
+ }
+ });
+ }
+ buttonCompositeList.add(buttonComposite);
+ buttonsHandled = true;
+ }
+
+ /*package*/ void handleLazyButtons() {
+ handleButtons(bodyWrapperComposite);
+ }
+
+ /**
+ * @see org.eclipse.ui.internal.cheatsheets.data.ViewItem#handleButtons(Composite)
+ */
+ private void handleSubButtons(Composite bodyWrapperComposite) throws Exception {
+ if (buttonsHandled)
+ return;
+ //Instantiate the list to store the sub item composites.
+ listOfSubItemCompositeHolders = new ArrayList(20);
+
+ ISubItem[] sublist = ((ContentItemWithSubItems) contentItem).getSubItems();
+
+ if(sublist.length<=1)
+ throw new Exception(ICheatSheetResource.LESS_THAN_2_SUBITEMS);
+
+
+ buttonComposite = new Composite(bodyWrapperComposite, SWT.NULL);
+ GridLayout xbuttonlayout = new GridLayout(1, false);
+ xbuttonlayout.marginHeight = 2;
+ xbuttonlayout.marginWidth = 2;
+ xbuttonlayout.verticalSpacing = 2;
+ GridData xbuttonData = new GridData(GridData.FILL_HORIZONTAL);
+ xbuttonData.grabExcessHorizontalSpace = true;
+ buttonComposite.setLayout(xbuttonlayout);
+ buttonComposite.setLayoutData(xbuttonData);
+ buttonComposite.setBackground(itemColor);
+
+ buttonCompositeList.add(buttonComposite);
+ //loop throught the number of sub items, make a new composite for each sub item.
+ //Add the spacer, the label, then the buttons that are applicable for each sub item.
+ for (int i = 0; i < sublist.length; i++) {
+ int added = 0;
+ //Get the sub item to add.
+ ISubItem sub = (ISubItem) sublist[i];
+
+ //composite added.
+ Composite b = new Composite(buttonComposite, SWT.NULL);
+
+ GridLayout buttonlayout = new GridLayout(6, false);
+ buttonlayout.marginHeight = 2;
+ buttonlayout.marginWidth = 2;
+ buttonlayout.verticalSpacing = 2;
+ GridData buttonData = new GridData(GridData.FILL_HORIZONTAL);
+ buttonData.grabExcessHorizontalSpace = true;
+
+ b.setLayout(buttonlayout);
+ b.setLayoutData(buttonData);
+ b.setBackground(itemColor);
+
+ //Spacer label added.
+ Label filllabel = new Label(b, SWT.NULL);
+ filllabel.setBackground(itemColor);
+ GridData filldata = new GridData();
+ filldata.widthHint = 16;
+ filllabel.setLayoutData(filldata);
+ added++;
+
+ //Now add the label.
+ StyledText label = new StyledText(b, SWT.NULL);
+ label.setText(sub.getLabel());
+ GridData labelData = new GridData();
+ label.setLayoutData(labelData);
+ label.setBackground(itemColor);
+ label.setEnabled(false);
+ label.getCaret().setVisible(false);
+ added++;
+
+ //Bold the title.
+ // StyleRange r = new StyleRange(0, label.getText().length(), null, null, SWT.BOLD);
+ // label.setStyleRange(r);
+
+ start = false;
+ complete = false;
+ skip = false;
+
+ //Get the action codes to display buttons for.
+ int[] actionCodes = getActionCodeArray(sub.getButtonCodes());
+
+ //Add the icons in order. Check each one when you add it.
+ for (int j = 0; j < actionCodes.length; j++) {
+ if (actionCodes[j] == 0) {
+ //perform
+ start = true;
+ } else if (actionCodes[j] == 1) {
+ //continue/skip
+ skip = true;
+ } else if (actionCodes[j] == 2) {
+ //done
+ complete = true;
+ }
+ }
+ final int fi = i;
+
+ if (start) {
+ added++;
+ startButton = new Button(b, SWT.NULL, startImage);
+ startButton.setData(this);
+ startButton.setBackground(itemColor);
+ startButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.PERFORM_TASK_TOOLTIP));
+ startButton.setFAccessibleDescription(bodyText.getText());
+ startButton.setFAccessibleName(startButton.getToolTipText());
+
+ startButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ theview.runSubItemPerformAction(startButton, fi);
+ }
+ });
+ }
+ if (skip) {
+ added++;
+ skipButton = new Button(b, SWT.NULL, skipImage);
+ skipButton.setData(this);
+ skipButton.setBackground(itemColor);
+ skipButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.SKIP_TASK_TOOLTIP));
+ skipButton.setFAccessibleName(skipButton.getToolTipText());
+ skipButton.setFAccessibleDescription(bodyText.getText());
+
+ skipButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ theview.advanceSubItem(skipButton, false, fi);
+ }
+ });
+ }
+ if (complete) {
+ added++;
+ completeButton = new Button(b, SWT.NULL, completeImage);
+ completeButton.setData(this);
+ completeButton.setBackground(itemColor);
+ completeButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.COMPLETE_TASK_TOOLTIP));
+ completeButton.setFAccessibleName(completeButton.getToolTipText());
+ completeButton.setFAccessibleDescription(bodyText.getText());
+
+ completeButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ theview.advanceSubItem(completeButton, true, fi);
+ }
+ });
+ }
+
+ while (added < 6) {
+ //Spacer label added.
+ Label xfilllabel = new Label(b, SWT.NULL);
+ xfilllabel.setBackground(itemColor);
+ GridData xfilldata = new GridData(GridData.FILL_HORIZONTAL);
+ xfilllabel.setLayoutData(xfilldata);
+ added++;
+ }
+ buttonCompositeList.add(b);
+ listOfSubItemCompositeHolders.add(new SubItemCompositeHolder(filllabel, startButton));
+ }
+ buttonsHandled = true;
+ }
+
+ protected void init() {
+ super.init();
+
+ IPluginDescriptor mydesc = CheatSheetPlugin.getPlugin().getDescriptor();
+
+ String imageFileName = "icons/full/clcl16/start_task.gif"; //$NON-NLS-1$
+ URL imageURL = mydesc.find(new Path(imageFileName));
+ ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ startImage = imageDescriptor.createImage();
+
+ imageFileName = "icons/full/clcl16/skip_task.gif"; //$NON-NLS-1$
+ imageURL = mydesc.find(new Path(imageFileName));
+ imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ skipImage = imageDescriptor.createImage();
+
+ imageFileName = "icons/full/clcl16/complete_task.gif"; //$NON-NLS-1$
+ imageURL = mydesc.find(new Path(imageFileName));
+ imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ completeImage = imageDescriptor.createImage();
+
+ imageFileName = "icons/full/clcl16/restart_task.gif"; //$NON-NLS-1$
+ imageURL = mydesc.find(new Path(imageFileName));
+ imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ restartImage = imageDescriptor.createImage();
+ }
+ /**
+ * Returns the complete.
+ * @return boolean
+ */
+ // public boolean isComplete() {
+ // //System.out.println("in isComplete() "+hashCode()+" "+titleText.getText()+" "+start+" "+skip+" "+complete);
+ // return complete;
+ // }
+
+ /**
+ * @param composite
+ */
+ /*package*/ void setBodyWrapperComposite(Composite composite) {
+ bodyWrapperComposite = composite;
+ }
+
+ /*package*/void setButtonsHandled(boolean handled){
+ buttonsHandled = handled;
+ }
+
+ /*package*/ void setIncomplete() {
+ super.setIncomplete();
+
+ //check for sub items and reset their icons.
+ ArrayList l = getListOfSubItemCompositeHolders();
+ if(l != null){
+ for(int j=0; j<l.size(); j++){
+ SubItemCompositeHolder s = (SubItemCompositeHolder)l.get(j);
+ if(s.isCompleted() || s.isSkipped())
+ s.getIconLabel().setImage(null);
+ if(s.startButton != null)
+ s.getStartButton().setImage(startImage);
+
+ }
+ }
+ }
+
+ /*package*/ void setRestartImage() {
+ if (startButton != null) {
+ startButton.setImage(restartImage);
+ startButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.RESTART_TASK_TOOLTIP));
+ }
+ }
+
+ /*package*/ void setStartImage() {
+ if (startButton != null) {
+ startButton.setImage(startImage);
+ startButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.PERFORM_TASK_TOOLTIP));
+ }
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHack.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHack.java
new file mode 100644
index 000000000..de6b6cd0a
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHack.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.lang.reflect.*;
+
+import org.eclipse.swt.custom.ViewForm;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.internal.*;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+
+/**
+ *
+ * A class to make a view a fast view only and follow the user as they switch perspectives.
+ *
+ */
+/* package */ class FastViewHack {
+
+ /**
+ * Ensure the given view is a fast view only and follows the
+ * user as they switch perspectives.
+ *
+ * @param aView - the view to ensure is a following fast view only
+ */
+ /* package */
+ static final void enableFollowingFastViewOnly(IViewPart aView) {
+ //System.out.println("enableFollowingFastViewOnly");
+ FastViewHackPerspectiveListener listener = new FastViewHackPerspectiveListener(aView);
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().addPerspectiveListener(listener);
+
+ FastViewHackPartListener partListener = new FastViewHackPartListener(aView, listener);
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addPartListener(partListener);
+ }
+
+
+ /**
+ * Disables dragging of the shortcut bar icon for the cheat sheet fast view.
+ */
+ /* package */
+ static final void disableDragShortcutBarIcon() {
+ // Disable dragging of the shortcut bar icon for the cheat sheet fast view
+ Display.getCurrent().asyncExec(new Runnable() {
+ public void run() {
+ if(true) return;
+ WorkbenchWindow window = (WorkbenchWindow)PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+
+ if( window == null ) {
+ return;
+ }
+
+ try {
+ String viewTitle = CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEETS);
+
+ Field field = window.getClass().getDeclaredField("shortcutBarPart"); //$NON-NLS-1$
+ field.setAccessible(true);
+//TODO: Port problem!
+// ShortcutBarPart shortcutBarPart = (ShortcutBarPart)field.get(window);
+//
+// ToolBar toolBar = (ToolBar)shortcutBarPart.getControl();
+ ToolBar toolBar = null;
+ ToolItem[] toolItems = toolBar.getItems();
+ for(int i=0; i<toolItems.length; ++i) {
+ ToolItem toolItem = toolItems[i];
+ //System.out.println("ShortcutBarPart item: "+toolItems[i].getToolTipText());
+ if( toolItem.getToolTipText() !=null &&
+ toolItem.getToolTipText().equalsIgnoreCase(viewTitle) ) {
+
+ //System.out.println("Found ShortcutBarPart item for Cheat Sheets");
+ toolItem.setData(ShowFastViewContribution.FAST_VIEW, null);
+ break;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+
+ /**
+ * Removes the fastview button from the view's title bar.
+ *
+ * @param viewPane - the view to remove the button from
+ */
+ /* package */
+ static void removeFastViewButton(ViewPane viewPane) {
+ String fastViewToolTip = WorkbenchMessages.getString("ViewPane.pin"); //$NON-NLS-1$
+ String fastViewDisabledToolTip = CheatSheetPlugin.getResourceString(ICheatSheetResource.FASTVIEW_DISABLED_FOR_CHEAT_SHEET);
+
+
+ // Remove the Fast View push pin toolbar item from the cheat sheet view
+ ViewForm viewForm = (ViewForm)viewPane.getControl();
+ Control[] controls = viewForm.getChildren();
+ boolean done = false;
+ for(int i=0; i<controls.length && !done; ++i) {
+ Control control = controls[i];
+
+ if( control instanceof ToolBar ) {
+ ToolBar toolBar = (ToolBar)control;
+
+ ToolItem[] toolItems = toolBar.getItems();
+ for(int j=0; j<toolItems.length; ++j) {
+ ToolItem toolItem = toolItems[j];
+ //System.out.println(toolItem.getToolTipText());
+ if( toolItem.getToolTipText() !=null &&
+ toolItem.getToolTipText().equalsIgnoreCase(fastViewToolTip) ) {
+ //System.out.println("Found push pin ToolBar item for Fast View");
+
+ try {
+ Method method = toolBar.getClass().getDeclaredMethod("destroyItem", new Class[] { ToolItem.class }); //$NON-NLS-1$
+ method.setAccessible(true);
+ method.invoke(toolBar, new ToolItem[] { toolItem });
+ } catch(Exception exc) {
+ // Throws an exception on Linux when trying to remove "Fast view" button
+ // from view toolbar. So if an exception occurs when trying to remove
+ // the button just disable the button instead.
+ toolItem.setToolTipText(fastViewDisabledToolTip);
+ toolItem.setEnabled(false);
+ }
+ done = true;
+
+ toolBar.getParent().layout(true);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Helper method used to debug methods available on a given object.
+ * @param object - the object to inspect
+ */
+ /* package */
+/*
+ static final void debugMethods(Object object) {
+ Method[] methods = object.getClass().getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ System.out.println("Method: " + method.getName());
+ Class[] params = method.getParameterTypes();
+ for (int j = 0; j < params.length; j++) {
+ Class param = params[j];
+ System.out.println("Param: " + param.getName());
+ }
+ }
+ }
+*/
+
+ /**
+ * Helper method used to debug fields available on a given object.
+ * @param object - the object to inspect
+ */
+ /* package */
+/*
+ static final void debugFields(Object object) {
+ Field[] fields = object.getClass().getDeclaredFields();
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ System.out.println("Field: " + field.getName());
+ Class type = field.getType();
+ System.out.println("Type: " + type.getName());
+ }
+ }
+*/
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHackPartListener.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHackPartListener.java
new file mode 100644
index 000000000..ecd2dcd79
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHackPartListener.java
@@ -0,0 +1,527 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.lang.reflect.*;
+
+import org.eclipse.jface.action.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ViewForm;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.internal.*;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+
+/**
+ * A class to handle the fast view lifecycle events.
+ * <p>
+ * The following items are handled by the listener when
+ * various part events occur:
+ * <ul>
+ * <li>disable dragging of the view
+ * </li>
+ * <li>disable dragging of the shortcut bar icon
+ * </li>
+ * <li>disable shortcut bar fastview menu item
+ * </li>
+ * <li>ensure the shortcut bar icon has the correct selection
+ * </li>
+ * <li>remove the fastview button
+ * </li>
+ * <li>remove the fastview popup menu item
+ * </li>
+ * <li>ensure the view is a fastview
+ * </li>
+ * <li>removes this listener and the perspective listener when the part is closed.
+ * </li>
+ * </ul>
+ */
+/* package */ class FastViewHackPartListener implements IPartListener {
+ private static IViewPart view;
+ private final String fastViewMenuText;
+ private final String viewTitle;
+ private IPerspectiveListener perspectiveListener;
+
+ private static boolean handledDisableShortcutBarMenu = false;
+ private static boolean handledPartActivated = false;
+// The following does not appear to be needed after there was
+// similar code added to controlMoved method.
+// private static final Rectangle zeroSizeRectangle = new Rectangle(0,0,0,0);
+
+
+ /**
+ * Creates a new FastViewHackPartListener for the given view.
+ *
+ * @param aView - the view to handle the part lifecycle events for
+ * @param aListener - the perspectiveListener to remove when the part is closed
+ */
+ /* package */ FastViewHackPartListener(IViewPart aView, IPerspectiveListener aListener) {
+ //System.out.println("FastViewHackPartListener");
+ view = aView;
+ perspectiveListener = aListener;
+
+ fastViewMenuText = WorkbenchMessages.getString("ViewPane.fastView"); //$NON-NLS-1$
+ viewTitle = CheatSheetPlugin.getResourceString(ICheatSheetResource.CHEAT_SHEETS);
+
+
+ ensureViewIsFastView();
+ }
+
+ /**
+ * @see org.eclipse.ui.IPartListener#partActivated(IWorkbenchPart)
+ */
+ public void partActivated(IWorkbenchPart part) {
+ if (view == part) {
+ //System.out.println("partActivated: " + part);
+
+ PartPane partPane = ((ViewSite) part.getSite()).getPane();
+
+ // This disables the view from being dragged. forcing the cheat sheet view
+ // to remain a fastview.
+ disableDragView(part, (ViewPane)partPane);
+
+ // Set the selection for the shortcut bar icon for the cheat sheet fast view
+ setFastViewIconSelection(true);
+
+ if( handledPartActivated ) {
+ return;
+ }
+
+ handledPartActivated = true;
+
+ // Ensure the selection for the shortcut bar icon for the cheat sheet fast view is always correct
+ ensureShortcutBarIconSelection(partPane);
+
+ // Remove the Fast View push pin toolbar item from the cheat sheet view
+ FastViewHack.removeFastViewButton((ViewPane)partPane);
+
+ // Remove the Fast View menu item from the cheat sheet view title bar pop-up menu
+ removeFastViewPopupMenuItem(partPane);
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.IPartListener#partBroughtToTop(IWorkbenchPart)
+ */
+ public void partBroughtToTop(IWorkbenchPart part) {
+ /*
+ if (view == part) {
+ System.out.println("partBroughtToTop: " + part);
+ }
+ */
+ }
+
+ /**
+ * Removes this listener and the perspective listener when the part is closed.
+ *
+ * @see org.eclipse.ui.IPartListener#partClosed(IWorkbenchPart)
+ */
+ public void partClosed(IWorkbenchPart part) {
+ if (view == part) {
+ //System.out.println("partClosed: " + part);
+
+ handledPartActivated = false;
+
+ // Remove the Perspective and Part listeners.
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ if( workbench != null ) {
+ IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
+ if( activeWorkbenchWindow != null ) {
+ //System.out.println("PerspectiveListener removed");
+ activeWorkbenchWindow.removePerspectiveListener(perspectiveListener);
+
+ IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage();
+ if( activePage != null ) {
+ //System.out.println("PartListener removed");
+ activePage.removePartListener(this);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Disable dragging of the shortcut bar icon each time a part is deactivated.
+ *
+ * @see org.eclipse.ui.IPartListener#partDeactivated(IWorkbenchPart)
+ */
+ public void partDeactivated(IWorkbenchPart part) {
+ //System.out.println("partDeactivated: " + part);
+
+ // Disable dragging of the shortcut bar icon for the cheat sheet fast view
+ FastViewHack.disableDragShortcutBarIcon();
+
+ if( view == part ) {
+ // Set the selection for the shortcut bar icon for the cheat sheet fast view
+ setFastViewIconSelection(false);
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.IPartListener#partOpened(IWorkbenchPart)
+ */
+ public void partOpened(IWorkbenchPart part) {
+ if (view == part) {
+ //System.out.println("partOpened: " + part);
+
+ disableShortcutBarMenu();
+ }
+ }
+
+
+ /**
+ * Disables the shortcut bar fastview menu item.
+ */
+ private void disableShortcutBarMenu() {
+ if( handledDisableShortcutBarMenu ) {
+ return;
+ }
+
+ handledDisableShortcutBarMenu = true;
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ ToolBarManager shortcutBar = null;
+ try {
+ Field field = window.getClass().getDeclaredField("shortcutBar"); //$NON-NLS-1$
+ field.setAccessible(true);
+ shortcutBar = (ToolBarManager)field.get(window);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+
+ ToolBar toolBar = shortcutBar.getControl();
+ final Menu fastViewBarMenu = new Menu(toolBar);
+
+ MenuItem closeItem = new MenuItem(fastViewBarMenu, SWT.NONE);
+ closeItem.setText(WorkbenchMessages.getString("WorkbenchWindow.close")); //$NON-NLS-1$
+ closeItem.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ ToolItem toolItem = (ToolItem) fastViewBarMenu.getData();
+ if (toolItem != null && !toolItem.isDisposed()) {
+ IViewPart view = (IViewPart)toolItem.getData(ShowFastViewContribution.FAST_VIEW);
+
+ if( view == null && toolItem.getToolTipText().equals(viewTitle) ) {
+ view = FastViewHackPartListener.view;
+ }
+ //System.out.println("view: "+view);
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(view);
+ }
+ }
+ });
+
+ MenuItem restoreItem = restoreItem = new MenuItem(fastViewBarMenu, SWT.CHECK);
+ restoreItem.setSelection(true);
+ restoreItem.setText(WorkbenchMessages.getString("WorkbenchWindow.restore")); //$NON-NLS-1$
+ restoreItem.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ ToolItem toolItem = (ToolItem) fastViewBarMenu.getData();
+ if (toolItem != null && !toolItem.isDisposed()) {
+ IViewReference view = (IViewReference)toolItem.getData(ShowFastViewContribution.FAST_VIEW);
+ ((WorkbenchPage)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()).removeFastView(view);
+
+ }
+ }
+ });
+
+ fastViewBarMenu.addMenuListener(new MenuListener() {
+ public void menuHidden(MenuEvent e) {
+ //System.out.println("menuHidden");
+ Menu menu = (Menu)e.widget;
+ MenuItem restoreItem = menu.getItem(1);
+ restoreItem.setEnabled(true);
+/*
+ // Following does not work correctly!
+ //
+ // It is suppose to add the Fast View menu item back to the menu but
+ // when the menu is shown the menu item has no text but functions correctly.
+ if( menu.getItemCount() != 2 ) {
+ try {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ Field restoreItemField = window.getClass().getDeclaredField("restoreItem");
+ restoreItemField.setAccessible(true);
+ MenuItem restoreItem = (MenuItem)restoreItemField.get(window);
+
+ Method method = menu.getClass().getDeclaredMethod("createItem", new Class[] { MenuItem.class, int.class });
+ method.setAccessible(true);
+ method.invoke(menu, new Object[] { restoreItem, new Integer(1) });
+ } catch(Exception exc) {
+ exc.printStackTrace();
+ }
+ }
+*/
+ }
+ public void menuShown(MenuEvent e) {
+ //System.out.println("menuShown, widget:"+e.widget+" source:"+e.getSource());
+ Menu menu = (Menu)e.widget;
+ ToolItem toolItem = (ToolItem)menu.getData();
+ if( toolItem.getToolTipText() !=null &&
+ toolItem.getToolTipText().equalsIgnoreCase(viewTitle) ) {
+ MenuItem restoreItem = menu.getItem(1);
+ restoreItem.setEnabled(false);
+
+/*
+ // Following does not work correctly!
+ //
+ // It is suppose to remove the Fast View menu item from the menu but
+ // when the menu is updated to include the item again, it has no text
+ // but functions correctly.
+ if( menu.getItemCount() == 2 ) {
+ MenuItem restoreItem = menu.getItem(1);
+ restoreItem.setEnabled(false);
+
+ try {
+ Method method = menu.getClass().getDeclaredMethod("destroyItem", new Class[] { MenuItem.class });
+ method.setAccessible(true);
+ method.invoke(menu, new MenuItem[] { restoreItem });
+ } catch(Exception exc) {
+ exc.printStackTrace();
+ restoreItem.setEnabled(false);
+ }
+ }
+*/
+ }
+ }
+ });
+
+ try {
+ Field fastViewBarMenuField = window.getClass().getDeclaredField("fastViewBarMenu"); //$NON-NLS-1$
+ fastViewBarMenuField.setAccessible(true);
+ fastViewBarMenuField.set(window, fastViewBarMenu);
+
+ Field restoreItemField = window.getClass().getDeclaredField("restoreItem"); //$NON-NLS-1$
+ restoreItemField.setAccessible(true);
+ restoreItemField.set(window, restoreItem);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ /**
+ * Disables the dragging of the given view.
+ *
+ * @param part - the view
+ * @param viewPane - the view's viewPane
+ */
+ private void disableDragView(IWorkbenchPart part, ViewPane viewPane) {
+ // This disables the view from being dragged. forcing the cheat sheet view
+ // to remain a fastview.
+ PerspectivePresentation perspectivePresentation = null;
+ try {
+ IWorkbenchPage page = part.getSite().getPage();
+ Method method = page.getClass().getDeclaredMethod("getActivePerspective", null); //$NON-NLS-1$
+ method.setAccessible(true);
+ Perspective perspective = (Perspective)method.invoke(page, null);
+ perspectivePresentation = perspective.getPresentation();
+ } catch(Exception exc) {
+ exc.printStackTrace();
+ }
+
+ if( perspectivePresentation != null ) {
+ try {
+ Method method = perspectivePresentation.getClass().getDeclaredMethod("disableDrag", new Class[] { ViewPane.class }); //$NON-NLS-1$
+ method.setAccessible(true);
+ method.invoke(perspectivePresentation, new ViewPane[] { viewPane });
+ } catch(Exception exc) {
+ exc.printStackTrace();
+ }
+ }
+ }
+
+
+ /**
+ * Ensures the shortcut bar icon for the given partpane has the correct selection.
+ *
+ * @param partPane - the partpane to correct select/unselect in the shortcut bar
+ */
+ private void ensureShortcutBarIconSelection(PartPane partPane) {
+ // Ensure the selection for the shortcut bar icon for the cheat sheet fast view is always correct
+ partPane.getControl().addControlListener(new ControlListener() {
+ public void controlMoved(ControlEvent e) {
+ //System.out.println("controlMoved");
+ //System.out.println(((ViewForm)e.widget).getBounds());
+ if( ((ViewForm)e.widget).getBounds().x < 0 ) {
+ setFastViewIconSelection(false);
+ }
+ }
+
+ public void controlResized(ControlEvent e) {
+/* The following is not needed after similar code added
+ * to controlMoved method.
+ */
+// //System.out.println("controlResized");
+//
+// if( ((ViewForm)e.widget).getBounds().equals(zeroSizeRectangle) ) {
+// //System.out.println("cheat sheet minimized");
+// // Set the selection for the shortcut bar icon for the cheat sheet fast view
+// setFastViewIconSelection(false);
+// } else {
+// //System.out.println("cheat sheet NOT minimized");
+// // Set the selection for the shortcut bar icon for the cheat sheet fast view
+// setFastViewIconSelection(true);
+// }
+ }
+ });
+ }
+
+
+ /**
+ * Ensures the view is a fastview.
+ */
+ private void ensureViewIsFastView() {
+ // Ensure that the view is a fast view even when opened via the Window->Show View menu
+ final WorkbenchPage realPage = (WorkbenchPage)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+
+ final String viewId = view.getSite().getId();
+ final IViewReference[] viewRefs = realPage.getViewReferences();
+ IViewReference viewReference = null;
+ for (int i = 0; i < viewRefs.length; i++) {
+ IViewReference reference = viewRefs[i];
+ if( reference.getId().equals(viewId) ) {
+ viewReference = reference;
+ break;
+ }
+ }
+
+ final IViewReference viewRef = viewReference;
+ if(view != null && !realPage.isFastView(viewRef) ) {
+ Display.getCurrent().asyncExec(new Runnable() {
+ public void run() {
+ // Double that view did not become a fast view while we were
+ // waiting to execute.
+ if( !realPage.isFastView(viewRef) ) {
+ realPage.addFastView(viewRef);
+ realPage.activate(view);
+
+ FastViewHack.removeFastViewButton((ViewPane)((ViewSite) view.getSite()).getPane());
+ }
+ }
+ });
+ }
+ }
+
+
+ /**
+ * Remove the fastview popup menu item from the view's system pop-up menu.
+ *
+ * @param partPane - the view to remove the menu item from
+ */
+ private void removeFastViewPopupMenuItem(PartPane partPane) {
+ // Remove the Fast View menu item from the cheat sheet view title bar pop-up menu
+ try {
+ Class[] innerClasses = PartPane.class.getDeclaredClasses();
+ Class paneContributionClass = null;
+ for(int i=0; i<innerClasses.length; ++i) {
+ //System.out.println("inner class: "+innerClasses[i].getName());
+ if( innerClasses[i].getName().equals("org.eclipse.ui.internal.PartPane$PaneContribution") ) { //$NON-NLS-1$
+ paneContributionClass = innerClasses[i];
+ break;
+ }
+ }
+
+ if( paneContributionClass != null ) {
+ Object paneContribution = null;
+ try {
+ Constructor constructor = paneContributionClass.getDeclaredConstructor(new Class[] { PartPane.class });
+ constructor.setAccessible(true);
+ paneContribution = constructor.newInstance(new Object[] { partPane });
+ } catch(Exception exc) {
+ exc.printStackTrace();
+ }
+
+ Field field = PartPane.class.getDeclaredField("paneMenuManager"); //$NON-NLS-1$
+ field.setAccessible(true);
+ MenuManager menuManager = new MenuManager();
+
+ if( paneContribution != null ) {
+ menuManager.add((IContributionItem)paneContribution);
+
+ menuManager.add(new ContributionItem() {
+ public boolean isDynamic() {
+ return true;
+ }
+ public void fill(Menu menu, int index) {
+ MenuItem[] items = menu.getItems();
+ MenuItem item = null;
+ for (int i = 0; i < items.length; i++) {
+ if( items[i].getText().equals(fastViewMenuText) ) {
+ item = items[i];
+ break;
+ }
+ }
+
+ if( item != null ) {
+ try {
+ Method method = menu.getClass().getDeclaredMethod("destroyItem", new Class[] { MenuItem.class }); //$NON-NLS-1$
+ method.setAccessible(true);
+ method.invoke(menu, new MenuItem[] { item });
+ } catch(Exception exc) {
+ // Throws an exception on Linux when trying to remove "Fast view" option
+ // from view pop up menu. So if an exception occurs when trying to remove
+ // the menu item just disable the menu item instead.
+ item.setEnabled(false);
+ }
+ }
+ }
+ });
+ }
+
+ field.set(partPane, menuManager);
+ }
+ } catch(Exception exc) {
+ exc.printStackTrace();
+ }
+ }
+
+
+ /**
+ * Sets the selection for the shortcut bar icon representing the cheat sheet fast view.
+ */
+ private void setFastViewIconSelection(boolean selected) {
+ final boolean selection = selected;
+
+ // Set the selection for the shortcut bar icon for the cheat sheet fast view
+ Display.getCurrent().asyncExec(new Runnable() {
+ public void run() {
+ if(true) return;
+ WorkbenchWindow window = (WorkbenchWindow)PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+
+ if( window == null ) {
+ return;
+ }
+
+ try {
+ Field field = window.getClass().getDeclaredField("shortcutBarPart"); //$NON-NLS-1$
+ field.setAccessible(true);
+//TODO: Port problem!
+// ShortcutBarPart shortcutBarPart = (ShortcutBarPart)field.get(window);
+//
+// ToolBar toolBar = (ToolBar)shortcutBarPart.getControl();
+ ToolBar toolBar = null;
+ ToolItem[] toolItems = toolBar.getItems();
+ for(int i=0; i<toolItems.length; ++i) {
+ ToolItem toolItem = toolItems[i];
+ //System.out.println("ShortcutBarPart item: "+toolItems[i].getToolTipText());
+ if( toolItem.getToolTipText() !=null &&
+ toolItem.getToolTipText().equalsIgnoreCase(viewTitle) ) {
+
+ //System.out.println("Found ShortcutBarPart item for Cheat Sheets");
+ toolItem.setSelection(selection);
+ break;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+}
+
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHackPerspectiveListener.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHackPerspectiveListener.java
new file mode 100644
index 000000000..39fc91067
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/FastViewHackPerspectiveListener.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.lang.reflect.*;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.*;
+import org.eclipse.ui.internal.*;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+
+/**
+ * A class to handle perspective lifecycle events.
+ * <p>
+ * The following items are handled by the listener when
+ * various perspective events occur:
+ * <ul>
+ * <li>ensure the view is available within the current perspective
+ * </li>
+ * <li>removes the view in all perspectives except for the current one
+ * </li>
+ * <li>disable dragging of the shortcut bar icon
+ * </li>
+ * </ul>
+ */
+/* package */
+class FastViewHackPerspectiveListener implements IPerspectiveListener {
+ private IViewPart view;
+
+ /**
+ * Creates a new FastViewHackPerspectiveListener for the given view.
+ *
+ * @param aView - the view to handle when perspective events occur
+ */
+ /* package */
+ FastViewHackPerspectiveListener(IViewPart aView) {
+ //System.out.println("FastViewHackPerspectiveListener");
+ view = aView;
+ }
+
+ /**
+ * @see org.eclipse.ui.IPerspectiveListener#perspectiveActivated(IWorkbenchPage, IPerspectiveDescriptor)
+ */
+ public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
+ //System.out.print("perspectiveActivated: " + page.getLabel());
+ //System.out.println(", " + perspective.getLabel());
+
+ ensureViewIsAvailable(page, view, false);
+
+ closeViewInPreviousPerspectives(page);
+
+ updateViewToolBar(view);
+ }
+
+ /**
+ * @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(IWorkbenchPage, IPerspectiveDescriptor, String)
+ */
+ public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) {
+ //System.out.print("perspectiveChanged: " + page.getLabel());
+ //System.out.print(", " + perspective.getLabel());
+ //System.out.println(", " + changeId);
+
+ if( changeId.equals(IWorkbenchPage.CHANGE_FAST_VIEW_REMOVE) ||
+ changeId.equals(IWorkbenchPage.CHANGE_FAST_VIEW_ADD) ) {
+
+ // Disable dragging of the shortcut bar icon for the cheat sheet fast view
+ FastViewHack.disableDragShortcutBarIcon();
+ }
+
+ }
+
+
+ /**
+ *
+ * This closes the cheat view in all perspectives except for the current one,
+ * forcing there to be only one view at a time. Thus when the cheat sheet
+ * view is closed by the user there will be no more view references remaining
+ * and the view is closed.
+ *
+ * @param page - the current workbenchpage
+ */
+ private void closeViewInPreviousPerspectives(IWorkbenchPage page) {
+ IWorkbenchWindow workbenchWindow = page.getWorkbenchWindow();
+ if (workbenchWindow != null) {
+ IWorkbenchPage[] pages = workbenchWindow.getPages();
+ for (int j = 0; j < pages.length; ++j) {
+ IWorkbenchPage currentPage = pages[j];
+
+ // This closes the cheat view in all perspectives except for the current one,
+ // forcing there to be only one view at a time. Thus when the cheat sheet
+ // view is closed by the user there will be no more view references remaining
+ // and the view is closed.
+ Perspective activePerspective = null;
+ try {
+ Method method = currentPage.getClass().getDeclaredMethod("getActivePerspective", null); //$NON-NLS-1$
+ method.setAccessible(true);
+ activePerspective = (Perspective)method.invoke(page, null);
+ } catch(Exception exc) {
+ exc.printStackTrace();
+ }
+
+ if( activePerspective != null ) {
+ Object perspectiveList = null;
+ try {
+ Field field = currentPage.getClass().getDeclaredField("perspList"); //$NON-NLS-1$
+ field.setAccessible(true);
+ perspectiveList = field.get(page);
+ } catch(Exception exc) {
+ exc.printStackTrace();
+ }
+
+ Perspective[] openPerspectives = null;
+ try {
+ Method method = perspectiveList.getClass().getDeclaredMethod("getOpenedPerspectives", null); //$NON-NLS-1$
+ method.setAccessible(true);
+ openPerspectives = (Perspective[])method.invoke(perspectiveList, null);
+ } catch(Exception exc) {
+ exc.printStackTrace();
+ }
+
+ if ( openPerspectives != null ) {
+ for (int i = 0; i < openPerspectives.length; i++) {
+ Perspective current = openPerspectives[i];
+ if( current != activePerspective && activePerspective.containsView(view) ) {
+ try {
+ IViewReference viewRef = activePerspective.findView(view.getViewSite().getId());
+ current.hideView(viewRef);
+ } catch(Exception exc) {
+ // Not much we can do, this exception occurs each time
+ // we start the workbench with the cheat view still open
+ // and multiple perspectives
+ //exc.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Ensures that given view is available within the current perspective.
+ *
+ * @param page - the page to make the view available on
+ * @param view - the view to make available
+ * @param activate - true if the view should be activiated, and false otherwise
+ */
+ private void ensureViewIsAvailable(IWorkbenchPage page, IViewPart view, boolean activate) {
+ //System.out.println("ensureViewIsAvailable");
+ WorkbenchPage realPage = (WorkbenchPage)page;
+ IViewPart viewPart = page.findView(view.getSite().getId());
+
+ if(viewPart == null) {
+ //the view doesn't exist in this perspective, so add it as a fast view.
+ try {
+ final String viewId = view.getSite().getId();
+ viewPart = realPage.showView(viewId);
+
+ final IViewReference[] viewRefs = realPage.getViewReferences();
+ IViewReference viewRef = null;
+ for (int i = 0; i < viewRefs.length; i++) {
+ IViewReference reference = viewRefs[i];
+ if( reference.getId().equals(viewId) ) {
+ viewRef = reference;
+ break;
+ }
+ }
+
+ if( viewRef != null ) {
+ //ensure that it's a fast view.
+ //This only works on a WorkbenchPage. It doesn't work on IWorkbenchPage.
+ realPage.addFastView(viewRef);
+ }
+ } catch(PartInitException e) {
+ MessageDialog.openError(realPage.getWorkbenchWindow().getShell(),
+ CheatSheetPlugin.getResourceString(ICheatSheetResource.FASTVIEW_ONLY_ERROR),
+ CheatSheetPlugin.getResourceString(ICheatSheetResource.FASTVIEW_ONLY_ERROR_MESSAGE) + e.getMessage());
+ return;
+ }
+ }
+
+ if(activate) {
+ realPage.activate(viewPart);
+ }
+ }
+
+
+ /**
+ * Update the given view's toolbar so the minimize button is available and
+ * the dock button is removed.
+ *
+ * @param view - the view to have its toolbar updated
+ */
+ private void updateViewToolBar(IViewPart view) {
+ //System.out.println("updateViewToolBar");
+ ViewSite viewSite = (ViewSite)view.getSite();
+ ViewPane viewPane = (ViewPane)viewSite.getPane();
+ viewPane.setFast(true);
+ viewPane.getMenuManager().update(true);
+ FastViewHack.removeFastViewButton(viewPane);
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/IntroItem.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/IntroItem.java
new file mode 100644
index 000000000..4b3f146e3
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/IntroItem.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.data.ContentItem;
+
+public class IntroItem extends ViewItem {
+ private Image startButtonImage;
+ private Image restartButtonImage;
+
+ private Button startButton;
+
+ /**
+ * Constructor for IntroItem.
+ * @param parent
+ * @param contentItem
+ */
+ public IntroItem(Composite parent, ContentItem contentItem, Color itemColor, CheatSheetView theview) {
+ super(parent, contentItem, itemColor, theview);
+
+ }
+
+ protected void init() {
+ super.init();
+ IPluginDescriptor mydesc = CheatSheetPlugin.getPlugin().getDescriptor();
+
+ String imageFileName = "icons/full/clcl16/start_cheatsheet.gif"; //$NON-NLS-1$
+ URL imageURL = mydesc.find(new Path(imageFileName));
+ ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ startButtonImage = imageDescriptor.createImage();
+
+ imageFileName = "icons/full/clcl16/restart_cheatsheet.gif"; //$NON-NLS-1$
+ imageURL = mydesc.find(new Path(imageFileName));
+ imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ restartButtonImage = imageDescriptor.createImage();
+ }
+
+ /*package*/ void setStartImage() {
+ startButton.setImage(startButtonImage);
+ startButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.START_CHEATSHEET_TOOLTIP));
+ startButton.setFAccessibleName(startButton.getToolTipText());
+ }
+
+ /*package*/ void setRestartImage() {
+ startButton.setImage(restartButtonImage);
+ startButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.RESTART_CHEATSHEET_TOOLTIP));
+ startButton.setFAccessibleName(startButton.getToolTipText());
+ }
+
+ /**
+ * @see org.eclipse.ui.internal.cheatsheets.data.ViewItem#handleButtons(Composite)
+ */
+ /*package*/ void handleButtons(Composite bodyWrapperComposite) {
+ buttonComposite = new Composite(bodyWrapperComposite, SWT.NONE);
+ GridLayout buttonlayout = new GridLayout(4, false);
+ buttonlayout.marginHeight = 2;
+ buttonlayout.marginWidth = 2;
+ buttonlayout.verticalSpacing = 2;
+
+ GridData buttonData = new GridData(GridData.FILL_HORIZONTAL);
+ buttonData.grabExcessHorizontalSpace = true;
+
+ buttonComposite.setLayout(buttonlayout);
+ buttonComposite.setLayoutData(buttonData);
+ buttonComposite.setBackground(itemColor);
+ Label filllabel = new Label(buttonComposite, SWT.NULL);
+ filllabel.setBackground(itemColor);
+ GridData filldata = new GridData();
+ filldata.widthHint = 16;
+ filllabel.setLayoutData(filldata);
+
+ startButton = new Button(buttonComposite, SWT.NULL, startButtonImage);
+ startButton.setData(this);
+ startButton.setBackground(itemColor);
+ startButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.START_CHEATSHEET_TOOLTIP));
+ startButton.setFAccessibleName(startButton.getToolTipText());
+ startButton.setFAccessibleDescription(bodyText.getText());
+ // addHandListener(startLabel);
+ startButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ theview.advanceIntroItem();
+ }
+ });
+ buttonCompositeList.add(buttonComposite);
+ }
+
+ /**
+ * @see org.eclipse.ui.internal.cheatsheets.views.ViewItem#disposeOfStuff()
+ */
+ public void dispose() {
+ super.dispose();
+ if (startButtonImage != null)
+ startButtonImage.dispose();
+ if (restartButtonImage != null)
+ restartButtonImage.dispose();
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/NoopAction.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/NoopAction.java
new file mode 100644
index 000000000..a7de56b63
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/NoopAction.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+public class NoopAction extends Action {
+
+ /**
+ * Constructor for NoopAction.
+ */
+ protected NoopAction() {
+ super();
+ }
+
+ /**
+ * Constructor for NoopAction.
+ * @param text
+ */
+ protected NoopAction(String text) {
+ super(text);
+ }
+
+ /**
+ * Constructor for NoopAction.
+ * @param text
+ * @param image
+ */
+ protected NoopAction(String text, ImageDescriptor image) {
+ super(text, image);
+ }
+
+
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/SubItemCompositeHolder.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/SubItemCompositeHolder.java
new file mode 100644
index 000000000..0e6cf3b4c
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/SubItemCompositeHolder.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import org.eclipse.swt.widgets.*;
+
+public class SubItemCompositeHolder {
+ private Label iconLabel;
+ private boolean skipped;
+ private boolean completed;
+ protected Button startButton;
+
+ /**
+ *
+ */
+ /*package*/ SubItemCompositeHolder(Label l, Button startb) {
+ super();
+ iconLabel = l;
+ startButton = startb;
+ }
+
+ /**
+ * @return Label
+ */
+ /*package*/ Label getIconLabel() {
+ return iconLabel;
+ }
+
+ /**
+ * @return
+ */
+ public boolean isCompleted() {
+ return completed;
+ }
+
+ /**
+ * @return
+ */
+ public boolean isSkipped() {
+ return skipped;
+ }
+
+ /**
+ * @param b
+ */
+ /*package*/ void setCompleted(boolean b) {
+ completed = b;
+ }
+
+ /**
+ * @param b
+ */
+ /*package*/ void setSkipped(boolean b) {
+ skipped = b;
+ }
+
+ /**
+ * @return
+ */
+ /*package*/ Button getStartButton() {
+ return startButton;
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleButton.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleButton.java
new file mode 100644
index 000000000..8e7bf6549
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleButton.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Composite;
+
+public class ToggleButton extends Button {
+
+ protected Image fCollapsedImage;
+ protected Image fExpandedImage;
+
+ /**
+ * Creates a new ToggleButton.
+ *
+ * @param parent
+ * @param style
+ * @param collapsedImage This is image to display when in the collapsed state, in terms
+ * of Windows Explorer this would be the + image.
+ * @param expandedImage This is image to display when in the expanded state, in terms
+ * of Windows Explorer this would be the - image.
+ */
+ /*package*/ ToggleButton(Composite parent, int style, Image collapsedImage, Image expandedImage) {
+ super(parent, style, collapsedImage);
+
+ fCollapsedImage = collapsedImage;
+ fExpandedImage = expandedImage;
+ }
+
+ protected void paint(GC gc) {
+ setToggle();
+ super.paint(gc);
+ }
+
+
+ private void setToggle() {
+ if( isCollapsed() )
+ setImage(fExpandedImage);
+ else
+ setImage(fCollapsedImage);
+ }
+
+ /**
+ * Returns the ToggledImage.
+ * @return Image
+ */
+ public Image getToggledImage() {
+ return fExpandedImage;
+ }
+
+ /**
+ * Returns the UnToggledImage.
+ * @return Image
+ */
+ public Image getUnToggledImage() {
+ return fCollapsedImage;
+ }
+
+ /**
+ * Sets the ExpandedImage.
+ * @param expandedImage The expandedImage to set
+ */
+ public void setExpandedImage(Image expandedImage) {
+ this.fExpandedImage = expandedImage;
+ }
+
+ /**
+ * Sets the CollapsedImage.
+ * @param collapsedImage The collapsedImage to set
+ */
+ public void setCollapsedImage(Image collapsedImage) {
+ this.fCollapsedImage = collapsedImage;
+ }
+
+ /**
+ * Returns the Collapsed state.
+ * @return boolean
+ */
+ public boolean isCollapsed() {
+ // default + = unToggledImage -> Selection is false
+ // - = toggleImage -> Selection is true
+ // thus isCollapsed is !selection
+ return !getSelection();
+ }
+
+ /**
+ * Sets the Collapsed state.
+ * @param fCollapsed The fCollapsed to set
+ */
+ /*package*/ void setCollapsed(boolean fCollapsed) {
+ // default + = unToggledImage -> Selection is false
+ // - = toggleImage -> Selection is true
+ // thus selection is !fCollapsed
+ setSelection(!fCollapsed);
+ setToggle();
+ redraw();
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleImage.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleImage.java
new file mode 100644
index 000000000..f5ef6a0b7
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleImage.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Composite;
+
+public class ToggleImage extends ToggleableControl {
+ protected Image theImage;
+ protected Rectangle theImageSize;
+ protected int toggleImageWidth;
+ protected int toggleImageHeight;
+
+ /**
+ * Constructor for MyImageToggle.
+ * @param parent
+ * @param style
+ */
+ public ToggleImage(Composite parent, int style, Image newImage) {
+ super(parent, style);
+ theImage = newImage;
+
+ calculateDimensions();
+ }
+
+ protected void calculateDimensions() {
+ theImageSize = theImage.getBounds();
+ toggleImageWidth = theImageSize.width + marginWidth*2;
+ toggleImageHeight = theImageSize.height + marginHeight*2;
+ }
+
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ return new Point(toggleImageWidth, toggleImageWidth);
+ }
+
+ public void setImage(Image myimage){
+ theImage = myimage;
+ calculateDimensions();
+ }
+
+ public Image getImage(){
+ return theImage;
+ }
+
+ /**
+ * @see org.eclipse.ui.internal.cheatsheets.views.MyToggle#paint(GC)
+ */
+ protected void paint(GC gc) {
+
+ if (hover && activeColor!=null)
+ gc.setBackground(activeColor);
+ else if (decorationColor!=null)
+ gc.setBackground(decorationColor);
+ else
+ gc.setBackground(getForeground());
+
+ // Find point to center image
+ Point size = getSize();
+ int x = (size.x - theImageSize.width)/2;
+ int y = (size.y - theImageSize.height)/2;
+
+ gc.drawImage(theImage, 0, 0, theImageSize.width, theImageSize.height, x, y, theImageSize.width, theImageSize.height);
+ gc.setBackground(getBackground());
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleableControl.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleableControl.java
new file mode 100644
index 000000000..100e95337
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ToggleableControl.java
@@ -0,0 +1,251 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.accessibility.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+public class ToggleableControl extends Canvas {
+ protected boolean selection;
+ protected Color decorationColor;
+ protected Color activeColor;
+ protected Cursor activeCursor;
+ protected boolean hasFocus;
+ protected boolean hover=false;
+ protected static final int marginWidth = 2;
+ protected static final int marginHeight = 2;
+ protected static final int WIDTH = 9;
+ protected static final int HEIGHT = 9;
+ protected static final int [] offPoints = { 0,2, 8,2, 4,6 };
+ protected static final int [] onPoints = { 2, -1, 2,8, 6,4 };
+
+ /* accessibility */
+ private String fName;
+ private String fDescription;
+
+ public ToggleableControl(Composite parent, int style) {
+ super(parent, style);
+ initAccessible();
+
+ addPaintListener(new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ paint(e);
+ }
+ });
+ addMouseListener(new MouseAdapter () {
+ public void mouseDown(MouseEvent e) {
+ notifyListeners(SWT.Selection);
+ }
+ });
+ addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (e.character == '\r' || e.character == ' ') {
+ // Activation
+ notifyListeners(SWT.Selection);
+ }
+ }
+ });
+ addListener(SWT.Traverse, new Listener () {
+ public void handleEvent(Event e) {
+ if (e.detail != SWT.TRAVERSE_RETURN)
+ e.doit = true;
+ }
+ });
+ addFocusListener(new FocusListener() {
+ public void focusGained(FocusEvent e) {
+ if (!hasFocus) {
+ hasFocus=true;
+ redraw();
+ }
+ }
+ public void focusLost(FocusEvent e) {
+ if (hasFocus) {
+ hasFocus=false;
+ redraw();
+ }
+ }
+ });
+
+ addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ selection = !selection;
+ redraw();
+ }
+ });
+
+ addMouseTrackListener(new MouseTrackAdapter() {
+ public void mouseEnter(MouseEvent e) {
+ hover = true;
+ if (activeCursor!=null)
+ setCursor(activeCursor);
+ redraw();
+ }
+ public void mouseExit(MouseEvent e) {
+ hover = false;
+ if (activeCursor!=null)
+ setCursor(null);
+ redraw();
+ }
+ });
+ }
+
+ private void addSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) return;
+ TypedListener typedListener = new TypedListener (listener);
+ addListener (SWT.Selection,typedListener);
+ }
+
+ public void setDecorationColor(Color decorationColor) {
+ this.decorationColor = decorationColor;
+ }
+
+ public Color getDecorationColor() {
+ return decorationColor;
+ }
+
+ public void setActiveDecorationColor(Color activeColor) {
+ this.activeColor = activeColor;
+ }
+
+ public void removeSelectionListener(SelectionListener listener) {
+ checkWidget ();
+ if (listener == null) return;
+ removeListener (SWT.Selection, listener);
+ }
+
+ public void setActiveCursor(Cursor activeCursor) {
+ this.activeCursor = activeCursor;
+ }
+
+ public Color getActiveDecorationColor() {
+ return activeColor;
+ }
+
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ int width, height;
+
+ if (wHint!=SWT.DEFAULT) width = wHint;
+ else
+ width = WIDTH + 2*marginWidth;
+ if (hHint!=SWT.DEFAULT) height = hHint;
+ else height = HEIGHT + 2*marginHeight;
+ return new Point(width, height);
+ }
+
+ protected void paint(PaintEvent e) {
+ GC gc = e.gc;
+ Point size = getSize();
+ gc.setFont(getFont());
+ paint(gc);
+ if (hasFocus) {
+ gc.setForeground(getForeground());
+ gc.drawFocus(0, 0, size.x, size.y);
+ }
+ }
+
+ /*
+ * @see SelectableControl#paint(GC)
+ */
+ protected void paint(GC gc) {
+ if (hover && activeColor!=null)
+ gc.setBackground(activeColor);
+ else if (decorationColor!=null)
+ gc.setBackground(decorationColor);
+ else
+ gc.setBackground(getForeground());
+ int [] data;
+ Point size = getSize();
+ int x = (size.x - 9)/2;
+ int y = (size.y - 5)/2;
+ if (selection)
+ //data = translate(downPoints, x, y);
+ data = translate(onPoints, x, y);
+
+ else
+ //data = translate(upPoints, x, y);
+ data = translate(offPoints, x, y);
+ gc.fillPolygon(data);
+ gc.setBackground(getBackground());
+ }
+
+ private void notifyListeners(int eventType) {
+ Event event = new Event();
+ event.type = eventType;
+ event.widget = this;
+ notifyListeners(eventType, event);
+ }
+
+ protected int [] translate(int [] data, int x, int y) {
+ int [] target = new int [data.length];
+ for (int i=0; i<data.length; i+=2) {
+ target[i] = data[i]+ x;
+ }
+ for (int i=1; i<data.length; i+=2) {
+ target[i] = data[i]+y;
+ }
+ return target;
+ }
+
+ public boolean getSelection() {
+ return selection;
+ }
+
+ public void setSelection(boolean selection) {
+ this.selection = selection;
+ }
+
+ public void setName(String name) {
+ fName = name;
+ }
+
+ public void setDescription(String description) {
+ fDescription = description;
+ }
+
+ private void initAccessible() {
+ getAccessible().addAccessibleListener(new AccessibleAdapter() {
+
+ public void getName(AccessibleEvent e) {
+ e.result = fName;
+ }
+
+ public void getDescription(AccessibleEvent e) {
+ e.result = fDescription;
+ }
+ });
+
+ getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() {
+
+ public void getLocation(AccessibleControlEvent e) {
+ Rectangle location = getBounds();
+ Point pt = toDisplay(new Point(location.x, location.y));
+ e.x = pt.x;
+ e.y = pt.y;
+ e.width = location.width;
+ e.height = location.height;
+ }
+
+ public void getChildCount(AccessibleControlEvent e) {
+ e.detail = 0;
+ }
+
+ public void getRole(AccessibleControlEvent e) {
+ e.detail = ACC.ROLE_CHECKBUTTON;
+ }
+
+ public void getState(AccessibleControlEvent e) {
+ e.detail = selection ? ACC.STATE_SELECTED : ACC.STATE_SELECTABLE;
+ }
+
+ });
+ }
+}
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
new file mode 100644
index 000000000..a9e093586
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ViewItem.java
@@ -0,0 +1,731 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.net.URL;
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.help.IHelp;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.resource.*;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+import org.eclipse.ui.internal.cheatsheets.*;
+import org.eclipse.ui.internal.cheatsheets.data.*;
+import org.eclipse.ui.cheatsheets.ICheatSheetItemExtensionElement;
+import org.eclipse.ui.cheatsheets.ICheatSheetAction;
+
+public abstract class ViewItem {
+
+ public final static byte VIEWITEM_ADVANCE = 0;
+ public final static byte VIEWITEM_DONOT_ADVANCE = 1;
+ private Composite bodyComp;
+
+ protected StyledText bodyText;
+ private Composite bodyWrapperComposite;
+ private Cursor busyCursor;
+ protected Composite buttonComposite;
+
+ protected ArrayList buttonCompositeList;
+ private boolean buttonExpanded = true;
+ private Composite checkAndMainItemComposite;
+ private Label checkDoneLabel;
+ private Image collapseImage;
+ private boolean completed = false;
+
+ private Image completeImage;
+ protected IContainsContent contentItem;
+
+ protected Color darkGrey;
+ private final RGB darkGreyRGB = new RGB(160, 192, 208);
+
+ protected boolean expanded = true;
+ private Image expandImage;
+
+ private ToggleButton expandToggle;
+ private Image helpImage;
+ private final RGB HIGHLIGHT_RGB = new RGB(230, 230, 230);
+ private boolean isSkipped = false;
+ protected Color itemColor;
+ protected Color lightGrey;
+ private Composite mainItemComposite;
+
+ private Composite parent;
+ private Image skipImage;
+ protected CheatSheetView theview;
+ private Composite titleComposite;
+ protected StyledText titleText;
+ protected Color white;
+ private boolean wizardLaunched;
+
+ /**
+ * Constructor for ViewItem.
+ */
+ public ViewItem(Composite parent, IContainsContent contentItem, Color itemColor, CheatSheetView theview) {
+ super();
+ this.parent = parent;
+ this.contentItem = contentItem;
+ this.itemColor = itemColor;
+ this.theview = theview;
+ lightGrey = new Color(parent.getDisplay(), HIGHLIGHT_RGB);
+ darkGrey = new Color(parent.getDisplay(), darkGreyRGB);
+ buttonCompositeList = new ArrayList(10);
+ // Initialize the item...
+ init();
+
+ IPluginDescriptor mydesc = CheatSheetPlugin.getPlugin().getDescriptor();
+
+ String imageFileName = "icons/full/obj16/skip_status.gif"; //$NON-NLS-1$
+ URL imageURL = mydesc.find(new Path(imageFileName));
+ ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ skipImage = imageDescriptor.createImage();
+
+ imageFileName = "icons/full/obj16/collapse_state.gif"; //$NON-NLS-1$
+ imageURL = mydesc.find(new Path(imageFileName));
+ imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ collapseImage = imageDescriptor.createImage();
+
+ imageFileName = "icons/full/obj16/complete_status.gif"; //$NON-NLS-1$
+ imageURL = mydesc.find(new Path(imageFileName));
+ imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ completeImage = imageDescriptor.createImage();
+
+ imageFileName = "icons/full/clcl16/linkto_help.gif"; //$NON-NLS-1$
+ imageURL = mydesc.find(new Path(imageFileName));
+ imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ helpImage = imageDescriptor.createImage();
+
+ imageFileName = "icons/full/obj16/expand_state.gif"; //$NON-NLS-1$
+ imageURL = mydesc.find(new Path(imageFileName));
+ imageDescriptor = ImageDescriptor.createFromURL(imageURL);
+ expandImage = imageDescriptor.createImage();
+
+ busyCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT);
+
+ addItem();
+ }
+
+ //Adds the item to the main composite.
+ private void addItem() {
+
+ Display display = parent.getDisplay();
+ Color bg = JFaceColors.getBannerBackground(display);
+ white = bg;
+
+ // Get the images.****************************************************************
+
+ // Set up the main composite for the item.******************************************
+ checkAndMainItemComposite = new Composite(parent, SWT.NULL);
+ GridLayout checklayout = new GridLayout(2, false);
+ GridData checkdata = new GridData(GridData.FILL_HORIZONTAL);
+ checkdata.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING;
+
+ checklayout.marginHeight = 0;
+ checklayout.marginWidth = 0;
+ checklayout.verticalSpacing = 0;
+ checkAndMainItemComposite.setBackground(white);
+ checkAndMainItemComposite.setLayout(checklayout);
+ checkAndMainItemComposite.setLayoutData(checkdata);
+
+ checkDoneLabel = new Label(checkAndMainItemComposite, SWT.NULL);
+ checkDoneLabel.setText(" "); //$NON-NLS-1$
+
+ GridData checkdonelabeldata = new GridData();
+ checkdonelabeldata.verticalAlignment = GridData.BEGINNING;
+ checkdonelabeldata.grabExcessVerticalSpace = true;
+ checkdonelabeldata.widthHint = Math.max(completeImage.getBounds().width, skipImage.getBounds().width);
+ checkDoneLabel.setLayoutData(checkdonelabeldata);
+ checkDoneLabel.setBackground(white);
+
+ mainItemComposite = new Composite(checkAndMainItemComposite, SWT.NULL);
+ GridLayout mylayout = new GridLayout(1, true);
+ GridData mydata = new GridData(GridData.FILL_HORIZONTAL);
+ mylayout.marginHeight = 0;
+ mylayout.marginWidth = 0;
+ mylayout.verticalSpacing = 0;
+ mainItemComposite.setBackground(itemColor);
+
+ mainItemComposite.setLayout(mylayout);
+ mainItemComposite.setLayoutData(mydata);
+
+ //check number of extensions for this item. adjust layout accordingly.
+ int number = 3;
+ ArrayList al = contentItem.getItemExtensions();
+ if (al != null)
+ for (int g = 0; g < al.size(); g++) {
+ ICheatSheetItemExtensionElement[] eea = (ICheatSheetItemExtensionElement[]) al.get(g);
+ number += eea.length;
+ }
+
+ // Set up the title composite for the item.*****************************************
+ titleComposite = new Composite(mainItemComposite, SWT.NULL);
+ mylayout = new GridLayout(number, false);
+ mydata = new GridData(GridData.FILL_BOTH);
+
+ titleComposite.setLayout(mylayout);
+ titleComposite.setLayoutData(mydata);
+ mylayout.marginWidth = 0;
+ mylayout.marginHeight = 0;
+ mylayout.verticalSpacing = 0;
+ titleComposite.setBackground(itemColor);
+
+ // Set the title bar composite content *********************************************
+ expandToggle = new ToggleButton(titleComposite, SWT.NULL, expandImage, collapseImage);
+ expandToggle.setFAccessibleDescription(contentItem.getText());
+ expandToggle.setFAccessibleName(contentItem.getTitle() + " " + contentItem.getText()); //$NON-NLS-1$
+ expandToggle.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (expandToggle.isCollapsed())
+ setCollapsed();
+ else
+ setExpanded();
+ theview.saveCurrentSheet();
+ }
+ });
+ expandToggle.setBackground(itemColor);
+
+ titleText = new StyledText(titleComposite, SWT.BOLD | SWT.WRAP | SWT.READ_ONLY);
+ String title = contentItem.getTitle();
+ if (title != null) {
+ titleText.setText(title);
+ } else {
+ titleText.setText(" "); //$NON-NLS-1$
+ }
+ titleText.getCaret().setVisible(false);
+ GridData egridData = new GridData();
+ egridData.verticalAlignment = GridData.BEGINNING;
+ egridData.horizontalAlignment = GridData.FILL;
+ egridData.grabExcessHorizontalSpace = true;
+ titleText.setLayoutData(egridData);
+ titleText.setBackground(itemColor);
+ titleText.setEnabled(false);
+
+ // handle item extensions here.
+ ArrayList itemExts = contentItem.getItemExtensions();
+ if (itemExts != null)
+ for (int x = 0; x < itemExts.size(); x++) {
+ ICheatSheetItemExtensionElement[] xe = (ICheatSheetItemExtensionElement[]) itemExts.get(x);
+ for (int g = 0; g < xe.length; g++) {
+ xe[g].createControl(titleComposite, itemColor);
+ }
+ }
+
+ //don't add the help icon unless there is a help link.
+ if (contentItem.getHref() != null) {
+ Button helpButton = new Button(titleComposite, SWT.NULL, helpImage);
+ helpButton.setBackground(itemColor);
+
+ helpButton.setToolTipText(CheatSheetPlugin.getResourceString(ICheatSheetResource.HELP_BUTTON_TOOLTIP));
+ helpButton.setFAccessibleName(helpButton.getToolTipText());
+ helpButton.setFAccessibleDescription(helpButton.getToolTipText());
+
+ helpButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ Button helpButton = (Button) e.widget;
+ helpButton.setCursor(busyCursor);
+ openHelpTopic(contentItem.getHref());
+ helpButton.setCursor(null);
+ }
+ });
+ }
+
+ //Body wrapper here. this composite will be hidden and shown as appropriate.
+ bodyWrapperComposite = new Composite(mainItemComposite, SWT.NULL);
+ GridLayout wrapperLayout = new GridLayout();
+ wrapperLayout.marginHeight = 0;
+ wrapperLayout.marginWidth = 0;
+ wrapperLayout.verticalSpacing = 0;
+ GridData wrapperData = new GridData(GridData.FILL_HORIZONTAL);
+ bodyWrapperComposite.setLayout(wrapperLayout);
+ bodyWrapperComposite.setLayoutData(wrapperData);
+ bodyWrapperComposite.setBackground(itemColor);
+
+ // Set up the body composite, for the body of the item text.
+ bodyComp = new Composite(bodyWrapperComposite, SWT.NULL);
+ GridLayout bodylayout = new GridLayout(1, false);
+ bodylayout.marginHeight = 0;
+ bodylayout.marginWidth = 0;
+ bodylayout.verticalSpacing = 0;
+
+ GridData bodyData = new GridData(GridData.FILL_HORIZONTAL);
+ bodyData.grabExcessHorizontalSpace = true;
+
+ bodyComp.setLayout(bodylayout);
+ bodyComp.setLayoutData(bodyData);
+ bodyComp.setBackground(itemColor);
+
+ bodyText = new StyledText(bodyComp, SWT.WRAP | SWT.READ_ONLY | SWT.NULL);
+
+ String btext = contentItem.getText();
+ if (btext != null) {
+ bodyText.setText(btext);
+ } else {
+ bodyText.setText(" "); //$NON-NLS-1$
+ }
+
+ //Set up the body text portion here.
+ GridData bgridData = new GridData();
+ bgridData.verticalAlignment = GridData.BEGINNING;
+ bgridData.horizontalAlignment = GridData.FILL;
+ bgridData.grabExcessHorizontalSpace = true;
+ bodyText.setLayoutData(bgridData);
+ bodyText.setEnabled(false);
+ bodyText.setBackground(itemColor);
+
+ //Handle the sub-steps and regular buttons here.
+ //First Check to see if there is sub steps. If there is, don't create the button comp,
+ //As it will be handled by the CoreItemWithSubs.
+ //If there is no sub steps, create a button composite and Pass it to CoreItem using the handleButtons.
+
+ if (contentItem.isDynamic()) {
+ ((CoreItem) this).setBodyWrapperComposite(bodyWrapperComposite);
+ } else {
+ handleButtons(bodyWrapperComposite);
+ }
+
+ mainItemComposite.pack();
+ mainItemComposite.layout(true);
+
+ setButtonsCollapsed();
+ setCollapsed();
+ }
+
+ /*package*/
+ void boldTitle() {
+ StyleRange r = new StyleRange(0, titleText.getText().length(), null, null, SWT.BOLD);
+ titleText.setStyleRange(r);
+
+ }
+
+ public void dispose() {
+ if (busyCursor != null)
+ busyCursor.dispose();
+ if (lightGrey != null)
+ lightGrey.dispose();
+ if (darkGrey != null)
+ darkGrey.dispose();
+ if (checkAndMainItemComposite != null)
+ checkAndMainItemComposite.dispose();
+ if (checkDoneLabel != null)
+ checkDoneLabel.dispose();
+ if (titleText != null)
+ titleText.dispose();
+ if (expandToggle != null)
+ expandToggle.dispose();
+ if (bodyText != null)
+ bodyText.dispose();
+ if (buttonComposite != null)
+ buttonComposite.dispose();
+ if (bodyComp != null)
+ bodyComp.dispose();
+ if (bodyWrapperComposite != null)
+ bodyWrapperComposite.dispose();
+ if (mainItemComposite != null)
+ mainItemComposite.dispose();
+ if (completeImage != null)
+ completeImage.dispose();
+ if (collapseImage != null)
+ collapseImage.dispose();
+ if (expandImage != null)
+ expandImage.dispose();
+ if (helpImage != null)
+ helpImage.dispose();
+ if (skipImage != null)
+ skipImage.dispose();
+ if (white != null)
+ white.dispose();
+ if (titleComposite != null)
+ titleComposite.dispose();
+
+ }
+ /**
+ * Returns the checkAndMainItemComposite.
+ * @return Composite
+ */
+ /*package*/
+ Composite getCheckAndMainItemComposite() {
+ return checkAndMainItemComposite;
+ }
+
+ /**
+ * @return
+ */
+ /*package*/
+ Image getCompleteImage() {
+ return completeImage;
+ }
+
+ /**
+ * @return
+ */
+ public IContainsContent getContentItem() {
+ return contentItem;
+ }
+
+ /**
+ * Returns the expandToggle.
+ * @return Label
+ */
+ /*package*/
+ ToggleButton getExpandToggle() {
+ return expandToggle;
+ }
+
+ /**
+ * Returns the mainItemComposite.
+ * @return Composite
+ */
+ /*package*/
+ Composite getMainItemComposite() {
+ return mainItemComposite;
+ }
+
+ /**
+ * @return
+ */
+ /*package*/
+ Image getSkipImage() {
+ return skipImage;
+ }
+
+ //Adds the buttons to the buttonComposite.
+ /*package*/
+ abstract void handleButtons(Composite buttonComposite);
+
+ protected void init() {
+
+ }
+
+ /**
+ * Returns the completed.
+ * @return boolean
+ */
+ public boolean isCompleted() {
+ return completed;
+ }
+
+ public boolean isExpanded() {
+ return expanded;
+ }
+
+ /*package*/
+ boolean isSkipped() {
+ return isSkipped;
+ }
+
+ private void layoutBody() {
+ bodyComp.layout(true);
+ }
+
+ /**
+ * Open a help topic
+ */
+ private void openHelpTopic(String href) {
+ IHelp helpSupport = WorkbenchHelp.getHelpSupport();
+ if (helpSupport != null) {
+ if (href != null)
+ helpSupport.displayHelpResource(href);
+
+ }
+ }
+
+ /*package*/
+ byte runAction(CheatSheetManager csm) {
+ return runAction(((ContentItem) contentItem).getActionPluginID(), ((ContentItem) contentItem).getActionClass(), ((ContentItem) contentItem).getActionParams(), csm);
+ }
+
+ /**
+ * Run an action
+ */
+ /*package*/
+ byte runAction(String pluginId, String className, String[] params, CheatSheetManager csm) {
+ IPluginDescriptor desc = Platform.getPluginRegistry().getPluginDescriptor(pluginId);
+ if (desc == null) {
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_FINDING_PLUGIN_FOR_ACTION), null);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ org.eclipse.jface.dialogs.ErrorDialog.openError(new Shell(), CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_FINDING_PLUGIN_FOR_ACTION), null, status);
+ return VIEWITEM_DONOT_ADVANCE;
+ }
+ Class actionClass;
+ IAction action;
+ try {
+ actionClass = desc.getPluginClassLoader().loadClass(className);
+ } catch (Exception e) {
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_LOADING_CLASS_FOR_ACTION), e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ org.eclipse.jface.dialogs.ErrorDialog.openError(new Shell(), CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_LOADING_CLASS_FOR_ACTION), null, status);
+ return VIEWITEM_DONOT_ADVANCE;
+ }
+ try {
+ action = (IAction) actionClass.newInstance();
+ } catch (Exception e) {
+ IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_CREATING_CLASS_FOR_ACTION), e);
+ CheatSheetPlugin.getPlugin().getLog().log(status);
+ org.eclipse.jface.dialogs.ErrorDialog.openError(new Shell(), CheatSheetPlugin.getResourceString(ICheatSheetResource.ERROR_CREATING_CLASS_FOR_ACTION), null, status);
+
+ //logActionLinkError(pluginId, className);
+ return VIEWITEM_DONOT_ADVANCE;
+ }
+
+ wizardLaunched = false;
+ ShellListener shellListener = new ShellAdapter() {
+ public void shellDeactivated(ShellEvent e) {
+ wizardLaunched = true;
+ }
+ };
+
+ // Add ShellListener to Workbench window, so we can detemine if a wizard is launched.
+ theview.getViewSite().getWorkbenchWindow().getShell().addShellListener(shellListener);
+
+ // Run the action for this ViewItem
+ if (action instanceof ICheatSheetAction) {
+ ((ICheatSheetAction) action).run(params, csm);
+ } else
+ action.run();
+
+ // Remove the ShellListener
+ theview.getViewSite().getWorkbenchWindow().getShell().removeShellListener(shellListener);
+
+ if (wizardLaunched) {
+ int returnCode = WizardReturnCodeHack.getLastWizardReturnCode();
+ if (returnCode == Window.OK) {
+ //System.out.println("OK");
+ return VIEWITEM_ADVANCE;
+ } else if (returnCode == Window.CANCEL) {
+ //System.out.println("Cancel");
+ return VIEWITEM_DONOT_ADVANCE;
+ }
+ }
+
+ return VIEWITEM_ADVANCE;
+ }
+
+ /*package*/
+ void setAsCurrentActiveItem() {
+ setColorAsCurrent(true);
+ if (!buttonExpanded)
+ setButtonsExpanded();
+ setExpanded();
+ boldTitle();
+ layoutBody();
+ getExpandToggle().setFocus();
+ }
+
+ /*package*/
+ void setAsNormalCollapsed() {
+ setColorAsCurrent(false);
+ if (expanded)
+ setCollapsed();
+ unboldTitle();
+ }
+
+ /*package*/
+ void setAsNormalNonCollapsed() {
+ setColorAsCurrent(false);
+ unboldTitle();
+ }
+
+ private void setBodyColor(Color color) {
+ mainItemComposite.setBackground(color);
+ bodyWrapperComposite.setBackground(color);
+ bodyComp.setBackground(color);
+
+ if (buttonComposite != null)
+ buttonComposite.setBackground(color);
+
+ Control[] bodyChildren = bodyComp.getChildren();
+ for (int i = 0; i < bodyChildren.length; i++) {
+ bodyChildren[i].setBackground(color);
+ }
+
+ if (buttonComposite != null)
+ for (int j = 0; j < buttonCompositeList.size(); j++) {
+ Composite c = (Composite) buttonCompositeList.get(j);
+ c.setBackground(color);
+ bodyChildren = c.getChildren();
+ for (int i = 0; i < bodyChildren.length; i++) {
+ bodyChildren[i].setBackground(color);
+ }
+ }
+
+ }
+
+ //collapses the item
+ /*package*/
+ void setButtonsCollapsed() {
+
+ if (buttonComposite != null)
+ if (buttonExpanded) {
+ // System.out.println("Buttons collapsing!!!");
+
+ buttonComposite.setVisible(false);
+ GridData mydata = (GridData) buttonComposite.getLayoutData();
+ mydata.heightHint = 0;
+
+ buttonExpanded = false;
+ parent.getParent().layout(true);
+ parent.layout(true);
+ mainItemComposite.layout(true);
+ bodyWrapperComposite.layout(true);
+ theview.layout();
+ }
+
+ }
+
+ //expands the item
+ /*package*/
+ void setButtonsExpanded() {
+
+ if (!buttonExpanded) {
+ // System.out.println("Buttons Expanding!!");
+ buttonComposite.setVisible(true);
+
+ GridData mydata = (GridData) buttonComposite.getLayoutData();
+ mydata.heightHint = SWT.DEFAULT;
+
+ buttonExpanded = true;
+
+ parent.getParent().layout(true);
+ parent.layout(true);
+ mainItemComposite.layout(true);
+ bodyWrapperComposite.layout(true);
+ theview.layout();
+ theview.updateScrolledComposite();
+ theview.scrollIfNeeded();
+ }
+ }
+
+ //collapses the item
+ /*package*/
+ void setCollapsed() {
+ if (expanded) {
+ bodyWrapperComposite.setVisible(false);
+ expandToggle.setCollapsed(true);
+
+ GridData mydata = (GridData) bodyWrapperComposite.getLayoutData();
+ mydata.heightHint = 0;
+ expanded = false;
+ parent.getParent().layout(true);
+ mainItemComposite.layout(true);
+ bodyWrapperComposite.layout(true);
+ theview.layout();
+
+ theview.updateScrolledComposite();
+ theview.scrollIfNeeded();
+ }
+ }
+
+ private void setColorAsCurrent(boolean active) {
+ if (active) {
+ setTitleColor(darkGrey);
+ setBodyColor(darkGrey);
+ } else {
+ setTitleColor(itemColor);
+ setBodyColor(itemColor);
+ }
+ }
+
+ //marks the item as complete.
+ /*package*/
+ void setComplete() {
+ try {
+ completed = true;
+ checkDoneLabel.setImage(completeImage);
+ checkAndMainItemComposite.layout(true);
+ } catch (Exception e) {
+ // System.out.println("in set complete");
+ }
+
+ }
+
+ //expands the item
+ /*package*/
+ void setExpanded() {
+ // System.out.println("Item is already expanded? : " + expanded);
+ if (!expanded) {
+ bodyWrapperComposite.setVisible(true);
+ expandToggle.setCollapsed(false);
+
+ GridData mydata = (GridData) bodyWrapperComposite.getLayoutData();
+ mydata.heightHint = SWT.DEFAULT;
+ expanded = true;
+
+ parent.getParent().layout(true);
+ mainItemComposite.layout(true);
+ bodyWrapperComposite.layout(true);
+ theview.layout();
+ theview.updateScrolledComposite();
+ theview.scrollIfNeeded();
+ //theview.saveCurrentSheet();
+ }
+ }
+
+ /*package*/
+ void setIncomplete() {
+ checkDoneLabel.setImage(null);
+ checkAndMainItemComposite.layout(true);
+ completed = false;
+ setStartImage();
+ //setCollapsed();
+ }
+
+ /**
+ * Sets the itemColor.
+ * @param itemColor The itemColor to set
+ */
+ /*package*/
+ void setItemColor(Color itemColor) {
+ this.itemColor = itemColor;
+ }
+
+ /*package*/
+ void setOriginalColor() {
+ setTitleColor(itemColor);
+ setBodyColor(itemColor);
+ }
+
+ /*package*/
+ abstract void setRestartImage();
+
+ /*package*/
+ void setSkipped() {
+ try {
+ isSkipped = true;
+ checkDoneLabel.setImage(skipImage);
+ checkAndMainItemComposite.layout(true);
+ } catch (Exception e) {
+
+ }
+ }
+ /*package*/
+ abstract void setStartImage();
+
+ private void setTitleColor(Color color) {
+ titleComposite.setBackground(color);
+
+ Control[] titlechildren = titleComposite.getChildren();
+ for (int i = 0; i < titlechildren.length; i++) {
+ titlechildren[i].setBackground(color);
+ }
+ }
+
+ /*package*/
+ void unboldTitle() {
+ StyleRange r = new StyleRange(0, titleText.getText().length(), null, null, SWT.NULL);
+ titleText.setStyleRange(r);
+ }
+
+}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/WizardReturnCodeHack.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/WizardReturnCodeHack.java
new file mode 100644
index 000000000..ddc32aa2e
--- /dev/null
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/WizardReturnCodeHack.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2000, 2003.
+ * All Rights Reserved.
+ * Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP schedule Contract with IBM Corp.
+*/
+package org.eclipse.ui.internal.cheatsheets.views;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.jface.window.Window;
+
+/**
+ *
+ * A class to access the last return code from org.eclipse.jface.window.Window.
+ *
+ */
+/* package */ class WizardReturnCodeHack {
+
+ /**
+ * Ensure the given view is a fast view only and follows the
+ * user as they switch perspectives.
+ *
+ * @param aView - the view to ensure is a following fast view only
+ */
+ /* package */
+ static final int getLastWizardReturnCode() {
+ Class window;
+ try {
+ window = Class.forName("org.eclipse.jface.window.Window"); //$NON-NLS-1$
+ } catch (ClassNotFoundException e) {
+ return Window.CANCEL;
+ }
+ Field field;
+ try {
+ field = window.getDeclaredField("globalReturnCode"); //$NON-NLS-1$
+ } catch (NoSuchFieldException e) {
+ return Window.CANCEL;
+ }
+ field.setAccessible(true);
+ int returnCode;
+ try {
+ returnCode = field.getInt(null);
+ } catch (IllegalAccessException e) {
+ return Window.CANCEL;
+ }
+
+ return returnCode;
+ }
+}

Back to the top