|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 package com.nokia.carbide.cpp; |
|
18 |
|
19 import java.net.URL; |
|
20 import java.util.ArrayList; |
|
21 import java.util.LinkedList; |
|
22 |
|
23 import org.eclipse.core.runtime.IBundleGroup; |
|
24 import org.eclipse.core.runtime.IBundleGroupProvider; |
|
25 import org.eclipse.core.runtime.IProduct; |
|
26 import org.eclipse.core.runtime.Platform; |
|
27 import org.eclipse.jface.dialogs.IDialogConstants; |
|
28 import org.eclipse.jface.resource.ImageDescriptor; |
|
29 import org.eclipse.jface.resource.JFaceColors; |
|
30 import org.eclipse.osgi.util.NLS; |
|
31 import org.eclipse.swt.SWT; |
|
32 import org.eclipse.swt.accessibility.AccessibleAdapter; |
|
33 import org.eclipse.swt.accessibility.AccessibleEvent; |
|
34 import org.eclipse.swt.custom.BusyIndicator; |
|
35 import org.eclipse.swt.custom.StyledText; |
|
36 import org.eclipse.swt.events.DisposeEvent; |
|
37 import org.eclipse.swt.events.DisposeListener; |
|
38 import org.eclipse.swt.events.SelectionAdapter; |
|
39 import org.eclipse.swt.events.SelectionEvent; |
|
40 import org.eclipse.swt.graphics.Color; |
|
41 import org.eclipse.swt.graphics.Cursor; |
|
42 import org.eclipse.swt.graphics.Image; |
|
43 import org.eclipse.swt.layout.GridData; |
|
44 import org.eclipse.swt.layout.GridLayout; |
|
45 import org.eclipse.swt.layout.RowLayout; |
|
46 import org.eclipse.swt.widgets.Button; |
|
47 import org.eclipse.swt.widgets.Composite; |
|
48 import org.eclipse.swt.widgets.Control; |
|
49 import org.eclipse.swt.widgets.Display; |
|
50 import org.eclipse.swt.widgets.Label; |
|
51 import org.eclipse.swt.widgets.Shell; |
|
52 import org.eclipse.ui.PlatformUI; |
|
53 import org.eclipse.ui.internal.BrandingProperties; |
|
54 import org.eclipse.ui.internal.IWorkbenchHelpContextIds; |
|
55 import org.eclipse.ui.internal.ProductProperties; |
|
56 import org.eclipse.ui.internal.WorkbenchMessages; |
|
57 import org.eclipse.ui.internal.about.AboutBundleGroupData; |
|
58 import org.eclipse.ui.internal.about.AboutFeaturesButtonManager; |
|
59 import org.eclipse.ui.internal.dialogs.AboutFeaturesDialog; |
|
60 import org.eclipse.ui.internal.dialogs.AboutPluginsDialog; |
|
61 import org.eclipse.ui.internal.dialogs.AboutSystemDialog; |
|
62 import org.eclipse.ui.internal.dialogs.ProductInfoDialog; |
|
63 |
|
64 public class CustomAboutDialog extends ProductInfoDialog { |
|
65 private final static int MAX_IMAGE_WIDTH_FOR_TEXT = 250; |
|
66 |
|
67 private final static int FEATURES_ID = IDialogConstants.CLIENT_ID + 1; |
|
68 |
|
69 private final static int PLUGINS_ID = IDialogConstants.CLIENT_ID + 2; |
|
70 |
|
71 private final static int INFO_ID = IDialogConstants.CLIENT_ID + 3; |
|
72 |
|
73 private String productName; |
|
74 |
|
75 private IProduct product; |
|
76 |
|
77 private AboutBundleGroupData[] bundleGroupInfos; |
|
78 |
|
79 private ArrayList images = new ArrayList(); |
|
80 |
|
81 private AboutFeaturesButtonManager buttonManager = new AboutFeaturesButtonManager(); |
|
82 |
|
83 // TODO should the styled text be disposed? if not then it likely |
|
84 // doesn't need to be a member |
|
85 private StyledText text; |
|
86 |
|
87 /** |
|
88 * Create an instance of the AboutDialog for the given window. |
|
89 * |
|
90 * @param parentShell The parent of the dialog. |
|
91 */ |
|
92 public CustomAboutDialog(Shell parentShell) { |
|
93 super(parentShell); |
|
94 setHelpAvailable(false); |
|
95 product = Platform.getProduct(); |
|
96 if (product != null) |
|
97 productName = product.getName(); |
|
98 if (productName == null) |
|
99 productName = WorkbenchMessages.AboutDialog_defaultProductName; |
|
100 |
|
101 // create a descriptive object for each BundleGroup |
|
102 IBundleGroupProvider[] providers = Platform.getBundleGroupProviders(); |
|
103 LinkedList groups = new LinkedList(); |
|
104 if (providers != null) |
|
105 for (int i = 0; i < providers.length; ++i) { |
|
106 IBundleGroup[] bundleGroups = providers[i].getBundleGroups(); |
|
107 for (int j = 0; j < bundleGroups.length; ++j) |
|
108 groups.add(new AboutBundleGroupData(bundleGroups[j])); |
|
109 } |
|
110 bundleGroupInfos = (AboutBundleGroupData[]) groups |
|
111 .toArray(new AboutBundleGroupData[0]); |
|
112 } |
|
113 |
|
114 /* |
|
115 * (non-Javadoc) Method declared on Dialog. |
|
116 */ |
|
117 protected void buttonPressed(int buttonId) { |
|
118 switch (buttonId) { |
|
119 case FEATURES_ID: |
|
120 new AboutFeaturesDialog(getShell(), productName, bundleGroupInfos) |
|
121 .open(); |
|
122 break; |
|
123 case PLUGINS_ID: |
|
124 new AboutPluginsDialog(getShell(), productName).open(); |
|
125 break; |
|
126 case INFO_ID: |
|
127 BusyIndicator.showWhile(null, new Runnable() { |
|
128 public void run() { |
|
129 new AboutSystemDialog(getShell()).open(); |
|
130 } |
|
131 }); |
|
132 break; |
|
133 default: |
|
134 super.buttonPressed(buttonId); |
|
135 break; |
|
136 } |
|
137 } |
|
138 |
|
139 public boolean close() { |
|
140 // dispose all images |
|
141 for (int i = 0; i < images.size(); ++i) { |
|
142 Image image = (Image) images.get(i); |
|
143 image.dispose(); |
|
144 } |
|
145 |
|
146 return super.close(); |
|
147 } |
|
148 |
|
149 /* |
|
150 * (non-Javadoc) Method declared on Window. |
|
151 */ |
|
152 protected void configureShell(Shell newShell) { |
|
153 super.configureShell(newShell); |
|
154 newShell.setText(NLS.bind(WorkbenchMessages.AboutDialog_shellTitle, |
|
155 productName)); |
|
156 PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, |
|
157 IWorkbenchHelpContextIds.ABOUT_DIALOG); |
|
158 } |
|
159 |
|
160 /** |
|
161 * Add buttons to the dialog's button bar. Subclasses should override. |
|
162 * |
|
163 * @param parent the button bar composite |
|
164 */ |
|
165 protected void createButtonsForButtonBar(Composite parent) { |
|
166 parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
167 |
|
168 createFeatureImageButtonRow(parent); |
|
169 |
|
170 // bug 64232: the feature details button should only be created if there |
|
171 // are features to show |
|
172 if (bundleGroupInfos != null && bundleGroupInfos.length > 0) |
|
173 createButton(parent, FEATURES_ID, |
|
174 WorkbenchMessages.AboutDialog_featureInfo, false); |
|
175 |
|
176 createButton(parent, PLUGINS_ID, |
|
177 WorkbenchMessages.AboutDialog_pluginInfo, false); |
|
178 createButton(parent, INFO_ID, WorkbenchMessages.AboutDialog_systemInfo, |
|
179 false); |
|
180 |
|
181 Label l = new Label(parent, SWT.NONE); |
|
182 l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
183 GridLayout layout = (GridLayout) parent.getLayout(); |
|
184 layout.numColumns = layout.numColumns + 2; |
|
185 layout.makeColumnsEqualWidth = false; |
|
186 |
|
187 Button b = createButton(parent, IDialogConstants.OK_ID, |
|
188 IDialogConstants.OK_LABEL, true); |
|
189 b.setFocus(); |
|
190 } |
|
191 |
|
192 /** |
|
193 * Creates and returns the contents of the upper part of the dialog (above |
|
194 * the button bar). Subclasses should overide. |
|
195 * |
|
196 * @param parent the parent composite to contain the dialog area |
|
197 * @return the dialog area control |
|
198 */ |
|
199 protected Control createDialogArea(Composite parent) { |
|
200 final Cursor hand = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND); |
|
201 final Cursor busy = new Cursor(parent.getDisplay(), SWT.CURSOR_WAIT); |
|
202 setHandCursor(hand); |
|
203 setBusyCursor(busy); |
|
204 getShell().addDisposeListener(new DisposeListener() { |
|
205 public void widgetDisposed(DisposeEvent e) { |
|
206 setHandCursor(null); |
|
207 hand.dispose(); |
|
208 setBusyCursor(null); |
|
209 busy.dispose(); |
|
210 } |
|
211 }); |
|
212 |
|
213 // brand the about box if there is product info |
|
214 Image aboutImage = null; |
|
215 if (product != null) { |
|
216 ImageDescriptor imageDescriptor = ProductProperties |
|
217 .getAboutImage(product); |
|
218 if (imageDescriptor != null) |
|
219 aboutImage = imageDescriptor.createImage(); |
|
220 |
|
221 // if the about image is small enough, then show the text |
|
222 if (aboutImage == null |
|
223 || aboutImage.getBounds().width <= MAX_IMAGE_WIDTH_FOR_TEXT) { |
|
224 String aboutText = ProductProperties.getAboutText(product); |
|
225 if (aboutText != null) |
|
226 setItem(scan(aboutText)); |
|
227 } |
|
228 |
|
229 if (aboutImage != null) |
|
230 images.add(aboutImage); |
|
231 } |
|
232 |
|
233 // create a composite which is the parent of the top area and the bottom |
|
234 // button bar, this allows there to be a second child of this composite |
|
235 // with |
|
236 // a banner background on top but not have on the bottom |
|
237 Composite workArea = new Composite(parent, SWT.NONE); |
|
238 GridLayout workLayout = new GridLayout(); |
|
239 workLayout.marginHeight = 0; |
|
240 workLayout.marginWidth = 0; |
|
241 workLayout.verticalSpacing = 0; |
|
242 workLayout.horizontalSpacing = 0; |
|
243 workArea.setLayout(workLayout); |
|
244 workArea.setLayoutData(new GridData(GridData.FILL_BOTH)); |
|
245 |
|
246 // page group |
|
247 Color background = JFaceColors.getBannerBackground(parent.getDisplay()); |
|
248 Color foreground = JFaceColors.getBannerForeground(parent.getDisplay()); |
|
249 Composite top = (Composite) super.createDialogArea(workArea); |
|
250 |
|
251 // override any layout inherited from createDialogArea |
|
252 GridLayout layout = new GridLayout(); |
|
253 layout.marginHeight = 0; |
|
254 layout.marginWidth = 0; |
|
255 layout.verticalSpacing = 0; |
|
256 layout.horizontalSpacing = 0; |
|
257 top.setLayout(layout); |
|
258 top.setLayoutData(new GridData(GridData.FILL_BOTH)); |
|
259 top.setBackground(background); |
|
260 top.setForeground(foreground); |
|
261 |
|
262 // the image & text |
|
263 Composite topContainer = new Composite(top, SWT.NONE); |
|
264 topContainer.setBackground(background); |
|
265 topContainer.setForeground(foreground); |
|
266 |
|
267 layout = new GridLayout(); |
|
268 layout.numColumns = (aboutImage == null || getItem() == null ? 1 : 2); |
|
269 layout.marginWidth = 0; |
|
270 layout.marginHeight = 0; |
|
271 layout.verticalSpacing = 0; |
|
272 layout.horizontalSpacing = 0; |
|
273 topContainer.setLayout(layout); |
|
274 GridData data = new GridData(); |
|
275 data.horizontalAlignment = GridData.FILL; |
|
276 data.grabExcessHorizontalSpace = true; |
|
277 topContainer.setLayoutData(data); |
|
278 |
|
279 // image on left side of dialog |
|
280 if (aboutImage != null) { |
|
281 Label imageLabel = new Label(topContainer, SWT.NONE); |
|
282 imageLabel.setBackground(background); |
|
283 imageLabel.setForeground(foreground); |
|
284 |
|
285 data = new GridData(); |
|
286 data.horizontalAlignment = GridData.FILL; |
|
287 data.verticalAlignment = GridData.BEGINNING; |
|
288 data.grabExcessHorizontalSpace = false; |
|
289 imageLabel.setLayoutData(data); |
|
290 imageLabel.setImage(aboutImage); |
|
291 } |
|
292 |
|
293 if (getItem() != null) { |
|
294 // there is no margins around the image, so insert an extra |
|
295 // composite |
|
296 // here to provide some margins for the text. |
|
297 Composite textContainer = new Composite(topContainer, SWT.NONE); |
|
298 textContainer.setBackground(background); |
|
299 textContainer.setForeground(foreground); |
|
300 |
|
301 layout = new GridLayout(); |
|
302 layout.numColumns = 1; |
|
303 layout.marginRight = 17; |
|
304 layout.marginTop = 0; |
|
305 textContainer.setLayout(layout); |
|
306 data = new GridData(); |
|
307 data.horizontalAlignment = GridData.FILL; |
|
308 data.verticalAlignment = GridData.BEGINNING; |
|
309 data.grabExcessHorizontalSpace = true; |
|
310 textContainer.setLayoutData(data); |
|
311 |
|
312 // Image on the right |
|
313 Label textImageLabel = new Label(textContainer, SWT.NONE); |
|
314 URL url = BrandingProperties |
|
315 .getUrl(product.getProperty("aboutTextImage"), product |
|
316 .getDefiningBundle()); |
|
317 Image textImage = ImageDescriptor.createFromURL(url).createImage(); |
|
318 textImageLabel.setImage(textImage); |
|
319 textImageLabel.setBackground(background); |
|
320 textImageLabel.setForeground(foreground); |
|
321 data = new GridData(); |
|
322 data.horizontalAlignment = SWT.RIGHT; |
|
323 data.verticalIndent = 7; |
|
324 textImageLabel.setLayoutData(data); |
|
325 |
|
326 // Version information on the right |
|
327 Label versionLabel = new Label(textContainer, SWT.NONE); |
|
328 data = new GridData(); |
|
329 data.horizontalAlignment = SWT.RIGHT; |
|
330 data.verticalIndent = 8; |
|
331 versionLabel.setText(product.getProperty("versionText")); |
|
332 versionLabel.setBackground(background); |
|
333 versionLabel.setForeground(foreground); |
|
334 versionLabel.setLayoutData(data); |
|
335 |
|
336 Label trialDaysLabel = new Label(textContainer, SWT.NONE); |
|
337 trialDaysLabel.setText(""); |
|
338 trialDaysLabel.setBackground(background); |
|
339 trialDaysLabel.setForeground(Display.getDefault() |
|
340 .getSystemColor(SWT.COLOR_RED)); |
|
341 data = new GridData(); |
|
342 data.horizontalAlignment = SWT.RIGHT; |
|
343 trialDaysLabel.setLayoutData(data); |
|
344 /* IRegistrationManager manager = ExtensionManager |
|
345 .getRegistrationManager(); |
|
346 if (manager != null) { |
|
347 RegistrationStatus status = manager.getStatus(); |
|
348 if (RegistrationStatus.REGISTERED != status) { |
|
349 int daysLeft = manager.getTrialDaysLeft(); |
|
350 if (RegistrationStatus.EXPIRED == status) { |
|
351 trialDaysLabel.setText(Messages.About_Trial_Expired); |
|
352 } else if (daysLeft < 2) { |
|
353 trialDaysLabel.setText(MessageFormat.format( |
|
354 Messages.About_One_TrialDay_Left_Text, |
|
355 new Object[] { daysLeft })); |
|
356 } else { |
|
357 trialDaysLabel.setText(MessageFormat.format( |
|
358 Messages.About_Several_TrialDays_Left_Text, |
|
359 new Object[] { daysLeft })); |
|
360 } |
|
361 } |
|
362 } |
|
363 */ |
|
364 // copyright text on the right |
|
365 text = new StyledText(textContainer, SWT.MULTI | SWT.READ_ONLY); |
|
366 text.setCaret(null); |
|
367 text.setFont(parent.getFont()); |
|
368 data = new GridData(); |
|
369 data.verticalIndent = 14; |
|
370 data.horizontalAlignment = GridData.FILL; |
|
371 data.verticalAlignment = GridData.BEGINNING; |
|
372 data.grabExcessHorizontalSpace = true; |
|
373 text.setText(getItem().getText()); |
|
374 text.setLayoutData(data); |
|
375 text.setCursor(null); |
|
376 text.setBackground(background); |
|
377 text.setForeground(foreground); |
|
378 |
|
379 setLinkRanges(text, getItem().getLinkRanges()); |
|
380 addListeners(text); |
|
381 } |
|
382 |
|
383 // horizontal bar |
|
384 Label bar = new Label(workArea, SWT.HORIZONTAL | SWT.SEPARATOR); |
|
385 data = new GridData(); |
|
386 data.horizontalAlignment = GridData.FILL; |
|
387 bar.setLayoutData(data); |
|
388 |
|
389 return workArea; |
|
390 } |
|
391 |
|
392 private void createFeatureImageButtonRow(Composite parent) { |
|
393 Composite featureContainer = new Composite(parent, SWT.NONE); |
|
394 RowLayout rowLayout = new RowLayout(); |
|
395 rowLayout.wrap = true; |
|
396 featureContainer.setLayout(rowLayout); |
|
397 GridData data = new GridData(); |
|
398 data.horizontalAlignment = GridData.FILL; |
|
399 featureContainer.setLayoutData(data); |
|
400 |
|
401 for (int i = 0; i < bundleGroupInfos.length; i++) |
|
402 createFeatureButton(featureContainer, bundleGroupInfos[i]); |
|
403 } |
|
404 |
|
405 private Button createFeatureButton(Composite parent, |
|
406 final AboutBundleGroupData info) { |
|
407 if (!buttonManager.add(info)) |
|
408 return null; |
|
409 |
|
410 ImageDescriptor desc = info.getFeatureImage(); |
|
411 Image featureImage = null; |
|
412 |
|
413 Button button = new Button(parent, SWT.FLAT | SWT.PUSH); |
|
414 button.setData(info); |
|
415 featureImage = desc.createImage(); |
|
416 images.add(featureImage); |
|
417 button.setImage(featureImage); |
|
418 button.setToolTipText(info.getProviderName()); |
|
419 |
|
420 button.getAccessible().addAccessibleListener(new AccessibleAdapter() { |
|
421 /* |
|
422 * (non-Javadoc) |
|
423 * |
|
424 * @see org.eclipse.swt.accessibility.AccessibleAdapter#getName(org.eclipse.swt.accessibility.AccessibleEvent) |
|
425 */ |
|
426 public void getName(AccessibleEvent e) { |
|
427 e.result = info.getProviderName(); |
|
428 } |
|
429 }); |
|
430 button.addSelectionListener(new SelectionAdapter() { |
|
431 public void widgetSelected(SelectionEvent event) { |
|
432 AboutBundleGroupData[] groupInfos = buttonManager |
|
433 .getRelatedInfos(info); |
|
434 AboutBundleGroupData selection = (AboutBundleGroupData) event.widget |
|
435 .getData(); |
|
436 |
|
437 AboutFeaturesDialog d = new AboutFeaturesDialog(getShell(), |
|
438 productName, groupInfos); |
|
439 d.setInitialSelection(selection); |
|
440 d.open(); |
|
441 } |
|
442 }); |
|
443 |
|
444 return button; |
|
445 } |
|
446 } |