Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 125936 Details for
Bug 246875
[About] allow for an extensible About dialog
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
replacement patch with new contribution mechanism
bug246875.patch (text/plain), 248.85 KB, created by
Susan McCourt
on 2009-02-17 14:54:50 EST
(
hide
)
Description:
replacement patch with new contribution mechanism
Filename:
MIME Type:
Creator:
Susan McCourt
Created:
2009-02-17 14:54:50 EST
Size:
248.85 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.equinox.p2.ui.sdk >Index: plugin.xml >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/p2/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.xml,v >retrieving revision 1.24 >diff -u -r1.24 plugin.xml >--- plugin.xml 20 Jan 2009 18:31:37 -0000 1.24 >+++ plugin.xml 17 Feb 2009 19:43:54 -0000 >@@ -107,15 +107,6 @@ > </command> > > </menuContribution> >- <menuContribution >- locationURI="menu:help?after=org.eclipse.equinox.p2.ui.sdk.install"> >- <command >- commandId="org.eclipse.ui.help.installationDialog" >- mnemonic="%TempInstallView.mnemonic" >- id="org.eclipse.equinox.p2.ui.sdk.tempInstallInfo"> >- </command> >- >- </menuContribution> > </extension> > <extension > point="org.eclipse.ui.activities"> >@@ -153,7 +144,7 @@ > <page > name="%installedSoftwarePage" > class="org.eclipse.equinox.internal.provisional.p2.ui.dialogs.InstalledSoftwarePage" >- id="org.eclipse.equinox.internal.p2.ui.sdk.InstalledSoftwarePage"> >+ id="10.org.eclipse.equinox.internal.p2.ui.sdk.InstalledSoftwarePage"> > </page> > <page > name="%installHistoryPage" >#P org.eclipse.ui.ide >Index: plugin.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/plugin.properties,v >retrieving revision 1.142 >diff -u -r1.142 plugin.properties >--- plugin.properties 19 Jan 2009 14:35:31 -0000 1.142 >+++ plugin.properties 17 Feb 2009 19:43:58 -0000 >@@ -284,3 +284,9 @@ > menu.mnemonic.0 = I > menu.showIn.label = Show In > menu.showIn.mnemonic = I >+ >+installationPage.feature.name = Features >+command.installationPageColumns.mnemonic = C >+command.installationPageLicense.name = License >+command.installationPageLicense.mnemonic = L >+command.installationPageLicense.description = Open a browser on the license >Index: plugin.xml >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/plugin.xml,v >retrieving revision 1.283 >diff -u -r1.283 plugin.xml >--- plugin.xml 19 Jan 2009 14:35:31 -0000 1.283 >+++ plugin.xml 17 Feb 2009 19:44:02 -0000 >@@ -2234,4 +2234,97 @@ > type="org.eclipse.core.resources.IMarker"> > </propertyTester> > </extension> >+ <extension >+ point="org.eclipse.ui.commands"> >+ <command >+ description="%command.installationPageLicense.description" >+ id="org.eclipse.ui.about.featureDialog.openLicense" >+ name="%command.installationPageLicense.name" >+ defaultHandler="org.eclipse.ui.internal.about.OpenBrowserHandler"/> >+ </extension> >+ >+ <extension >+ point="org.eclipse.ui.installationPages"> >+ <page >+ name="%installationPage.feature.name" >+ class="org.eclipse.ui.internal.about.AboutFeaturesPage" >+ id="20.FeaturesPage"> >+ </page> >+ </extension> >+ <extension >+ point="org.eclipse.ui.menus"> >+ <menuContribution >+ locationURI="toolbar:org.eclipse.ui.installationDialog.buttonbar"> >+ <command >+ commandId="org.eclipse.ui.about.columns" >+ mnemonic="%command.installationPageColumns.mnemonic" >+ style="push"> >+ <visibleWhen> >+ <with variable="org.eclipse.ui.installationPage.activePage.id"> >+ <equals value="20.FeaturesPage"/> >+ </with> >+ </visibleWhen> >+ </command> >+ <command >+ commandId="org.eclipse.ui.about.openBrowser" >+ label="%command.installationPageLicense.name" >+ mnemonic="%command.installationPageLicense.mnemonic" >+ style="push"> >+ <visibleWhen> >+ <with variable="org.eclipse.ui.installationPage.activePage.id"> >+ <equals value="20.FeaturesPage"/> >+ </with> >+ </visibleWhen> >+ </command> >+ </menuContribution> >+ <menuContribution >+ locationURI="toolbar:org.eclipse.ui.installationDialog.buttonbar.productInfo.features"> >+ <command >+ commandId="org.eclipse.ui.about.columns" >+ mnemonic="%command.installationPageColumns.mnemonic" >+ style="push"> >+ </command> >+ <command >+ commandId="org.eclipse.ui.about.featureDialog.openLicense" >+ label="%command.installationPageLicense.name" >+ mnemonic="%command.installationPageLicense.mnemonic" >+ style="push"> >+ </command> >+ </menuContribution> >+ </extension> >+ <extension >+ point="org.eclipse.ui.handlers"> >+ <handler >+ class="org.eclipse.ui.internal.about.OpenBrowserHandler" >+ commandId="org.eclipse.ui.about.openBrowser"> >+ <activeWhen> >+ <with >+ variable="org.eclipse.ui.installationPage.activePage.id"> >+ <equals value="20.FeaturesPage"/> >+ </with> >+ </activeWhen> >+ <enabledWhen> >+ <with >+ variable="org.eclipse.ui.installationPage.activePage.selection"> >+ <count value="1"/> >+ </with> >+ </enabledWhen> >+ </handler> >+ <handler >+ class="org.eclipse.ui.internal.about.OpenBrowserHandler" >+ commandId="org.eclipse.ui.about.featureDialog.openLicense"> >+ <activeWhen> >+ <with >+ variable="org.eclipse.ui.internal.about.activeProductDialogPageId"> >+ <equals value="productInfo.features"/> >+ </with> >+ </activeWhen> >+ <enabledWhen> >+ <with >+ variable="org.eclipse.ui.internal.about.activeProductDialogSelection"> >+ <count value="1"/> >+ </with> >+ </enabledWhen> >+ </handler> >+ </extension> > </plugin> >#P org.eclipse.ui >Index: plugin.xml >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui/plugin.xml,v >retrieving revision 1.438 >diff -u -r1.438 plugin.xml >--- plugin.xml 25 Jan 2009 15:47:00 -0000 1.438 >+++ plugin.xml 17 Feb 2009 19:44:08 -0000 >@@ -2221,4 +2221,171 @@ > type="java.lang.Object"> > </propertyTester> > </extension> >+ <extension >+ point="org.eclipse.ui.services"> >+ <sourceProvider >+ provider="org.eclipse.ui.internal.about.InstallationDialogSourceProvider"> >+ <variable >+ name="org.eclipse.ui.installationPage.activePage" >+ priorityLevel="activeContexts"> >+ </variable> >+ <variable >+ name="org.eclipse.ui.installationPage.activePage.id" >+ priorityLevel="activeContexts"> >+ </variable> >+ <variable >+ name="org.eclipse.ui.installationPage.activePage.selection" >+ priorityLevel="activeContexts"> >+ </variable> >+ <variable >+ name="org.eclipse.ui.internal.about.activeProductDialogPage" >+ priorityLevel="activeContexts"> >+ </variable> >+ <variable >+ name="org.eclipse.ui.internal.about.activeProductDialogPageId" >+ priorityLevel="activeContexts"> >+ </variable> >+ </sourceProvider> >+ </extension> >+ <extension >+ point="org.eclipse.ui.installationPages"> >+ <page >+ name="%installationPage.plugins.name" >+ class="org.eclipse.ui.internal.about.AboutPluginsPage" >+ id="15.PluginPage"> >+ </page> >+ <page >+ name="%installationPage.system.name" >+ class="org.eclipse.ui.internal.about.AboutSystemPage" >+ id="16.SystemPage"> >+ </page> >+ </extension> >+ <extension >+ point="org.eclipse.ui.commands"> >+ <command >+ description="%command.installationPageColumns.description" >+ id="org.eclipse.ui.about.columns" >+ name="%command.installationPageColumns.name" >+ defaultHandler="org.eclipse.ui.internal.about.ConfigureColumnsHandler"/> >+ <command >+ description="%command.installationPageOpenBrowser.description" >+ id="org.eclipse.ui.about.openBrowser" >+ name="%command.installationPageOpenBrowser.name" >+ defaultHandler="org.eclipse.ui.internal.about.OpenBrowserHandler"/> >+ <command >+ description="%command.installationPageOpenBrowser.description" >+ id="org.eclipse.ui.about.pluginsDialog.openLegal" >+ name="%command.installationPageOpenBrowser.name" >+ defaultHandler="org.eclipse.ui.internal.about.OpenBrowserHandler"/> >+ <command >+ description="%command.installationPageViewErrorLog.description" >+ id="org.eclipse.ui.about.viewErrorLog" >+ name="%command.installationPageViewErrorLog.name" >+ defaultHandler="org.eclipse.ui.internal.about.ViewErrorLogHandler"/> >+ </extension> >+ <extension >+ point="org.eclipse.ui.menus"> >+ <menuContribution >+ locationURI="toolbar:org.eclipse.ui.installationDialog.buttonbar"> >+ <command >+ commandId="org.eclipse.ui.edit.copy" >+ style="push"> >+ <visibleWhen> >+ <with variable="org.eclipse.ui.installationPage.activePage.id"> >+ <equals value="16.SystemPage"/> >+ </with> >+ </visibleWhen> >+ </command> >+ <command >+ commandId="org.eclipse.ui.about.viewErrorLog" >+ mnemonic="%command.installationPageViewErrorLog.mnemonic" >+ style="push"> >+ <visibleWhen> >+ <with variable="org.eclipse.ui.installationPage.activePage.id"> >+ <equals value="16.SystemPage"/> >+ </with> >+ </visibleWhen> >+ </command> >+ <command >+ commandId="org.eclipse.ui.about.columns" >+ mnemonic="%command.installationPageColumns.mnemonic" >+ style="push"> >+ <visibleWhen> >+ <with variable="org.eclipse.ui.installationPage.activePage.id"> >+ <equals value="15.PluginPage"/> >+ </with> >+ </visibleWhen> >+ </command> >+ <command >+ commandId="org.eclipse.ui.about.openBrowser" >+ label="%command.installationPageLegalInfo.name" >+ mnemonic="%command.installationPageLegalInfo.mnemonic" >+ style="push"> >+ <visibleWhen> >+ <with variable="org.eclipse.ui.installationPage.activePage.id"> >+ <equals value="15.PluginPage"/> >+ </with> >+ </visibleWhen> >+ </command> >+ </menuContribution> >+ <menuContribution >+ locationURI="toolbar:org.eclipse.ui.installationDialog.buttonbar.productInfo.plugins"> >+ <command >+ commandId="org.eclipse.ui.about.columns" >+ mnemonic="%command.installationPageColumns.mnemonic" >+ style="push"> >+ </command> >+ <command >+ commandId="org.eclipse.ui.about.pluginsDialog.openLegal" >+ label="%command.installationPageLegalInfo.name" >+ mnemonic="%command.installationPageLegalInfo.mnemonic" >+ style="push"> >+ </command> >+ </menuContribution> >+ </extension> >+ <extension >+ point="org.eclipse.ui.handlers"> >+ <handler >+ class="org.eclipse.ui.internal.about.CopyHandler" >+ commandId="org.eclipse.ui.edit.copy"> >+ <activeWhen> >+ <with >+ variable="org.eclipse.ui.installationPage.activePage.id"> >+ <equals value="16.SystemPage"/> >+ </with> >+ </activeWhen> >+ </handler> >+ <handler >+ class="org.eclipse.ui.internal.about.OpenBrowserHandler" >+ commandId="org.eclipse.ui.about.openBrowser"> >+ <activeWhen> >+ <with >+ variable="org.eclipse.ui.installationPage.activePage.id"> >+ <equals value="15.PluginPage"/> >+ </with> >+ </activeWhen> >+ <enabledWhen> >+ <with >+ variable="org.eclipse.ui.installationPage.activePage.selection"> >+ <count value="1"/> >+ </with> >+ </enabledWhen> >+ </handler> >+ <handler >+ class="org.eclipse.ui.internal.about.OpenBrowserHandler" >+ commandId="org.eclipse.ui.about.pluginsDialog.openLegal"> >+ <activeWhen> >+ <with >+ variable="org.eclipse.ui.internal.about.activeProductDialogPageId"> >+ <equals value="productInfo.plugins"/> >+ </with> >+ </activeWhen> >+ <enabledWhen> >+ <with >+ variable="org.eclipse.ui.internal.about.activeProductDialogSelection"> >+ <count value="1"/> >+ </with> >+ </enabledWhen> >+ </handler> >+ </extension> > </plugin> >Index: plugin.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui/plugin.properties,v >retrieving revision 1.215 >diff -u -r1.215 plugin.properties >--- plugin.properties 12 Sep 2008 19:54:46 -0000 1.215 >+++ plugin.properties 17 Feb 2009 19:44:05 -0000 >@@ -330,4 +330,18 @@ > command.quickMenu.name = Open Quick Menu > command.quickMenu.uri.name = Location URI > command.showIn.name = Show In >-command.showIn.targetId.name = Show In Target Id >\ No newline at end of file >+command.showIn.targetId.name = Show In Target Id >+ >+installationPage.main.name = About >+installationPage.system.name = Configuration >+installationPage.plugins.name = Plug-ins >+command.installationPageColumns.name = Columns >+command.installationPageColumns.description = Open a dialog to set the column widths >+command.installationPageColumns.mnemonic = C >+command.installationPageOpenBrowser.name = More >+command.installationPageOpenBrowser.description = Open a browser on additional information >+command.installationPageLegalInfo.name = Legal Info >+command.installationPageLegalInfo.mnemonic = L >+command.installationPageViewErrorLog.name = View Error Log >+command.installationPageViewErrorLog.description = Open a browser on the error log >+command.installationPageViewErrorLog.mnemonic = V >\ No newline at end of file >Index: schema/installationPages.exsd >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui/schema/installationPages.exsd,v >retrieving revision 1.1 >diff -u -r1.1 installationPages.exsd >--- schema/installationPages.exsd 12 Sep 2008 19:54:47 -0000 1.1 >+++ schema/installationPages.exsd 17 Feb 2009 19:44:08 -0000 >@@ -2,19 +2,23 @@ > <!-- Schema file written by PDE --> > <schema targetNamespace="org.eclipse.ui" xmlns="http://www.w3.org/2001/XMLSchema"> > <annotation> >- <appinfo> >+ <appInfo> > <meta.schema plugin="org.eclipse.ui" id="installationPages" name="Installation Dialog Pages"/> >- </appinfo> >+ </appInfo> > <documentation> >- This is an experimental extension point for an extensible about dialog. It is not ready for production and is included at this time only for evaluation by downstream clients. Use at your own risk. >+ <p>The Eclipse UI provides an AboutDialog that can be branded and reused by client product plugins. This dialog typically shows the product splash image and other descriptive information about the product. The about dialog includes a button that allows the user to launch a secondary dialog, the <b>Installation Details</b> dialog.</p> >+<p>The purpose of this extension point is to allow plug-ins to add >+pages to the installation details dialog. When the installation details dialog is opened, the pages contributed in this way will be added to the dialog box. These pages are used to supply additional detail about the product configuration.</p> >+ >+<p>This is an experimental extension point for an extensible about dialog. It is not ready for production and is included at this time only for evaluation by downstream clients. Use at your own risk.</p> > </documentation> > </annotation> > > <element name="extension"> > <annotation> >- <appinfo> >+ <appInfo> > <meta.element /> >- </appinfo> >+ </appInfo> > </annotation> > <complexType> > <sequence> >@@ -39,9 +43,9 @@ > <documentation> > > </documentation> >- <appinfo> >+ <appInfo> > <meta.attribute translatable="true"/> >- </appinfo> >+ </appInfo> > </annotation> > </attribute> > </complexType> >@@ -61,9 +65,9 @@ > <documentation> > > </documentation> >- <appinfo> >+ <appInfo> > <meta.attribute kind="java" basedOn="org.eclipse.ui.branding.InstallationPage:"/> >- </appinfo> >+ </appInfo> > </annotation> > </attribute> > <attribute name="name" type="string" use="required"> >@@ -71,49 +75,77 @@ > <documentation> > > </documentation> >- <appinfo> >+ <appInfo> > <meta.attribute translatable="true"/> >- </appinfo> >+ </appInfo> > </annotation> > </attribute> > </complexType> > </element> > > <annotation> >- <appinfo> >+ <appInfo> > <meta.section type="since"/> >- </appinfo> >+ </appInfo> > <documentation> >- [Enter the first release in which this extension point appears.] >+ 3.5 > </documentation> > </annotation> > > <annotation> >- <appinfo> >+ <appInfo> > <meta.section type="examples"/> >- </appinfo> >+ </appInfo> > <documentation> >- [Enter extension point usage example here.] >+ The following is an example installation page: >+<p> >+<pre> >+ <extension point="org.eclipse.ui.installationPages"> >+ <page >+ name="XYZ Info" >+ class="org.eclipse.ui.internal.XYZInstallInfoPage" >+ id="org.eclipse.ui.internal.xyz> >+ </page> >+ </extension> >+</pre> >+</p> > </documentation> > </annotation> > > <annotation> >- <appinfo> >+ <appInfo> > <meta.section type="apiinfo"/> >- </appinfo> >+ </appInfo> > <documentation> >- [Enter API information here.] >+ The value of the attribute class must represent a fully qualified name of a class that is a concrete subclass of >+<samp>org.eclipse.ui.about.InstallationPage</samp>. > </documentation> > </annotation> > > <annotation> >- <appinfo> >+ <appInfo> > <meta.section type="implementation"/> >- </appinfo> >+ </appInfo> > <documentation> >- [Enter information about supplied implementation of this extension point.] >+ The Workbench uses this extension point to provide the following pages in the installation details dialog: >+<ul> >+<li>Plug-ins: A list of all of the plug-ins in the running the system, including details about each plug-in.</li> >+<li>Configuration: The configuration information contributed via the <samp>org.eclipse.ui.systemSummarySections</samp> extension.</li> >+</ul> > </documentation> > </annotation> > >+ <annotation> >+ <appInfo> >+ <meta.section type="copyright"/> >+ </appInfo> >+ <documentation> >+ Copyright (c) 2008, 2009 IBM Corporation and others.<br> >+All rights reserved. This program and the accompanying materials are made >+available under the terms of the Eclipse Public License v1.0 which accompanies >+this distribution, and is available at <a >+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a> >+ </documentation> >+ </annotation> > > </schema> >Index: schema/systemSummarySections.exsd >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui/schema/systemSummarySections.exsd,v >retrieving revision 1.9 >diff -u -r1.9 systemSummarySections.exsd >--- schema/systemSummarySections.exsd 16 Mar 2007 18:00:05 -0000 1.9 >+++ schema/systemSummarySections.exsd 17 Feb 2009 19:44:08 -0000 >@@ -1,16 +1,21 @@ > <?xml version='1.0' encoding='UTF-8'?> > <!-- Schema file written by PDE --> >-<schema targetNamespace="org.eclipse.ui"> >+<schema targetNamespace="org.eclipse.ui" xmlns="http://www.w3.org/2001/XMLSchema"> > <annotation> > <appInfo> > <meta.schema plugin="org.eclipse.ui" id="systemSummarySections" name="System Summary Sections"/> > </appInfo> > <documentation> >- The Eclipse UI provides an AboutDialog that can be branded and reused by client product plugins. This dialog includes a SystemSummary dialog that contains configuration details. By extending the org.eclipse.ui.systemSummarySections extension point clients are able to put their own information into the log. >+ The Eclipse UI provides an AboutDialog that can be branded and reused by client product plugins. This dialog includes SystemSummary information that contains configuration details. By extending the org.eclipse.ui.systemSummarySections extension point clients are able to put their own information into the log. > </documentation> > </annotation> > > <element name="extension"> >+ <annotation> >+ <appInfo> >+ <meta.element /> >+ </appInfo> >+ </annotation> > <complexType> > <sequence> > <element ref="section" minOccurs="1" maxOccurs="unbounded"/> >#P org.eclipse.equinox.p2.ui >Index: src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/RevertProfilePage.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/p2/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/RevertProfilePage.java,v >retrieving revision 1.4 >diff -u -r1.4 RevertProfilePage.java >--- src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/RevertProfilePage.java 27 Jan 2009 19:25:02 -0000 1.4 >+++ src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/RevertProfilePage.java 17 Feb 2009 19:44:11 -0000 >@@ -35,8 +35,7 @@ > import org.eclipse.swt.layout.GridLayout; > import org.eclipse.swt.widgets.*; > import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.about.IInstallationPageContainer; >-import org.eclipse.ui.about.InstallationPage; >+import org.eclipse.ui.about.*; > import org.eclipse.ui.menus.*; > import org.eclipse.ui.services.IServiceLocator; > import org.eclipse.ui.statushandlers.StatusManager; >@@ -75,7 +74,7 @@ > factory = new AbstractContributionFactory(pageContainer.getButtonBarURI(), null) { > > public void createContributionItems(IServiceLocator serviceLocator, IContributionRoot additions) { >- additions.addContributionItem(new ActionContributionItem(revertAction), null); >+ additions.addContributionItem(new ActionContributionItem(revertAction), new ActiveInstallationPageExpression(RevertProfilePage.this)); > } > }; > menuService.addContributionFactory(factory); >@@ -179,7 +178,7 @@ > return; > boolean finish = revert(); > if (finish) { >- pageContainer.close(); >+ pageContainer.closeContainer(); > } > } > }; >Index: src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/InstalledSoftwarePage.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.equinox/p2/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/InstalledSoftwarePage.java,v >retrieving revision 1.4 >diff -u -r1.4 InstalledSoftwarePage.java >--- src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/InstalledSoftwarePage.java 7 Jan 2009 23:53:29 -0000 1.4 >+++ src/org/eclipse/equinox/internal/provisional/p2/ui/dialogs/InstalledSoftwarePage.java 17 Feb 2009 19:44:11 -0000 >@@ -30,8 +30,7 @@ > import org.eclipse.swt.layout.GridLayout; > import org.eclipse.swt.widgets.*; > import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.about.IInstallationPageContainer; >-import org.eclipse.ui.about.InstallationPage; >+import org.eclipse.ui.about.*; > import org.eclipse.ui.menus.*; > import org.eclipse.ui.services.IServiceLocator; > >@@ -98,6 +97,7 @@ > > detailsArea = new Text(group, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY | SWT.WRAP); > detailsArea.setLayoutData(gd); >+ detailsArea.setBackground(detailsArea.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); > > setControl(composite); > } >@@ -111,6 +111,7 @@ > factory = new AbstractContributionFactory(pageContainer.getButtonBarURI(), null) { > > public void createContributionItems(IServiceLocator serviceLocator, IContributionRoot additions) { >+ ActiveInstallationPageExpression whenPageActive = new ActiveInstallationPageExpression(InstalledSoftwarePage.this); > // For the update action, we create a custom selection provider that will interpret no > // selection as checking for updates to everything. > // We also override the run method to close the containing dialog >@@ -143,24 +144,24 @@ > public void run() { > super.run(); > if (getReturnCode() == Window.OK) >- pageContainer.close(); >+ pageContainer.closeContainer(); > } > }; >- additions.addContributionItem(new ActionContributionItem(action), null); >+ additions.addContributionItem(new ActionContributionItem(action), whenPageActive); > > // Uninstall action > action = new UninstallAction(Policy.getDefault(), installedIUGroup.getStructuredViewer(), profileId) { > public void run() { > super.run(); > if (getReturnCode() == Window.OK) >- pageContainer.close(); >+ pageContainer.closeContainer(); > } > }; >- additions.addContributionItem(new ActionContributionItem(action), null); >+ additions.addContributionItem(new ActionContributionItem(action), whenPageActive); > > // Properties action > action = new PropertyDialogAction(new SameShellProvider(getShell()), installedIUGroup.getStructuredViewer()); >- additions.addContributionItem(new ActionContributionItem(action), null); >+ additions.addContributionItem(new ActionContributionItem(action), whenPageActive); > } > }; > menuService.addContributionFactory(factory); >#P org.eclipse.ui.workbench >Index: Eclipse UI/org/eclipse/ui/internal/dialogs/AboutFeaturesDialog.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/AboutFeaturesDialog.java,v >retrieving revision 1.30 >diff -u -r1.30 AboutFeaturesDialog.java >--- Eclipse UI/org/eclipse/ui/internal/dialogs/AboutFeaturesDialog.java 30 Jul 2008 15:53:11 -0000 1.30 >+++ Eclipse UI/org/eclipse/ui/internal/dialogs/AboutFeaturesDialog.java 17 Feb 2009 19:44:17 -0000 >@@ -12,99 +12,22 @@ > *******************************************************************************/ > package org.eclipse.ui.internal.dialogs; > >-import java.util.HashMap; >-import java.util.Iterator; >-import java.util.Map; >- >-import org.eclipse.core.runtime.IBundleGroup; >-import org.eclipse.jface.dialogs.IDialogConstants; >-import org.eclipse.jface.dialogs.MessageDialog; >-import org.eclipse.jface.internal.ConfigureColumnsDialog; >-import org.eclipse.jface.resource.ImageDescriptor; >-import org.eclipse.jface.window.Window; > import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.SWT; >-import org.eclipse.swt.custom.StyledText; >-import org.eclipse.swt.events.DisposeEvent; >-import org.eclipse.swt.events.DisposeListener; >-import org.eclipse.swt.events.SelectionAdapter; >-import org.eclipse.swt.events.SelectionEvent; >-import org.eclipse.swt.graphics.Cursor; >-import org.eclipse.swt.graphics.Font; >-import org.eclipse.swt.graphics.Image; >-import org.eclipse.swt.layout.GridData; >-import org.eclipse.swt.layout.GridLayout; >-import org.eclipse.swt.widgets.Button; >-import org.eclipse.swt.widgets.Composite; >-import org.eclipse.swt.widgets.Control; >-import org.eclipse.swt.widgets.Label; > import org.eclipse.swt.widgets.Shell; >-import org.eclipse.swt.widgets.Table; >-import org.eclipse.swt.widgets.TableColumn; >-import org.eclipse.swt.widgets.TableItem; >-import org.eclipse.ui.PlatformUI; > import org.eclipse.ui.internal.IWorkbenchHelpContextIds; > import org.eclipse.ui.internal.WorkbenchMessages; > import org.eclipse.ui.internal.about.AboutBundleGroupData; >-import org.eclipse.ui.internal.about.AboutData; >-import org.osgi.framework.Bundle; >+import org.eclipse.ui.internal.about.AboutFeaturesPage; >+import org.eclipse.ui.internal.about.ProductInfoDialog; > > /** > * Displays information about the product plugins. >- * >- * PRIVATE >- * This class is internal to the workbench and must not be called outside >- * the workbench. >+ * >+ * PRIVATE This class is internal to the workbench and must not be called >+ * outside the workbench. > */ > public class AboutFeaturesDialog extends ProductInfoDialog { >- >- /** >- * Table height in dialog units (value 150). >- */ >- private static final int TABLE_HEIGHT = 150; >- >- private static final int INFO_HEIGHT = 100; >- >- private final static int MORE_ID = IDialogConstants.CLIENT_ID + 1; >- >- private final static int PLUGINS_ID = IDialogConstants.CLIENT_ID + 2; >- >- private final static int COLUMNS_ID = IDialogConstants.CLIENT_ID + 3; >- >- private Table table; >- >- private Label imageLabel; >- >- private StyledText text; >- >- private Composite infoArea; >- >- private Map cachedImages = new HashMap(); >- >- private String columnTitles[] = { >- WorkbenchMessages.AboutFeaturesDialog_provider, >- WorkbenchMessages.AboutFeaturesDialog_featureName, >- WorkbenchMessages.AboutFeaturesDialog_version, >- WorkbenchMessages.AboutFeaturesDialog_featureId, >- }; >- >- private String productName; >- >- private AboutBundleGroupData[] bundleGroupInfos; >- >- private int lastColumnChosen = 0; // initially sort by provider >- >- private boolean reverseSort = false; // initially sort ascending >- >- private AboutBundleGroupData lastSelection = null; >- >- private Button moreButton; >- >- private Button pluginsButton; >- >- private static Map featuresMap; >- >- /** >+ /** > * Constructor for AboutFeaturesDialog. > * > * @param parentShell the parent shell >@@ -112,426 +35,17 @@ > * @param bundleGroupInfos the bundle info > */ > public AboutFeaturesDialog(Shell parentShell, String productName, >- AboutBundleGroupData[] bundleGroupInfos) { >+ AboutBundleGroupData[] bundleGroupInfos, AboutBundleGroupData initialSelection) { > super(parentShell); >- this.productName = productName; >- >- // the order of the array may be changed due to sorting, so create a >- // copy >- this.bundleGroupInfos = new AboutBundleGroupData[bundleGroupInfos.length]; >- System.arraycopy(bundleGroupInfos, 0, this.bundleGroupInfos, 0, >- bundleGroupInfos.length); >- >- AboutData.sortByProvider(reverseSort, this.bundleGroupInfos); >- } >- >- /** >- * The More Info button was pressed. Open a browser with the license for the >- * selected item or an information dialog if there is no license, or the browser >- * cannot be opened. >- */ >- private void handleMoreInfoPressed() { >- TableItem[] items = table.getSelection(); >- if (items.length <= 0) { >- return; >- } >- >- AboutBundleGroupData info = (AboutBundleGroupData) items[0].getData(); >- if (info == null || !openBrowser(info.getLicenseUrl())) { >- MessageDialog.openInformation(getShell(), WorkbenchMessages.AboutFeaturesDialog_noInfoTitle, >- WorkbenchMessages.AboutFeaturesDialog_noInformation); >- } >- } >- >- /** >- * The Plugins button was pressed. Open an about dialog on the plugins for >- * the selected feature. >- */ >- private void handlePluginInfoPressed() { >- TableItem[] items = table.getSelection(); >- if (items.length <= 0) { >- return; >- } >- >- AboutBundleGroupData info = (AboutBundleGroupData) items[0].getData(); >- IBundleGroup bundleGroup = info.getBundleGroup(); >- Bundle[] bundles = bundleGroup == null ? new Bundle[0] : bundleGroup >- .getBundles(); >- >- AboutPluginsDialog d = new AboutPluginsDialog(getShell(), productName, >- bundles, WorkbenchMessages.AboutFeaturesDialog_pluginInfoTitle, >- NLS.bind(WorkbenchMessages.AboutFeaturesDialog_pluginInfoMessage, bundleGroup.getIdentifier()), >- IWorkbenchHelpContextIds.ABOUT_FEATURES_PLUGINS_DIALOG); >- d.open(); >- } >- >- /* >- * (non-Javadoc) Method declared on Dialog. >- */ >- protected void buttonPressed(int buttonId) { >- switch (buttonId) { >- case MORE_ID: >- handleMoreInfoPressed(); >- break; >- case PLUGINS_ID: >- handlePluginInfoPressed(); >- break; >- case COLUMNS_ID: >- handleColumnsPressed(); >- break; >- default: >- super.buttonPressed(buttonId); >- break; >- } >- } >- >- /** >- * >- */ >- private void handleColumnsPressed() { >- ConfigureColumnsDialog d = new ConfigureColumnsDialog(this, table); >- d.open(); >- } >- >- /* >- * (non-Javadoc) Method declared on Window. >- */ >- protected void configureShell(Shell newShell) { >- super.configureShell(newShell); >- if (productName != null) { >- newShell.setText(NLS.bind(WorkbenchMessages.AboutFeaturesDialog_shellTitle, productName)); >- } >- >- PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, >- IWorkbenchHelpContextIds.ABOUT_FEATURES_DIALOG); >- } >- >- /** >- * Add buttons to the dialog's button bar. >- * >- * Subclasses should override. >- * >- * @param parent >- * the button bar composite >- */ >- protected void createButtonsForButtonBar(Composite parent) { >- parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); >- >- moreButton = createButton(parent, MORE_ID, WorkbenchMessages.AboutFeaturesDialog_moreInfo, false); >- pluginsButton = createButton(parent, PLUGINS_ID, WorkbenchMessages.AboutFeaturesDialog_pluginsInfo, false); >- createButton(parent, COLUMNS_ID, WorkbenchMessages.AboutFeaturesDialog_columns, false); >- Label l = new Label(parent, SWT.NONE); >- l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); >- GridLayout layout = (GridLayout) parent.getLayout(); >- layout.numColumns++; >- layout.makeColumnsEqualWidth = false; >- >- Button b = createButton(parent, IDialogConstants.OK_ID, >- IDialogConstants.OK_LABEL, true); >- b.setFocus(); >- >- TableItem[] items = table.getSelection(); >- if (items.length > 0) { >- updateButtons((AboutBundleGroupData) items[0].getData()); >- } >- } >- >- /** >- * Create the contents of the dialog (above the button bar). >- * >- * Subclasses should overide. >- * >- * @param parent the parent composite to contain the dialog area >- * @return the dialog area control >- */ >- protected Control createDialogArea(Composite parent) { >- setHandCursor(new Cursor(parent.getDisplay(), SWT.CURSOR_HAND)); >- setBusyCursor(new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT)); >- getShell().addDisposeListener(new DisposeListener() { >- public void widgetDisposed(DisposeEvent e) { >- if (getHandCursor() != null) { >- getHandCursor().dispose(); >- } >- if (getBusyCursor() != null) { >- getBusyCursor().dispose(); >- } >- } >- }); >- >- Composite outer = (Composite) super.createDialogArea(parent); >- >- createTable(outer); >- createInfoArea(outer); >- >- return outer; >- } >- >- /** >- * Create the info area containing the image and text >- */ >- protected void createInfoArea(Composite parent) { >- Font font = parent.getFont(); >- >- infoArea = new Composite(parent, SWT.NULL); >- GridData data = new GridData(GridData.FILL, GridData.FILL, true, true); >- // need to provide space for arbitrary feature infos, not just the >- // one selected by default >- data.heightHint = convertVerticalDLUsToPixels(INFO_HEIGHT); >- infoArea.setLayoutData(data); >- >- GridLayout layout = new GridLayout(); >- layout.numColumns = 2; >- infoArea.setLayout(layout); >- >- imageLabel = new Label(infoArea, SWT.NONE); >- data = new GridData(GridData.FILL, GridData.BEGINNING, false, false); >- data.widthHint = 32; >- data.heightHint = 32; >- imageLabel.setLayoutData(data); >- imageLabel.setFont(font); >- >- // text on the right >- text = new StyledText(infoArea, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY); >- text.setCaret(null); >- text.setFont(parent.getFont()); >- data = new GridData(GridData.FILL, GridData.FILL, true, true); >- text.setLayoutData(data); >- text.setFont(font); >- text.setCursor(null); >- text.setBackground(infoArea.getBackground()); >- addListeners(text); >- >- TableItem[] items = table.getSelection(); >- if (items.length > 0) { >- updateInfoArea((AboutBundleGroupData) items[0].getData()); >- } >- } >- >- /** >- * Create the table part of the dialog. >- * >- * @param parent the parent composite to contain the dialog area >- */ >- protected void createTable(Composite parent) { >- table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE >- | SWT.FULL_SELECTION | SWT.BORDER); >- >- GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, >- true); >- gridData.heightHint = convertVerticalDLUsToPixels(TABLE_HEIGHT); >- table.setLayoutData(gridData); >- table.setHeaderVisible(true); >- >- table.setLinesVisible(true); >- table.setFont(parent.getFont()); >- table.addSelectionListener(new SelectionAdapter() { >- public void widgetSelected(SelectionEvent e) { >- AboutBundleGroupData info = (AboutBundleGroupData) e.item >- .getData(); >- updateInfoArea(info); >- updateButtons(info); >- } >- }); >- >- int[] columnWidths = { convertHorizontalDLUsToPixels(120), >- convertHorizontalDLUsToPixels(120), >- convertHorizontalDLUsToPixels(70), >- convertHorizontalDLUsToPixels(130) }; >- >- for (int i = 0; i < columnTitles.length; i++) { >- TableColumn tableColumn = new TableColumn(table, SWT.NULL); >- tableColumn.setWidth(columnWidths[i]); >- tableColumn.setText(columnTitles[i]); >- final int columnIndex = i; >- tableColumn.addSelectionListener(new SelectionAdapter() { >- public void widgetSelected(SelectionEvent e) { >- sort(columnIndex); >- } >- }); >- } >- >- // create a table row for each bundle group >- String selId = lastSelection == null ? null : lastSelection.getId(); >- int sel = 0; >- for (int i = 0; i < bundleGroupInfos.length; i++) { >- if (bundleGroupInfos[i].getId().equals(selId)) { >- sel = i; >- } >- >- TableItem item = new TableItem(table, SWT.NULL); >- item.setText(createRow(bundleGroupInfos[i])); >- item.setData(bundleGroupInfos[i]); >- } >- >- // if an item was specified during construction, it should be >- // selected when the table is created >- if (bundleGroupInfos.length > 0) { >- table.setSelection(sel); >- table.showSelection(); >- } >- } >- >- /** >- * @see Window#close() >- */ >- public boolean close() { >- boolean ret = super.close(); >- >- Iterator iter = cachedImages.values().iterator(); >- while (iter.hasNext()) { >- Image image = (Image) iter.next(); >- image.dispose(); >- } >- >- return ret; >- } >- >- /** >- * Update the button enablement >- */ >- private void updateButtons(AboutBundleGroupData info) { >- if (info == null) { >- moreButton.setEnabled(false); >- pluginsButton.setEnabled(false); >- return; >- } >- >- // Creating the feature map is too much just to determine enablement, so if >- // it doesn't already exist, just enable the buttons. If this was the wrong >- // choice, then when the button is actually pressed an dialog will be opened. >- if (featuresMap == null) { >- moreButton.setEnabled(true); >- pluginsButton.setEnabled(true); >- return; >- } >- >- moreButton.setEnabled(info.getLicenseUrl() != null); >- pluginsButton.setEnabled(true); >- } >- >- /** >- * Update the info area >- */ >- private void updateInfoArea(AboutBundleGroupData info) { >- if (info == null) { >- imageLabel.setImage(null); >- text.setText(""); //$NON-NLS-1$ >- return; >- } >- >- ImageDescriptor desc = info.getFeatureImage(); >- Image image = (Image) cachedImages.get(desc); >- if (image == null && desc != null) { >- image = desc.createImage(); >- cachedImages.put(desc, image); >- } >- imageLabel.setImage(image); >- >- String aboutText = info.getAboutText(); >- setItem(null); >- if (aboutText != null) { >- setItem(scan(aboutText)); >- } >- >- if (getItem() == null) { >- text.setText(WorkbenchMessages.AboutFeaturesDialog_noInformation); >- } else { >- text.setText(getItem().getText()); >- text.setCursor(null); >- setLinkRanges(text, getItem().getLinkRanges()); >- } >- } >- >- /** >- * Select the initial selection >- * >- * @param info the info >- */ >- public void setInitialSelection(AboutBundleGroupData info) { >- lastSelection = info; >- } >- >- /** >- * Sort the rows of the table based on the selected column. >- * >- * @param column >- * index of table column selected as sort criteria >- */ >- private void sort(int column) { >- if (lastColumnChosen == column) { >- reverseSort = !reverseSort; >- } else { >- reverseSort = false; >- lastColumnChosen = column; >- } >- >- if (table.getItemCount() <= 1) { >- return; >- } >- >- // Remember the last selection >- int sel = table.getSelectionIndex(); >- if (sel != -1) { >- lastSelection = bundleGroupInfos[sel]; >- } >- >- switch (column) { >- case 0: >- AboutData.sortByProvider(reverseSort, bundleGroupInfos); >- break; >- case 1: >- AboutData.sortByName(reverseSort, bundleGroupInfos); >- break; >- case 2: >- AboutData.sortByVersion(reverseSort, bundleGroupInfos); >- break; >- case 3: >- AboutData.sortById(reverseSort, bundleGroupInfos); >- break; >- } >- >- refreshTable(); >- } >- >- /** >- * Refresh the rows of the table based on the selected column. Maintain >- * selection from before sort action request. >- */ >- private void refreshTable() { >- TableItem[] items = table.getItems(); >- >- // create new order of table items >- for (int i = 0; i < items.length; i++) { >- items[i].setText(createRow(bundleGroupInfos[i])); >- items[i].setData(bundleGroupInfos[i]); >- } >- >- // Maintain the original selection >- int sel = -1; >- if (lastSelection != null) { >- String oldId = lastSelection.getId(); >- for (int k = 0; k < bundleGroupInfos.length; k++) { >- if (oldId.equalsIgnoreCase(bundleGroupInfos[k].getId())) { >- sel = k; >- } >- } >- >- table.setSelection(sel); >- table.showSelection(); >- } >- >- updateInfoArea(lastSelection); >- } >- >- /** >- * Return an array of strings containing the argument's information in the >- * proper order for this table's columns. >- * >- * @param info >- * the source information for the new row, must not be null >- */ >- private static String[] createRow(AboutBundleGroupData info) { >- return new String[] { info.getProviderName(), info.getName(), >- info.getVersion(), info.getId() }; >+ AboutFeaturesPage page = new AboutFeaturesPage(); >+ page.setProductName(productName); >+ page.setBundleGroupInfos(bundleGroupInfos); >+ page.setInitialSelection(initialSelection); >+ String title; >+ if (productName != null) >+ title = NLS.bind(WorkbenchMessages.AboutFeaturesDialog_shellTitle, productName); >+ else >+ title = WorkbenchMessages.AboutFeaturesDialog_SimpleTitle; >+ initializeDialog(page, title, IWorkbenchHelpContextIds.ABOUT_FEATURES_DIALOG); > } > } >Index: Eclipse UI/org/eclipse/ui/internal/dialogs/AboutDialog.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/AboutDialog.java,v >retrieving revision 1.31 >diff -u -r1.31 AboutDialog.java >--- Eclipse UI/org/eclipse/ui/internal/dialogs/AboutDialog.java 17 Nov 2008 18:57:22 -0000 1.31 >+++ Eclipse UI/org/eclipse/ui/internal/dialogs/AboutDialog.java 17 Feb 2009 19:44:17 -0000 >@@ -19,6 +19,7 @@ > import org.eclipse.core.runtime.Platform; > import org.eclipse.jface.action.MenuManager; > import org.eclipse.jface.dialogs.IDialogConstants; >+import org.eclipse.jface.dialogs.TrayDialog; > import org.eclipse.jface.resource.ImageDescriptor; > import org.eclipse.jface.resource.JFaceColors; > import org.eclipse.osgi.util.NLS; >@@ -35,7 +36,6 @@ > import org.eclipse.swt.events.SelectionAdapter; > import org.eclipse.swt.events.SelectionEvent; > import org.eclipse.swt.graphics.Color; >-import org.eclipse.swt.graphics.Cursor; > import org.eclipse.swt.graphics.GC; > import org.eclipse.swt.graphics.Image; > import org.eclipse.swt.graphics.Point; >@@ -47,26 +47,26 @@ > import org.eclipse.swt.widgets.Control; > import org.eclipse.swt.widgets.Label; > import org.eclipse.swt.widgets.Shell; >+import org.eclipse.ui.IWorkbenchWindow; > import org.eclipse.ui.PlatformUI; > import org.eclipse.ui.internal.IWorkbenchHelpContextIds; > import org.eclipse.ui.internal.ProductProperties; > import org.eclipse.ui.internal.WorkbenchMessages; > import org.eclipse.ui.internal.about.AboutBundleGroupData; > import org.eclipse.ui.internal.about.AboutFeaturesButtonManager; >+import org.eclipse.ui.internal.about.AboutItem; >+import org.eclipse.ui.internal.about.AboutTextManager; >+import org.eclipse.ui.internal.about.InstallationDialog; > import org.eclipse.ui.menus.CommandContributionItem; > import org.eclipse.ui.menus.CommandContributionItemParameter; > > /** > * Displays information about the product. > */ >-public class AboutDialog extends ProductInfoDialog { >+public class AboutDialog extends TrayDialog { > private final static int MAX_IMAGE_WIDTH_FOR_TEXT = 250; > >- private final static int FEATURES_ID = IDialogConstants.CLIENT_ID + 1; >- >- private final static int PLUGINS_ID = IDialogConstants.CLIENT_ID + 2; >- >- private final static int INFO_ID = IDialogConstants.CLIENT_ID + 3; >+ private final static int DETAILS_ID = IDialogConstants.CLIENT_ID + 1; > > private String productName; > >@@ -78,9 +78,9 @@ > > private AboutFeaturesButtonManager buttonManager = new AboutFeaturesButtonManager(); > >- // TODO should the styled text be disposed? if not then it likely >- // doesn't need to be a member > private StyledText text; >+ >+ private AboutTextManager aboutTextManager; > > /** > * Create an instance of the AboutDialog for the given window. >@@ -117,25 +117,12 @@ > */ > protected void buttonPressed(int buttonId) { > switch (buttonId) { >- case FEATURES_ID: >+ case DETAILS_ID: > BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { > public void run() { >- new AboutFeaturesDialog(getShell(), productName, bundleGroupInfos) >- .open(); >- } >- }); >- break; >- case PLUGINS_ID: >- BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { >- public void run() { >- new AboutPluginsDialog(getShell(), productName).open(); >- } >- }); >- break; >- case INFO_ID: >- BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { >- public void run() { >- new AboutSystemDialog(getShell()).open(); >+ IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); >+ InstallationDialog dialog = new InstallationDialog(getShell(), workbenchWindow); >+ dialog.open(); > } > }); > break; >@@ -176,14 +163,7 @@ > protected void createButtonsForButtonBar(Composite parent) { > parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); > >- // bug 64232: the feature details button should only be created if there >- // are features to show >- if (bundleGroupInfos != null && bundleGroupInfos.length > 0) { >- createButton(parent, FEATURES_ID, WorkbenchMessages.AboutDialog_featureInfo, false); >- } >- >- createButton(parent, PLUGINS_ID, WorkbenchMessages.AboutDialog_pluginInfo, false); >- createButton(parent, INFO_ID, WorkbenchMessages.AboutDialog_systemInfo, false); >+ createButton(parent, DETAILS_ID, WorkbenchMessages.AboutDialog_DetailsButton, false); > > Label l = new Label(parent, SWT.NONE); > l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); >@@ -206,21 +186,9 @@ > * @return the dialog area control > */ > protected Control createDialogArea(Composite parent) { >- final Cursor hand = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND); >- final Cursor busy = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT); >- setHandCursor(hand); >- setBusyCursor(busy); >- getShell().addDisposeListener(new DisposeListener() { >- public void widgetDisposed(DisposeEvent e) { >- setHandCursor(null); >- hand.dispose(); >- setBusyCursor(null); >- busy.dispose(); >- } >- }); >- >- // brand the about box if there is product info >+ // brand the about box if there is product info > Image aboutImage = null; >+ AboutItem item = null; > if (product != null) { > ImageDescriptor imageDescriptor = ProductProperties > .getAboutImage(product); >@@ -233,7 +201,7 @@ > || aboutImage.getBounds().width <= MAX_IMAGE_WIDTH_FOR_TEXT) { > String aboutText = ProductProperties.getAboutText(product); > if (aboutText != null) { >- setItem(scan(aboutText)); >+ item = AboutTextManager.scan(aboutText); > } > } > >@@ -276,7 +244,7 @@ > topContainer.setForeground(foreground); > > layout = new GridLayout(); >- layout.numColumns = (aboutImage == null || getItem() == null ? 1 : 2); >+ layout.numColumns = (aboutImage == null || item == null ? 1 : 2); > layout.marginWidth = 0; > layout.marginHeight = 0; > layout.verticalSpacing = 0; >@@ -318,7 +286,7 @@ > data.heightHint = topContainerHeightHint; > topContainer.setLayoutData(data); > >- if (getItem() != null) { >+ if (item != null) { > final int minWidth = 400; // This value should really be calculated > // from the computeSize(SWT.DEFAULT, > // SWT.DEFAULT) of all the >@@ -340,12 +308,13 @@ > text = new StyledText(textComposite, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY); > text.setCaret(null); > text.setFont(parent.getFont()); >- text.setText(getItem().getText()); >+ text.setText(item.getText()); > text.setCursor(null); > text.setBackground(background); > text.setForeground(foreground); >- setLinkRanges(text, getItem().getLinkRanges()); >- addListeners(text); >+ >+ aboutTextManager = new AboutTextManager(text); >+ aboutTextManager.setItem(item); > > createTextMenu(); > >@@ -487,8 +456,7 @@ > .getData(); > > AboutFeaturesDialog d = new AboutFeaturesDialog(getShell(), >- productName, groupInfos); >- d.setInitialSelection(selection); >+ productName, groupInfos, selection); > d.open(); > } > }); >Index: Eclipse UI/org/eclipse/ui/internal/dialogs/BundleSigningTray.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/dialogs/BundleSigningTray.java >diff -N Eclipse UI/org/eclipse/ui/internal/dialogs/BundleSigningTray.java >--- Eclipse UI/org/eclipse/ui/internal/dialogs/BundleSigningTray.java 24 Mar 2008 19:21:57 -0000 1.4 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,301 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2007, 2008 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >- >-package org.eclipse.ui.internal.dialogs; >- >-import java.io.IOException; >-import java.security.GeneralSecurityException; >-import java.security.cert.Certificate; >-import java.security.cert.X509Certificate; >-import java.text.DateFormat; >-import java.util.ArrayList; >-import java.util.Date; >-import java.util.Iterator; >-import java.util.List; >-import java.util.Map; >-import java.util.Properties; >-import java.util.StringTokenizer; >-import java.util.Map.Entry; >- >-import org.eclipse.core.runtime.IProgressMonitor; >-import org.eclipse.core.runtime.IStatus; >-import org.eclipse.core.runtime.OperationCanceledException; >-import org.eclipse.core.runtime.Status; >-import org.eclipse.core.runtime.jobs.Job; >-import org.eclipse.jface.dialogs.Dialog; >-import org.eclipse.jface.dialogs.DialogTray; >-import org.eclipse.jface.dialogs.TrayDialog; >-import org.eclipse.jface.resource.JFaceResources; >-import org.eclipse.osgi.signedcontent.SignedContent; >-import org.eclipse.osgi.signedcontent.SignedContentFactory; >-import org.eclipse.osgi.signedcontent.SignerInfo; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.SWT; >-import org.eclipse.swt.custom.StyledText; >-import org.eclipse.swt.graphics.Color; >-import org.eclipse.swt.graphics.GC; >-import org.eclipse.swt.graphics.Point; >-import org.eclipse.swt.layout.GridData; >-import org.eclipse.swt.layout.GridLayout; >-import org.eclipse.swt.widgets.Composite; >-import org.eclipse.swt.widgets.Control; >-import org.eclipse.swt.widgets.Display; >-import org.eclipse.swt.widgets.Label; >-import org.eclipse.swt.widgets.Shell; >-import org.eclipse.swt.widgets.Text; >-import org.eclipse.ui.internal.WorkbenchMessages; >-import org.eclipse.ui.internal.WorkbenchPlugin; >-import org.eclipse.ui.internal.about.AboutBundleData; >-import org.eclipse.ui.statushandlers.StatusManager; >-import org.osgi.framework.BundleContext; >-import org.osgi.framework.ServiceReference; >- >-/** >- * @since 3.3 >- * >- */ >-public class BundleSigningTray extends DialogTray { >- >- >- private Text date; >- private StyledText certificate; >- private AboutBundleData data; >- private TrayDialog dialog; >- >- /** >- * >- */ >- public BundleSigningTray(TrayDialog dialog) { >- this.dialog = dialog; >- } >- >- public void setData(AboutBundleData data) { >- this.data = data; >- startJobs(); >- } >- >- /* (non-Javadoc) >- * @see org.eclipse.jface.dialogs.DialogTray#createContents(org.eclipse.swt.widgets.Composite) >- */ >- protected Control createContents(Composite parent) { >- Composite content = new Composite(parent, SWT.NONE); >- content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); >- GridLayout layout = new GridLayout(2, false); >- content.setLayout(layout); >- // date >- Color backgroundColor = parent.getDisplay().getSystemColor( >- SWT.COLOR_WIDGET_BACKGROUND); >- { >- Label label = new Label(content, SWT.NONE); >- label.setText(WorkbenchMessages.BundleSigningTray_Signing_Date); >- GridData data = new GridData(SWT.FILL, SWT.BEGINNING, true, false); >- date = new Text(content, SWT.READ_ONLY); >- GC gc = new GC(date); >- gc.setFont(JFaceResources.getDialogFont()); >- Point size = gc.stringExtent(DateFormat.getDateTimeInstance().format(new Date())); >- data.widthHint = size.x; >- gc.dispose(); >- date.setText(WorkbenchMessages.BundleSigningTray_Working); >- date.setLayoutData(data); >- date.setBackground(backgroundColor); >- } >- // signer >- { >- Label label = new Label(content, SWT.NONE); >- label.setText(WorkbenchMessages.BundleSigningTray_Signing_Certificate); >- GridData data = new GridData(SWT.BEGINNING, SWT.BEGINNING, true, false); >- data.horizontalSpan = 2; >- data = new GridData(SWT.FILL, SWT.FILL, true, true); >- data.horizontalSpan = 2; >- certificate = new StyledText(content, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP); >- certificate.setText(WorkbenchMessages.BundleSigningTray_Working); >- certificate.setLayoutData(data); >- } >- >- // problems >-// { >-// Label label = new Label(content, SWT.NONE); >-// label.setText("Problems:"); //$NON-NLS-1$ >-// >-// } >- Dialog.applyDialogFont(content); >- >- startJobs(); // start the jobs that will prime the content >- >- return content; >- } >- >- /** >- * >- */ >- private void startJobs() { >- if (!isOpen()) >- return; >- certificate.setText(WorkbenchMessages.BundleSigningTray_Working); >- date.setText(WorkbenchMessages.BundleSigningTray_Working); >- final BundleContext bundleContext = WorkbenchPlugin.getDefault() >- .getBundleContext(); >- final ServiceReference factoryRef = bundleContext >- .getServiceReference(SignedContentFactory.class.getName()); >- if (factoryRef == null) { >- StatusManager.getManager().handle( >- new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH, >- WorkbenchMessages.BundleSigningTray_Cant_Find_Service), >- StatusManager.LOG); >- return; >- } >- >- final SignedContentFactory contentFactory = (SignedContentFactory) bundleContext >- .getService(factoryRef); >- if (contentFactory == null) { >- StatusManager.getManager().handle( >- new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH, >- WorkbenchMessages.BundleSigningTray_Cant_Find_Service), >- StatusManager.LOG); >- return; >- } >- >- final AboutBundleData myData = data; >- final Job signerJob = new Job(NLS.bind(WorkbenchMessages.BundleSigningTray_Determine_Signer_For, myData.getId())) { >- >- protected IStatus run(IProgressMonitor monitor) { >- try { >- if (myData != data) >- return Status.OK_STATUS; >- SignedContent signedContent = contentFactory.getSignedContent(myData >- .getBundle()); >- if (myData != data) >- return Status.OK_STATUS; >- SignerInfo[] signers = signedContent.getSignerInfos(); >- final String signerText, dateText; >- final Shell dialogShell = dialog.getShell(); >- if (!isOpen() && BundleSigningTray.this.data == myData) >- return Status.OK_STATUS; >- >- if (signers.length == 0) { >- signerText = WorkbenchMessages.BundleSigningTray_Unsigned; >- dateText = WorkbenchMessages.BundleSigningTray_Unsigned; >- } else { >- Properties [] certs = parseCerts(signers[0].getCertificateChain()); >- if (certs.length == 0) >- signerText = WorkbenchMessages.BundleSigningTray_Unknown; >- else { >- StringBuffer buffer = new StringBuffer(); >- for (Iterator i = certs[0].entrySet().iterator(); i.hasNext(); ) { >- Map.Entry entry = (Entry) i.next(); >- buffer.append(entry.getKey()); >- buffer.append('='); >- buffer.append(entry.getValue()); >- if (i.hasNext()) >- buffer.append('\n'); >- } >- signerText = buffer.toString(); >- } >- >- Date signDate = signedContent.getSigningTime(signers[0]); >- if (signDate != null) >- dateText = DateFormat.getDateTimeInstance().format( >- signDate); >- else >- dateText = WorkbenchMessages.BundleSigningTray_Unknown; >- } >- >- Display display = dialogShell.getDisplay(); >- display.asyncExec(new Runnable() { >- >- public void run() { >- // check to see if the tray is still visible and if we're still looking at the same item >- if (!isOpen() && BundleSigningTray.this.data != myData) >- return; >- certificate.setText(signerText); >- date.setText(dateText); >- } >- }); >- >- } catch (IOException e) { >- return new Status(IStatus.ERROR, >- WorkbenchPlugin.PI_WORKBENCH, e.getMessage(), e); >- } catch (GeneralSecurityException e) { >- return new Status(IStatus.ERROR, >- WorkbenchPlugin.PI_WORKBENCH, e.getMessage(), e); >- } >- return Status.OK_STATUS; >- } >- }; >- signerJob.setSystem(true); >- signerJob.belongsTo(signerJob); >- signerJob.schedule(); >- >- Job cleanup = new Job(WorkbenchMessages.BundleSigningTray_Unget_Signing_Service) { >- >- protected IStatus run(IProgressMonitor monitor) { >- try { >- getJobManager().join(signerJob, monitor); >- } catch (OperationCanceledException e) { >- } catch (InterruptedException e) { >- } >- bundleContext.ungetService(factoryRef); >- return Status.OK_STATUS; >- } >- }; >- cleanup.setSystem(true); >- cleanup.schedule(); >- >- } >- >- /** >- * >- */ >- private boolean isOpen() { >- return certificate != null && !certificate.isDisposed(); >- } >- >- private Properties[] parseCerts(Certificate[] chain) { >- List certs = new ArrayList(chain.length); >- for (int i = 0; i < chain.length; i++) { >- if (!(chain[i] instanceof X509Certificate)) >- continue; >- Map cert = parseCert(((X509Certificate) chain[i]).getSubjectDN().getName()); >- if (cert != null) >- certs.add(cert); >- } >- return (Properties []) certs.toArray(new Properties[certs.size()]); >- >- >- } >- >- /** >- * @param certString >- * @return >- */ >- private Properties parseCert(String certString) { >- StringTokenizer toker = new StringTokenizer(certString, ","); //$NON-NLS-1$ >- Properties cert = new Properties(); >- while (toker.hasMoreTokens()) { >- String pair = toker.nextToken(); >- int idx = pair.indexOf('='); >- if (idx > 0 && idx < pair.length() - 2) { >- String key = pair.substring(0, idx).trim(); >- String value = pair.substring(idx + 1).trim(); >- if (value.length() > 2) { >- if (value.charAt(0) == '\"') >- value = value.substring(1); >- >- if (value.charAt(value.length() - 1) == '\"') >- value = value.substring(0, value.length() - 1); >- } >- cert.setProperty(key, value); >- } >- } >- return cert; >- } >- >-} >Index: Eclipse UI/org/eclipse/ui/internal/dialogs/ProductInfoDialog.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/dialogs/ProductInfoDialog.java >diff -N Eclipse UI/org/eclipse/ui/internal/dialogs/ProductInfoDialog.java >--- Eclipse UI/org/eclipse/ui/internal/dialogs/ProductInfoDialog.java 2 Jul 2007 22:56:24 -0000 1.28 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,478 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2007 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.ui.internal.dialogs; >- >-import java.io.IOException; >-import java.net.MalformedURLException; >-import java.net.URL; >-import java.util.ArrayList; >-import java.util.StringTokenizer; >- >-import org.eclipse.core.runtime.IStatus; >-import org.eclipse.core.runtime.Platform; >-import org.eclipse.jface.dialogs.TrayDialog; >-import org.eclipse.jface.resource.JFaceColors; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.SWT; >-import org.eclipse.swt.custom.StyleRange; >-import org.eclipse.swt.custom.StyledText; >-import org.eclipse.swt.events.KeyAdapter; >-import org.eclipse.swt.events.KeyEvent; >-import org.eclipse.swt.events.MouseAdapter; >-import org.eclipse.swt.events.MouseEvent; >-import org.eclipse.swt.events.MouseMoveListener; >-import org.eclipse.swt.events.TraverseEvent; >-import org.eclipse.swt.events.TraverseListener; >-import org.eclipse.swt.graphics.Color; >-import org.eclipse.swt.graphics.Cursor; >-import org.eclipse.swt.graphics.Point; >-import org.eclipse.swt.widgets.Shell; >-import org.eclipse.ui.PartInitException; >-import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.browser.IWebBrowser; >-import org.eclipse.ui.browser.IWorkbenchBrowserSupport; >-import org.eclipse.ui.internal.WorkbenchMessages; >-import org.eclipse.ui.internal.WorkbenchPlugin; >-import org.eclipse.ui.internal.about.AboutItem; >-import org.eclipse.ui.internal.misc.StatusUtil; >-import org.eclipse.ui.statushandlers.StatusManager; >- >-/** >- * Abstract superclass of about dialogs >- */ >- >-public abstract class ProductInfoDialog extends TrayDialog { >- >- private AboutItem item; >- >- private Cursor handCursor; >- >- private Cursor busyCursor; >- >- private boolean mouseDown = false; >- >- private boolean dragEvent = false; >- >- /** >- * Create an instance of this Dialog >- */ >- public ProductInfoDialog(Shell parentShell) { >- super(parentShell); >- } >- >- /** >- * Adds listeners to the given styled text >- */ >- protected void addListeners(StyledText styledText) { >- styledText.addMouseListener(new MouseAdapter() { >- public void mouseDown(MouseEvent e) { >- if (e.button != 1) { >- return; >- } >- mouseDown = true; >- } >- >- public void mouseUp(MouseEvent e) { >- mouseDown = false; >- StyledText text = (StyledText) e.widget; >- int offset = text.getCaretOffset(); >- if (dragEvent) { >- // don't activate a link during a drag/mouse up operation >- dragEvent = false; >- if (item != null && item.isLinkAt(offset)) { >- text.setCursor(handCursor); >- } >- } else if (item != null && item.isLinkAt(offset)) { >- text.setCursor(busyCursor); >- openLink(item.getLinkAt(offset)); >- StyleRange selectionRange = getCurrentRange(text); >- text.setSelectionRange(selectionRange.start, >- selectionRange.length); >- text.setCursor(null); >- } >- } >- }); >- >- styledText.addMouseMoveListener(new MouseMoveListener() { >- public void mouseMove(MouseEvent e) { >- // Do not change cursor on drag events >- if (mouseDown) { >- if (!dragEvent) { >- StyledText text = (StyledText) e.widget; >- text.setCursor(null); >- } >- dragEvent = true; >- return; >- } >- StyledText text = (StyledText) e.widget; >- int offset = -1; >- try { >- offset = text.getOffsetAtLocation(new Point(e.x, e.y)); >- } catch (IllegalArgumentException ex) { >- // leave value as -1 >- } >- if (offset == -1) { >- text.setCursor(null); >- } else if (item != null && item.isLinkAt(offset)) { >- text.setCursor(handCursor); >- } else { >- text.setCursor(null); >- } >- } >- }); >- >- styledText.addTraverseListener(new TraverseListener() { >- public void keyTraversed(TraverseEvent e) { >- StyledText text = (StyledText) e.widget; >- switch (e.detail) { >- case SWT.TRAVERSE_ESCAPE: >- e.doit = true; >- break; >- case SWT.TRAVERSE_TAB_NEXT: >- //Previously traverse out in the backward direction? >- Point nextSelection = text.getSelection(); >- int charCount = text.getCharCount(); >- if ((nextSelection.x == charCount) >- && (nextSelection.y == charCount)) { >- text.setSelection(0); >- } >- StyleRange nextRange = findNextRange(text); >- if (nextRange == null) { >- // Next time in start at beginning, also used by >- // TRAVERSE_TAB_PREVIOUS to indicate we traversed out >- // in the forward direction >- text.setSelection(0); >- e.doit = true; >- } else { >- text.setSelectionRange(nextRange.start, >- nextRange.length); >- e.doit = true; >- e.detail = SWT.TRAVERSE_NONE; >- } >- break; >- case SWT.TRAVERSE_TAB_PREVIOUS: >- //Previously traverse out in the forward direction? >- Point previousSelection = text.getSelection(); >- if ((previousSelection.x == 0) >- && (previousSelection.y == 0)) { >- text.setSelection(text.getCharCount()); >- } >- StyleRange previousRange = findPreviousRange(text); >- if (previousRange == null) { >- // Next time in start at the end, also used by >- // TRAVERSE_TAB_NEXT to indicate we traversed out >- // in the backward direction >- text.setSelection(text.getCharCount()); >- e.doit = true; >- } else { >- text.setSelectionRange(previousRange.start, >- previousRange.length); >- e.doit = true; >- e.detail = SWT.TRAVERSE_NONE; >- } >- break; >- default: >- break; >- } >- } >- }); >- >- //Listen for Tab and Space to allow keyboard navigation >- styledText.addKeyListener(new KeyAdapter() { >- public void keyPressed(KeyEvent event) { >- StyledText text = (StyledText) event.widget; >- if (event.character == ' ' || event.character == SWT.CR) { >- if (item != null) { >- //Be sure we are in the selection >- int offset = text.getSelection().x + 1; >- >- if (item.isLinkAt(offset)) { >- text.setCursor(busyCursor); >- openLink(item.getLinkAt(offset)); >- StyleRange selectionRange = getCurrentRange(text); >- text.setSelectionRange(selectionRange.start, >- selectionRange.length); >- text.setCursor(null); >- } >- } >- return; >- } >- } >- }); >- } >- >- /** >- * Gets the busy cursor. >- * @return the busy cursor >- */ >- protected Cursor getBusyCursor() { >- return busyCursor; >- } >- >- /** >- * Sets the busy cursor. >- * @param busyCursor the busy cursor >- */ >- protected void setBusyCursor(Cursor busyCursor) { >- this.busyCursor = busyCursor; >- } >- >- /** >- * Gets the hand cursor. >- * @return Returns a hand cursor >- */ >- protected Cursor getHandCursor() { >- return handCursor; >- } >- >- /** >- * Sets the hand cursor. >- * @param handCursor The hand cursor to set >- */ >- protected void setHandCursor(Cursor handCursor) { >- this.handCursor = handCursor; >- } >- >- /** >- * Gets the about item. >- * @return the about item >- */ >- protected AboutItem getItem() { >- return item; >- } >- >- /** >- * Sets the about item. >- * @param item about item >- */ >- protected void setItem(AboutItem item) { >- this.item = item; >- } >- >- /** >- * Find the range of the current selection. >- */ >- protected StyleRange getCurrentRange(StyledText text) { >- StyleRange[] ranges = text.getStyleRanges(); >- int currentSelectionEnd = text.getSelection().y; >- int currentSelectionStart = text.getSelection().x; >- >- for (int i = 0; i < ranges.length; i++) { >- if ((currentSelectionStart >= ranges[i].start) >- && (currentSelectionEnd <= (ranges[i].start + ranges[i].length))) { >- return ranges[i]; >- } >- } >- return null; >- } >- >- /** >- * Find the next range after the current >- * selection. >- */ >- protected StyleRange findNextRange(StyledText text) { >- StyleRange[] ranges = text.getStyleRanges(); >- int currentSelectionEnd = text.getSelection().y; >- >- for (int i = 0; i < ranges.length; i++) { >- if (ranges[i].start >= currentSelectionEnd) { >- return ranges[i]; >- } >- } >- return null; >- } >- >- /** >- * Find the previous range before the current selection. >- */ >- protected StyleRange findPreviousRange(StyledText text) { >- StyleRange[] ranges = text.getStyleRanges(); >- int currentSelectionStart = text.getSelection().x; >- >- for (int i = ranges.length - 1; i > -1; i--) { >- if ((ranges[i].start + ranges[i].length - 1) < currentSelectionStart) { >- return ranges[i]; >- } >- } >- return null; >- } >- >- /** >- * display an error message >- */ >- private void openWebBrowserError(final String href, final Throwable t) { >- String title = WorkbenchMessages.ProductInfoDialog_errorTitle; >- String msg = NLS.bind( >- WorkbenchMessages.ProductInfoDialog_unableToOpenWebBrowser, >- href); >- IStatus status = WorkbenchPlugin.getStatus(t); >- StatusUtil.handleStatus(status, title + ": " + msg, StatusManager.SHOW, //$NON-NLS-1$ >- getShell()); >- } >- >- /** >- * Open a link >- */ >- protected void openLink(String href) { >- // format the href for an html file (file:///<filename.html> >- // required for Mac only. >- if (href.startsWith("file:")) { //$NON-NLS-1$ >- href = href.substring(5); >- while (href.startsWith("/")) { //$NON-NLS-1$ >- href = href.substring(1); >- } >- href = "file:///" + href; //$NON-NLS-1$ >- } >- IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport(); >- try { >- IWebBrowser browser = support.getExternalBrowser(); >- browser.openURL(new URL(urlEncodeForSpaces(href.toCharArray()))); >- } >- catch (MalformedURLException e) { >- openWebBrowserError(href, e); >- } >- catch (PartInitException e) { >- openWebBrowserError(href, e); >- } >- } >- >- /** >- * This method encodes the url, removes the spaces from the url and replaces >- * the same with <code>"%20"</code>. This method is required to fix Bug >- * 77840. >- * >- * @since 3.0.2 >- */ >- private String urlEncodeForSpaces(char[] input) { >- StringBuffer retu = new StringBuffer(input.length); >- for (int i = 0; i < input.length; i++) { >- if (input[i] == ' ') { >- retu.append("%20"); //$NON-NLS-1$ >- } else { >- retu.append(input[i]); >- } >- } >- return retu.toString(); >- } >- >- /** >- * Open a browser with the argument title on the argument url. If the url refers to a >- * resource within a bundle, then a temp copy of the file will be extracted and opened. >- * @see <code>Platform.asLocalUrl</code> >- * @param url The target url to be displayed, null will be safely ignored >- * @return true if the url was successfully displayed and false otherwise >- */ >- protected boolean openBrowser(URL url) { >- if (url != null) { >- try { >- url = Platform.asLocalURL(url); >- } catch (IOException e) { >- return false; >- } >- } >- if (url == null) { >- return false; >- } >- openLink(url.toString()); >- return true; >- } >- >- /** >- * Sets the styled text's bold ranges >- */ >- protected void setBoldRanges(StyledText styledText, int[][] boldRanges) { >- for (int i = 0; i < boldRanges.length; i++) { >- StyleRange r = new StyleRange(boldRanges[i][0], boldRanges[i][1], >- null, null, SWT.BOLD); >- styledText.setStyleRange(r); >- } >- } >- >- /** >- * Sets the styled text's link (blue) ranges >- */ >- protected void setLinkRanges(StyledText styledText, int[][] linkRanges) { >- Color fg = JFaceColors.getHyperlinkText(styledText.getShell() >- .getDisplay()); >- for (int i = 0; i < linkRanges.length; i++) { >- StyleRange r = new StyleRange(linkRanges[i][0], linkRanges[i][1], >- fg, null); >- styledText.setStyleRange(r); >- } >- } >- >- /** >- * Scan the contents of the about text >- */ >- protected AboutItem scan(String s) { >- ArrayList linkRanges = new ArrayList(); >- ArrayList links = new ArrayList(); >- >- // slightly modified version of jface url detection >- // see org.eclipse.jface.text.hyperlink.URLHyperlinkDetector >- >- int urlSeparatorOffset= s.indexOf("://"); //$NON-NLS-1$ >- while(urlSeparatorOffset >= 0) { >- >- boolean startDoubleQuote= false; >- >- // URL protocol (left to "://") >- int urlOffset= urlSeparatorOffset; >- char ch; >- do { >- urlOffset--; >- ch= ' '; >- if (urlOffset > -1) >- ch= s.charAt(urlOffset); >- startDoubleQuote= ch == '"'; >- } while (Character.isUnicodeIdentifierStart(ch)); >- urlOffset++; >- >- >- // Right to "://" >- StringTokenizer tokenizer= new StringTokenizer(s.substring(urlSeparatorOffset + 3), " \t\n\r\f<>", false); //$NON-NLS-1$ >- if (!tokenizer.hasMoreTokens()) >- return null; >- >- int urlLength= tokenizer.nextToken().length() + 3 + urlSeparatorOffset - urlOffset; >- >- if (startDoubleQuote) { >- int endOffset= -1; >- int nextDoubleQuote= s.indexOf('"', urlOffset); >- int nextWhitespace= s.indexOf(' ', urlOffset); >- if (nextDoubleQuote != -1 && nextWhitespace != -1) >- endOffset= Math.min(nextDoubleQuote, nextWhitespace); >- else if (nextDoubleQuote != -1) >- endOffset= nextDoubleQuote; >- else if (nextWhitespace != -1) >- endOffset= nextWhitespace; >- if (endOffset != -1) >- urlLength= endOffset - urlOffset; >- } >- >- linkRanges.add(new int[] { urlOffset, urlLength }); >- links.add(s.substring(urlOffset, urlOffset+urlLength)); >- >- urlSeparatorOffset= s.indexOf("://", urlOffset+urlLength+1); //$NON-NLS-1$ >- } >- return new AboutItem(s, (int[][]) linkRanges.toArray(new int[linkRanges >- .size()][2]), (String[]) links >- .toArray(new String[links.size()])); >- } >- >- /* >- * (non-Javadoc) >- * @see org.eclipse.jface.dialogs.Dialog#isResizable() >- */ >- protected boolean isResizable() { >- return true; >- } >-} >Index: Eclipse UI/org/eclipse/ui/internal/dialogs/AboutPluginsDialog.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/AboutPluginsDialog.java,v >retrieving revision 1.40 >diff -u -r1.40 AboutPluginsDialog.java >--- Eclipse UI/org/eclipse/ui/internal/dialogs/AboutPluginsDialog.java 14 Aug 2008 14:21:27 -0000 1.40 >+++ Eclipse UI/org/eclipse/ui/internal/dialogs/AboutPluginsDialog.java 17 Feb 2009 19:44:17 -0000 >@@ -12,661 +12,28 @@ > *******************************************************************************/ > package org.eclipse.ui.internal.dialogs; > >-import java.io.IOException; >-import java.net.URL; >-import java.util.ArrayList; >-import java.util.HashMap; >-import java.util.LinkedList; >-import java.util.List; >-import java.util.Map; >- >-import org.eclipse.core.runtime.IPath; >-import org.eclipse.core.runtime.IProgressMonitor; >-import org.eclipse.core.runtime.IStatus; >-import org.eclipse.core.runtime.Path; >-import org.eclipse.core.runtime.Platform; >-import org.eclipse.core.runtime.Status; >-import org.eclipse.core.runtime.jobs.Job; >-import org.eclipse.jface.dialogs.DialogTray; >-import org.eclipse.jface.dialogs.IDialogConstants; >-import org.eclipse.jface.internal.ConfigureColumnsDialog; >-import org.eclipse.jface.viewers.ArrayContentProvider; >-import org.eclipse.jface.viewers.IBaseLabelProvider; >-import org.eclipse.jface.viewers.ISelectionChangedListener; >-import org.eclipse.jface.viewers.IStructuredSelection; >-import org.eclipse.jface.viewers.ITableLabelProvider; >-import org.eclipse.jface.viewers.LabelProvider; >-import org.eclipse.jface.viewers.LabelProviderChangedEvent; >-import org.eclipse.jface.viewers.SelectionChangedEvent; >-import org.eclipse.jface.viewers.TableViewer; >-import org.eclipse.jface.viewers.Viewer; >-import org.eclipse.jface.viewers.ViewerComparator; > import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.SWT; >-import org.eclipse.swt.events.SelectionAdapter; >-import org.eclipse.swt.events.SelectionEvent; >-import org.eclipse.swt.graphics.Image; >-import org.eclipse.swt.layout.GridData; >-import org.eclipse.swt.layout.GridLayout; >-import org.eclipse.swt.widgets.Button; >-import org.eclipse.swt.widgets.Composite; >-import org.eclipse.swt.widgets.Control; >-import org.eclipse.swt.widgets.Label; > import org.eclipse.swt.widgets.Shell; >-import org.eclipse.swt.widgets.TableColumn; >-import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.internal.IWorkbenchGraphicConstants; >-import org.eclipse.ui.internal.IWorkbenchHelpContextIds; >-import org.eclipse.ui.internal.WorkbenchImages; > import org.eclipse.ui.internal.WorkbenchMessages; >-import org.eclipse.ui.internal.WorkbenchPlugin; >-import org.eclipse.ui.internal.about.AboutBundleData; >-import org.eclipse.ui.internal.misc.StatusUtil; >-import org.eclipse.ui.internal.util.BundleUtility; >-import org.eclipse.ui.progress.WorkbenchJob; >-import org.eclipse.ui.statushandlers.StatusManager; >+import org.eclipse.ui.internal.about.AboutPluginsPage; > import org.osgi.framework.Bundle; >+import org.eclipse.ui.internal.about.ProductInfoDialog; > > /** > * Displays information about the product plugins. >- * >- * PRIVATE >- * this class is internal to the ide >+ * >+ * PRIVATE this class is internal to the ide > */ > public class AboutPluginsDialog extends ProductInfoDialog { >- >- public class BundleTableLabelProvider extends LabelProvider implements ITableLabelProvider { >- >- /** >- * Queue containing bundle signing info to be resolved. >- */ >- private LinkedList resolveQueue = new LinkedList(); >- >- /** >- * Queue containing bundle data that's been resolve and needs updating. >- */ >- private List updateQueue = new ArrayList(); >- >- /* >- * this job will attempt to discover the signing state of a given bundle >- * and then send it along to the update job >- */ >- private Job resolveJob= new Job(AboutPluginsDialog.class.getName()) { >- { >- setSystem(true); >- setPriority(Job.SHORT); >- } >- >- protected IStatus run(IProgressMonitor monitor) { >- while (true) { >- Shell dialogShell = getShell(); >- // the shell has gone down since we were asked to render >- if (dialogShell == null || dialogShell.isDisposed()) >- return Status.OK_STATUS; >- AboutBundleData data = null; >- synchronized (resolveQueue) { >- if (resolveQueue.isEmpty()) >- return Status.OK_STATUS; >- data = (AboutBundleData) resolveQueue.removeFirst(); >- } >- try { >- // following is an expensive call >- data.isSigned(); >- >- synchronized (updateQueue) { >- updateQueue.add(data); >- } >- // start the update job >- updateJob.schedule(); >- } catch (IllegalStateException e) { >- // the bundle we're testing has been unloaded. Do nothing. >- } >- } >- } >- }; >- >- /* >- * this job is responsible for feeding label change events into the >- * viewer as they become available from the resolve job >- */ >- private Job updateJob= new WorkbenchJob(getShell().getDisplay(), AboutPluginsDialog.class.getName()) { >- { >- setSystem(true); >- setPriority(Job.DECORATE); >- } >- >- /* (non-Javadoc) >- * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) >- */ >- public IStatus runInUIThread(IProgressMonitor monitor) { >- while (true) { >- Shell dialogShell = getShell(); >- // the shell has gone down since we were asked to render >- if (dialogShell == null || dialogShell.isDisposed()) >- return Status.OK_STATUS; >- AboutBundleData[] data = null; >- synchronized (updateQueue) { >- if (updateQueue.isEmpty()) >- return Status.OK_STATUS; >- >- data = (AboutBundleData[]) updateQueue >- .toArray(new AboutBundleData[updateQueue.size()]); >- updateQueue.clear(); >- >- } >- fireLabelProviderChanged(new LabelProviderChangedEvent( >- BundleTableLabelProvider.this, data)); >- } >- } >- }; >- >- /* (non-Javadoc) >- * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int) >- */ >- public Image getColumnImage(Object element, int columnIndex) { >- if (columnIndex == 0) { >- if (element instanceof AboutBundleData) { >- final AboutBundleData data = (AboutBundleData) element; >- if (data.isSignedDetermined()) { >- return WorkbenchImages >- .getImage(data.isSigned() ? IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_YES >- : IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_NO); >- } >- >- synchronized (resolveQueue) { >- resolveQueue.add(data); >- } >- resolveJob.schedule(); >- >- return WorkbenchImages >- .getImage(IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_UNKNOWN); >- } >- } >- return null; >- } >- >- /* (non-Javadoc) >- * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) >- */ >- public String getColumnText(Object element, int columnIndex) { >- if (element instanceof AboutBundleData) { >- AboutBundleData data = (AboutBundleData) element; >- switch (columnIndex) { >- case 1: >- return data.getProviderName(); >- case 2: >- return data.getName(); >- case 3: >- return data.getVersion(); >- case 4: >- return data.getId(); >- } >- } >- return ""; //$NON-NLS-1$ >- } >- } >- >- /** >- * Table height in dialog units (value 200). >- */ >- private static final int TABLE_HEIGHT = 200; >- >- private static final IPath baseNLPath = new Path("$nl$"); //$NON-NLS-1$ >- >- private static final String PLUGININFO = "about.html"; //$NON-NLS-1$ >- >- private final static int MORE_ID = IDialogConstants.CLIENT_ID + 1; >- private final static int SIGNING_ID = MORE_ID + 1; >- private final static int COLUMNS_ID = MORE_ID + 2; >- >- private static final int PLUGIN_NAME_COLUMN_INDEX = 2; >- >- private TableViewer vendorInfo; >- >- private Button moreInfo, signingInfo; >- >- private String title; >- >- private String message; >- >- private String helpContextId; >- >- private String columnTitles[] = { >- WorkbenchMessages.AboutPluginsDialog_signed, >- WorkbenchMessages.AboutPluginsDialog_provider, >- WorkbenchMessages.AboutPluginsDialog_pluginName, >- WorkbenchMessages.AboutPluginsDialog_version, >- WorkbenchMessages.AboutPluginsDialog_pluginId, >- >- }; >- >- private String productName; >- >- private AboutBundleData[] bundleInfos; >- >- /** >- * Constructor for AboutPluginsDialog. >- * >- * @param parentShell the parent shell >- * @param productName the product name >- */ >- public AboutPluginsDialog(Shell parentShell, String productName) { >- this(parentShell, productName, WorkbenchPlugin.getDefault() >- .getBundles(), null, null, IWorkbenchHelpContextIds.ABOUT_PLUGINS_DIALOG); >- WorkbenchPlugin.class.getSigners(); >- } >- >- /** >- * Constructor for AboutPluginsDialog. >- * >- * @param parentShell >- * the parent shell >- * @param productName >- * must not be null >- * @param bundles >- * must not be null >- * @param title >- * the title >- * @param message >- * the message >- * @param helpContextId >- * the help context id >- */ > public AboutPluginsDialog(Shell parentShell, String productName, > Bundle[] bundles, String title, String message, String helpContextId) { >- super(parentShell); >- this.title = title; >- this.message = message; >- this.helpContextId = helpContextId; >- this.productName = productName; >- >- // create a data object for each bundle, remove duplicates, and include only resolved bundles (bug 65548) >- Map map = new HashMap(); >- for (int i = 0; i < bundles.length; ++i) { >- AboutBundleData data = new AboutBundleData(bundles[i]); >- if (BundleUtility.isReady(data.getState()) && !map.containsKey(data.getVersionedId())) { >- map.put(data.getVersionedId(), data); >- } >- } >- bundleInfos = (AboutBundleData[]) map.values().toArray( >- new AboutBundleData[0]); >- } >- >- /* >- * (non-Javadoc) Method declared on Dialog. >- */ >- protected void buttonPressed(int buttonId) { >- switch (buttonId) { >- case MORE_ID: >- handleMoreInfoPressed(); >- break; >- case SIGNING_ID: >- handleSigningInfoPressed(); >- break; >- case COLUMNS_ID: >- handleColumnsPressed(); >- break; >- default: >- super.buttonPressed(buttonId); >- break; >- } >- } >- >- /** >- * >- */ >- private void handleColumnsPressed() { >- ConfigureColumnsDialog d = new ConfigureColumnsDialog(this, vendorInfo.getTable()); >- d.open(); >- } >- >- /** >- */ >- private void handleSigningInfoPressed() { >- DialogTray existingTray = getTray(); >- if (existingTray instanceof BundleSigningTray) { >- // hide >- getButton(SIGNING_ID).setText(WorkbenchMessages.AboutPluginsDialog_signingInfo_show); >- closeTray(); >- } >- else { >- //show >- getButton(SIGNING_ID).setText(WorkbenchMessages.AboutPluginsDialog_signingInfo_hide); >- if (existingTray != null) >- closeTray(); >- AboutBundleData bundleInfo = (AboutBundleData) ((IStructuredSelection) vendorInfo >- .getSelection()).getFirstElement(); >- BundleSigningTray tray = new BundleSigningTray(this); >- tray.setData(bundleInfo); >- openTray(tray); >- } >- >- } >- >- /* >- * (non-Javadoc) Method declared on Window. >- */ >- protected void configureShell(Shell newShell) { >- super.configureShell(newShell); >- >- //signImage = new Image( this.getParentShell().getDisplay(), AboutPluginsDialog.class.getResourceAsStream("Signed.gif")); //$NON-NLS-1$ >- >- if (title == null && productName != null) { >- title = NLS.bind(WorkbenchMessages.AboutPluginsDialog_shellTitle, productName); >- } >- >- if (title != null) { >- newShell.setText(title); >- } >- >- PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, >- helpContextId); >- } >- >- /** >- * Add buttons to the dialog's button bar. >- * >- * Subclasses should override. >- * >- * @param parent >- * the button bar composite >- */ >- protected void createButtonsForButtonBar(Composite parent) { >- parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); >- >- moreInfo = createButton(parent, MORE_ID, WorkbenchMessages.AboutPluginsDialog_moreInfo, false); >- moreInfo.setEnabled(false); >- >- signingInfo = createButton(parent, SIGNING_ID, WorkbenchMessages.AboutPluginsDialog_signingInfo_show, false); >- signingInfo.setEnabled(false); >- >- createButton(parent, COLUMNS_ID, WorkbenchMessages.AboutPluginsDialog_columns, false); >- >- Label l = new Label(parent, SWT.NONE); >- l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); >- GridLayout layout = (GridLayout) parent.getLayout(); >- layout.numColumns++; >- layout.makeColumnsEqualWidth = false; >- >- createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, >- true); >- } >- >- /** >- * Create the contents of the dialog (above the button bar). >- * >- * Subclasses should overide. >- * >- * @param parent >- * the parent composite to contain the dialog area >- * @return the dialog area control >- */ >- protected Control createDialogArea(Composite parent) { >- Composite outer = (Composite) super.createDialogArea(parent); >- >- if (message != null) { >- Label label = new Label(outer, SWT.NONE); >- label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); >- label.setFont(parent.getFont()); >- label.setText(message); >- } >- >- createTable(outer); >- >- return outer; >- } >- >- /** >- * Create the table part of the dialog. >- * >- * @param parent >- * the parent composite to contain the dialog area >- */ >- protected void createTable(Composite parent) { >- vendorInfo = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE >- | SWT.FULL_SELECTION | SWT.BORDER); >- vendorInfo.setUseHashlookup(true); >- vendorInfo.getTable().setHeaderVisible(true); >- vendorInfo.getTable().setLinesVisible(true); >- vendorInfo.getTable().setFont(parent.getFont()); >- vendorInfo.addSelectionChangedListener(new ISelectionChangedListener() { >- >- public void selectionChanged(SelectionChangedEvent event) { >- // enable if there is an item selected and that >- // item has additional info >- IStructuredSelection selection = (IStructuredSelection) event.getSelection(); >- if (selection.getFirstElement() instanceof AboutBundleData) { >- AboutBundleData selected = (AboutBundleData) selection.getFirstElement(); >- moreInfo.setEnabled(selectionHasInfo(selected)); >- signingInfo.setEnabled(true); >- if (getTray() instanceof BundleSigningTray) { >- ((BundleSigningTray)getTray()).setData(selected); >- } >- } >- else { >- moreInfo.setEnabled(false); >- signingInfo.setEnabled(false); >- } >- }}); >- >- final TableComparator comparator = new TableComparator(); >- vendorInfo.setComparator(comparator); >- int[] columnWidths = { >- convertHorizontalDLUsToPixels(30), //signature >- convertHorizontalDLUsToPixels(120), >- convertHorizontalDLUsToPixels(120), >- convertHorizontalDLUsToPixels(70), >- convertHorizontalDLUsToPixels(130), >- }; >- >- >- // create table headers >- for (int i = 0; i < columnTitles.length; i++) { >- TableColumn column = new TableColumn(vendorInfo.getTable(), SWT.NULL); >- if (i == PLUGIN_NAME_COLUMN_INDEX) { // prime initial sorting >- updateTableSorting(i); >- } >- column.setWidth(columnWidths[i]); >- column.setText(columnTitles[i]); >- final int columnIndex = i; >- column.addSelectionListener(new SelectionAdapter() { >- public void widgetSelected(SelectionEvent e) { >- updateTableSorting(columnIndex); >- } >- }); >- } >- >- vendorInfo.setContentProvider(new ArrayContentProvider()); >- vendorInfo.setLabelProvider(new BundleTableLabelProvider()); >- >- GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, >- true); >- gridData.heightHint = convertVerticalDLUsToPixels(TABLE_HEIGHT); >- vendorInfo.getTable().setLayoutData(gridData); >- >- vendorInfo.setInput(bundleInfos); >- } >- >- /** >- * Update the sort information on both the comparator and the table. >- * >- * @param columnIndex >- * the index to sort by >- * @since 3.4 >- */ >- private void updateTableSorting(final int columnIndex) { >- TableComparator comparator = (TableComparator) vendorInfo >- .getComparator(); >- // toggle direction if it's the same column >- if (columnIndex == comparator.getSortColumn()) { >- comparator.setAscending(!comparator.isAscending()); >- } >- comparator.setSortColumn(columnIndex); >- vendorInfo.getTable().setSortColumn( >- vendorInfo.getTable().getColumn(columnIndex)); >- vendorInfo.getTable().setSortDirection( >- comparator.isAscending() ? SWT.UP : SWT.DOWN); >- vendorInfo.refresh(false); >- } >- >- /** >- * Check if the currently selected plugin has additional information to >- * show. >- * @param bundleInfo >- * >- * @return true if the selected plugin has additional info available to >- * display >- */ >- private boolean selectionHasInfo(AboutBundleData bundleInfo) { >- >- URL infoURL = getMoreInfoURL(bundleInfo, false); >- >- // only report ini problems if the -debug command line argument is used >- if (infoURL == null && WorkbenchPlugin.DEBUG) { >- WorkbenchPlugin.log("Problem reading plugin info for: " //$NON-NLS-1$ >- + bundleInfo.getName()); >- } >- >- return infoURL != null; >- } >- >- /** >- * The More Info button was pressed. Open a browser showing the license information >- * for the selected bundle or an error dialog if the browser cannot be opened. >- */ >- protected void handleMoreInfoPressed() { >- if (vendorInfo == null) { >- return; >- } >- >- if (vendorInfo.getSelection().isEmpty()) >- return; >- >- AboutBundleData bundleInfo = (AboutBundleData) ((IStructuredSelection) vendorInfo >- .getSelection()).getFirstElement(); >- >- if (!openBrowser(getMoreInfoURL(bundleInfo, true))) { >- String message = NLS.bind( >- WorkbenchMessages.AboutPluginsDialog_unableToOpenFile, >- PLUGININFO, bundleInfo.getId()); >- StatusUtil.handleStatus( >- WorkbenchMessages.AboutPluginsDialog_errorTitle >- + ": " + message, StatusManager.SHOW, getShell()); //$NON-NLS-1$ >- } >- } >- >- /** >- * Return an url to the plugin's about.html file (what is shown when "More info" is >- * pressed) or null if no such file exists. The method does nl lookup to allow for >- * i18n. >- * >- * @param bundleInfo the bundle info >- * @param makeLocal whether to make the about content local >- * @return the url or <code>null</code> >- */ >- private URL getMoreInfoURL(AboutBundleData bundleInfo, boolean makeLocal) { >- Bundle bundle = Platform.getBundle(bundleInfo.getId()); >- if (bundle == null) { >- return null; >- } >- >- URL aboutUrl = Platform.find(bundle, baseNLPath.append(PLUGININFO), null); >- if (!makeLocal) { >- return aboutUrl; >- } >- if (aboutUrl != null) { >- try { >- URL result = Platform.asLocalURL(aboutUrl); >- try { >- // Make local all content in the "about" directory. >- // This is needed to handle jar'ed plug-ins. >- // See Bug 88240 [About] About dialog needs to extract subdirs. >- URL about = new URL(aboutUrl, "about_files"); //$NON-NLS-1$ >- if (about != null) { >- Platform.asLocalURL(about); >- } >- } catch (IOException e) { >- // skip the about dir if its not found or there are other problems. >- } >- return result; >- } catch(IOException e) { >- // do nothing >- } >- } >- return null; >- } >-} >- >- >-class TableComparator extends ViewerComparator { >- >- private int sortColumn = 0; >- private boolean ascending = true; >- >- /* (non-Javadoc) >- * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) >- */ >- public int compare(Viewer viewer, Object e1, Object e2) { >- if (sortColumn == 0 && e1 instanceof AboutBundleData && e2 instanceof AboutBundleData) { >- AboutBundleData d1= (AboutBundleData) e1; >- AboutBundleData d2= (AboutBundleData) e2; >- int diff= getSignedSortValue(d1) - getSignedSortValue(d2); >- return ascending ? diff : -diff; >- } >- if (viewer instanceof TableViewer) { >- TableViewer tableViewer = (TableViewer) viewer; >- IBaseLabelProvider baseLabel = tableViewer.getLabelProvider(); >- if (baseLabel instanceof ITableLabelProvider) { >- ITableLabelProvider tableProvider = (ITableLabelProvider) baseLabel; >- String e1p = tableProvider.getColumnText(e1, sortColumn); >- String e2p = tableProvider.getColumnText(e2, sortColumn); >- int result = getComparator().compare(e1p, e2p); >- return ascending ? result : (-1) * result; >- } >- } >- >- return super.compare(viewer, e1, e2); >- } >- >- /** >- * @param data >- * @return a sort value depending on the signed state >- */ >- private int getSignedSortValue(AboutBundleData data) { >- if (! data.isSignedDetermined()) { >- return 0; >- } else if (data.isSigned()) { >- return 1; >- } else { >- return -1; >- } >- } >- >- /** >- * @return Returns the sortColumn. >- */ >- public int getSortColumn() { >- return sortColumn; >- } >- >- /** >- * @param sortColumn The sortColumn to set. >- */ >- public void setSortColumn(int sortColumn) { >- this.sortColumn = sortColumn; >- } >- >- /** >- * @return Returns the ascending. >- */ >- public boolean isAscending() { >- return ascending; >- } >- >- /** >- * @param ascending The ascending to set. >- */ >- public void setAscending(boolean ascending) { >- this.ascending = ascending; >+ super(parentShell); >+ AboutPluginsPage page = new AboutPluginsPage(); >+ page.setHelpContextId(helpContextId); >+ page.setBundles(bundles); >+ page.setMessage(message); >+ if (title == null && page.getProductName() != null) >+ title = NLS.bind(WorkbenchMessages.AboutPluginsDialog_shellTitle, productName); >+ initializeDialog(page, title, helpContextId); > } > } >Index: Eclipse UI/org/eclipse/ui/internal/dialogs/AboutSystemDialog.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/dialogs/AboutSystemDialog.java >diff -N Eclipse UI/org/eclipse/ui/internal/dialogs/AboutSystemDialog.java >--- Eclipse UI/org/eclipse/ui/internal/dialogs/AboutSystemDialog.java 24 Mar 2008 19:21:56 -0000 1.26 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,229 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2003, 2008 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.ui.internal.dialogs; >- >-import java.io.File; >-import java.io.FileNotFoundException; >-import java.io.FileReader; >-import java.io.FileWriter; >-import java.io.IOException; >- >-import org.eclipse.core.runtime.IPath; >-import org.eclipse.core.runtime.Platform; >-import org.eclipse.jface.dialogs.IDialogConstants; >-import org.eclipse.jface.dialogs.MessageDialog; >-import org.eclipse.jface.resource.JFaceResources; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.SWT; >-import org.eclipse.swt.dnd.Clipboard; >-import org.eclipse.swt.dnd.TextTransfer; >-import org.eclipse.swt.dnd.Transfer; >-import org.eclipse.swt.layout.GridData; >-import org.eclipse.swt.layout.GridLayout; >-import org.eclipse.swt.widgets.Button; >-import org.eclipse.swt.widgets.Composite; >-import org.eclipse.swt.widgets.Control; >-import org.eclipse.swt.widgets.Label; >-import org.eclipse.swt.widgets.Shell; >-import org.eclipse.swt.widgets.Text; >-import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.internal.ConfigurationInfo; >-import org.eclipse.ui.internal.IWorkbenchHelpContextIds; >-import org.eclipse.ui.internal.WorkbenchMessages; >-import org.eclipse.ui.internal.WorkbenchPlugin; >- >- >-/** >- * Displays system information about the eclipse application. The content of >- * what is displayed is selectable through the >- * <code>org.eclipse.ui.systemSummaryExtensions</code> extension point. >- */ >-public final class AboutSystemDialog extends ProductInfoDialog { >- >- private Text text; >- >- private final static int BROWSE_ERROR_LOG_BUTTON = IDialogConstants.CLIENT_ID; >- >- private final static int COPY_TO_CLIPBOARD_BUTTON = IDialogConstants.CLIENT_ID + 1; >- >- private final static String ERROR_LOG_COPY_FILENAME = "log"; //$NON-NLS-1$ >- >- /** >- * Create an instance of this dialog. >- * >- * @param parentShell the parent shell >- */ >- public AboutSystemDialog(Shell parentShell) { >- super(parentShell); >- } >- >- /* (non-Javadoc) >- * Method declared on Window. >- */ >- protected void configureShell(Shell newShell) { >- super.configureShell(newShell); >- newShell.setText(WorkbenchMessages.SystemSummary_title); >- PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, >- IWorkbenchHelpContextIds.SYSTEM_SUMMARY_DIALOG); >- } >- >- /* (non-Javadoc) >- * Method declared on Dialog. >- */ >- protected void createButtonsForButtonBar(Composite parent) { >- parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); >- >- Button button = createButton(parent, BROWSE_ERROR_LOG_BUTTON, WorkbenchMessages.AboutSystemDialog_browseErrorLogName, false); >- String filename = Platform.getLogFileLocation().toOSString(); >- button.setEnabled(new File(filename).exists()); >- >- createButton(parent, COPY_TO_CLIPBOARD_BUTTON, WorkbenchMessages.AboutSystemDialog_copyToClipboardName, false); >- >- new Label(parent, SWT.NONE).setLayoutData(new GridData( >- GridData.FILL_HORIZONTAL)); >- GridLayout layout = (GridLayout) parent.getLayout(); >- layout.numColumns++; >- layout.makeColumnsEqualWidth = false; >- >- createButton(parent, IDialogConstants.CLOSE_ID, >- IDialogConstants.CLOSE_LABEL, true); >- } >- >- /* (non-Javadoc) >- * Method declared on Dialog. >- */ >- protected Control createDialogArea(Composite parent) { >- Composite outer = (Composite) super.createDialogArea(parent); >- >- text = new Text(outer, SWT.MULTI | SWT.BORDER | SWT.READ_ONLY >- | SWT.V_SCROLL | SWT.NO_FOCUS | SWT.H_SCROLL); >- text.setBackground(parent.getDisplay().getSystemColor( >- SWT.COLOR_LIST_BACKGROUND)); >- GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL >- | GridData.VERTICAL_ALIGN_FILL); >- gridData.grabExcessVerticalSpace = true; >- gridData.grabExcessHorizontalSpace = true; >- gridData.heightHint = convertVerticalDLUsToPixels(300); >- gridData.widthHint = convertHorizontalDLUsToPixels(400); >- text.setLayoutData(gridData); >- text.setText(ConfigurationInfo.getSystemSummary()); >- text.setFont(JFaceResources.getTextFont()); >- return outer; >- } >- >- /* (non-Javadoc) >- * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int) >- */ >- protected void buttonPressed(int buttonId) { >- switch (buttonId) { >- case IDialogConstants.CLOSE_ID: >- close(); >- break; >- case BROWSE_ERROR_LOG_BUTTON: >- openErrorLogBrowser(); >- break; >- case COPY_TO_CLIPBOARD_BUTTON: >- runCopyToClipboard(); >- break; >- } >- super.buttonPressed(buttonId); >- } >- >- private void openErrorLogBrowser() { >- String filename = Platform.getLogFileLocation().toOSString(); >- >- File log = new File(filename); >- if (log.exists()) { >- // Make a copy of the file with a temporary name. >- // Working around an issue with windows file associations/browser malfunction >- // whereby the browser doesn't open on ".log" and we aren't returned an error. >- // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97783 >- File logCopy = makeDisplayCopy(log); >- if (logCopy != null) { >- openLink("file:///" + logCopy.getAbsolutePath()); //$NON-NLS-1$ >- return; >- } >- // Couldn't make copy, try to open the original log. >- // We try the original in this case rather than putting up an error, >- // because the copy could fail due to an I/O or out of space problem. >- // In that case we may still be able to show the original log, >- // depending on the platform. The risk is that users with configurations >- // that have bug #97783 will still get nothing (vs. an error) but we'd rather >- // try again than put up an error dialog on platforms where the ability to >- // view the original log works just fine. >- openLink("file:///" + filename); //$NON-NLS-1$ >- return; >- } >- MessageDialog.openInformation(getShell(), WorkbenchMessages.AboutSystemDialog_noLogTitle, >- NLS.bind(WorkbenchMessages.AboutSystemDialog_noLogMessage, filename )); >- } >- >- /** >- * Returns a copy of the given file to be used for display in >- * a browser. >- * >- * @return the file, or <code>null</code> >- */ >- private File makeDisplayCopy(File file) { >- IPath path = WorkbenchPlugin.getDefault().getDataLocation(); >- if(path == null) { >- return null; >- } >- path = path.append(ERROR_LOG_COPY_FILENAME); >- File copy = path.toFile(); >- FileReader in = null; >- FileWriter out = null; >- try { >- in = new FileReader(file); >- // don't append data, overwrite what was there >- out = new FileWriter(copy); >- char buffer[] = new char[4096]; >- int count; >- while ((count = in.read(buffer, 0, buffer.length)) > 0) { >- out.write(buffer, 0, count); >- } >- } catch (FileNotFoundException e) { >- return null; >- } catch (IOException e) { >- return null; >- } finally { >- try { >- if (in != null) { >- in.close(); >- } >- if (out != null) { >- out.close(); >- } >- } catch (IOException e) { >- return null; >- } >- } >- return copy; >- >- } >- >- private void runCopyToClipboard() { >- if (text == null) { >- return; >- } >- >- Clipboard clipboard = null; >- try { >- clipboard = new Clipboard(getShell().getDisplay()); >- clipboard.setContents(new Object[] { text.getText() }, >- new Transfer[] { TextTransfer.getInstance() }); >- } finally { >- if (clipboard != null) { >- clipboard.dispose(); >- } >- } >- } >-} >Index: Eclipse UI/org/eclipse/ui/internal/about/InstallationDialog.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/about/InstallationDialog.java,v >retrieving revision 1.4 >diff -u -r1.4 InstallationDialog.java >--- Eclipse UI/org/eclipse/ui/internal/about/InstallationDialog.java 22 Oct 2008 14:40:10 -0000 1.4 >+++ Eclipse UI/org/eclipse/ui/internal/about/InstallationDialog.java 17 Feb 2009 19:44:16 -0000 >@@ -11,25 +11,23 @@ > > package org.eclipse.ui.internal.about; > >+import org.eclipse.core.expressions.Expression; > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IConfigurationElement; > import org.eclipse.core.runtime.IExtensionPoint; >+import org.eclipse.core.runtime.IProduct; > import org.eclipse.core.runtime.Platform; > import org.eclipse.jface.action.ContributionManager; > import org.eclipse.jface.action.IContributionItem; >-import org.eclipse.jface.action.ToolBarManager; > import org.eclipse.jface.dialogs.Dialog; > import org.eclipse.jface.dialogs.IDialogConstants; >-import org.eclipse.jface.resource.ColorRegistry; >-import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.jface.dialogs.IDialogSettings; >+import org.eclipse.osgi.util.NLS; > import org.eclipse.swt.SWT; >-import org.eclipse.swt.custom.CTabFolder; >-import org.eclipse.swt.custom.CTabItem; > import org.eclipse.swt.events.DisposeEvent; > import org.eclipse.swt.events.DisposeListener; > import org.eclipse.swt.events.SelectionAdapter; > import org.eclipse.swt.events.SelectionEvent; >-import org.eclipse.swt.graphics.Color; > import org.eclipse.swt.graphics.FontMetrics; > import org.eclipse.swt.graphics.GC; > import org.eclipse.swt.graphics.Point; >@@ -39,39 +37,107 @@ > import org.eclipse.swt.widgets.Control; > import org.eclipse.swt.widgets.Label; > import org.eclipse.swt.widgets.Shell; >-import org.eclipse.swt.widgets.ToolBar; >-import org.eclipse.ui.IWorkbenchPreferenceConstants; >-import org.eclipse.ui.PlatformUI; >+import org.eclipse.swt.widgets.TabFolder; >+import org.eclipse.swt.widgets.TabItem; >+import org.eclipse.ui.about.ActiveInstallationPageExpression; > import org.eclipse.ui.about.IInstallationPageContainer; > import org.eclipse.ui.about.InstallationPage; >-import org.eclipse.ui.internal.IWorkbenchThemeConstants; >-import org.eclipse.ui.internal.menus.InternalMenuService; >-import org.eclipse.ui.internal.menus.SlaveMenuService; >+import org.eclipse.ui.internal.ConfigurationInfo; >+import org.eclipse.ui.internal.WorkbenchMessages; >+import org.eclipse.ui.internal.WorkbenchPlugin; > import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; >+import org.eclipse.ui.internal.services.IServiceLocatorCreator; > import org.eclipse.ui.menus.IMenuService; >+import org.eclipse.ui.services.AbstractServiceFactory; >+import org.eclipse.ui.services.IDisposable; > import org.eclipse.ui.services.IServiceLocator; >+import org.eclipse.ui.services.ISourceProviderService; > > /** > * @since 3.5 > * > */ >-public class InstallationDialog extends Dialog { >- private static final String ID = "ID"; //$NON-NLS-1$ >+public class InstallationDialog extends Dialog implements >+ IInstallationPageContainer { >+ class ButtonManager extends ContributionManager { > >- private CTabFolder folder; >+ private Composite composite; >+ >+ public ButtonManager(Composite composite) { >+ this.composite = composite; >+ } >+ >+ public Composite getParent() { >+ return composite; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.jface.action.IContributionManager#update(boolean) >+ */ >+ public void update(boolean force) { >+ if (composite == null || composite.isDisposed()) >+ return; >+ GC metricsGC = new GC(composite); >+ FontMetrics metrics = metricsGC.getFontMetrics(); >+ metricsGC.dispose(); >+ IContributionItem[] items = getItems(); >+ Control[] children = composite.getChildren(); >+ >+ int visibleChildren = 0; >+ for (int i = 0; i < children.length; i++) { >+ Control control = children[i]; >+ control.dispose(); >+ } >+ >+ for (int i = 0; i < items.length; i++) { >+ IContributionItem item = items[i]; >+ if (item.isVisible()) { >+ item.fill(composite); >+ children = composite.getChildren(); >+ Control itemControl = children[children.length - 1]; >+ setButtonLayoutData(metrics, itemControl); >+ visibleChildren++; >+ } >+ } >+ GridLayout compositeLayout = (GridLayout) composite.getLayout(); >+ compositeLayout.numColumns = visibleChildren; >+ composite.layout(true); >+ } >+ >+ protected void setButtonLayoutData(FontMetrics metrics, Control button) { >+ GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); >+ int widthHint = Dialog.convertHorizontalDLUsToPixels(metrics, >+ IDialogConstants.BUTTON_WIDTH); >+ Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); >+ data.widthHint = Math.max(widthHint, minSize.x); >+ button.setLayoutData(data); >+ } >+ >+ } >+ >+ protected static final String ID = "ID"; //$NON-NLS-1$ >+ private static final String DIALOG_SETTINGS_SECTION = "InstallationDialogSettings"; //$NON-NLS-1$ >+ private static final String URI = "toolbar:org.eclipse.ui.installationDialog.buttonbar"; //$NON-NLS-1$ >+ private TabFolder folder; > private IServiceLocator serviceLocator; >- private ToolBarManager toolbarManager; > private ButtonManager buttonManager; >- private IMenuService menuService = null; >+ private InstallationDialogSourceProvider sourceProvider = null; > > /** > * @param parentShell >+ * @param locator > */ >- protected InstallationDialog(Shell parentShell, IServiceLocator locator) { >+ public InstallationDialog(Shell parentShell, IServiceLocator locator) { > super(parentShell); >- this.serviceLocator = locator; >- menuService = new SlaveMenuService((InternalMenuService) serviceLocator >- .getService(IMenuService.class), serviceLocator, null); >+ IServiceLocatorCreator slc = (IServiceLocatorCreator) locator >+ .getService(IServiceLocatorCreator.class); >+ createDialogServiceLocator(slc, locator); >+ ISourceProviderService sps = (ISourceProviderService) serviceLocator >+ .getService(ISourceProviderService.class); >+ sourceProvider = (InstallationDialogSourceProvider) sps >+ .getSourceProvider(InstallationDialogSourceProvider.ACTIVE_PRODUCT_DIALOG_PAGE); > > } > >@@ -84,18 +150,17 @@ > */ > protected void configureShell(Shell newShell) { > super.configureShell(newShell); >- // TODO >- // This should use the title of the about dialog, this >- // is a temporary hack so that p2 can launch the dialog >- // with a proper title until this is actually hooked into >- // the about dialog. >- newShell.setText("Installation Information"); //$NON-NLS-1$ >- newShell.setSize(600, 768); >- >+ String productName = ""; //$NON-NLS-1$ >+ IProduct product = Platform.getProduct(); >+ if (product != null && product.getName() != null) >+ productName = product.getName(); >+ newShell.setText(NLS.bind( >+ WorkbenchMessages.InstallationDialog_ShellTitle, productName)); > } >- >+ > /* > * (non-Javadoc) >+ * > * @see org.eclipse.jface.dialogs.Dialog#isResizable() > */ > protected boolean isResizable() { >@@ -112,103 +177,115 @@ > protected Control createDialogArea(Composite parent) { > Composite composite = (Composite) super.createDialogArea(parent); > >- createToolbar(composite); >- >- folder = new CTabFolder(composite, SWT.MULTI | SWT.BORDER); >+ folder = new TabFolder(composite, SWT.NONE); > configureFolder(); >+ createFolderItems(folder); >+ > GridData folderData = new GridData(SWT.FILL, SWT.FILL, true, true); > folderData.widthHint = SWT.DEFAULT; > folderData.heightHint = SWT.DEFAULT; > folder.setLayoutData(folderData); >+ folder.addSelectionListener(createFolderSelectionListener()); >+ folder.addDisposeListener(new DisposeListener() { >+ public void widgetDisposed(DisposeEvent e) { >+ releaseContributions(); >+ resetVariables(sourceProvider); >+ } >+ }); >+ return composite; >+ } > >- IConfigurationElement[] elements = loadElements(); >+ protected void createFolderItems(TabFolder folder) { >+ IConfigurationElement[] elements = ConfigurationInfo >+ .getSortedExtensions(loadElements()); > for (int i = 0; i < elements.length; i++) { > IConfigurationElement element = elements[i]; >- CTabItem item = new CTabItem(folder, SWT.NONE); >+ TabItem item = new TabItem(folder, SWT.NONE); > item.setText(element > .getAttribute(IWorkbenchRegistryConstants.ATT_NAME)); > item.setData(element); > Composite control = new Composite(folder, SWT.BORDER); > control.setLayout(new GridLayout()); > item.setControl(control); >- > } >- folder.addSelectionListener(createFolderSelectionListener()); >- return composite; >+ } >+ >+ protected Control createContents(Composite parent) { >+ Control control = super.createContents(parent); >+ if (folder.getItemCount() > 0) >+ tabSelected(folder.getItem(0)); >+ return control; > } > > private SelectionAdapter createFolderSelectionListener() { > return new SelectionAdapter() { > > public void widgetSelected(SelectionEvent e) { >- final CTabItem item = (CTabItem) e.item; >- String id = null; >- if (item.getData() instanceof IConfigurationElement) { >- final IConfigurationElement element = (IConfigurationElement) item >- .getData(); >- >- id = element >- .getAttribute(IWorkbenchRegistryConstants.ATT_ID); >- item.setData(ID, id); >- >- Composite pageComposite = (Composite) item.getControl(); >- try { >- final InstallationPage page = (InstallationPage) element >- .createExecutableExtension(IWorkbenchRegistryConstants.ATT_CLASS); >- page.createControl(pageComposite); >- page.init(createDialogServiceLocator(item)); >- item.setData(page); >- item.addDisposeListener(new DisposeListener() { >- >- public void widgetDisposed(DisposeEvent e) { >- page.dispose(); >- } >- }); >- pageComposite.layout(true, true); >- >- } catch (CoreException e1) { >- Label label = new Label(pageComposite, SWT.NONE); >- label.setText(e1.getMessage()); >- item.setData(null); >- } >- >- >- } else { >- id = (String) item.getData(ID); >- } >- >- menuService.releaseContributions(toolbarManager); >- menuService.populateContributionManager(toolbarManager, >- InstallationDialog.this.getToolbarURI(id)); >- toolbarManager.update(true); >- >- menuService.releaseContributions(buttonManager); >- menuService.populateContributionManager(buttonManager, >- InstallationDialog.this.getButtonBarURI(id)); >- buttonManager.update(true); >- createButton(buttonManager.getParent(), IDialogConstants.OK_ID, >- IDialogConstants.OK_LABEL, true); >- // Layout the button manager again now that the OK button is there. >- // Must do this before we layout the button bar or else the button >- // manager will not know about the OK button >- buttonManager.getParent().layout(); >- // Now we layout the button bar itself so it will accommodate the >- // button manager's buttons >- getButtonBar().getParent().layout(); >+ tabSelected((TabItem) e.item); > } > }; > } > >- private void createToolbar(Composite composite) { >- toolbarManager = new ToolBarManager(SWT.NONE); >- toolbarManager.createControl(composite); >- ToolBar toolbar = toolbarManager.getControl(); >- { >- GridData toolbarData = new GridData(SWT.FILL, SWT.FILL, true, false); >- toolbarData.widthHint = SWT.DEFAULT; >- toolbarData.heightHint = SWT.DEFAULT; >- toolbar.setLayoutData(toolbarData); >+ /* >+ * Must be called after contributions and button manager are created. >+ */ >+ private void tabSelected(TabItem item) { >+ String id = null; >+ if (item.getData() instanceof IConfigurationElement) { >+ final IConfigurationElement element = (IConfigurationElement) item >+ .getData(); >+ >+ id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID); >+ item.setData(ID, id); >+ >+ Composite pageComposite = (Composite) item.getControl(); >+ try { >+ final InstallationPage page = (InstallationPage) element >+ .createExecutableExtension(IWorkbenchRegistryConstants.ATT_CLASS); >+ page.createControl(pageComposite); >+ page.init(serviceLocator); >+ item.setData(page); >+ item.addDisposeListener(new DisposeListener() { >+ >+ public void widgetDisposed(DisposeEvent e) { >+ page.dispose(); >+ } >+ }); >+ pageComposite.layout(true, true); >+ >+ } catch (CoreException e1) { >+ Label label = new Label(pageComposite, SWT.NONE); >+ label.setText(e1.getMessage()); >+ item.setData(null); >+ } >+ >+ } else { >+ id = (String) item.getData(ID); > } >+ updateContributions(id, (InstallationPage) item.getData()); >+ createButton(buttonManager.getParent(), IDialogConstants.OK_ID, >+ IDialogConstants.OK_LABEL, true); >+ // Layout the button manager again now that the OK button is there. >+ // Must do this before we layout the button bar or else the button >+ // manager will not know about the OK button >+ buttonManager.getParent().layout(); >+ // Now we layout the button bar itself so it will accommodate the >+ // button manager's buttons >+ getButtonBar().getParent().layout(); >+ } >+ >+ protected void updateContributions(String id, InstallationPage page) { >+ // Changing the source provider will cause the contributions and the >+ // button manager to be updated. If for some reason we don't have a >+ // source provider, update it ourselves. >+ if (sourceProvider != null) >+ sourceProvider.setCurrentPage(id, page); >+ else >+ buttonManager.update(true); >+ } >+ >+ protected InstallationDialogSourceProvider getSourceProvider() { >+ return sourceProvider; > } > > /* >@@ -220,140 +297,87 @@ > */ > protected void createButtonsForButtonBar(Composite parent) { > buttonManager = new ButtonManager(parent); >+ ((IMenuService) serviceLocator.getService(IMenuService.class)) >+ .populateContributionManager(buttonManager, getButtonBarURI()); > } > >- /** >- * @param folder2 >- */ > private void configureFolder() { >- ColorRegistry reg = JFaceResources.getColorRegistry(); >- Color c1 = reg.get(IWorkbenchThemeConstants.ACTIVE_TAB_BG_START), c2 = reg >- .get(IWorkbenchThemeConstants.ACTIVE_TAB_BG_END); >- folder.setSelectionBackground(new Color[] { c1, c2 }, new int[] { 50 }, >- true); >- folder.setSelectionForeground(reg >- .get(IWorkbenchThemeConstants.ACTIVE_TAB_TEXT_COLOR)); >- folder.setSimple(PlatformUI.getPreferenceStore().getBoolean( >- IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS)); >- > } > >- /** >- * @return >- */ > private IConfigurationElement[] loadElements() { > IExtensionPoint point = Platform.getExtensionRegistry() > .getExtensionPoint("org.eclipse.ui", "installationPages"); //$NON-NLS-1$ //$NON-NLS-2$ > return point.getConfigurationElements(); > } > >- private String getButtonBarURI(String id) { >- return "toolbar:org.eclipse.ui.installationDialog.buttonbar/" + id; //$NON-NLS-1$ >- } >- >- protected String getToolbarURI(String id) { >- return "toolbar:org.eclipse.ui.installationDialog/" + id; //$NON-NLS-1$ >- } >- >- private IServiceLocator createDialogServiceLocator(final CTabItem item) { >- return new IServiceLocator() { >- >- public Object getService(Class api) { >- if (api == IInstallationPageContainer.class) >- return new IInstallationPageContainer() { >- >- public String getButtonBarURI() { >- return InstallationDialog.this >- .getButtonBarURI((String) item.getData(ID)); >- } >- >- public String getToolbarURI() { >- return InstallationDialog.this >- .getToolbarURI((String) item.getData(ID)); >- } >- >- public void updateMessage() { >- // TBD >- >- } >- >- public void close() { >- InstallationDialog.this.close(); >- } >- }; >- else if (api == IMenuService.class) { >- return menuService; >+ protected void createDialogServiceLocator(IServiceLocatorCreator slc, >+ IServiceLocator locator) { >+ AbstractServiceFactory localFactory = new AbstractServiceFactory() { >+ public Object create(Class serviceInterface, >+ IServiceLocator parentLocator, IServiceLocator locator) { >+ if (serviceInterface == IInstallationPageContainer.class) { >+ return InstallationDialog.this; > } >- return serviceLocator.getService(api); >- } >- >- public boolean hasService(Class api) { >- if (api == IInstallationPageContainer.class) >- return true; >- return serviceLocator.hasService(api); >+ return parentLocator.getService(serviceInterface); > } > }; >+ this.serviceLocator = slc.createServiceLocator(locator, localFactory, >+ new IDisposable() { >+ public void dispose() { >+ close(); >+ } >+ }); > } >-} > >-class ButtonManager extends ContributionManager { >+ protected IDialogSettings getDialogBoundsSettings() { >+ IDialogSettings settings = WorkbenchPlugin.getDefault() >+ .getDialogSettings(); >+ IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION); >+ if (section == null) { >+ section = settings.addNewSection(DIALOG_SETTINGS_SECTION); >+ } >+ return section; >+ } > >- private Composite composite; >+ protected void releaseContributions() { >+ ((IMenuService) serviceLocator.getService(IMenuService.class)) >+ .releaseContributions(buttonManager); >+ buttonManager.removeAll(); >+ } > >- /** >+ /* >+ * (non-Javadoc) > * >+ * @see org.eclipse.ui.about.IInstallationPageContainer#getButtonBarURI() > */ >- public ButtonManager(Composite composite) { >- this.composite = composite; >+ public String getButtonBarURI() { >+ return URI; > } > >- /** >- * @return >- */ >- public Composite getParent() { >- return composite; >+ public void closeContainer() { >+ close(); >+ } >+ >+ protected IServiceLocator getDialogServiceLocator() { >+ return serviceLocator; >+ } >+ >+ protected ButtonManager getButtonManager() { >+ return buttonManager; > } > > /* > * (non-Javadoc) > * >- * @see org.eclipse.jface.action.IContributionManager#update(boolean) >+ * @see >+ * org.eclipse.ui.about.IInstallationPageContainer#getActivePageExpression >+ * (org.eclipse.ui.about.InstallationPage) > */ >- public void update(boolean force) { >- if (composite == null || composite.isDisposed()) >- return; >- GC metricsGC = new GC(composite); >- FontMetrics metrics = metricsGC.getFontMetrics(); >- metricsGC.dispose(); >- IContributionItem[] items = getItems(); >- Control[] children = composite.getChildren(); >- >- int visibleChildren = 0; >- for (int i = 0; i < children.length; i++) { >- Control control = children[i]; >- control.dispose(); >- } >- >- for (int i = 0; i < items.length; i++) { >- IContributionItem item = items[i]; >- if (item.isVisible()) { >- item.fill(composite); >- children = composite.getChildren(); >- Control itemControl = children[children.length - 1]; >- setButtonLayoutData(metrics, itemControl); >- visibleChildren++; >- } >- } >- GridLayout compositeLayout = (GridLayout) composite.getLayout(); >- compositeLayout.numColumns = visibleChildren; >- composite.layout(true); >+ public Expression getActivePageExpression(InstallationPage page) { >+ return new ActiveInstallationPageExpression(page); > } >- >- protected void setButtonLayoutData(FontMetrics metrics, Control button) { >- GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); >- int widthHint = Dialog.convertHorizontalDLUsToPixels(metrics, IDialogConstants.BUTTON_WIDTH); >- Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); >- data.widthHint = Math.max(widthHint, minSize.x); >- button.setLayoutData(data); >+ >+ protected void resetVariables(InstallationDialogSourceProvider sp) { >+ sp.resetAll(); > } > } >Index: Eclipse UI/org/eclipse/ui/about/InstallationPage.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/about/InstallationPage.java,v >retrieving revision 1.1 >diff -u -r1.1 InstallationPage.java >--- Eclipse UI/org/eclipse/ui/about/InstallationPage.java 12 Sep 2008 19:54:44 -0000 1.1 >+++ Eclipse UI/org/eclipse/ui/about/InstallationPage.java 17 Feb 2009 19:44:13 -0000 >@@ -6,15 +6,15 @@ > /** > * An installation dialog page. > * >- * The counterpart, {@link IInstallationPageContainer}, may be accessed by the >- * page (via the provided service locator) to update the status message in the >- * hosting dialog. >+ * The counterpart, {@link IInstallationPageContainer}, may be accessed using >+ * the service locator. > * >- * <em>This API is experiemental and will change before 3.5 ships</em> >+ * <em>This API is experimental and will change before 3.5 ships</em> > * > * @since 3.5 > */ > public abstract class InstallationPage extends DialogPage { > > public abstract void init(IServiceLocator locator); >+ > } >Index: Eclipse UI/org/eclipse/ui/about/IInstallationPageContainer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/about/IInstallationPageContainer.java,v >retrieving revision 1.3 >diff -u -r1.3 IInstallationPageContainer.java >--- Eclipse UI/org/eclipse/ui/about/IInstallationPageContainer.java 25 Sep 2008 22:11:28 -0000 1.3 >+++ Eclipse UI/org/eclipse/ui/about/IInstallationPageContainer.java 17 Feb 2009 19:44:13 -0000 >@@ -11,6 +11,7 @@ > > package org.eclipse.ui.about; > >+ > /** > * <em>This API is experimental and will change before 3.5 ships</em> > * >@@ -19,24 +20,6 @@ > public interface IInstallationPageContainer { > > /** >- * Updates the message (or error message) shown in the message line to >- * reflect the state of the currently active page in this container. >- * <p> >- * This method is called by the container itself when its preference page >- * changes and may be called by the page at other times to force a message >- * update. >- * </p> >- */ >- public void updateMessage(); >- >- /** >- * URI to be provided to the IMenuService for additions to the toolbar. >- * >- * @return the toolbar uri >- */ >- public String getToolbarURI(); >- >- /** > * URI to be provided to the IMenuService for additions to the button bar. > * > * This may not be desirable. We've never had a "button manager" before now, >@@ -49,6 +32,6 @@ > /** > * Closes the window that is hosting this container. > */ >- public void close(); >+ public void closeContainer(); > > } >Index: Eclipse UI/org/eclipse/ui/internal/messages.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/messages.properties,v >retrieving revision 1.390 >diff -u -r1.390 messages.properties >--- Eclipse UI/org/eclipse/ui/internal/messages.properties 19 Dec 2008 11:52:57 -0000 1.390 >+++ Eclipse UI/org/eclipse/ui/internal/messages.properties 17 Feb 2009 19:44:16 -0000 >@@ -59,6 +59,8 @@ > ExportResourcesAction_toolTip = Export > ImportResourcesAction_text = &Import... > ImportResourcesAction_toolTip = Import >+OpenBrowserHandler_NoInfoDialogMessage=There was no additional information available. >+OpenBrowserHandler_NoInfoDialogTitle=No Further Information > OpenRecent_errorTitle = Problems opening editor > OpenRecent_unableToOpen = Unable to open ''{0}''. > Exit_text = E&xit >@@ -243,10 +245,8 @@ > DynamicHelpAction_text = &Dynamic Help > DynamicHelpAction_toolTip = Dynamic Help > AboutDialog_shellTitle = About {0} >-AboutDialog_featureInfo = &Feature Details >-AboutDialog_pluginInfo = &Plug-in Details >-AboutDialog_systemInfo = &Configuration Details > AboutDialog_defaultProductName = >+AboutDialog_DetailsButton=&Installation Details > ProductInfoDialog_errorTitle = Problems Opening Link > ProductInfoDialog_unableToOpenWebBrowser = Unable to open web browser on {0} > PreferencesExportDialog_ErrorDialogTitle=Error >@@ -282,6 +282,7 @@ > AboutFeaturesDialog_pluginInfoTitle = Feature Plug-ins > AboutFeaturesDialog_pluginInfoMessage = Plug-ins contributed by feature: {0} > AboutFeaturesDialog_noInfoTitle = No Further Information >+AboutFeaturesDialog_SimpleTitle=Features > AboutSystemDialog_browseErrorLogName = &View Error Log > AboutSystemDialog_copyToClipboardName = Copy &to Clipboard > AboutSystemDialog_noLogTitle = Error Log Not Found >@@ -518,6 +519,7 @@ > # ============================================================================== > Error = Error > Information = Information >+InstallationDialog_ShellTitle={0} Installation Details > > Workbench_NeedsClose_Title = Restart Needed > Workbench_NeedsClose_Message = A required plug-in is no longer available and the Workbench needs to be restarted. You will be prompted to save if there is any unsaved work. >Index: Eclipse UI/org/eclipse/ui/internal/ConfigurationInfo.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ConfigurationInfo.java,v >retrieving revision 1.6 >diff -u -r1.6 ConfigurationInfo.java >--- Eclipse UI/org/eclipse/ui/internal/ConfigurationInfo.java 10 Feb 2008 22:18:38 -0000 1.6 >+++ Eclipse UI/org/eclipse/ui/internal/ConfigurationInfo.java 17 Feb 2009 19:44:13 -0000 >@@ -80,7 +80,10 @@ > * extension point. > */ > private static void appendExtensions(PrintWriter writer) { >- IConfigurationElement[] configElements = getSortedExtensions(); >+ IConfigurationElement[] configElements = getSortedExtensions(Platform >+ .getExtensionRegistry().getConfigurationElementsFor( >+ PlatformUI.PLUGIN_ID, >+ IWorkbenchRegistryConstants.PL_SYSTEM_SUMMARY_SECTIONS)); > for (int i = 0; i < configElements.length; ++i) { > IConfigurationElement element = configElements[i]; > >@@ -108,11 +111,7 @@ > } > } > >- private static IConfigurationElement[] getSortedExtensions() { >- IConfigurationElement[] configElements = Platform >- .getExtensionRegistry().getConfigurationElementsFor( >- PlatformUI.PLUGIN_ID, >- IWorkbenchRegistryConstants.PL_SYSTEM_SUMMARY_SECTIONS); >+ public static IConfigurationElement[] getSortedExtensions(IConfigurationElement[] configElements) { > > Arrays.sort(configElements, new Comparator() { > Collator collator = Collator.getInstance(Locale.getDefault()); >Index: Eclipse UI/org/eclipse/ui/internal/WorkbenchMessages.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchMessages.java,v >retrieving revision 1.112 >diff -u -r1.112 WorkbenchMessages.java >--- Eclipse UI/org/eclipse/ui/internal/WorkbenchMessages.java 19 Dec 2008 11:52:57 -0000 1.112 >+++ Eclipse UI/org/eclipse/ui/internal/WorkbenchMessages.java 17 Feb 2009 19:44:14 -0000 >@@ -98,6 +98,12 @@ > public static String ExportResourcesAction_toolTip; > public static String ImportResourcesAction_text; > public static String ImportResourcesAction_toolTip; >+ public static String OpenBrowserHandler_NoInfoDialogMessage; >+ >+ >+ public static String OpenBrowserHandler_NoInfoDialogTitle; >+ >+ > public static String OpenRecent_errorTitle; > public static String OpenRecent_unableToOpen; > public static String Exit_text; >@@ -283,10 +289,10 @@ > public static String DynamicHelpAction_text; > public static String DynamicHelpAction_toolTip; > public static String AboutDialog_shellTitle; >- public static String AboutDialog_featureInfo; >- public static String AboutDialog_pluginInfo; >- public static String AboutDialog_systemInfo; > public static String AboutDialog_defaultProductName; >+ >+ >+ public static String AboutDialog_DetailsButton; > public static String ProductInfoDialog_errorTitle; > public static String ProductInfoDialog_unableToOpenWebBrowser; > public static String PreferencesExportDialog_ErrorDialogTitle; >@@ -322,6 +328,9 @@ > public static String AboutFeaturesDialog_pluginInfoTitle; > public static String AboutFeaturesDialog_pluginInfoMessage; > public static String AboutFeaturesDialog_noInfoTitle; >+ >+ >+ public static String AboutFeaturesDialog_SimpleTitle; > public static String AboutSystemDialog_browseErrorLogName; > public static String AboutSystemDialog_copyToClipboardName; > public static String AboutSystemDialog_noLogTitle; >@@ -551,6 +560,9 @@ > // ============================================================================== > public static String Error; > public static String Information; >+ >+ >+ public static String InstallationDialog_ShellTitle; > > public static String Workbench_NeedsClose_Title; > public static String Workbench_NeedsClose_Message; >Index: Eclipse UI/org/eclipse/ui/internal/about/ProductInfoDialog.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/ProductInfoDialog.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/ProductInfoDialog.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/ProductInfoDialog.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,140 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.ui.internal.about; >+ >+import org.eclipse.core.expressions.Expression; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.events.DisposeEvent; >+import org.eclipse.swt.events.DisposeListener; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.TabFolder; >+import org.eclipse.swt.widgets.TabItem; >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.about.InstallationPage; >+ >+/** >+ * Abstract superclass of the individual about dialogs that appear outside of >+ * the InstallationDialog These dialogs contain a single installation page, and >+ * scope the page to something more specific than it would be in the standard >+ * installation dialog. >+ * >+ * It is important that the visibility and enablement expressions of >+ * contributions to this dialog, and the source variables that drive them, do >+ * not conflict with those used inside the normal InstallationDialog. Otherwise, >+ * the button manager of the InstallationDialog will be affected by changes in >+ * the launched dialog. Where commands have enablement expressions in this >+ * dialog, we use a unique command id so that there are no handler conflicts >+ * with the regular dialog. >+ */ >+ >+public abstract class ProductInfoDialog extends InstallationDialog { >+ >+ ProductInfoPage page; >+ String title; >+ String helpContextId; >+ Object previouslyActivePage; >+ Object previouslyActiveSelection; >+ >+ protected ProductInfoDialog(Shell shell) { >+ super(shell, PlatformUI.getWorkbench().getActiveWorkbenchWindow()); >+ // capture the previous variables values. This is used for >+ // nested product info dialogs, such as a feature dialog that opens a >+ // plugins dialog >+ previouslyActivePage = getSourceProvider().getCurrentState().get( >+ InstallationDialogSourceProvider.ACTIVE_PRODUCT_DIALOG_PAGE); >+ previouslyActiveSelection = getSourceProvider() >+ .getCurrentState() >+ .get( >+ InstallationDialogSourceProvider.ACTIVE_PRODUCT_DIALOG_PAGE_SELECTION); >+ >+ } >+ >+ public void initializeDialog(ProductInfoPage page, String title, >+ String helpContextId) { >+ this.page = page; >+ this.title = title; >+ this.helpContextId = helpContextId; >+ } >+ >+ protected void createFolderItems(TabFolder folder) { >+ TabItem item = new TabItem(folder, SWT.NONE); >+ item.setText(title); >+ Composite control = new Composite(folder, SWT.BORDER); >+ control.setLayout(new GridLayout()); >+ item.setControl(control); >+ page.createControl(control); >+ // must set up the page data before creating the service locator. >+ // The id is used by the dialog service locator >+ item.setData(page); >+ item.setData(ID, page.getId()); >+ page.init(getDialogServiceLocator()); >+ item.addDisposeListener(new DisposeListener() { >+ >+ public void widgetDisposed(DisposeEvent e) { >+ page.dispose(); >+ } >+ }); >+ control.layout(true, true); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see >+ * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets >+ * .Shell) >+ */ >+ protected void configureShell(Shell newShell) { >+ super.configureShell(newShell); >+ newShell.setText(title); >+ if (helpContextId != null) >+ PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, >+ helpContextId); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.about.IInstallationPageContainer#getButtonBarURI() >+ */ >+ public String getButtonBarURI() { >+ return super.getButtonBarURI() + "." + page.getId(); //$NON-NLS-1$ >+ } >+ >+ protected void updateContributions(String id, InstallationPage page) { >+ InstallationDialogSourceProvider sp = getSourceProvider(); >+ if (sp != null) { >+ sp.setProductDialogPage((ProductInfoPage) page); >+ } >+ getButtonManager().update(true); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see >+ * org.eclipse.ui.about.IInstallationPageContainer#getActivePageExpression >+ * (org.eclipse.ui.about.InstallationPage) >+ */ >+ public Expression getActivePageExpression(InstallationPage page) { >+ // We have our own menu URI and do not share with other pages, so >+ // there is no visibility expression needed. >+ return null; >+ } >+ >+ protected void resetVariables(InstallationDialogSourceProvider sp) { >+ sp.setProductDialogPage(previouslyActivePage); >+ sp.setProductDialogPageSelection(previouslyActiveSelection); >+ } >+ >+} >Index: Eclipse UI/org/eclipse/ui/about/ActiveInstallationPageExpression.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/about/ActiveInstallationPageExpression.java >diff -N Eclipse UI/org/eclipse/ui/about/ActiveInstallationPageExpression.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/about/ActiveInstallationPageExpression.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,105 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.ui.about; >+ >+import org.eclipse.core.expressions.EvaluationResult; >+import org.eclipse.core.expressions.Expression; >+import org.eclipse.core.expressions.ExpressionInfo; >+import org.eclipse.core.expressions.IEvaluationContext; >+ >+/** >+ * <p> >+ * An expression that checks the active InstallationPage variable. The variable >+ * name is <code>IInstallationPageSources.ACTIVE_PAGE</code>. >+ * </p> >+ * >+ * <em>This API is experimental and will change before 3.5 ships</em> >+ * >+ * @since 3.5 >+ */ >+public final class ActiveInstallationPageExpression extends Expression { >+ >+ /** >+ * The seed for the hash code for all schemes. >+ */ >+ private static final int HASH_INITIAL = ActiveInstallationPageExpression.class >+ .getName().hashCode(); >+ >+ /** >+ * The page that must be active for this expression to evaluate to >+ * <code>true</code>. If this value is <code>null</code>, then any page may >+ * be active. >+ */ >+ private final InstallationPage page; >+ >+ /** >+ * Constructs a new instance of <code>ActiveShellExpression</code> >+ * >+ * @param page >+ * The page to match with the active installation page; >+ * <code>null</code> if it will match any active page. >+ */ >+ public ActiveInstallationPageExpression(final InstallationPage page) { >+ this.page = page; >+ } >+ >+ /** >+ * Expression information for this expression. >+ * >+ * @since 3.5 >+ */ >+ public final void collectExpressionInfo(final ExpressionInfo info) { >+ info.addVariableNameAccess(IInstallationPageSources.ACTIVE_PAGE); >+ } >+ >+ protected final int computeHashCode() { >+ return HASH_INITIAL * HASH_FACTOR + hashCode(page); >+ } >+ >+ public final boolean equals(final Object object) { >+ if (object instanceof ActiveInstallationPageExpression) { >+ final ActiveInstallationPageExpression that = (ActiveInstallationPageExpression) object; >+ return equals(this.page, that.page); >+ } >+ >+ return false; >+ } >+ >+ /** >+ * Evaluates this expression. If the active page defined by the context >+ * matches the page from this expression, then this evaluates to >+ * <code>EvaluationResult.TRUE</code>. >+ * >+ * @param context >+ * The context from which the current state is determined; must >+ * not be <code>null</code>. >+ * @return <code>EvaluationResult.TRUE</code> if the page is active; >+ * <code>EvaluationResult.FALSE</code> otherwise. >+ */ >+ public final EvaluationResult evaluate(final IEvaluationContext context) { >+ if (page != null) { >+ Object value = context >+ .getVariable(IInstallationPageSources.ACTIVE_PAGE); >+ if (page.equals(value)) >+ return EvaluationResult.TRUE; >+ } >+ return EvaluationResult.FALSE; >+ } >+ >+ public final String toString() { >+ final StringBuffer buffer = new StringBuffer(); >+ buffer.append("ActiveInstallationPageExpression("); //$NON-NLS-1$ >+ buffer.append(page); >+ buffer.append(')'); >+ return buffer.toString(); >+ } >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/ProductInfoPage.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/ProductInfoPage.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/ProductInfoPage.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/ProductInfoPage.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,148 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2007 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.ui.internal.about; >+ >+import org.eclipse.core.runtime.IProduct; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.jface.window.IShellProvider; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.events.DisposeEvent; >+import org.eclipse.swt.events.DisposeListener; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.ui.about.IInstallationPageContainer; >+import org.eclipse.ui.about.InstallationPage; >+import org.eclipse.ui.internal.WorkbenchMessages; >+import org.eclipse.ui.menus.AbstractContributionFactory; >+import org.eclipse.ui.menus.IMenuService; >+import org.eclipse.ui.services.IServiceLocator; >+ >+/** >+ * Abstract superclass of about dialog installation pages. The ProductInfoPage >+ * is set up so that the page can be hosted as one of many pages in the >+ * InstallationDialog, or as the only page in a ProductInfoDialog. >+ * When hosted inside a ProductInfoDialog, the page id, source variables, >+ * command contributions, and associated visibility/enablement expressions, are >+ * different than when hosted as a page in the InstallationDialog. This is important >+ * because another instance of the page may be launched from an InstallationDialog, and >+ * this secondary page should not affect the contributions of the originating dialog. >+ */ >+ >+public abstract class ProductInfoPage extends InstallationPage implements >+ IShellProvider { >+ >+ private IMenuService menuService; >+ >+ private InstallationDialog dialog; >+ >+ private AbstractContributionFactory factory; >+ >+ private IProduct product; >+ >+ private String productName; >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @seeorg.eclipse.ui.about.InstallationPage#init(org.eclipse.ui.services. >+ * IServiceLocator) >+ */ >+ public void init(IServiceLocator locator) { >+ IInstallationPageContainer pageContainer = (IInstallationPageContainer) locator >+ .getService(IInstallationPageContainer.class); >+ // Must cast to dialog because we rely on the ProductInfoDialog framework >+ // to provide us with the appropriate variables and visibility expressions >+ dialog = (InstallationDialog)pageContainer; >+ menuService = (IMenuService) locator.getService(IMenuService.class); >+ // this assumes that the control is created before init >+ addButtons(); >+ } >+ >+ protected IMenuService getMenuService() { >+ return menuService; >+ } >+ >+ protected InstallationDialog getInstallationDialog() { >+ return dialog; >+ } >+ >+ protected IProduct getProduct() { >+ if (product == null) >+ product = Platform.getProduct(); >+ return product; >+ } >+ >+ public String getProductName() { >+ if (productName == null) { >+ if (getProduct() != null) { >+ productName = getProduct().getName(); >+ } >+ if (productName == null) { >+ productName = WorkbenchMessages.AboutDialog_defaultProductName; >+ } >+ } >+ return productName; >+ } >+ >+ public void setProductName(String name) { >+ productName = name; >+ } >+ >+ abstract String getId(); >+ >+ public final void createControl(Composite parent) { >+ Control control = createPageControl(parent); >+ control.addDisposeListener(new DisposeListener() { >+ public void widgetDisposed(DisposeEvent e) { >+ releaseContributionFactory(); >+ } >+ }); >+ setControl(control); >+ } >+ >+ protected abstract Control createPageControl(Composite parent); >+ >+ protected Composite createOuterComposite(Composite parent) { >+ Composite composite = new Composite(parent, SWT.NONE); >+ GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); >+ composite.setLayoutData(gd); >+ GridLayout layout = new GridLayout(); >+ layout.marginWidth = 0; >+ layout.marginHeight = 0; >+ composite.setLayout(layout); >+ return composite; >+ } >+ >+ private void addButtons() { >+ if (menuService == null) >+ return; >+ factory = makeContributionFactory(); >+ if (factory != null) >+ menuService.addContributionFactory(factory); >+ } >+ >+ protected AbstractContributionFactory makeContributionFactory() { >+ return null; >+ } >+ >+ protected void releaseContributionFactory() { >+ if (factory != null) { >+ menuService.removeContributionFactory(factory); >+ factory = null; >+ } >+ } >+ >+ protected void copyToClipboard() { >+ // Do nothing by default >+ } >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/InstallationDialogSourceProvider.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/InstallationDialogSourceProvider.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/InstallationDialogSourceProvider.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/InstallationDialogSourceProvider.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,138 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.ui.internal.about; >+ >+import java.util.HashMap; >+import java.util.Map; >+ >+import org.eclipse.core.expressions.IEvaluationContext; >+import org.eclipse.ui.AbstractSourceProvider; >+import org.eclipse.ui.ISources; >+import org.eclipse.ui.about.IInstallationPageSources; >+import org.eclipse.ui.about.InstallationPage; >+ >+/** >+ * A registered source provider that can update variables associated with an >+ * InstallationDialog. >+ * >+ * @since 3.5 >+ */ >+public class InstallationDialogSourceProvider extends AbstractSourceProvider { >+ Map currentState; >+ >+ /** >+ * These variables are internal to the about framework. They are only needed >+ * because some of the platform about pages can be launched into their own >+ * nested ProductInfoDialog from another platform about page. We need >+ * different variables for the visibility expressions for those cases, >+ * because the launching InstallationDialog is still open and using the >+ * regular variables. >+ */ >+ public static final String ACTIVE_PRODUCT_DIALOG_PAGE = "org.eclipse.ui.internal.about.activeProductDialogPage"; //$NON-NLS-1$ >+ public static final String ACTIVE_PRODUCT_DIALOG_PAGE_ID = "org.eclipse.ui.internal.about.activeProductDialogPageId"; //$NON-NLS-1$ >+ public static final String ACTIVE_PRODUCT_DIALOG_PAGE_SELECTION = "org.eclipse.ui.internal.about.activeProductDialogSelection"; //$NON-NLS-1$ >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.ISourceProvider#dispose() >+ */ >+ public void dispose() { >+ currentState = null; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.ISourceProvider#getCurrentState() >+ */ >+ public Map getCurrentState() { >+ if (currentState == null) { >+ currentState = new HashMap(); >+ currentState.put(IInstallationPageSources.ACTIVE_PAGE, >+ IEvaluationContext.UNDEFINED_VARIABLE); >+ currentState.put(IInstallationPageSources.ACTIVE_PAGE_ID, >+ IEvaluationContext.UNDEFINED_VARIABLE); >+ currentState.put(IInstallationPageSources.ACTIVE_PAGE_SELECTION, >+ IEvaluationContext.UNDEFINED_VARIABLE); >+ currentState.put(ACTIVE_PRODUCT_DIALOG_PAGE, >+ IEvaluationContext.UNDEFINED_VARIABLE); >+ currentState.put(ACTIVE_PRODUCT_DIALOG_PAGE_ID, >+ IEvaluationContext.UNDEFINED_VARIABLE); >+ currentState.put(ACTIVE_PRODUCT_DIALOG_PAGE_SELECTION, >+ IEvaluationContext.UNDEFINED_VARIABLE); >+ } >+ return currentState; >+ } >+ >+ public void setCurrentPage(String id, InstallationPage page) { >+ Map map = getCurrentState(); >+ map.put(IInstallationPageSources.ACTIVE_PAGE_ID, id); >+ map.put(IInstallationPageSources.ACTIVE_PAGE, page); >+ fireSourceChanged(ISources.WORKBENCH, >+ IInstallationPageSources.ACTIVE_PAGE_ID, id); >+ fireSourceChanged(ISources.WORKBENCH, >+ IInstallationPageSources.ACTIVE_PAGE, page); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.ISourceProvider#getProvidedSourceNames() >+ */ >+ public String[] getProvidedSourceNames() { >+ return new String[] { IInstallationPageSources.ACTIVE_PAGE, >+ IInstallationPageSources.ACTIVE_PAGE_ID, >+ IInstallationPageSources.ACTIVE_PAGE_SELECTION, >+ ACTIVE_PRODUCT_DIALOG_PAGE, ACTIVE_PRODUCT_DIALOG_PAGE_ID, >+ ACTIVE_PRODUCT_DIALOG_PAGE_SELECTION }; >+ } >+ >+ public void setProductDialogPage(Object page) { >+ Map map = getCurrentState(); >+ Object pageValue, idValue; >+ if (page instanceof ProductInfoPage) { >+ map.put(ACTIVE_PRODUCT_DIALOG_PAGE, pageValue = page); >+ map.put(ACTIVE_PRODUCT_DIALOG_PAGE_ID, >+ idValue = ((ProductInfoPage) page).getId()); >+ } else { >+ map.put(ACTIVE_PRODUCT_DIALOG_PAGE, >+ pageValue = IEvaluationContext.UNDEFINED_VARIABLE); >+ map.put(ACTIVE_PRODUCT_DIALOG_PAGE_ID, >+ idValue = IEvaluationContext.UNDEFINED_VARIABLE); >+ } >+ fireSourceChanged(ISources.WORKBENCH, ACTIVE_PRODUCT_DIALOG_PAGE, >+ pageValue); >+ fireSourceChanged(ISources.WORKBENCH, ACTIVE_PRODUCT_DIALOG_PAGE_ID, >+ idValue); >+ } >+ >+ public void setPageSelection(Object selection) { >+ Map map = getCurrentState(); >+ map.put(IInstallationPageSources.ACTIVE_PAGE_SELECTION, selection); >+ fireSourceChanged(ISources.WORKBENCH, >+ IInstallationPageSources.ACTIVE_PAGE_SELECTION, selection); >+ } >+ >+ public void setProductDialogPageSelection(Object selection) { >+ Map map = getCurrentState(); >+ map.put(ACTIVE_PRODUCT_DIALOG_PAGE_SELECTION, selection); >+ fireSourceChanged(ISources.WORKBENCH, >+ ACTIVE_PRODUCT_DIALOG_PAGE_SELECTION, selection); >+ } >+ >+ public void resetAll() { >+ currentState = null; >+ Map map = getCurrentState(); >+ fireSourceChanged(ISources.WORKBENCH, map); >+ } >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/BundleSigningInfo.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/BundleSigningInfo.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/BundleSigningInfo.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/BundleSigningInfo.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,303 @@ >+/******************************************************************************* >+ * Copyright (c) 2007, 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.ui.internal.about; >+ >+import java.io.IOException; >+import java.security.GeneralSecurityException; >+import java.security.cert.Certificate; >+import java.security.cert.X509Certificate; >+import java.text.DateFormat; >+import java.util.ArrayList; >+import java.util.Date; >+import java.util.Iterator; >+import java.util.List; >+import java.util.Map; >+import java.util.Properties; >+import java.util.StringTokenizer; >+import java.util.Map.Entry; >+ >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.OperationCanceledException; >+import org.eclipse.core.runtime.Status; >+import org.eclipse.core.runtime.jobs.Job; >+import org.eclipse.jface.dialogs.Dialog; >+import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.osgi.signedcontent.SignedContent; >+import org.eclipse.osgi.signedcontent.SignedContentFactory; >+import org.eclipse.osgi.signedcontent.SignerInfo; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.custom.StyledText; >+import org.eclipse.swt.graphics.GC; >+import org.eclipse.swt.graphics.Point; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Label; >+import org.eclipse.swt.widgets.Text; >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.internal.WorkbenchMessages; >+import org.eclipse.ui.internal.WorkbenchPlugin; >+import org.eclipse.ui.statushandlers.StatusManager; >+import org.osgi.framework.BundleContext; >+import org.osgi.framework.ServiceReference; >+ >+/** >+ * @since 3.3 >+ * >+ */ >+public class BundleSigningInfo { >+ >+ private Composite composite; >+ private Text date; >+ private StyledText certificate; >+ private AboutBundleData data; >+ >+ public BundleSigningInfo() { >+ } >+ >+ public void setData(AboutBundleData data) { >+ this.data = data; >+ startJobs(); >+ } >+ >+ public Control createContents(Composite parent) { >+ >+ composite = new Composite(parent, SWT.BORDER); >+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); >+ GridLayout layout = new GridLayout(2, false); >+ layout.marginHeight = 0; >+ layout.marginWidth = 0; >+ composite.setLayout(layout); >+ >+ // date >+ { >+ Label label = new Label(composite, SWT.NONE); >+ label.setText(WorkbenchMessages.BundleSigningTray_Signing_Date); >+ GridData data = new GridData(SWT.FILL, SWT.BEGINNING, true, false); >+ date = new Text(composite, SWT.READ_ONLY); >+ GC gc = new GC(date); >+ gc.setFont(JFaceResources.getDialogFont()); >+ Point size = gc.stringExtent(DateFormat.getDateTimeInstance() >+ .format(new Date())); >+ data.widthHint = size.x; >+ gc.dispose(); >+ date.setText(WorkbenchMessages.BundleSigningTray_Working); >+ date.setLayoutData(data); >+ } >+ // signer >+ { >+ Label label = new Label(composite, SWT.NONE); >+ label >+ .setText(WorkbenchMessages.BundleSigningTray_Signing_Certificate); >+ GridData data = new GridData(SWT.BEGINNING, SWT.BEGINNING, true, >+ false); >+ data.horizontalSpan = 2; >+ data = new GridData(SWT.FILL, SWT.FILL, true, true); >+ data.horizontalSpan = 2; >+ certificate = new StyledText(composite, SWT.READ_ONLY | SWT.MULTI >+ | SWT.WRAP); >+ certificate.setText(WorkbenchMessages.BundleSigningTray_Working); >+ certificate.setLayoutData(data); >+ } >+ Dialog.applyDialogFont(composite); >+ >+ startJobs(); // start the jobs that will prime the content >+ return composite; >+ } >+ >+ /** >+ * >+ */ >+ private void startJobs() { >+ if (!isOpen()) >+ return; >+ certificate.setText(WorkbenchMessages.BundleSigningTray_Working); >+ date.setText(WorkbenchMessages.BundleSigningTray_Working); >+ final BundleContext bundleContext = WorkbenchPlugin.getDefault() >+ .getBundleContext(); >+ final ServiceReference factoryRef = bundleContext >+ .getServiceReference(SignedContentFactory.class.getName()); >+ if (factoryRef == null) { >+ StatusManager >+ .getManager() >+ .handle( >+ new Status( >+ IStatus.WARNING, >+ WorkbenchPlugin.PI_WORKBENCH, >+ WorkbenchMessages.BundleSigningTray_Cant_Find_Service), >+ StatusManager.LOG); >+ return; >+ } >+ >+ final SignedContentFactory contentFactory = (SignedContentFactory) bundleContext >+ .getService(factoryRef); >+ if (contentFactory == null) { >+ StatusManager >+ .getManager() >+ .handle( >+ new Status( >+ IStatus.WARNING, >+ WorkbenchPlugin.PI_WORKBENCH, >+ WorkbenchMessages.BundleSigningTray_Cant_Find_Service), >+ StatusManager.LOG); >+ return; >+ } >+ >+ final AboutBundleData myData = data; >+ final Job signerJob = new Job(NLS.bind( >+ WorkbenchMessages.BundleSigningTray_Determine_Signer_For, >+ myData.getId())) { >+ >+ protected IStatus run(IProgressMonitor monitor) { >+ try { >+ if (myData != data) >+ return Status.OK_STATUS; >+ SignedContent signedContent = contentFactory >+ .getSignedContent(myData.getBundle()); >+ if (myData != data) >+ return Status.OK_STATUS; >+ SignerInfo[] signers = signedContent.getSignerInfos(); >+ final String signerText, dateText; >+ if (!isOpen() && BundleSigningInfo.this.data == myData) >+ return Status.OK_STATUS; >+ >+ if (signers.length == 0) { >+ signerText = WorkbenchMessages.BundleSigningTray_Unsigned; >+ dateText = WorkbenchMessages.BundleSigningTray_Unsigned; >+ } else { >+ Properties[] certs = parseCerts(signers[0] >+ .getCertificateChain()); >+ if (certs.length == 0) >+ signerText = WorkbenchMessages.BundleSigningTray_Unknown; >+ else { >+ StringBuffer buffer = new StringBuffer(); >+ for (Iterator i = certs[0].entrySet().iterator(); i >+ .hasNext();) { >+ Map.Entry entry = (Entry) i.next(); >+ buffer.append(entry.getKey()); >+ buffer.append('='); >+ buffer.append(entry.getValue()); >+ if (i.hasNext()) >+ buffer.append('\n'); >+ } >+ signerText = buffer.toString(); >+ } >+ >+ Date signDate = signedContent >+ .getSigningTime(signers[0]); >+ if (signDate != null) >+ dateText = DateFormat.getDateTimeInstance().format( >+ signDate); >+ else >+ dateText = WorkbenchMessages.BundleSigningTray_Unknown; >+ } >+ >+ PlatformUI.getWorkbench().getDisplay().asyncExec( >+ new Runnable() { >+ public void run() { >+ // check to see if the tray is still visible >+ // and if >+ // we're still looking at the same item >+ if (!isOpen() >+ && BundleSigningInfo.this.data != myData) >+ return; >+ certificate.setText(signerText); >+ date.setText(dateText); >+ } >+ }); >+ >+ } catch (IOException e) { >+ return new Status(IStatus.ERROR, >+ WorkbenchPlugin.PI_WORKBENCH, e.getMessage(), e); >+ } catch (GeneralSecurityException e) { >+ return new Status(IStatus.ERROR, >+ WorkbenchPlugin.PI_WORKBENCH, e.getMessage(), e); >+ } >+ return Status.OK_STATUS; >+ } >+ }; >+ signerJob.setSystem(true); >+ signerJob.belongsTo(signerJob); >+ signerJob.schedule(); >+ >+ Job cleanup = new Job( >+ WorkbenchMessages.BundleSigningTray_Unget_Signing_Service) { >+ >+ protected IStatus run(IProgressMonitor monitor) { >+ try { >+ getJobManager().join(signerJob, monitor); >+ } catch (OperationCanceledException e) { >+ } catch (InterruptedException e) { >+ } >+ bundleContext.ungetService(factoryRef); >+ return Status.OK_STATUS; >+ } >+ }; >+ cleanup.setSystem(true); >+ cleanup.schedule(); >+ >+ } >+ >+ /** >+ * >+ */ >+ private boolean isOpen() { >+ return certificate != null && !certificate.isDisposed(); >+ } >+ >+ private Properties[] parseCerts(Certificate[] chain) { >+ List certs = new ArrayList(chain.length); >+ for (int i = 0; i < chain.length; i++) { >+ if (!(chain[i] instanceof X509Certificate)) >+ continue; >+ Map cert = parseCert(((X509Certificate) chain[i]).getSubjectDN() >+ .getName()); >+ if (cert != null) >+ certs.add(cert); >+ } >+ return (Properties[]) certs.toArray(new Properties[certs.size()]); >+ >+ } >+ >+ /** >+ * @param certString >+ * @return >+ */ >+ private Properties parseCert(String certString) { >+ StringTokenizer toker = new StringTokenizer(certString, ","); //$NON-NLS-1$ >+ Properties cert = new Properties(); >+ while (toker.hasMoreTokens()) { >+ String pair = toker.nextToken(); >+ int idx = pair.indexOf('='); >+ if (idx > 0 && idx < pair.length() - 2) { >+ String key = pair.substring(0, idx).trim(); >+ String value = pair.substring(idx + 1).trim(); >+ if (value.length() > 2) { >+ if (value.charAt(0) == '\"') >+ value = value.substring(1); >+ >+ if (value.charAt(value.length() - 1) == '\"') >+ value = value.substring(0, value.length() - 1); >+ } >+ cert.setProperty(key, value); >+ } >+ } >+ return cert; >+ } >+ >+ public void dispose() { >+ composite.dispose(); >+ } >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/AboutPluginsPage.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/AboutPluginsPage.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/AboutPluginsPage.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/AboutPluginsPage.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,647 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog >+ * font should be activated and used by other components. >+ *******************************************************************************/ >+package org.eclipse.ui.internal.about; >+ >+import java.io.IOException; >+import java.net.URL; >+import java.util.ArrayList; >+import java.util.Collection; >+import java.util.HashMap; >+import java.util.LinkedList; >+import java.util.List; >+import java.util.Map; >+ >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.core.runtime.Status; >+import org.eclipse.core.runtime.jobs.Job; >+import org.eclipse.jface.action.Action; >+import org.eclipse.jface.action.ActionContributionItem; >+import org.eclipse.jface.viewers.ArrayContentProvider; >+import org.eclipse.jface.viewers.IBaseLabelProvider; >+import org.eclipse.jface.viewers.ISelectionChangedListener; >+import org.eclipse.jface.viewers.IStructuredSelection; >+import org.eclipse.jface.viewers.ITableLabelProvider; >+import org.eclipse.jface.viewers.LabelProvider; >+import org.eclipse.jface.viewers.LabelProviderChangedEvent; >+import org.eclipse.jface.viewers.SelectionChangedEvent; >+import org.eclipse.jface.viewers.TableViewer; >+import org.eclipse.jface.viewers.Viewer; >+import org.eclipse.jface.viewers.ViewerComparator; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.custom.SashForm; >+import org.eclipse.swt.events.SelectionAdapter; >+import org.eclipse.swt.events.SelectionEvent; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.layout.FillLayout; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Label; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.TableColumn; >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.internal.IWorkbenchGraphicConstants; >+import org.eclipse.ui.internal.IWorkbenchHelpContextIds; >+import org.eclipse.ui.internal.WorkbenchImages; >+import org.eclipse.ui.internal.WorkbenchMessages; >+import org.eclipse.ui.internal.WorkbenchPlugin; >+import org.eclipse.ui.internal.util.BundleUtility; >+import org.eclipse.ui.menus.AbstractContributionFactory; >+import org.eclipse.ui.menus.IContributionRoot; >+import org.eclipse.ui.progress.WorkbenchJob; >+import org.eclipse.ui.services.IServiceLocator; >+import org.osgi.framework.Bundle; >+ >+/** >+ * Displays information about the product plugins. >+ * >+ * PRIVATE this class is internal to the ide >+ */ >+public class AboutPluginsPage extends TableListPage { >+ >+ public class BundleTableLabelProvider extends LabelProvider implements >+ ITableLabelProvider { >+ >+ /** >+ * Queue containing bundle signing info to be resolved. >+ */ >+ private LinkedList resolveQueue = new LinkedList(); >+ >+ /** >+ * Queue containing bundle data that's been resolve and needs updating. >+ */ >+ private List updateQueue = new ArrayList(); >+ >+ /* >+ * this job will attempt to discover the signing state of a given bundle >+ * and then send it along to the update job >+ */ >+ private Job resolveJob = new Job(AboutPluginsPage.class.getName()) { >+ { >+ setSystem(true); >+ setPriority(Job.SHORT); >+ } >+ >+ protected IStatus run(IProgressMonitor monitor) { >+ while (true) { >+ // If the UI has not been created, nothing to do. >+ if (vendorInfo == null) >+ return Status.OK_STATUS; >+ // If the UI has been disposed since we were asked to >+ // render, nothing to do. >+ Table table = vendorInfo.getTable(); >+ // the table has been disposed since we were asked to render >+ if (table == null || table.isDisposed()) >+ return Status.OK_STATUS; >+ AboutBundleData data = null; >+ synchronized (resolveQueue) { >+ if (resolveQueue.isEmpty()) >+ return Status.OK_STATUS; >+ data = (AboutBundleData) resolveQueue.removeFirst(); >+ } >+ try { >+ // following is an expensive call >+ data.isSigned(); >+ >+ synchronized (updateQueue) { >+ updateQueue.add(data); >+ } >+ // start the update job >+ updateJob.schedule(); >+ } catch (IllegalStateException e) { >+ // the bundle we're testing has been unloaded. Do >+ // nothing. >+ } >+ } >+ } >+ }; >+ >+ /* >+ * this job is responsible for feeding label change events into the >+ * viewer as they become available from the resolve job >+ */ >+ private Job updateJob = new WorkbenchJob(PlatformUI.getWorkbench() >+ .getDisplay(), AboutPluginsPage.class.getName()) { >+ { >+ setSystem(true); >+ setPriority(Job.DECORATE); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see >+ * org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core. >+ * runtime.IProgressMonitor) >+ */ >+ public IStatus runInUIThread(IProgressMonitor monitor) { >+ while (true) { >+ Shell dialogShell = getShell(); >+ // the shell has gone down since we were asked to render >+ if (dialogShell == null || dialogShell.isDisposed()) >+ return Status.OK_STATUS; >+ AboutBundleData[] data = null; >+ synchronized (updateQueue) { >+ if (updateQueue.isEmpty()) >+ return Status.OK_STATUS; >+ >+ data = (AboutBundleData[]) updateQueue >+ .toArray(new AboutBundleData[updateQueue.size()]); >+ updateQueue.clear(); >+ >+ } >+ fireLabelProviderChanged(new LabelProviderChangedEvent( >+ BundleTableLabelProvider.this, data)); >+ } >+ } >+ }; >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see >+ * org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java >+ * .lang.Object, int) >+ */ >+ public Image getColumnImage(Object element, int columnIndex) { >+ if (columnIndex == 0) { >+ if (element instanceof AboutBundleData) { >+ final AboutBundleData data = (AboutBundleData) element; >+ if (data.isSignedDetermined()) { >+ return WorkbenchImages >+ .getImage(data.isSigned() ? IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_YES >+ : IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_NO); >+ } >+ >+ synchronized (resolveQueue) { >+ resolveQueue.add(data); >+ } >+ resolveJob.schedule(); >+ >+ return WorkbenchImages >+ .getImage(IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_UNKNOWN); >+ } >+ } >+ return null; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see >+ * org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java. >+ * lang.Object, int) >+ */ >+ public String getColumnText(Object element, int columnIndex) { >+ if (element instanceof AboutBundleData) { >+ AboutBundleData data = (AboutBundleData) element; >+ switch (columnIndex) { >+ case 1: >+ return data.getProviderName(); >+ case 2: >+ return data.getName(); >+ case 3: >+ return data.getVersion(); >+ case 4: >+ return data.getId(); >+ } >+ } >+ return ""; //$NON-NLS-1$ >+ } >+ } >+ >+ // This id should *not* be the same id used for contributing the page in >+ // the installationPage extension. It is used by ProductInfoDialog >+ // to ensure a different namespace for button contributions than the id >+ // for the page appearing in the InstallationDialog >+ private static final String ID = "productInfo.plugins"; //$NON-NLS-1$ >+ >+ /** >+ * Table height in dialog units (value 200). >+ */ >+ private static final int TABLE_HEIGHT = 200; >+ >+ private static final IPath baseNLPath = new Path("$nl$"); //$NON-NLS-1$ >+ >+ private static final String PLUGININFO = "about.html"; //$NON-NLS-1$ >+ >+ private static final int PLUGIN_NAME_COLUMN_INDEX = 2; >+ >+ private static final int SIGNING_AREA_PERCENTAGE = 30; >+ >+ private TableViewer vendorInfo; >+ >+ private Action signingInfo; >+ >+ private String message; >+ >+ private String helpContextId = IWorkbenchHelpContextIds.ABOUT_PLUGINS_DIALOG; >+ >+ private String columnTitles[] = { >+ WorkbenchMessages.AboutPluginsDialog_signed, >+ WorkbenchMessages.AboutPluginsDialog_provider, >+ WorkbenchMessages.AboutPluginsDialog_pluginName, >+ WorkbenchMessages.AboutPluginsDialog_version, >+ WorkbenchMessages.AboutPluginsDialog_pluginId, >+ >+ }; >+ private Bundle[] bundles = WorkbenchPlugin.getDefault().getBundles(); >+ private AboutBundleData[] bundleInfos; >+ private SashForm sashForm; >+ private BundleSigningInfo signingArea; >+ >+ public void setBundles(Bundle[] bundles) { >+ this.bundles = bundles; >+ } >+ >+ public void setHelpContextId(String id) { >+ this.helpContextId = id; >+ } >+ >+ public void setMessage(String message) { >+ this.message = message; >+ } >+ >+ /** >+ */ >+ protected void handleSigningInfoPressed() { >+ if (signingArea == null) { >+ signingArea = new BundleSigningInfo(); >+ AboutBundleData bundleInfo = (AboutBundleData) ((IStructuredSelection) vendorInfo >+ .getSelection()).getFirstElement(); >+ signingArea.setData(bundleInfo); >+ >+ signingArea.createContents(sashForm); >+ sashForm.setWeights(new int[] { 100 - SIGNING_AREA_PERCENTAGE, >+ SIGNING_AREA_PERCENTAGE }); >+ signingInfo >+ .setText(WorkbenchMessages.AboutPluginsDialog_signingInfo_hide); >+ >+ } else { >+ // hide >+ signingInfo >+ .setText(WorkbenchMessages.AboutPluginsDialog_signingInfo_show); >+ signingArea.dispose(); >+ signingArea = null; >+ sashForm.setWeights(new int[] { 100 }); >+ } >+ } >+ >+ protected AbstractContributionFactory makeContributionFactory() { >+ return new AbstractContributionFactory(getInstallationDialog() >+ .getButtonBarURI(), null) { >+ >+ public void createContributionItems(IServiceLocator serviceLocator, >+ IContributionRoot additions) { >+ >+ signingInfo = new Action( >+ WorkbenchMessages.AboutPluginsDialog_signingInfo_show) { >+ public void run() { >+ handleSigningInfoPressed(); >+ } >+ }; >+ checkSigningEnablement(); >+ additions.addContributionItem(new ActionContributionItem( >+ signingInfo), getInstallationDialog() >+ .getActivePageExpression(AboutPluginsPage.this)); >+ } >+ }; >+ } >+ >+ protected Control createPageControl(Composite parent) { >+ initializeDialogUnits(parent); >+ >+ // create a data object for each bundle, remove duplicates, and include >+ // only resolved bundles (bug 65548) >+ Map map = new HashMap(); >+ for (int i = 0; i < bundles.length; ++i) { >+ AboutBundleData data = new AboutBundleData(bundles[i]); >+ if (BundleUtility.isReady(data.getState()) >+ && !map.containsKey(data.getVersionedId())) { >+ map.put(data.getVersionedId(), data); >+ } >+ } >+ bundleInfos = (AboutBundleData[]) map.values().toArray( >+ new AboutBundleData[0]); >+ WorkbenchPlugin.class.getSigners(); >+ >+ sashForm = new SashForm(parent, SWT.HORIZONTAL | SWT.SMOOTH); >+ FillLayout layout = new FillLayout(); >+ sashForm.setLayout(layout); >+ layout.marginHeight = 0; >+ layout.marginWidth = 0; >+ GridData data = new GridData(GridData.FILL_BOTH); >+ sashForm.setLayoutData(data); >+ >+ Composite outer = createOuterComposite(sashForm); >+ PlatformUI.getWorkbench().getHelpSystem().setHelp(outer, helpContextId); >+ >+ if (message != null) { >+ Label label = new Label(outer, SWT.NONE); >+ label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); >+ label.setFont(parent.getFont()); >+ label.setText(message); >+ } >+ >+ createTable(outer); >+ return outer; >+ } >+ >+ /** >+ * Create the table part of the dialog. >+ * >+ * @param parent >+ * the parent composite to contain the dialog area >+ */ >+ protected void createTable(Composite parent) { >+ vendorInfo = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL >+ | SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER); >+ vendorInfo.setUseHashlookup(true); >+ vendorInfo.getTable().setHeaderVisible(true); >+ vendorInfo.getTable().setLinesVisible(true); >+ vendorInfo.getTable().setFont(parent.getFont()); >+ vendorInfo.addSelectionChangedListener(new ISelectionChangedListener() { >+ >+ public void selectionChanged(SelectionChangedEvent event) { >+ checkSigningEnablement(); >+ AboutPluginsPage.this.selectionChanged(); >+ } >+ }); >+ >+ final TableComparator comparator = new TableComparator(); >+ vendorInfo.setComparator(comparator); >+ int[] columnWidths = { >+ convertHorizontalDLUsToPixels(30), // signature >+ convertHorizontalDLUsToPixels(120), >+ convertHorizontalDLUsToPixels(120), >+ convertHorizontalDLUsToPixels(70), >+ convertHorizontalDLUsToPixels(130), }; >+ >+ // create table headers >+ for (int i = 0; i < columnTitles.length; i++) { >+ TableColumn column = new TableColumn(vendorInfo.getTable(), >+ SWT.NULL); >+ if (i == PLUGIN_NAME_COLUMN_INDEX) { // prime initial sorting >+ updateTableSorting(i); >+ } >+ column.setWidth(columnWidths[i]); >+ column.setText(columnTitles[i]); >+ final int columnIndex = i; >+ column.addSelectionListener(new SelectionAdapter() { >+ public void widgetSelected(SelectionEvent e) { >+ updateTableSorting(columnIndex); >+ } >+ }); >+ } >+ >+ vendorInfo.setContentProvider(new ArrayContentProvider()); >+ vendorInfo.setLabelProvider(new BundleTableLabelProvider()); >+ >+ GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, >+ true); >+ gridData.heightHint = convertVerticalDLUsToPixels(TABLE_HEIGHT); >+ vendorInfo.getTable().setLayoutData(gridData); >+ >+ vendorInfo.setInput(bundleInfos); >+ } >+ >+ /** >+ * Update the sort information on both the comparator and the table. >+ * >+ * @param columnIndex >+ * the index to sort by >+ * @since 3.4 >+ */ >+ private void updateTableSorting(final int columnIndex) { >+ TableComparator comparator = (TableComparator) vendorInfo >+ .getComparator(); >+ // toggle direction if it's the same column >+ if (columnIndex == comparator.getSortColumn()) { >+ comparator.setAscending(!comparator.isAscending()); >+ } >+ comparator.setSortColumn(columnIndex); >+ vendorInfo.getTable().setSortColumn( >+ vendorInfo.getTable().getColumn(columnIndex)); >+ vendorInfo.getTable().setSortDirection( >+ comparator.isAscending() ? SWT.UP : SWT.DOWN); >+ vendorInfo.refresh(false); >+ } >+ >+ /** >+ * Return an url to the plugin's about.html file (what is shown when >+ * "More info" is pressed) or null if no such file exists. The method does >+ * nl lookup to allow for i18n. >+ * >+ * @param bundleInfo >+ * the bundle info >+ * @param makeLocal >+ * whether to make the about content local >+ * @return the url or <code>null</code> >+ */ >+ private URL getMoreInfoURL(AboutBundleData bundleInfo, boolean makeLocal) { >+ Bundle bundle = Platform.getBundle(bundleInfo.getId()); >+ if (bundle == null) { >+ return null; >+ } >+ >+ URL aboutUrl = Platform.find(bundle, baseNLPath.append(PLUGININFO), >+ null); >+ if (!makeLocal) { >+ return aboutUrl; >+ } >+ if (aboutUrl != null) { >+ try { >+ URL result = Platform.asLocalURL(aboutUrl); >+ try { >+ // Make local all content in the "about" directory. >+ // This is needed to handle jar'ed plug-ins. >+ // See Bug 88240 [About] About dialog needs to extract >+ // subdirs. >+ URL about = new URL(aboutUrl, "about_files"); //$NON-NLS-1$ >+ if (about != null) { >+ Platform.asLocalURL(about); >+ } >+ } catch (IOException e) { >+ // skip the about dir if its not found or there are other >+ // problems. >+ } >+ return result; >+ } catch (IOException e) { >+ // do nothing >+ } >+ } >+ return null; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.internal.about.ProductInfoPage#getId() >+ */ >+ String getId() { >+ return ID; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.internal.about.ColumnsPage#getTable() >+ */ >+ protected Table getTable() { >+ return vendorInfo.getTable(); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.internal.about.TableListPage#getURL() >+ */ >+ protected URL getURL() { >+ if (vendorInfo == null) >+ return null; >+ >+ if (vendorInfo.getSelection().isEmpty()) >+ return null; >+ >+ AboutBundleData bundleInfo = (AboutBundleData) ((IStructuredSelection) vendorInfo >+ .getSelection()).getFirstElement(); >+ URL url = getMoreInfoURL(bundleInfo, true); >+ >+ // only report problems if the -debug command line argument is used >+ if (url == null && WorkbenchPlugin.DEBUG) { >+ WorkbenchPlugin.log("Problem reading plugin info for: " //$NON-NLS-1$ >+ + bundleInfo.getName()); >+ } >+ return url; >+ } >+ >+ private void checkSigningEnablement() { >+ // enable if there is an item selected and that >+ // item has additional info >+ IStructuredSelection selection = (IStructuredSelection) vendorInfo >+ .getSelection(); >+ if (selection.getFirstElement() instanceof AboutBundleData) { >+ AboutBundleData selected = (AboutBundleData) selection >+ .getFirstElement(); >+ signingInfo.setEnabled(true); >+ if (signingArea != null) { >+ signingArea.setData(selected); >+ } >+ } else { >+ signingInfo.setEnabled(false); >+ } >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.internal.about.TableListPage#getSelectionValue() >+ */ >+ protected Collection getSelectionValue() { >+ if (vendorInfo == null) >+ return null; >+ IStructuredSelection selection = (IStructuredSelection) vendorInfo >+ .getSelection(); >+ if (selection.getFirstElement() instanceof AboutBundleData) { >+ ArrayList list = new ArrayList(1); >+ list.add(selection.getFirstElement()); >+ return list; >+ } >+ return null; >+ } >+} >+ >+class TableComparator extends ViewerComparator { >+ >+ private int sortColumn = 0; >+ private boolean ascending = true; >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see >+ * org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface. >+ * viewers.Viewer, java.lang.Object, java.lang.Object) >+ */ >+ public int compare(Viewer viewer, Object e1, Object e2) { >+ if (sortColumn == 0 && e1 instanceof AboutBundleData >+ && e2 instanceof AboutBundleData) { >+ AboutBundleData d1 = (AboutBundleData) e1; >+ AboutBundleData d2 = (AboutBundleData) e2; >+ int diff = getSignedSortValue(d1) - getSignedSortValue(d2); >+ return ascending ? diff : -diff; >+ } >+ if (viewer instanceof TableViewer) { >+ TableViewer tableViewer = (TableViewer) viewer; >+ IBaseLabelProvider baseLabel = tableViewer.getLabelProvider(); >+ if (baseLabel instanceof ITableLabelProvider) { >+ ITableLabelProvider tableProvider = (ITableLabelProvider) baseLabel; >+ String e1p = tableProvider.getColumnText(e1, sortColumn); >+ String e2p = tableProvider.getColumnText(e2, sortColumn); >+ int result = getComparator().compare(e1p, e2p); >+ return ascending ? result : (-1) * result; >+ } >+ } >+ >+ return super.compare(viewer, e1, e2); >+ } >+ >+ /** >+ * @param data >+ * @return a sort value depending on the signed state >+ */ >+ private int getSignedSortValue(AboutBundleData data) { >+ if (!data.isSignedDetermined()) { >+ return 0; >+ } else if (data.isSigned()) { >+ return 1; >+ } else { >+ return -1; >+ } >+ } >+ >+ /** >+ * @return Returns the sortColumn. >+ */ >+ public int getSortColumn() { >+ return sortColumn; >+ } >+ >+ /** >+ * @param sortColumn >+ * The sortColumn to set. >+ */ >+ public void setSortColumn(int sortColumn) { >+ this.sortColumn = sortColumn; >+ } >+ >+ /** >+ * @return Returns the ascending. >+ */ >+ public boolean isAscending() { >+ return ascending; >+ } >+ >+ /** >+ * @param ascending >+ * The ascending to set. >+ */ >+ public void setAscending(boolean ascending) { >+ this.ascending = ascending; >+ } >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/CopyHandler.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/CopyHandler.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/CopyHandler.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/CopyHandler.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,25 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.ui.internal.about; >+ >+import org.eclipse.core.commands.ExecutionEvent; >+import org.eclipse.ui.about.InstallationPage; >+ >+public class CopyHandler extends ProductInfoPageHandler { >+ >+ protected Object execute(InstallationPage page, ExecutionEvent event) { >+ if (page instanceof ProductInfoPage) { >+ ((ProductInfoPage)page).copyToClipboard(); >+ } >+ return null; >+ } >+} >\ No newline at end of file >Index: Eclipse UI/org/eclipse/ui/internal/about/AboutSystemPage.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/AboutSystemPage.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/AboutSystemPage.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/AboutSystemPage.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,128 @@ >+/******************************************************************************* >+ * Copyright (c) 2003, 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.ui.internal.about; >+ >+import org.eclipse.core.commands.AbstractHandler; >+import org.eclipse.core.commands.ExecutionEvent; >+import org.eclipse.core.commands.ExecutionException; >+import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.dnd.Clipboard; >+import org.eclipse.swt.dnd.TextTransfer; >+import org.eclipse.swt.dnd.Transfer; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Text; >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.internal.ConfigurationInfo; >+import org.eclipse.ui.internal.IWorkbenchHelpContextIds; >+ >+/** >+ * Displays system information about the eclipse application. The content of >+ * what is displayed is selectable through the >+ * <code>org.eclipse.ui.systemSummaryExtensions</code> extension point. >+ */ >+public final class AboutSystemPage extends ProductInfoPage { >+ >+ class CopyHandler extends AbstractHandler { >+ /* >+ * (non-Javadoc) >+ * >+ * @see >+ * org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands >+ * .ExecutionEvent) >+ */ >+ public Object execute(ExecutionEvent event) throws ExecutionException { >+ if (text == null) { >+ return null; >+ } >+ >+ Clipboard clipboard = null; >+ try { >+ clipboard = new Clipboard(getShell().getDisplay()); >+ String contents = text.getSelectionText(); >+ if (contents.length() == 0) >+ contents = text.getText(); >+ clipboard.setContents(new Object[] { contents }, >+ new Transfer[] { TextTransfer.getInstance() }); >+ } finally { >+ if (clipboard != null) { >+ clipboard.dispose(); >+ } >+ } >+ return null; >+ } >+ >+ public boolean isEnabled() { >+ return true; >+ } >+ } >+ >+ // This id should *not* be the same id used for contributing the page in >+ // the installationPage extension. It is used by ProductInfoDialog >+ // to ensure a different namespace for button contributions than the id >+ // for the page appearing in the InstallationDialog >+ private static final String ID = "productInfo.system"; //$NON-NLS-1$ >+ >+ private Text text; >+ >+ protected Control createPageControl(Composite parent) { >+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, >+ IWorkbenchHelpContextIds.SYSTEM_SUMMARY_DIALOG); >+ >+ Composite outer = createOuterComposite(parent); >+ >+ text = new Text(outer, SWT.MULTI | SWT.BORDER | SWT.READ_ONLY >+ | SWT.V_SCROLL | SWT.NO_FOCUS | SWT.H_SCROLL); >+ text.setBackground(parent.getDisplay().getSystemColor( >+ SWT.COLOR_LIST_BACKGROUND)); >+ GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL >+ | GridData.VERTICAL_ALIGN_FILL); >+ gridData.grabExcessVerticalSpace = true; >+ gridData.grabExcessHorizontalSpace = true; >+ gridData.heightHint = convertVerticalDLUsToPixels(300); >+ gridData.widthHint = convertHorizontalDLUsToPixels(400); >+ text.setLayoutData(gridData); >+ text.setText(ConfigurationInfo.getSystemSummary()); >+ text.setFont(JFaceResources.getTextFont()); >+ return outer; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.internal.about.ProductInfoPage#getId() >+ */ >+ String getId() { >+ return ID; >+ } >+ >+ public void copyToClipboard() { >+ if (text == null) { >+ return; >+ } >+ >+ Clipboard clipboard = null; >+ try { >+ clipboard = new Clipboard(text.getShell().getDisplay()); >+ String contents = text.getSelectionText(); >+ if (contents.length() == 0) >+ contents = text.getText(); >+ clipboard.setContents(new Object[] { contents }, >+ new Transfer[] { TextTransfer.getInstance() }); >+ } finally { >+ if (clipboard != null) { >+ clipboard.dispose(); >+ } >+ } >+ } >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/ConfigureColumnsHandler.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/ConfigureColumnsHandler.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/ConfigureColumnsHandler.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/ConfigureColumnsHandler.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,24 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.ui.internal.about; >+ >+import org.eclipse.core.commands.ExecutionEvent; >+import org.eclipse.ui.about.InstallationPage; >+ >+public class ConfigureColumnsHandler extends ProductInfoPageHandler { >+ >+ protected Object execute(InstallationPage page, ExecutionEvent event) { >+ if (page instanceof TableListPage) >+ ((TableListPage)page).handleColumnsPressed(); >+ return null; >+ } >+} >\ No newline at end of file >Index: Eclipse UI/org/eclipse/ui/about/IInstallationPageSources.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/about/IInstallationPageSources.java >diff -N Eclipse UI/org/eclipse/ui/about/IInstallationPageSources.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/about/IInstallationPageSources.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,26 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.ui.about; >+ >+/** >+ * <em>This API is experimental and will change before 3.5 ships</em> >+ * >+ * @since 3.5 >+ */ >+public interface IInstallationPageSources { >+ >+ public static final String ACTIVE_PAGE = "org.eclipse.ui.installationPage.activePage"; //$NON-NLS-1$ >+ public static final String ACTIVE_PAGE_ID = "org.eclipse.ui.installationPage.activePage.id"; //$NON-NLS-1$ >+ public static final String ACTIVE_PAGE_SELECTION = "org.eclipse.ui.installationPage.activePage.selection"; //$NON-NLS-1$ >+ >+ >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/OpenBrowserHandler.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/OpenBrowserHandler.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/OpenBrowserHandler.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/OpenBrowserHandler.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,39 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.ui.internal.about; >+ >+import java.net.URL; >+ >+import org.eclipse.core.commands.ExecutionEvent; >+import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.ui.about.InstallationPage; >+import org.eclipse.ui.handlers.HandlerUtil; >+import org.eclipse.ui.internal.WorkbenchMessages; >+ >+public class OpenBrowserHandler extends ProductInfoPageHandler { >+ >+ protected Object execute(InstallationPage page, ExecutionEvent event) { >+ Shell shell = HandlerUtil.getActiveShell(event); >+ if (page instanceof TableListPage) { >+ TableListPage p = (TableListPage) page; >+ URL url = p.getURL(); >+ if (url != null && AboutUtils.openBrowser(shell, url)) >+ return null; >+ } >+ // nothing to show, but the user is expecting feedback. >+ MessageDialog.openInformation(HandlerUtil.getActiveShell(event), >+ WorkbenchMessages.OpenBrowserHandler_NoInfoDialogTitle, >+ WorkbenchMessages.OpenBrowserHandler_NoInfoDialogMessage); >+ return null; >+ } >+} >\ No newline at end of file >Index: Eclipse UI/org/eclipse/ui/internal/about/AboutUtils.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/AboutUtils.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/AboutUtils.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/AboutUtils.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,270 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.ui.internal.about; >+ >+import java.io.File; >+import java.io.FileNotFoundException; >+import java.io.FileReader; >+import java.io.FileWriter; >+import java.io.IOException; >+import java.net.MalformedURLException; >+import java.net.URL; >+import java.util.ArrayList; >+import java.util.StringTokenizer; >+ >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.ui.PartInitException; >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.browser.IWebBrowser; >+import org.eclipse.ui.browser.IWorkbenchBrowserSupport; >+import org.eclipse.ui.internal.WorkbenchMessages; >+import org.eclipse.ui.internal.WorkbenchPlugin; >+import org.eclipse.ui.internal.misc.StatusUtil; >+import org.eclipse.ui.statushandlers.StatusManager; >+ >+/** >+ * Manages links in styled text. >+ */ >+ >+public class AboutUtils { >+ >+ private final static String ERROR_LOG_COPY_FILENAME = "log"; //$NON-NLS-1$ >+ >+ /** >+ * Scan the contents of the about text >+ * >+ * @param s >+ * @return >+ */ >+ public static AboutItem scan(String s) { >+ ArrayList linkRanges = new ArrayList(); >+ ArrayList links = new ArrayList(); >+ >+ // slightly modified version of jface url detection >+ // see org.eclipse.jface.text.hyperlink.URLHyperlinkDetector >+ >+ int urlSeparatorOffset = s.indexOf("://"); //$NON-NLS-1$ >+ while (urlSeparatorOffset >= 0) { >+ >+ boolean startDoubleQuote = false; >+ >+ // URL protocol (left to "://") >+ int urlOffset = urlSeparatorOffset; >+ char ch; >+ do { >+ urlOffset--; >+ ch = ' '; >+ if (urlOffset > -1) >+ ch = s.charAt(urlOffset); >+ startDoubleQuote = ch == '"'; >+ } while (Character.isUnicodeIdentifierStart(ch)); >+ urlOffset++; >+ >+ // Right to "://" >+ StringTokenizer tokenizer = new StringTokenizer(s >+ .substring(urlSeparatorOffset + 3), " \t\n\r\f<>", false); //$NON-NLS-1$ >+ if (!tokenizer.hasMoreTokens()) >+ return null; >+ >+ int urlLength = tokenizer.nextToken().length() + 3 >+ + urlSeparatorOffset - urlOffset; >+ >+ if (startDoubleQuote) { >+ int endOffset = -1; >+ int nextDoubleQuote = s.indexOf('"', urlOffset); >+ int nextWhitespace = s.indexOf(' ', urlOffset); >+ if (nextDoubleQuote != -1 && nextWhitespace != -1) >+ endOffset = Math.min(nextDoubleQuote, nextWhitespace); >+ else if (nextDoubleQuote != -1) >+ endOffset = nextDoubleQuote; >+ else if (nextWhitespace != -1) >+ endOffset = nextWhitespace; >+ if (endOffset != -1) >+ urlLength = endOffset - urlOffset; >+ } >+ >+ linkRanges.add(new int[] { urlOffset, urlLength }); >+ links.add(s.substring(urlOffset, urlOffset + urlLength)); >+ >+ urlSeparatorOffset = s.indexOf("://", urlOffset + urlLength + 1); //$NON-NLS-1$ >+ } >+ return new AboutItem(s, (int[][]) linkRanges.toArray(new int[linkRanges >+ .size()][2]), (String[]) links >+ .toArray(new String[links.size()])); >+ } >+ >+ /** >+ * Open a browser with the argument title on the argument url. If the url >+ * refers to a resource within a bundle, then a temp copy of the file will >+ * be extracted and opened. >+ * >+ * @see <code>Platform.asLocalUrl</code> >+ * @param url >+ * The target url to be displayed, null will be safely ignored >+ * @return true if the url was successfully displayed and false otherwise >+ */ >+ public static boolean openBrowser(Shell shell, URL url) { >+ if (url != null) { >+ try { >+ url = Platform.asLocalURL(url); >+ } catch (IOException e) { >+ return false; >+ } >+ } >+ if (url == null) { >+ return false; >+ } >+ openLink(shell, url.toString()); >+ return true; >+ } >+ >+ /** >+ * Open a link >+ */ >+ public static void openLink(Shell shell, String href) { >+ // format the href for an html file (file:///<filename.html> >+ // required for Mac only. >+ if (href.startsWith("file:")) { //$NON-NLS-1$ >+ href = href.substring(5); >+ while (href.startsWith("/")) { //$NON-NLS-1$ >+ href = href.substring(1); >+ } >+ href = "file:///" + href; //$NON-NLS-1$ >+ } >+ IWorkbenchBrowserSupport support = PlatformUI.getWorkbench() >+ .getBrowserSupport(); >+ try { >+ IWebBrowser browser = support.getExternalBrowser(); >+ browser.openURL(new URL(urlEncodeForSpaces(href.toCharArray()))); >+ } catch (MalformedURLException e) { >+ openWebBrowserError(shell, href, e); >+ } catch (PartInitException e) { >+ openWebBrowserError(shell, href, e); >+ } >+ } >+ >+ /** >+ * This method encodes the url, removes the spaces from the url and replaces >+ * the same with <code>"%20"</code>. This method is required to fix Bug >+ * 77840. >+ * >+ * @since 3.0.2 >+ */ >+ private static String urlEncodeForSpaces(char[] input) { >+ StringBuffer retu = new StringBuffer(input.length); >+ for (int i = 0; i < input.length; i++) { >+ if (input[i] == ' ') { >+ retu.append("%20"); //$NON-NLS-1$ >+ } else { >+ retu.append(input[i]); >+ } >+ } >+ return retu.toString(); >+ } >+ >+ /** >+ * display an error message >+ */ >+ private static void openWebBrowserError(Shell shell, final String href, >+ final Throwable t) { >+ String title = WorkbenchMessages.ProductInfoDialog_errorTitle; >+ String msg = NLS.bind( >+ WorkbenchMessages.ProductInfoDialog_unableToOpenWebBrowser, >+ href); >+ IStatus status = WorkbenchPlugin.getStatus(t); >+ StatusUtil.handleStatus(status, title + ": " + msg, StatusManager.SHOW, //$NON-NLS-1$ >+ shell); >+ } >+ >+ public static void openErrorLogBrowser(Shell shell) { >+ String filename = Platform.getLogFileLocation().toOSString(); >+ >+ File log = new File(filename); >+ if (log.exists()) { >+ // Make a copy of the file with a temporary name. >+ // Working around an issue with windows file associations/browser >+ // malfunction whereby the browser doesn't open on ".log" and we >+ // aren't returned an error. >+ // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97783 >+ File logCopy = makeDisplayCopy(log); >+ if (logCopy != null) { >+ AboutUtils.openLink(shell, >+ "file:///" + logCopy.getAbsolutePath()); //$NON-NLS-1$ >+ return; >+ } >+ // Couldn't make copy, try to open the original log. >+ // We try the original in this case rather than putting up an error, >+ // because the copy could fail due to an I/O or out of space >+ // problem. >+ // In that case we may still be able to show the original log, >+ // depending on the platform. The risk is that users with >+ // configurations that have bug #97783 will still get nothing >+ // (vs. an error) but we'd rather >+ // try again than put up an error dialog on platforms where the >+ // ability to view the original log works just fine. >+ AboutUtils.openLink(shell, "file:///" + filename); //$NON-NLS-1$ >+ return; >+ } >+ MessageDialog.openInformation(shell, >+ WorkbenchMessages.AboutSystemDialog_noLogTitle, NLS.bind( >+ WorkbenchMessages.AboutSystemDialog_noLogMessage, >+ filename)); >+ } >+ >+ /** >+ * Returns a copy of the given file to be used for display in a browser. >+ * >+ * @return the file, or <code>null</code> >+ */ >+ private static File makeDisplayCopy(File file) { >+ IPath path = WorkbenchPlugin.getDefault().getDataLocation(); >+ if (path == null) { >+ return null; >+ } >+ path = path.append(ERROR_LOG_COPY_FILENAME); >+ File copy = path.toFile(); >+ FileReader in = null; >+ FileWriter out = null; >+ try { >+ in = new FileReader(file); >+ // don't append data, overwrite what was there >+ out = new FileWriter(copy); >+ char buffer[] = new char[4096]; >+ int count; >+ while ((count = in.read(buffer, 0, buffer.length)) > 0) { >+ out.write(buffer, 0, count); >+ } >+ } catch (FileNotFoundException e) { >+ return null; >+ } catch (IOException e) { >+ return null; >+ } finally { >+ try { >+ if (in != null) { >+ in.close(); >+ } >+ if (out != null) { >+ out.close(); >+ } >+ } catch (IOException e) { >+ return null; >+ } >+ } >+ return copy; >+ >+ } >+ >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/AboutTextManager.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/AboutTextManager.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/AboutTextManager.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/AboutTextManager.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,350 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.ui.internal.about; >+ >+import java.util.ArrayList; >+import java.util.StringTokenizer; >+ >+import org.eclipse.jface.resource.JFaceColors; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.custom.StyleRange; >+import org.eclipse.swt.custom.StyledText; >+import org.eclipse.swt.events.DisposeEvent; >+import org.eclipse.swt.events.DisposeListener; >+import org.eclipse.swt.events.KeyAdapter; >+import org.eclipse.swt.events.KeyEvent; >+import org.eclipse.swt.events.MouseAdapter; >+import org.eclipse.swt.events.MouseEvent; >+import org.eclipse.swt.events.MouseMoveListener; >+import org.eclipse.swt.events.TraverseEvent; >+import org.eclipse.swt.events.TraverseListener; >+import org.eclipse.swt.graphics.Color; >+import org.eclipse.swt.graphics.Cursor; >+import org.eclipse.swt.graphics.Point; >+ >+/** >+ * Manages links in styled text. >+ */ >+ >+public class AboutTextManager { >+ >+ /** >+ * Scan the contents of the about text >+ * @param s >+ * @return >+ */ >+ public static AboutItem scan(String s) { >+ ArrayList linkRanges = new ArrayList(); >+ ArrayList links = new ArrayList(); >+ >+ // slightly modified version of jface url detection >+ // see org.eclipse.jface.text.hyperlink.URLHyperlinkDetector >+ >+ int urlSeparatorOffset= s.indexOf("://"); //$NON-NLS-1$ >+ while(urlSeparatorOffset >= 0) { >+ >+ boolean startDoubleQuote= false; >+ >+ // URL protocol (left to "://") >+ int urlOffset= urlSeparatorOffset; >+ char ch; >+ do { >+ urlOffset--; >+ ch= ' '; >+ if (urlOffset > -1) >+ ch= s.charAt(urlOffset); >+ startDoubleQuote= ch == '"'; >+ } while (Character.isUnicodeIdentifierStart(ch)); >+ urlOffset++; >+ >+ >+ // Right to "://" >+ StringTokenizer tokenizer= new StringTokenizer(s.substring(urlSeparatorOffset + 3), " \t\n\r\f<>", false); //$NON-NLS-1$ >+ if (!tokenizer.hasMoreTokens()) >+ return null; >+ >+ int urlLength= tokenizer.nextToken().length() + 3 + urlSeparatorOffset - urlOffset; >+ >+ if (startDoubleQuote) { >+ int endOffset= -1; >+ int nextDoubleQuote= s.indexOf('"', urlOffset); >+ int nextWhitespace= s.indexOf(' ', urlOffset); >+ if (nextDoubleQuote != -1 && nextWhitespace != -1) >+ endOffset= Math.min(nextDoubleQuote, nextWhitespace); >+ else if (nextDoubleQuote != -1) >+ endOffset= nextDoubleQuote; >+ else if (nextWhitespace != -1) >+ endOffset= nextWhitespace; >+ if (endOffset != -1) >+ urlLength= endOffset - urlOffset; >+ } >+ >+ linkRanges.add(new int[] { urlOffset, urlLength }); >+ links.add(s.substring(urlOffset, urlOffset+urlLength)); >+ >+ urlSeparatorOffset= s.indexOf("://", urlOffset+urlLength+1); //$NON-NLS-1$ >+ } >+ return new AboutItem(s, (int[][]) linkRanges.toArray(new int[linkRanges >+ .size()][2]), (String[]) links >+ .toArray(new String[links.size()])); >+ } >+ private StyledText styledText; >+ >+ private Cursor handCursor; >+ >+ private Cursor busyCursor; >+ >+ private boolean mouseDown = false; >+ >+ private boolean dragEvent = false; >+ >+ private AboutItem item; >+ >+ public AboutTextManager(StyledText text) { >+ this.styledText = text; >+ createCursors(); >+ addListeners(); >+ } >+ >+ private void createCursors() { >+ handCursor = new Cursor(styledText.getDisplay(), SWT.CURSOR_HAND); >+ busyCursor = new Cursor(styledText.getDisplay(), SWT.CURSOR_WAIT); >+ styledText.addDisposeListener(new DisposeListener() { >+ public void widgetDisposed(DisposeEvent e) { >+ handCursor.dispose(); >+ handCursor = null; >+ busyCursor.dispose(); >+ busyCursor = null; >+ } >+ }); >+ } >+ >+ >+ /** >+ * Adds listeners to the given styled text >+ */ >+ protected void addListeners() { >+ styledText.addMouseListener(new MouseAdapter() { >+ public void mouseDown(MouseEvent e) { >+ if (e.button != 1) { >+ return; >+ } >+ mouseDown = true; >+ } >+ >+ public void mouseUp(MouseEvent e) { >+ mouseDown = false; >+ int offset = styledText.getCaretOffset(); >+ if (dragEvent) { >+ // don't activate a link during a drag/mouse up operation >+ dragEvent = false; >+ if (item != null && item.isLinkAt(offset)) { >+ styledText.setCursor(handCursor); >+ } >+ } else if (item != null && item.isLinkAt(offset)) { >+ styledText.setCursor(busyCursor); >+ AboutUtils.openLink(styledText.getShell(), item.getLinkAt(offset)); >+ StyleRange selectionRange = getCurrentRange(); >+ styledText.setSelectionRange(selectionRange.start, >+ selectionRange.length); >+ styledText.setCursor(null); >+ } >+ } >+ }); >+ >+ styledText.addMouseMoveListener(new MouseMoveListener() { >+ public void mouseMove(MouseEvent e) { >+ // Do not change cursor on drag events >+ if (mouseDown) { >+ if (!dragEvent) { >+ StyledText text = (StyledText) e.widget; >+ text.setCursor(null); >+ } >+ dragEvent = true; >+ return; >+ } >+ StyledText text = (StyledText) e.widget; >+ int offset = -1; >+ try { >+ offset = text.getOffsetAtLocation(new Point(e.x, e.y)); >+ } catch (IllegalArgumentException ex) { >+ // leave value as -1 >+ } >+ if (offset == -1) { >+ text.setCursor(null); >+ } else if (item != null && item.isLinkAt(offset)) { >+ text.setCursor(handCursor); >+ } else { >+ text.setCursor(null); >+ } >+ } >+ }); >+ >+ styledText.addTraverseListener(new TraverseListener() { >+ public void keyTraversed(TraverseEvent e) { >+ switch (e.detail) { >+ case SWT.TRAVERSE_ESCAPE: >+ e.doit = true; >+ break; >+ case SWT.TRAVERSE_TAB_NEXT: >+ //Previously traverse out in the backward direction? >+ Point nextSelection = styledText.getSelection(); >+ int charCount = styledText.getCharCount(); >+ if ((nextSelection.x == charCount) >+ && (nextSelection.y == charCount)) { >+ styledText.setSelection(0); >+ } >+ StyleRange nextRange = findNextRange(); >+ if (nextRange == null) { >+ // Next time in start at beginning, also used by >+ // TRAVERSE_TAB_PREVIOUS to indicate we traversed out >+ // in the forward direction >+ styledText.setSelection(0); >+ e.doit = true; >+ } else { >+ styledText.setSelectionRange(nextRange.start, >+ nextRange.length); >+ e.doit = true; >+ e.detail = SWT.TRAVERSE_NONE; >+ } >+ break; >+ case SWT.TRAVERSE_TAB_PREVIOUS: >+ //Previously traverse out in the forward direction? >+ Point previousSelection = styledText.getSelection(); >+ if ((previousSelection.x == 0) >+ && (previousSelection.y == 0)) { >+ styledText.setSelection(styledText.getCharCount()); >+ } >+ StyleRange previousRange = findPreviousRange(); >+ if (previousRange == null) { >+ // Next time in start at the end, also used by >+ // TRAVERSE_TAB_NEXT to indicate we traversed out >+ // in the backward direction >+ styledText.setSelection(styledText.getCharCount()); >+ e.doit = true; >+ } else { >+ styledText.setSelectionRange(previousRange.start, >+ previousRange.length); >+ e.doit = true; >+ e.detail = SWT.TRAVERSE_NONE; >+ } >+ break; >+ default: >+ break; >+ } >+ } >+ }); >+ >+ //Listen for Tab and Space to allow keyboard navigation >+ styledText.addKeyListener(new KeyAdapter() { >+ public void keyPressed(KeyEvent event) { >+ StyledText text = (StyledText) event.widget; >+ if (event.character == ' ' || event.character == SWT.CR) { >+ if (item != null) { >+ //Be sure we are in the selection >+ int offset = text.getSelection().x + 1; >+ >+ if (item.isLinkAt(offset)) { >+ text.setCursor(busyCursor); >+ AboutUtils.openLink(styledText.getShell(), item.getLinkAt(offset)); >+ StyleRange selectionRange = getCurrentRange(); >+ text.setSelectionRange(selectionRange.start, >+ selectionRange.length); >+ text.setCursor(null); >+ } >+ } >+ return; >+ } >+ } >+ }); >+ } >+ >+ /** >+ * Gets the about item. >+ * @return the about item >+ */ >+ public AboutItem getItem() { >+ return item; >+ } >+ >+ /** >+ * Sets the about item. >+ * @param item about item >+ */ >+ public void setItem(AboutItem item) { >+ this.item = item; >+ if (item != null) { >+ styledText.setText(item.getText()); >+ setLinkRanges(item.getLinkRanges()); >+ } >+ } >+ >+ /** >+ * Find the range of the current selection. >+ */ >+ private StyleRange getCurrentRange() { >+ StyleRange[] ranges = styledText.getStyleRanges(); >+ int currentSelectionEnd = styledText.getSelection().y; >+ int currentSelectionStart = styledText.getSelection().x; >+ >+ for (int i = 0; i < ranges.length; i++) { >+ if ((currentSelectionStart >= ranges[i].start) >+ && (currentSelectionEnd <= (ranges[i].start + ranges[i].length))) { >+ return ranges[i]; >+ } >+ } >+ return null; >+ } >+ >+ /** >+ * Find the next range after the current >+ * selection. >+ */ >+ private StyleRange findNextRange() { >+ StyleRange[] ranges = styledText.getStyleRanges(); >+ int currentSelectionEnd = styledText.getSelection().y; >+ >+ for (int i = 0; i < ranges.length; i++) { >+ if (ranges[i].start >= currentSelectionEnd) { >+ return ranges[i]; >+ } >+ } >+ return null; >+ } >+ >+ /** >+ * Find the previous range before the current selection. >+ */ >+ private StyleRange findPreviousRange() { >+ StyleRange[] ranges = styledText.getStyleRanges(); >+ int currentSelectionStart = styledText.getSelection().x; >+ >+ for (int i = ranges.length - 1; i > -1; i--) { >+ if ((ranges[i].start + ranges[i].length - 1) < currentSelectionStart) { >+ return ranges[i]; >+ } >+ } >+ return null; >+ } >+ >+ /** >+ * Sets the styled text's link (blue) ranges >+ */ >+ private void setLinkRanges(int[][] linkRanges) { >+ Color fg = JFaceColors.getHyperlinkText(styledText.getShell() >+ .getDisplay()); >+ for (int i = 0; i < linkRanges.length; i++) { >+ StyleRange r = new StyleRange(linkRanges[i][0], linkRanges[i][1], >+ fg, null); >+ styledText.setStyleRange(r); >+ } >+ } >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/TableListPage.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/TableListPage.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/TableListPage.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/TableListPage.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,67 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog >+ * font should be activated and used by other components. >+ *******************************************************************************/ >+package org.eclipse.ui.internal.about; >+ >+import java.net.URL; >+import java.util.Collection; >+ >+import org.eclipse.core.expressions.IEvaluationContext; >+import org.eclipse.jface.internal.ConfigureColumnsDialog; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.ui.about.IInstallationPageSources; >+import org.eclipse.ui.services.IServiceLocator; >+import org.eclipse.ui.services.ISourceProviderService; >+ >+/** >+ * Displays information about the product plugins. >+ * >+ * PRIVATE This class is internal to the workbench and must not be called >+ * outside the workbench. >+ */ >+abstract class TableListPage extends ProductInfoPage { >+ >+ InstallationDialogSourceProvider sourceProvider; >+ >+ public void init(IServiceLocator locator) { >+ super.init(locator); >+ // cache the source provider and prime the selection variable >+ ISourceProviderService sps = (ISourceProviderService) locator >+ .getService(ISourceProviderService.class); >+ sourceProvider = (InstallationDialogSourceProvider) sps >+ .getSourceProvider(IInstallationPageSources.ACTIVE_PAGE_SELECTION); >+ selectionChanged(); >+ } >+ >+ public void handleColumnsPressed() { >+ ConfigureColumnsDialog d = new ConfigureColumnsDialog(this, getTable()); >+ d.open(); >+ } >+ >+ protected abstract URL getURL(); >+ >+ protected abstract Table getTable(); >+ >+ protected void selectionChanged() { >+ Object selection = getSelectionValue(); >+ if (selection == null) >+ selection = IEvaluationContext.UNDEFINED_VARIABLE; >+ // This is an ugly hack, but necessary for maintaining different >+ // selection variables in different contexts. >+ if (getInstallationDialog() instanceof ProductInfoDialog) >+ sourceProvider.setProductDialogPageSelection(selection); >+ else >+ sourceProvider.setPageSelection(selection); >+ } >+ >+ protected abstract Collection getSelectionValue(); >+} >Index: Eclipse UI/org/eclipse/ui/internal/about/ViewErrorLogHandler.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/ViewErrorLogHandler.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/ViewErrorLogHandler.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/ViewErrorLogHandler.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,29 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.ui.internal.about; >+ >+import org.eclipse.core.commands.ExecutionEvent; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.about.InstallationPage; >+import org.eclipse.ui.handlers.HandlerUtil; >+ >+public class ViewErrorLogHandler extends ProductInfoPageHandler { >+ >+ protected Object execute(InstallationPage page, ExecutionEvent event) { >+ Shell shell = HandlerUtil.getActiveShell(event); >+ if (shell == null) >+ shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); >+ AboutUtils.openErrorLogBrowser(shell); >+ return null; >+ } >+} >\ No newline at end of file >Index: Eclipse UI/org/eclipse/ui/internal/about/ProductInfoPageHandler.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/ProductInfoPageHandler.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/ProductInfoPageHandler.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/ProductInfoPageHandler.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,50 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.ui.internal.about; >+ >+import org.eclipse.core.commands.AbstractHandler; >+import org.eclipse.core.commands.ExecutionEvent; >+import org.eclipse.core.commands.ExecutionException; >+import org.eclipse.ui.about.IInstallationPageSources; >+import org.eclipse.ui.about.InstallationPage; >+import org.eclipse.ui.handlers.HandlerUtil; >+ >+abstract class ProductInfoPageHandler extends AbstractHandler { >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands >+ * .ExecutionEvent) >+ */ >+ public Object execute(ExecutionEvent event) throws ExecutionException { >+ InstallationPage page = getInstallationPage(event.getApplicationContext()); >+ if (page != null) >+ return execute(page, event); >+ return null; >+ } >+ >+ protected InstallationPage getInstallationPage(Object executionContext) { >+ // First look for an open product info dialog and use its page. >+ InstallationPage page = (InstallationPage) HandlerUtil.getVariable( >+ executionContext, >+ InstallationDialogSourceProvider.ACTIVE_PRODUCT_DIALOG_PAGE); >+ if (page == null) { >+ // Look for the active page in the installation dialog >+ page = (InstallationPage) HandlerUtil.getVariable(executionContext, >+ IInstallationPageSources.ACTIVE_PAGE); >+ } >+ return page; >+ } >+ >+ protected abstract Object execute(InstallationPage page, >+ ExecutionEvent event); >+} >\ No newline at end of file >Index: Eclipse UI/org/eclipse/ui/internal/about/AboutFeaturesPage.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/about/AboutFeaturesPage.java >diff -N Eclipse UI/org/eclipse/ui/internal/about/AboutFeaturesPage.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/about/AboutFeaturesPage.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,516 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog >+ * font should be activated and used by other components. >+ *******************************************************************************/ >+package org.eclipse.ui.internal.about; >+ >+import java.net.URL; >+import java.util.ArrayList; >+import java.util.Collection; >+import java.util.HashMap; >+import java.util.Iterator; >+import java.util.LinkedList; >+import java.util.Map; >+ >+import org.eclipse.core.runtime.IBundleGroup; >+import org.eclipse.core.runtime.IBundleGroupProvider; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.jface.action.Action; >+import org.eclipse.jface.action.ActionContributionItem; >+import org.eclipse.jface.resource.ImageDescriptor; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.custom.StyledText; >+import org.eclipse.swt.events.DisposeEvent; >+import org.eclipse.swt.events.DisposeListener; >+import org.eclipse.swt.events.SelectionAdapter; >+import org.eclipse.swt.events.SelectionEvent; >+import org.eclipse.swt.graphics.Font; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Label; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.TableColumn; >+import org.eclipse.swt.widgets.TableItem; >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.internal.IWorkbenchHelpContextIds; >+import org.eclipse.ui.internal.WorkbenchMessages; >+import org.eclipse.ui.internal.dialogs.AboutPluginsDialog; >+import org.eclipse.ui.menus.AbstractContributionFactory; >+import org.eclipse.ui.menus.IContributionRoot; >+import org.eclipse.ui.services.IServiceLocator; >+import org.osgi.framework.Bundle; >+ >+/** >+ * Displays information about the product plugins. >+ * >+ * PRIVATE This class is internal to the workbench and must not be called >+ * outside the workbench. >+ */ >+public class AboutFeaturesPage extends TableListPage { >+ >+ // This id should *not* be the same id used for contributing the page in >+ // the installationPage extension. It is used by ProductInfoDialog >+ // to ensure a different namespace for button contributions than the id >+ // for the page appearing in the InstallationDialog >+ private static final String ID = "productInfo.features"; //$NON-NLS-1$ >+ /** >+ * Table height in dialog units (value 150). >+ */ >+ private static final int TABLE_HEIGHT = 150; >+ >+ private static final int INFO_HEIGHT = 100; >+ >+ private Table table; >+ >+ private Label imageLabel; >+ >+ private StyledText text; >+ >+ private AboutTextManager textManager; >+ >+ private Composite infoArea; >+ >+ private Map cachedImages = new HashMap(); >+ >+ private AboutBundleGroupData[] bundleGroupInfos; >+ >+ private String columnTitles[] = { >+ WorkbenchMessages.AboutFeaturesDialog_provider, >+ WorkbenchMessages.AboutFeaturesDialog_featureName, >+ WorkbenchMessages.AboutFeaturesDialog_version, >+ WorkbenchMessages.AboutFeaturesDialog_featureId, }; >+ >+ private int lastColumnChosen = 0; // initially sort by provider >+ >+ private boolean reverseSort = false; // initially sort ascending >+ >+ private AboutBundleGroupData lastSelection = null; >+ >+ private Action pluginsAction; >+ >+ private static Map featuresMap; >+ >+ public void setBundleGroupInfos(AboutBundleGroupData[] bundleGroupInfos) { >+ this.bundleGroupInfos = bundleGroupInfos; >+ } >+ >+ String getId() { >+ return ID; >+ } >+ >+ private void initializeBundleGroupInfos() { >+ if (bundleGroupInfos == null) { >+ IBundleGroupProvider[] providers = Platform >+ .getBundleGroupProviders(); >+ >+ // create a descriptive object for each BundleGroup >+ LinkedList groups = new LinkedList(); >+ if (providers != null) { >+ for (int i = 0; i < providers.length; ++i) { >+ IBundleGroup[] bundleGroups = providers[i] >+ .getBundleGroups(); >+ for (int j = 0; j < bundleGroups.length; ++j) { >+ groups.add(new AboutBundleGroupData(bundleGroups[j])); >+ } >+ } >+ } >+ bundleGroupInfos = (AboutBundleGroupData[]) groups >+ .toArray(new AboutBundleGroupData[0]); >+ } else { >+ // the order of the array may be changed due to sorting, so create a >+ // copy, since the client set this value. >+ AboutBundleGroupData[] clientArray = bundleGroupInfos; >+ bundleGroupInfos = new AboutBundleGroupData[clientArray.length]; >+ System.arraycopy(clientArray, 0, bundleGroupInfos, 0, >+ clientArray.length); >+ } >+ AboutData.sortByProvider(reverseSort, bundleGroupInfos); >+ } >+ >+ /** >+ * The Plugins button was pressed. Open an about dialog on the plugins for >+ * the selected feature. >+ */ >+ private void handlePluginInfoPressed() { >+ TableItem[] items = table.getSelection(); >+ if (items.length <= 0) { >+ return; >+ } >+ >+ AboutBundleGroupData info = (AboutBundleGroupData) items[0].getData(); >+ IBundleGroup bundleGroup = info.getBundleGroup(); >+ Bundle[] bundles = bundleGroup == null ? new Bundle[0] : bundleGroup >+ .getBundles(); >+ >+ AboutPluginsDialog d = new AboutPluginsDialog( >+ getShell(), >+ getProductName(), >+ bundles, >+ WorkbenchMessages.AboutFeaturesDialog_pluginInfoTitle, >+ NLS >+ .bind( >+ WorkbenchMessages.AboutFeaturesDialog_pluginInfoMessage, >+ bundleGroup.getIdentifier()), >+ IWorkbenchHelpContextIds.ABOUT_FEATURES_PLUGINS_DIALOG); >+ d.open(); >+ } >+ >+ protected AbstractContributionFactory makeContributionFactory() { >+ return new AbstractContributionFactory(getInstallationDialog() >+ .getButtonBarURI(), null) { >+ >+ public void createContributionItems(IServiceLocator serviceLocator, >+ IContributionRoot additions) { >+ >+ pluginsAction = new Action( >+ WorkbenchMessages.AboutFeaturesDialog_pluginsInfo) { >+ public void run() { >+ handlePluginInfoPressed(); >+ } >+ }; >+ additions.addContributionItem(new ActionContributionItem( >+ pluginsAction), getInstallationDialog().getActivePageExpression(AboutFeaturesPage.this)); >+ } >+ }; >+ } >+ >+ protected Control createPageControl(Composite parent) { >+ initializeDialogUnits(parent); >+ parent.getShell().addDisposeListener(new DisposeListener() { >+ public void widgetDisposed(DisposeEvent arg0) { >+ disposeImages(); >+ } >+ }); >+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, >+ IWorkbenchHelpContextIds.ABOUT_FEATURES_DIALOG); >+ >+ Composite outer = createOuterComposite(parent); >+ >+ createTable(outer); >+ createInfoArea(outer); >+ return outer; >+ } >+ >+ /** >+ * Create the info area containing the image and text >+ */ >+ protected void createInfoArea(Composite parent) { >+ Font font = parent.getFont(); >+ >+ infoArea = new Composite(parent, SWT.NULL); >+ GridData data = new GridData(GridData.FILL, GridData.FILL, true, true); >+ // need to provide space for arbitrary feature infos, not just the >+ // one selected by default >+ data.heightHint = convertVerticalDLUsToPixels(INFO_HEIGHT); >+ infoArea.setLayoutData(data); >+ >+ GridLayout layout = new GridLayout(); >+ layout.numColumns = 2; >+ infoArea.setLayout(layout); >+ >+ imageLabel = new Label(infoArea, SWT.NONE); >+ data = new GridData(GridData.FILL, GridData.BEGINNING, false, false); >+ data.widthHint = 32; >+ data.heightHint = 32; >+ imageLabel.setLayoutData(data); >+ imageLabel.setFont(font); >+ >+ // text on the right >+ text = new StyledText(infoArea, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY); >+ text.setCaret(null); >+ text.setFont(parent.getFont()); >+ data = new GridData(GridData.FILL, GridData.FILL, true, true); >+ text.setLayoutData(data); >+ text.setFont(font); >+ text.setCursor(null); >+ >+ textManager = new AboutTextManager(text); >+ >+ TableItem[] items = table.getSelection(); >+ if (items.length > 0) { >+ updateInfoArea((AboutBundleGroupData) items[0].getData()); >+ } >+ } >+ >+ /** >+ * Create the table part of the dialog. >+ * >+ * @param parent >+ * the parent composite to contain the dialog area >+ */ >+ protected void createTable(Composite parent) { >+ >+ initializeBundleGroupInfos(); >+ >+ table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE >+ | SWT.FULL_SELECTION | SWT.BORDER); >+ >+ GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, >+ true); >+ gridData.heightHint = convertVerticalDLUsToPixels(TABLE_HEIGHT); >+ table.setLayoutData(gridData); >+ table.setHeaderVisible(true); >+ >+ table.setLinesVisible(true); >+ table.setFont(parent.getFont()); >+ table.addSelectionListener(new SelectionAdapter() { >+ public void widgetSelected(SelectionEvent e) { >+ AboutBundleGroupData info = (AboutBundleGroupData) e.item >+ .getData(); >+ updateInfoArea(info); >+ updateButtons(info); >+ selectionChanged(); >+ } >+ }); >+ >+ int[] columnWidths = { convertHorizontalDLUsToPixels(120), >+ convertHorizontalDLUsToPixels(120), >+ convertHorizontalDLUsToPixels(70), >+ convertHorizontalDLUsToPixels(130) }; >+ >+ for (int i = 0; i < columnTitles.length; i++) { >+ TableColumn tableColumn = new TableColumn(table, SWT.NULL); >+ tableColumn.setWidth(columnWidths[i]); >+ tableColumn.setText(columnTitles[i]); >+ final int columnIndex = i; >+ tableColumn.addSelectionListener(new SelectionAdapter() { >+ public void widgetSelected(SelectionEvent e) { >+ sort(columnIndex); >+ } >+ }); >+ } >+ >+ // create a table row for each bundle group >+ String selId = lastSelection == null ? null : lastSelection.getId(); >+ int sel = 0; >+ for (int i = 0; i < bundleGroupInfos.length; i++) { >+ if (bundleGroupInfos[i].getId().equals(selId)) { >+ sel = i; >+ } >+ >+ TableItem item = new TableItem(table, SWT.NULL); >+ item.setText(createRow(bundleGroupInfos[i])); >+ item.setData(bundleGroupInfos[i]); >+ } >+ >+ // if an item was specified during construction, it should be >+ // selected when the table is created >+ if (bundleGroupInfos.length > 0) { >+ table.setSelection(sel); >+ table.showSelection(); >+ } >+ } >+ >+ private void disposeImages() { >+ Iterator iter = cachedImages.values().iterator(); >+ while (iter.hasNext()) { >+ Image image = (Image) iter.next(); >+ image.dispose(); >+ } >+ } >+ >+ /** >+ * Update the button enablement >+ */ >+ private void updateButtons(AboutBundleGroupData info) { >+ >+ // called too early >+ if (pluginsAction == null) >+ return; >+ >+ if (info == null) { >+ pluginsAction.setEnabled(false); >+ return; >+ } >+ >+ // Creating the feature map is too much just to determine enablement, so >+ // if doesn't already exist, just enable the buttons. If this was the >+ // wrong choice, then when the button is actually pressed an dialog will >+ // be >+ // opened. >+ if (featuresMap == null) { >+ pluginsAction.setEnabled(true); >+ return; >+ } >+ >+ pluginsAction.setEnabled(true); >+ } >+ >+ /** >+ * Update the info area >+ */ >+ private void updateInfoArea(AboutBundleGroupData info) { >+ if (info == null) { >+ imageLabel.setImage(null); >+ text.setText(""); //$NON-NLS-1$ >+ return; >+ } >+ >+ ImageDescriptor desc = info.getFeatureImage(); >+ Image image = (Image) cachedImages.get(desc); >+ if (image == null && desc != null) { >+ image = desc.createImage(); >+ cachedImages.put(desc, image); >+ } >+ imageLabel.setImage(image); >+ >+ String aboutText = info.getAboutText(); >+ textManager.setItem(null); >+ if (aboutText != null) { >+ textManager.setItem(AboutUtils.scan(aboutText)); >+ } >+ >+ if (textManager.getItem() == null) { >+ text.setText(WorkbenchMessages.AboutFeaturesDialog_noInformation); >+ } >+ } >+ >+ /** >+ * Select the initial selection >+ * >+ * @param info >+ * the info >+ */ >+ public void setInitialSelection(AboutBundleGroupData info) { >+ lastSelection = info; >+ } >+ >+ /** >+ * Sort the rows of the table based on the selected column. >+ * >+ * @param column >+ * index of table column selected as sort criteria >+ */ >+ private void sort(int column) { >+ if (lastColumnChosen == column) { >+ reverseSort = !reverseSort; >+ } else { >+ reverseSort = false; >+ lastColumnChosen = column; >+ } >+ >+ if (table.getItemCount() <= 1) { >+ return; >+ } >+ >+ // Remember the last selection >+ int sel = table.getSelectionIndex(); >+ if (sel != -1) { >+ lastSelection = bundleGroupInfos[sel]; >+ } >+ >+ switch (column) { >+ case 0: >+ AboutData.sortByProvider(reverseSort, bundleGroupInfos); >+ break; >+ case 1: >+ AboutData.sortByName(reverseSort, bundleGroupInfos); >+ break; >+ case 2: >+ AboutData.sortByVersion(reverseSort, bundleGroupInfos); >+ break; >+ case 3: >+ AboutData.sortById(reverseSort, bundleGroupInfos); >+ break; >+ } >+ >+ refreshTable(); >+ } >+ >+ /** >+ * Refresh the rows of the table based on the selected column. Maintain >+ * selection from before sort action request. >+ */ >+ private void refreshTable() { >+ TableItem[] items = table.getItems(); >+ >+ // create new order of table items >+ for (int i = 0; i < items.length; i++) { >+ items[i].setText(createRow(bundleGroupInfos[i])); >+ items[i].setData(bundleGroupInfos[i]); >+ } >+ >+ // Maintain the original selection >+ int sel = -1; >+ if (lastSelection != null) { >+ String oldId = lastSelection.getId(); >+ for (int k = 0; k < bundleGroupInfos.length; k++) { >+ if (oldId.equalsIgnoreCase(bundleGroupInfos[k].getId())) { >+ sel = k; >+ } >+ } >+ >+ table.setSelection(sel); >+ table.showSelection(); >+ } >+ >+ updateInfoArea(lastSelection); >+ } >+ >+ /** >+ * Return an array of strings containing the argument's information in the >+ * proper order for this table's columns. >+ * >+ * @param info >+ * the source information for the new row, must not be null >+ */ >+ private static String[] createRow(AboutBundleGroupData info) { >+ return new String[] { info.getProviderName(), info.getName(), >+ info.getVersion(), info.getId() }; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.internal.about.ColumnsPage#getTable() >+ */ >+ protected Table getTable() { >+ return table; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.ui.internal.about.TableListPage#getURL() >+ */ >+ protected URL getURL() { >+ if (table == null || table.isDisposed()) >+ return null; >+ TableItem[] items = table.getSelection(); >+ if (items.length <= 0) >+ return null; >+ >+ AboutBundleGroupData info = (AboutBundleGroupData) items[0].getData(); >+ if (info == null) >+ return null; >+ >+ return info.getLicenseUrl(); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.ui.internal.about.TableListPage#getSelectionValue() >+ */ >+ protected Collection getSelectionValue() { >+ if (table == null || table.isDisposed()) >+ return null; >+ TableItem[] items = table.getSelection(); >+ if (items.length <= 0) { >+ return null; >+ } >+ ArrayList list = new ArrayList(1); >+ list.add(items[0].getData()); >+ return list; >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 246875
:
112344
|
112420
|
115725
|
125194
| 125936