KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > dialogs > AboutPluginsDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog
11  * font should be activated and used by other components.
12  *******************************************************************************/

13 package org.eclipse.ui.internal.dialogs;
14
15 import java.io.IOException JavaDoc;
16 import java.net.URL JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.Path;
24 import org.eclipse.core.runtime.Platform;
25 import org.eclipse.core.runtime.Status;
26 import org.eclipse.core.runtime.jobs.Job;
27 import org.eclipse.jface.dialogs.DialogTray;
28 import org.eclipse.core.runtime.jobs.ISchedulingRule;
29 import org.eclipse.jface.dialogs.IDialogConstants;
30 import org.eclipse.jface.viewers.ArrayContentProvider;
31 import org.eclipse.jface.viewers.IBaseLabelProvider;
32 import org.eclipse.jface.viewers.ISelectionChangedListener;
33 import org.eclipse.jface.viewers.IStructuredSelection;
34 import org.eclipse.jface.viewers.ITableLabelProvider;
35 import org.eclipse.jface.viewers.LabelProvider;
36 import org.eclipse.jface.viewers.LabelProviderChangedEvent;
37 import org.eclipse.jface.viewers.SelectionChangedEvent;
38 import org.eclipse.jface.viewers.TableViewer;
39 import org.eclipse.jface.viewers.Viewer;
40 import org.eclipse.jface.viewers.ViewerComparator;
41 import org.eclipse.osgi.util.NLS;
42 import org.eclipse.swt.SWT;
43 import org.eclipse.swt.events.SelectionAdapter;
44 import org.eclipse.swt.events.SelectionEvent;
45 import org.eclipse.swt.graphics.Image;
46 import org.eclipse.swt.layout.GridData;
47 import org.eclipse.swt.layout.GridLayout;
48 import org.eclipse.swt.widgets.Button;
49 import org.eclipse.swt.widgets.Composite;
50 import org.eclipse.swt.widgets.Control;
51 import org.eclipse.swt.widgets.Label;
52 import org.eclipse.swt.widgets.Shell;
53 import org.eclipse.swt.widgets.TableColumn;
54 import org.eclipse.ui.PlatformUI;
55 import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
56 import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
57 import org.eclipse.ui.internal.WorkbenchImages;
58 import org.eclipse.ui.internal.WorkbenchMessages;
59 import org.eclipse.ui.internal.WorkbenchPlugin;
60 import org.eclipse.ui.internal.about.AboutBundleData;
61 import org.eclipse.ui.internal.misc.StatusUtil;
62 import org.eclipse.ui.internal.util.BundleUtility;
63 import org.eclipse.ui.statushandlers.StatusManager;
64 import org.osgi.framework.Bundle;
65
66 /**
67  * Displays information about the product plugins.
68  *
69  * PRIVATE
70  * this class is internal to the ide
71  */

