KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import org.eclipse.core.runtime.IBundleGroup;
20 import org.eclipse.jface.dialogs.IDialogConstants;
21 import org.eclipse.jface.dialogs.MessageDialog;
22 import org.eclipse.jface.resource.ImageDescriptor;
23 import org.eclipse.jface.window.Window;
24 import org.eclipse.osgi.util.NLS;
25 import org.eclipse.swt.SWT;
26 import org.eclipse.swt.custom.StyledText;
27 import org.eclipse.swt.events.DisposeEvent;
28 import org.eclipse.swt.events.DisposeListener;
29 import org.eclipse.swt.events.SelectionAdapter;
30 import org.eclipse.swt.events.SelectionEvent;
31 import org.eclipse.swt.graphics.Cursor;
32 import org.eclipse.swt.graphics.Font;
33 import org.eclipse.swt.graphics.Image;
34 import org.eclipse.swt.layout.GridData;
35 import org.eclipse.swt.layout.GridLayout;
36 import org.eclipse.swt.widgets.Button;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Control;
39 import org.eclipse.swt.widgets.Label;
40 import org.eclipse.swt.widgets.Shell;
41 import org.eclipse.swt.widgets.Table;
42 import org.eclipse.swt.widgets.TableColumn;
43 import org.eclipse.swt.widgets.TableItem;
44 import org.eclipse.ui.PlatformUI;
45 import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
46 import org.eclipse.ui.internal.WorkbenchMessages;
47 import org.eclipse.ui.internal.about.AboutBundleGroupData;
48 import org.eclipse.ui.internal.about.AboutData;
49 import org.osgi.framework.Bundle;
50
51 /**
52  * Displays information about the product plugins.
53  *
54  * PRIVATE
55  * This class is internal to the workbench and must not be called outside
56  * the workbench.
57  */

58 public class AboutFeaturesDialog extends ProductInfoDialog {
59
60     /**
61      * Table height in dialog units (value 150).
62      */

63     private static final int TABLE_HEIGHT = 150;
64
65     private static final int INFO_HEIGHT = 100;
66
67     private final static int MORE_ID = IDialogConstants.CLIENT_ID + 1;
68
69     private final static int PLUGINS_ID = IDialogConstants.CLIENT_ID + 2;
70
71     private Table table;
72
73     private Label imageLabel;
74
75     private StyledText text;
76
77     private Composite infoArea;
78
79     private Map JavaDoc cachedImages = new HashMap JavaDoc();
80
81     private String JavaDoc columnTitles[] = {
82             WorkbenchMessages.AboutFeaturesDialog_provider,
83             WorkbenchMessages.AboutFeaturesDialog_featureName,
84             WorkbenchMessages.AboutFeaturesDialog_version,
85             WorkbenchMessages.AboutFeaturesDialog_featureId,
86     };
87
88     private String JavaDoc productName;
89
90     private AboutBundleGroupData[] bundleGroupInfos;
91
92     private int lastColumnChosen = 0; // initially sort by provider
93

94     private boolean reverseSort = false; // initially sort ascending
95

96     private AboutBundleGroupData lastSelection = null;
97
98     private Button moreButton;
99
100     private Button pluginsButton;
101
102     private static Map JavaDoc featuresMap;
103
104     /**
105      * Constructor for AboutFeaturesDialog.
106      *
107      * @param parentShell the parent shell
108      * @param productName the product name
109      * @param bundleGroupInfos the bundle info
110      */

111     public AboutFeaturesDialog(Shell parentShell, String JavaDoc productName,
112             AboutBundleGroupData[] bundleGroupInfos) {
113         super(parentShell);
114         setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
115
116         this.productName = productName;
117
118         // the order of the array may be changed due to sorting, so create a
119
// copy
120
this.bundleGroupInfos = new AboutBundleGroupData[bundleGroupInfos.length];
121         System.arraycopy(bundleGroupInfos, 0, this.bundleGroupInfos, 0,
122                 bundleGroupInfos.length);
123
124         AboutData.sortByProvider(reverseSort, this.bundleGroupInfos);
125     }
126
127     /**
128      * The More Info button was pressed. Open a browser with the license for the
129      * selected item or an information dialog if there is no license, or the browser
130      * cannot be opened.
131      */

132     private void handleMoreInfoPressed() {
133         TableItem[] items = table.getSelection();
134         if (items.length <= 0) {
135             return;
136         }
137
138         AboutBundleGroupData info = (AboutBundleGroupData) items[0].getData();
139         if (info == null || !openBrowser(info.getLicenseUrl())) {
140             MessageDialog.openInformation(getShell(), WorkbenchMessages.AboutFeaturesDialog_noInfoTitle,
141                     WorkbenchMessages.AboutFeaturesDialog_noInformation);
142         }
143     }
144
145     /**
146      * The Plugins button was pressed. Open an about dialog on the plugins for
147      * the selected feature.
148      */

149     private void handlePluginInfoPressed() {
150         TableItem[] items = table.getSelection();
151         if (items.length <= 0) {
152             return;
153         }
154
155         AboutBundleGroupData info = (AboutBundleGroupData) items[0].getData();
156         IBundleGroup bundleGroup = info.getBundleGroup();
157         Bundle[] bundles = bundleGroup == null ? new Bundle[0] : bundleGroup
158                 .getBundles();
159
160         AboutPluginsDialog d = new AboutPluginsDialog(getShell(), productName,
161                 bundles, WorkbenchMessages.AboutFeaturesDialog_pluginInfoTitle,
162                 NLS.bind(WorkbenchMessages.AboutFeaturesDialog_pluginInfoMessage, bundleGroup.getIdentifier()),
163                 IWorkbenchHelpContextIds.ABOUT_FEATURES_PLUGINS_DIALOG);
164         d.open();
165     }
166
167     /*
168      * (non-Javadoc) Method declared on Dialog.
169      */

170     protected void buttonPressed(int buttonId) {
171         switch (buttonId) {
172         case MORE_ID:
173             handleMoreInfoPressed();
174             break;
175         case PLUGINS_ID:
176             handlePluginInfoPressed();
177             break;
178         default:
179             super.buttonPressed(buttonId);
180             break;
181         }
182     }
183
184     /*
185      * (non-Javadoc) Method declared on Window.
186      */

187     protected void configureShell(Shell newShell) {
188         super.configureShell(newShell);
189         if (productName != null) {
190             newShell.setText(NLS.bind(WorkbenchMessages.AboutFeaturesDialog_shellTitle,productName));
191         }
192
193         PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell,
194                 IWorkbenchHelpContextIds.ABOUT_FEATURES_DIALOG);
195     }
196
197     /**
198      * Add buttons to the dialog's button bar.
199      *
200      * Subclasses should override.
201      *
202      * @param parent
203      * the button bar composite
204      */

205     protected void createButtonsForButtonBar(Composite parent) {
206         parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
207
208         moreButton = createButton(parent, MORE_ID, WorkbenchMessages.AboutFeaturesDialog_moreInfo, false);
209         pluginsButton = createButton(parent, PLUGINS_ID, WorkbenchMessages.AboutFeaturesDialog_pluginsInfo, false);
210         Label l = new Label(parent, SWT.NONE);
211         l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
212         GridLayout layout = (GridLayout) parent.getLayout();
213         layout.numColumns++;
214         layout.makeColumnsEqualWidth = false;
215
216         Button b = createButton(parent, IDialogConstants.OK_ID,
217                 IDialogConstants.OK_LABEL, true);
218         b.setFocus();
219
220         TableItem[] items = table.getSelection();
221         if (items.length > 0) {
222             updateButtons((AboutBundleGroupData) items[0].getData());
223         }
224     }
225
226     /**
227      * Create the contents of the dialog (above the button bar).
228      *
229      * Subclasses should overide.
230      *
231      * @param parent the parent composite to contain the dialog area
232      * @return the dialog area control
233      */

234     protected Control createDialogArea(Composite parent) {
235         setHandCursor(new Cursor(parent.getDisplay(), SWT.CURSOR_HAND));
236         setBusyCursor(new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT));
237         getShell().addDisposeListener(new DisposeListener() {
238             public void widgetDisposed(DisposeEvent e) {
239                 if (getHandCursor() != null) {
240                     getHandCursor().dispose();
241                 }
242                 if (getBusyCursor() != null) {
243                     getBusyCursor().dispose();
244                 }
245             }
246         });
247
248         Composite outer = (Composite) super.createDialogArea(parent);
249
250         createTable(outer);
251         createInfoArea(outer);
252         
253         return outer;
254     }
255
256     /**
257      * Create the info area containing the image and text
258      */