72 public class AboutPluginsDialog extends ProductInfoDialog {
73
74     public class BundleTableLabelProvider extends LabelProvider implements ITableLabelProvider {
75         
76         /**
77          * Scheduling rule for resolve jobs.
78          */

79         private ISchedulingRule resolveRule = new ISchedulingRule() {
80
81             public boolean contains(ISchedulingRule rule) {
82                 return rule == this;
83             }
84
85             public boolean isConflicting(ISchedulingRule rule) {
86                 return rule == this;
87             }};
88             
89         /* (non-Javadoc)
90          * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
91          */

92         public Image getColumnImage(Object JavaDoc element, int columnIndex) {
93             if (columnIndex == 0) {
94                 if (element instanceof AboutBundleData) {
95                     final AboutBundleData data = (AboutBundleData) element;
96                     if (data.isSignedDetermined()) {
97                         return WorkbenchImages
98                                 .getImage(data.isSigned() ? IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_YES
99                                         : IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_NO);
100                     }
101                     Job resolveJob = new Job(data.getId()){
102
103                         protected IStatus run(IProgressMonitor monitor) {
104                             
105                             data.isSigned();
106                             Shell dialogShell = getShell();
107                             if (dialogShell == null || dialogShell.isDisposed())
108                                 return Status.OK_STATUS;
109                                 
110                             dialogShell.getDisplay().asyncExec(new Runnable JavaDoc() {
111
112                                 public void run() {
113                                     fireLabelProviderChanged(new LabelProviderChangedEvent(
114                                             BundleTableLabelProvider.this, data));
115                                 }
116                             });
117
118
119                             return Status.OK_STATUS;
120                         }
121                     };
122                     resolveJob.setRule(resolveRule);
123                     resolveJob.setSystem(true);
124                     resolveJob.schedule();
125                     return WorkbenchImages
126                             .getImage(IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_UNKNOWN);
127                 }
128             }
129             return null;
130         }
131
132         /* (non-Javadoc)
133          * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
134          */

135         public String JavaDoc getColumnText(Object JavaDoc element, int columnIndex) {
136             if (element instanceof AboutBundleData) {
137                 AboutBundleData data = (AboutBundleData) element;
138                 switch (columnIndex) {
139                 case 1:
140                     return data.getProviderName();
141                 case 2:
142                     return data.getName();
143                 case 3:
144                     return data.getVersion();
145                 case 4:
146                     return data.getId();
147                 }
148             }
149             return ""; //$NON-NLS-1$
150
}
151     }
152     
153     /**
154      * Table height in dialog units (value 200).
155      */

156     private static final int TABLE_HEIGHT = 200;
157
158     private static final IPath baseNLPath = new Path("$nl$"); //$NON-NLS-1$
159

160     private static final String JavaDoc PLUGININFO = "about.html"; //$NON-NLS-1$
161

162     private final static int MORE_ID = IDialogConstants.CLIENT_ID + 1;
163     private final static int SIGNING_ID = MORE_ID + 1;
164
165     private TableViewer vendorInfo;
166
167     private Button moreInfo, signingInfo;
168
169     private String JavaDoc title;
170
171     private String JavaDoc message;
172     
173     private String JavaDoc helpContextId;
174
175     private String JavaDoc columnTitles[] = {
176             WorkbenchMessages.AboutPluginsDialog_signed,
177             WorkbenchMessages.AboutPluginsDialog_provider,
178             WorkbenchMessages.AboutPluginsDialog_pluginName,
179             WorkbenchMessages.AboutPluginsDialog_version,
180             WorkbenchMessages.AboutPluginsDialog_pluginId,
181             
182     };
183
184     private String JavaDoc productName;
185
186     private AboutBundleData[] bundleInfos;
187     
188     /**
189      * Constructor for AboutPluginsDialog.
190      *
191      * @param parentShell the parent shell
192      * @param productName the product name
193      */

194     public AboutPluginsDialog(Shell parentShell, String JavaDoc productName) {
195         this(parentShell, productName, WorkbenchPlugin.getDefault()
196                 .getBundles(), null, null, IWorkbenchHelpContextIds.ABOUT_PLUGINS_DIALOG);
197         WorkbenchPlugin.class.getSigners();
198     }
199
200     /**
201      * Constructor for AboutPluginsDialog.
202      *
203      * @param parentShell
204      * the parent shell
205      * @param productName
206      * must not be null
207      * @param bundles
208      * must not be null
209      * @param title
210      * the title
211      * @param message
212      * the message
213      * @param helpContextId
214      * the help context id
215      */

216     public AboutPluginsDialog(Shell parentShell, String JavaDoc productName,
217             Bundle[] bundles, String JavaDoc title, String JavaDoc message, String JavaDoc helpContextId) {
218         super(parentShell);
219         setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
220         this.title = title;
221         this.message = message;
222         this.helpContextId = helpContextId;
223         this.productName = productName;
224         
225         // create a data object for each bundle, remove duplicates, and include only resolved bundles (bug 65548)
226
Map JavaDoc map = new HashMap JavaDoc();
227         for (int i = 0; i < bundles.length; ++i) {
228             AboutBundleData data = new AboutBundleData(bundles[i]);
229             if (BundleUtility.isReady(data.getState()) && !map.containsKey(data.getVersionedId())) {
230                 map.put(data.getVersionedId(), data);
231             }
232         }
233         bundleInfos = (AboutBundleData[]) map.values().toArray(
234                 new AboutBundleData[0]);
235     }
236
237     /*
238      * (non-Javadoc) Method declared on Dialog.
239      */

240     protected void buttonPressed(int buttonId) {
241         switch (buttonId) {
242         case MORE_ID:
243             handleMoreInfoPressed();
244             break;
245         case SIGNING_ID:
246             handleSigningInfoPressed();
247             break;
248         default:
249             super.buttonPressed(buttonId);
250             break;
251         }
252     }
253
254     /**
255      */

256     private void handleSigningInfoPressed() {
257         DialogTray existingTray = getTray();
258         if (existingTray instanceof BundleSigningTray) {
259             // hide
260
getButton(SIGNING_ID).setText(WorkbenchMessages.AboutPluginsDialog_signingInfo_show);
261             closeTray();
262         }
263         else {
264             //show
265
getButton(SIGNING_ID).setText(WorkbenchMessages.AboutPluginsDialog_signingInfo_hide);
266             if (existingTray != null)
267                 closeTray();
268             AboutBundleData bundleInfo = (AboutBundleData) ((IStructuredSelection) vendorInfo
269                     .getSelection()).getFirstElement();
270             BundleSigningTray tray = new BundleSigningTray(this);
271             tray.setData(bundleInfo);
272             openTray(tray);
273         }
274         
275     }
276
277     /*
278      * (non-Javadoc) Method declared on Window.
279      */

280     protected void configureShell(Shell newShell) {
281         super.configureShell(newShell);
282         
283         //signImage = new Image( this.getParentShell().getDisplay(), AboutPluginsDialog.class.getResourceAsStream("Signed.gif")); //$NON-NLS-1$
284

285         if (title == null && productName != null) {
286             title = NLS.bind(WorkbenchMessages.AboutPluginsDialog_shellTitle, productName);
287         }
288
289         if (title != null) {
290             newShell.setText(title);
291         }
292
293         PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
294                 helpContextId);
295     }
296     
297     /**
298      * Add buttons to the dialog's button bar.
299      *
300      * Subclasses should override.
301      *
302      * @param parent
303      * the button bar composite
304      */

305     protected void createButtonsForButtonBar(Composite parent) {
306         parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
307
308         moreInfo = createButton(parent, MORE_ID, WorkbenchMessages.AboutPluginsDialog_moreInfo, false);
309         moreInfo.setEnabled(false);
310         
311         signingInfo = createButton(parent, SIGNING_ID, WorkbenchMessages.AboutPluginsDialog_signingInfo_show, false);
312         signingInfo.setEnabled(false);
313
314         Label l = new Label(parent, SWT.NONE);
315         l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
316         GridLayout layout = (GridLayout) parent.getLayout();
317         layout.numColumns++;
318         layout.makeColumnsEqualWidth = false;
319
320         createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
321                 true);
322     }
323
324     /**
325      * Create the contents of the dialog (above the button bar).
326      *
327      * Subclasses should overide.
328      *
329      * @param parent
330      * the parent composite to contain the dialog area
331      * @return the dialog area control
332      */

333     protected Control createDialogArea(Composite parent) {
334         Composite outer = (Composite) super.createDialogArea(parent);
335
336         if (message != null) {
337             Label label = new Label(outer, SWT.NONE);
338             label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
339             label.setFont(parent.getFont());
340             label.setText(message);
341         }
342
343         createTable(outer);
344
345         return outer;
346     }
347
348     /**
349      * Create the table part of the dialog.
350      *
351      * @param parent
352      * the parent composite to contain the dialog area
353      */