259     protected void createInfoArea(Composite parent) {
260         Font font = parent.getFont();
261
262         infoArea = new Composite(parent, SWT.NULL);
263         GridData data = new GridData(GridData.FILL, GridData.FILL, true, true);
264         // need to provide space for arbitrary feature infos, not just the
265
// one selected by default
266
data.heightHint = convertVerticalDLUsToPixels(INFO_HEIGHT);
267         infoArea.setLayoutData(data);
268
269         GridLayout layout = new GridLayout();
270         layout.numColumns = 2;
271         infoArea.setLayout(layout);
272
273         imageLabel = new Label(infoArea, SWT.NONE);
274         data = new GridData(GridData.FILL, GridData.BEGINNING, false, false);
275         data.widthHint = 32;
276         data.heightHint = 32;
277         imageLabel.setLayoutData(data);
278         imageLabel.setFont(font);
279
280         // text on the right
281
text = new StyledText(infoArea, SWT.MULTI | SWT.READ_ONLY);
282         text.setCaret(null);
283         text.setFont(parent.getFont());
284         data = new GridData(GridData.FILL, GridData.FILL, true, true);
285         text.setLayoutData(data);
286         text.setFont(font);
287         text.setCursor(null);
288         text.setBackground(infoArea.getBackground());
289         addListeners(text);
290
291         TableItem[] items = table.getSelection();
292         if (items.length > 0) {
293             updateInfoArea((AboutBundleGroupData) items[0].getData());
294         }
295     }
296
297     /**
298      * Create the table part of the dialog.
299      *
300      * @param parent the parent composite to contain the dialog area
301      */

302     protected void createTable(Composite parent) {
303         table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE
304                 | SWT.FULL_SELECTION | SWT.BORDER);
305         
306         GridData gridData = new GridData(GridData.FILL, GridData.FILL, true,
307                 true);
308         gridData.heightHint = convertVerticalDLUsToPixels(TABLE_HEIGHT);
309         table.setLayoutData(gridData);
310         table.setHeaderVisible(true);
311         
312         table.setLinesVisible(true);
313         table.setFont(parent.getFont());
314         table.addSelectionListener(new SelectionAdapter() {
315             public void widgetSelected(SelectionEvent e) {
316                 AboutBundleGroupData info = (AboutBundleGroupData) e.item
317                         .getData();
318                 updateInfoArea(info);
319                 updateButtons(info);
320             }
321         });
322         
323         int[] columnWidths = { convertHorizontalDLUsToPixels(120),
324                 convertHorizontalDLUsToPixels(120),
325                 convertHorizontalDLUsToPixels(70),
326                 convertHorizontalDLUsToPixels(130) };
327
328         for (int i = 0; i < columnTitles.length; i++) {
329             TableColumn tableColumn = new TableColumn(table, SWT.NULL);
330             tableColumn.setWidth(columnWidths[i]);
331             tableColumn.setText(columnTitles[i]);
332             final int columnIndex = i;
333             tableColumn.addSelectionListener(new SelectionAdapter() {
334                 public void widgetSelected(SelectionEvent e) {
335                     sort(columnIndex);
336                 }
337             });
338         }
339
340         // create a table row for each bundle group
341
String JavaDoc selId = lastSelection == null ? null : lastSelection.getId();
342         int sel = 0;
343         for (int i = 0; i < bundleGroupInfos.length; i++) {
344             if (bundleGroupInfos[i].getId().equals(selId)) {
345                 sel = i;
346             }
347
348             TableItem item = new TableItem(table, SWT.NULL);
349             item.setText(createRow(bundleGroupInfos[i]));
350             item.setData(bundleGroupInfos[i]);
351         }
352
353         // if an item was specified during construction, it should be
354
// selected when the table is created
355
if (bundleGroupInfos.length > 0) {
356             table.setSelection(sel);
357             table.showSelection();
358         }
359     }
360
361     /**
362      * @see Window#close()
363      */

364     public boolean close() {
365         boolean ret = super.close();
366
367         Iterator JavaDoc iter = cachedImages.values().iterator();
368         while (iter.hasNext()) {
369             Image image = (Image) iter.next();
370             image.dispose();
371         }
372
373         return ret;
374     }
375
376     /**
377      * Update the button enablement
378      */

379     private void updateButtons(AboutBundleGroupData info) {
380         if (info == null) {
381             moreButton.setEnabled(false);
382             pluginsButton.setEnabled(false);
383             return;
384         }
385
386         // Creating the feature map is too much just to determine enablement, so if
387
// it doesn't already exist, just enable the buttons. If this was the wrong
388
// choice, then when the button is actually pressed an dialog will be opened.
389
if (featuresMap == null) {
390             moreButton.setEnabled(true);
391             pluginsButton.setEnabled(true);
392             return;
393         }
394
395         moreButton.setEnabled(info.getLicenseUrl() != null);
396         pluginsButton.setEnabled(true);
397     }
398
399     /**
400      * Update the info area
401      */

402     private void updateInfoArea(AboutBundleGroupData info) {
403         if (info == null) {
404             imageLabel.setImage(null);
405             text.setText(""); //$NON-NLS-1$
406
return;
407         }
408
409         ImageDescriptor desc = info.getFeatureImage();
410         Image image = (Image) cachedImages.get(desc);
411         if (image == null && desc != null) {
412             image = desc.createImage();
413             cachedImages.put(desc, image);
414         }
415         imageLabel.setImage(image);
416
417         String JavaDoc aboutText = info.getAboutText();
418         setItem(null);
419         if (aboutText != null) {
420             setItem(scan(aboutText));
421         }
422
423         if (getItem() == null) {
424             text.setText(WorkbenchMessages.AboutFeaturesDialog_noInformation);
425         } else {
426             text.setText(getItem().getText());
427             text.setCursor(null);
428             setLinkRanges(text, getItem().getLinkRanges());
429         }
430     }
431
432     /**
433      * Select the initial selection
434      *
435      * @param info the info
436      */

437     public void setInitialSelection(AboutBundleGroupData info) {
438         lastSelection = info;
439     }
440
441     /**
442      * Sort the rows of the table based on the selected column.
443      *
444      * @param column
445      * index of table column selected as sort criteria
446      */

447     private void sort(int column) {
448         if (lastColumnChosen == column) {
449             reverseSort = !reverseSort;
450         } else {
451             reverseSort = false;
452             lastColumnChosen = column;
453         }
454
455         if (table.getItemCount() <= 1) {
456             return;
457         }
458
459         // Remember the last selection
460
int sel = table.getSelectionIndex();
461         if (sel != -1) {
462             lastSelection = bundleGroupInfos[sel];
463         }
464
465         switch (column) {
466         case 0:
467             AboutData.sortByProvider(reverseSort, bundleGroupInfos);
468             break;
469         case 1:
470             AboutData.sortByName(reverseSort, bundleGroupInfos);
471             break;
472         case 2:
473             AboutData.sortByVersion(reverseSort, bundleGroupInfos);
474             break;
475         case 3:
476             AboutData.sortById(reverseSort, bundleGroupInfos);
477             break;
478         }
479
480         refreshTable();
481     }
482
483     /**
484      * Refresh the rows of the table based on the selected column. Maintain
485      * selection from before sort action request.
486      */

487     private void refreshTable() {
488         TableItem[] items = table.getItems();
489
490         // create new order of table items
491
for (int i = 0; i < items.length; i++) {
492             items[i].setText(createRow(bundleGroupInfos[i]));
493             items[i].setData(bundleGroupInfos[i]);
494         }
495
496         // Maintain the original selection
497
int sel = -1;
498         if (lastSelection != null) {
499             String JavaDoc oldId = lastSelection.getId();
500             for (int k = 0; k < bundleGroupInfos.length; k++) {
501                 if (oldId.equalsIgnoreCase(bundleGroupInfos[k].getId())) {
502                     sel = k;
503                 }
504             }
505
506             table.setSelection(sel);
507             table.showSelection();
508         }
509
510         updateInfoArea(lastSelection);
511     }
512
513     /**
514      * Return an array of strings containing the argument's information in the
515      * proper order for this table's columns.
516      *
517      * @param info
518      * the source information for the new row, must not be null
519      */

520     private static String JavaDoc[] createRow(AboutBundleGroupData info) {
521         return new String JavaDoc[] { info.getProviderName(), info.getName(),
522                 info.getVersion(), info.getId() };
523     }
524 }
525
Popular Tags