354     protected void createTable(Composite parent) {
355         vendorInfo = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE
356                 | SWT.FULL_SELECTION | SWT.BORDER);
357         vendorInfo.setUseHashlookup(true);
358         vendorInfo.getTable().setHeaderVisible(true);
359         vendorInfo.getTable().setLinesVisible(true);
360         vendorInfo.getTable().setFont(parent.getFont());
361         vendorInfo.addSelectionChangedListener(new ISelectionChangedListener() {
362
363             public void selectionChanged(SelectionChangedEvent event) {
364                 // enable if there is an item selected and that
365
// item has additional info
366
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
367                 if (selection.getFirstElement() instanceof AboutBundleData) {
368                     AboutBundleData selected = (AboutBundleData) selection.getFirstElement();
369                     moreInfo.setEnabled(selectionHasInfo(selected));
370                     signingInfo.setEnabled(true);
371                     if (getTray() instanceof BundleSigningTray) {
372                         ((BundleSigningTray)getTray()).setData(selected);
373                     }
374                 }
375                 else {
376                     moreInfo.setEnabled(false);
377                     signingInfo.setEnabled(false);
378                 }
379             }});
380         
381         final TableComparator comparator = new TableComparator();
382         comparator.setSortColumn(1); // sort on name initially
383

384         int[] columnWidths = {
385                 convertHorizontalDLUsToPixels(30), //signature
386
convertHorizontalDLUsToPixels(120),
387                 convertHorizontalDLUsToPixels(120),
388                 convertHorizontalDLUsToPixels(70),
389                 convertHorizontalDLUsToPixels(130),
390                 };
391
392         
393         // create table headers
394
for (int i = 0; i < columnTitles.length; i++) {
395             TableColumn column = new TableColumn(vendorInfo.getTable(), SWT.NULL);
396             column.setWidth(columnWidths[i]);
397             column.setText(columnTitles[i]);
398             final int columnIndex = i;
399             column.addSelectionListener(new SelectionAdapter() {
400                 public void widgetSelected(SelectionEvent e) {
401                     if (columnIndex == comparator.getSortColumn()) {
402                         comparator.setAscending(!comparator.isAscending());
403                     }
404                     comparator.setSortColumn(columnIndex);
405                     vendorInfo.refresh();
406                 }
407             });
408         }
409         
410         vendorInfo.setComparator(comparator);
411         vendorInfo.setContentProvider(new ArrayContentProvider());
412         vendorInfo.setLabelProvider(new BundleTableLabelProvider());
413        
414         GridData gridData = new GridData(GridData.FILL, GridData.FILL, true,
415                 true);
416         gridData.heightHint = convertVerticalDLUsToPixels(TABLE_HEIGHT);
417         vendorInfo.getTable().setLayoutData(gridData);
418         
419         vendorInfo.setInput(bundleInfos);
420     }
421
422     /**
423      * Check if the currently selected plugin has additional information to
424      * show.
425      * @param bundleInfo
426      *
427      * @return true if the selected plugin has additional info available to
428      * display
429      */

430     private boolean selectionHasInfo(AboutBundleData bundleInfo) {
431         
432         URL JavaDoc infoURL = getMoreInfoURL(bundleInfo, false);
433
434         // only report ini problems if the -debug command line argument is used
435
if (infoURL == null && WorkbenchPlugin.DEBUG) {
436             WorkbenchPlugin.log("Problem reading plugin info for: " //$NON-NLS-1$
437
+ bundleInfo.getName());
438         }
439
440         return infoURL != null;
441     }
442
443     /**
444      * The More Info button was pressed. Open a browser showing the license information
445      * for the selected bundle or an error dialog if the browser cannot be opened.
446      */

447     protected void handleMoreInfoPressed() {
448         if (vendorInfo == null) {
449             return;
450         }
451         
452         if (vendorInfo.getSelection().isEmpty())
453             return;
454         
455         AboutBundleData bundleInfo = (AboutBundleData) ((IStructuredSelection) vendorInfo
456                 .getSelection()).getFirstElement();
457         
458         if (!openBrowser(getMoreInfoURL(bundleInfo, true))) {
459             String JavaDoc message = NLS.bind(
460                     WorkbenchMessages.AboutPluginsDialog_unableToOpenFile,
461                     PLUGININFO, bundleInfo.getId());
462             StatusUtil.handleStatus(
463                     WorkbenchMessages.AboutPluginsDialog_errorTitle
464                             + ": " + message, StatusManager.SHOW, getShell()); //$NON-NLS-1$
465
}
466     }
467
468     /**
469      * Return an url to the plugin's about.html file (what is shown when "More info" is
470      * pressed) or null if no such file exists. The method does nl lookup to allow for
471      * i18n.
472      *
473      * @param bundleInfo the bundle info
474      * @param makeLocal whether to make the about content local
475      * @return the url or <code>null</code>
476      */

477     private URL JavaDoc getMoreInfoURL(AboutBundleData bundleInfo, boolean makeLocal) {
478         Bundle bundle = Platform.getBundle(bundleInfo.getId());
479         if (bundle == null) {
480             return null;
481         }
482
483         URL JavaDoc aboutUrl = Platform.find(bundle, baseNLPath.append(PLUGININFO), null);
484         if (!makeLocal) {
485             return aboutUrl;
486         }
487         if (aboutUrl != null) {
488             try {
489                 URL JavaDoc result = Platform.asLocalURL(aboutUrl);
490                 try {
491                     // Make local all content in the "about" directory.
492
// This is needed to handle jar'ed plug-ins.
493
// See Bug 88240 [About] About dialog needs to extract subdirs.
494
URL JavaDoc about = new URL JavaDoc(aboutUrl, "about_files"); //$NON-NLS-1$
495
if (about != null) {
496                         Platform.asLocalURL(about);
497                     }
498                 } catch (IOException JavaDoc e) {
499                     // skip the about dir if its not found or there are other problems.
500
}
501                 return result;
502             } catch(IOException JavaDoc e) {
503                 // do nothing
504
}
505         }
506         return null;
507     }
508 }
509
510
511 class TableComparator extends ViewerComparator {
512
513     private int sortColumn = 0;
514     private boolean ascending = true;
515     
516     /* (non-Javadoc)
517      * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
518      */

519     public int compare(Viewer viewer, Object JavaDoc e1, Object JavaDoc e2) {
520         if (viewer instanceof TableViewer) {
521             TableViewer tableViewer = (TableViewer) viewer;
522             IBaseLabelProvider baseLabel = tableViewer.getLabelProvider();
523             if (baseLabel instanceof ITableLabelProvider) {
524                 ITableLabelProvider tableProvider = (ITableLabelProvider) baseLabel;
525                 String JavaDoc e1p = tableProvider.getColumnText(e1, sortColumn);
526                 String JavaDoc e2p = tableProvider.getColumnText(e2, sortColumn);
527                 int result = getComparator().compare(e1p, e2p);
528                 return ascending ? result : (-1) * result;
529             }
530         }
531         
532         return super.compare(viewer, e1, e2);
533     }
534
535     /**
536      * @return Returns the sortColumn.
537      */

538     public int getSortColumn() {
539         return sortColumn;
540     }
541
542     /**
543      * @param sortColumn The sortColumn to set.
544      */

545     public void setSortColumn(int sortColumn) {
546         this.sortColumn = sortColumn;
547     }
548
549     /**
550      * @return Returns the ascending.
551      */

552     public boolean isAscending() {
553         return ascending;
554     }
555
556     /**
557      * @param ascending The ascending to set.
558      */

559     public void setAscending(boolean ascending) {
560         this.ascending = ascending;
561     }
562 }
563
Popular Tags