|
1 /* |
|
2 * Copyright (c) 2008 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 "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 |
|
18 package com.nokia.s60tools.crashanalyser.ui.dialogs; |
|
19 |
|
20 import org.eclipse.jface.dialogs.Dialog; |
|
21 import org.eclipse.jface.dialogs.IDialogConstants; |
|
22 import org.eclipse.jface.viewers.ListViewer; |
|
23 import org.eclipse.jface.viewers.SelectionChangedEvent; |
|
24 import org.eclipse.jface.viewers.StructuredSelection; |
|
25 import org.eclipse.jface.viewers.ViewerSorter; |
|
26 import org.eclipse.swt.SWT; |
|
27 import org.eclipse.swt.widgets.Text; |
|
28 import org.eclipse.swt.browser.Browser; |
|
29 import org.eclipse.swt.layout.GridData; |
|
30 import org.eclipse.swt.layout.GridLayout; |
|
31 import org.eclipse.swt.layout.RowLayout; |
|
32 import org.eclipse.swt.widgets.Composite; |
|
33 import org.eclipse.swt.widgets.Control; |
|
34 import org.eclipse.swt.widgets.Link; |
|
35 import org.eclipse.swt.widgets.Shell; |
|
36 import org.eclipse.swt.widgets.TabFolder; |
|
37 import org.eclipse.swt.widgets.TabItem; |
|
38 import org.eclipse.swt.events.*; |
|
39 import org.eclipse.swt.widgets.Display; |
|
40 import org.eclipse.ui.PlatformUI; |
|
41 import com.nokia.s60tools.crashanalyser.resources.HelpContextIDs; |
|
42 import com.nokia.s60tools.crashanalyser.search.TextViewerFilter; |
|
43 import com.nokia.s60tools.crashanalyser.containers.ErrorLibraryError; |
|
44 import com.nokia.s60tools.crashanalyser.data.*; |
|
45 import com.nokia.s60tools.crashanalyser.model.PanicsViewerSorter; |
|
46 import com.nokia.s60tools.crashanalyser.model.ErrorsViewerSorter; |
|
47 import com.nokia.s60tools.crashanalyser.model.HtmlFormatter; |
|
48 import org.eclipse.jface.viewers.ISelectionChangedListener; |
|
49 |
|
50 /** |
|
51 * A dialog which contains all errors, panics and panic categories. |
|
52 * |
|
53 * Dialog contains three tab pages: Panic search, Category search and Error search. |
|
54 * |
|
55 */ |
|
56 public class ErrorLibraryDialog extends Dialog implements ModifyListener, |
|
57 SelectionListener, |
|
58 ISelectionChangedListener { |
|
59 Text textPanicSearch; |
|
60 Text textCategorySearch; |
|
61 Text textErrorSearch; |
|
62 ListViewer listPanics; |
|
63 ListViewer listCategories; |
|
64 ListViewer listErrors; |
|
65 Browser browserPanicDescription; |
|
66 Browser browserCategoryDescription; |
|
67 Browser browserErrorDescription; |
|
68 ErrorLibraryContentProvider contentPanics; |
|
69 ErrorLibraryContentProvider contentCategories; |
|
70 ErrorLibraryContentProvider contentErrors; |
|
71 ErrorLibrary errorLibrary; |
|
72 Link linkMailTo; |
|
73 |
|
74 /** |
|
75 * Constructor |
|
76 * @param parentShell shell |
|
77 * @param library error library |
|
78 */ |
|
79 public ErrorLibraryDialog(Shell parentShell, ErrorLibrary library) { |
|
80 super(parentShell); |
|
81 setShellStyle(getShellStyle() | SWT.RESIZE | SWT.HELP); |
|
82 errorLibrary = library; |
|
83 } |
|
84 |
|
85 @Override |
|
86 protected Control createDialogArea(Composite parent) { |
|
87 Composite dialogAreaComposite = (Composite) super.createDialogArea(parent); |
|
88 |
|
89 GridLayout gdl = new GridLayout(1, false); |
|
90 GridData gd = new GridData(GridData.FILL_BOTH); |
|
91 gd.widthHint = 600; |
|
92 gd.heightHint = 600; |
|
93 dialogAreaComposite.setLayout(gdl); |
|
94 dialogAreaComposite.setLayoutData(gd); |
|
95 |
|
96 // create tab |
|
97 TabFolder tabFolder = new TabFolder(dialogAreaComposite, SWT.NONE); |
|
98 tabFolder.setLayoutData(gd); |
|
99 |
|
100 // create tab pages |
|
101 createPanicsPage(tabFolder); |
|
102 createCategoriesPage(tabFolder); |
|
103 createErrorsPage(tabFolder); |
|
104 |
|
105 // mail to link, which can be used to notify about missing panic descriptions |
|
106 linkMailTo = new Link(dialogAreaComposite, SWT.NONE); |
|
107 linkMailTo.setText("<a href=\"mailto:S60RnDtools@nokia.com?subject=Crash Analyser - Missing Panic\">Report a missing panic or error</a>"); |
|
108 linkMailTo.addSelectionListener(this); |
|
109 |
|
110 tabFolder.setSelection(0); |
|
111 |
|
112 // load data to tab pages asynchronously |
|
113 loadDataAsync(); |
|
114 |
|
115 return dialogAreaComposite; |
|
116 } |
|
117 |
|
118 @Override |
|
119 protected void createButtonsForButtonBar(Composite parent) { |
|
120 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.CLOSE_LABEL, false); |
|
121 setHelps(); |
|
122 } |
|
123 |
|
124 @Override |
|
125 protected void configureShell(Shell newShell) { |
|
126 super.configureShell(newShell); |
|
127 newShell.setText("Crash Analyser - Error Library"); |
|
128 } |
|
129 |
|
130 /** |
|
131 * Called when user types something into search boxes |
|
132 */ |
|
133 public void modifyText(ModifyEvent item) { |
|
134 // panic search text was modified, filter list accordingly |
|
135 if (item.widget == textPanicSearch) { |
|
136 listPanics.resetFilters(); |
|
137 String text = textPanicSearch.getText(); |
|
138 if (text.length() > 0) { |
|
139 listPanics.addFilter(new TextViewerFilter(text)); |
|
140 } |
|
141 if (listPanics.getList().getItemCount() > 0) { |
|
142 listPanics.setSelection(new StructuredSelection(listPanics.getElementAt(0)), true); |
|
143 } else { |
|
144 browserPanicDescription.setText(""); |
|
145 } |
|
146 |
|
147 // category search text was modified, filter list accordingly |
|
148 } else if (item.widget == textCategorySearch) { |
|
149 listCategories.resetFilters(); |
|
150 String text = textCategorySearch.getText(); |
|
151 if (text.length() > 0) { |
|
152 listCategories.addFilter(new TextViewerFilter(text)); |
|
153 } |
|
154 if (listCategories.getList().getItemCount() > 0) { |
|
155 listCategories.setSelection(new StructuredSelection(listCategories.getElementAt(0)), true); |
|
156 } else { |
|
157 browserCategoryDescription.setText(""); |
|
158 } |
|
159 |
|
160 // error search text was modified, filter list accordingly |
|
161 } else if (item.widget == textErrorSearch) { |
|
162 listErrors.resetFilters(); |
|
163 String text = textErrorSearch.getText(); |
|
164 if (text.length() > 0) { |
|
165 listErrors.addFilter(new TextViewerFilter(text)); |
|
166 } |
|
167 if (listErrors.getList().getItemCount() > 0) { |
|
168 listErrors.setSelection(new StructuredSelection(listErrors.getElementAt(0)), true); |
|
169 } else { |
|
170 browserErrorDescription.setText(""); |
|
171 } |
|
172 } |
|
173 } |
|
174 |
|
175 /** |
|
176 * Called when user selects something from list |
|
177 */ |
|
178 public void selectionChanged(SelectionChangedEvent event) { |
|
179 // user selected from panics list |
|
180 if (event.getSource() == listPanics) { |
|
181 int index = listPanics.getList().getSelectionIndex(); |
|
182 if (index >= 0) { |
|
183 ErrorLibraryError p = (ErrorLibraryError)listPanics.getElementAt(index); |
|
184 if (p != null) |
|
185 browserPanicDescription.setText(HtmlFormatter.formatHtmlStyle(textPanicSearch.getFont(), |
|
186 p.getDescription())); |
|
187 } |
|
188 |
|
189 // user selected from categories list |
|
190 } else if (event.getSource() == listCategories) { |
|
191 int index = listCategories.getList().getSelectionIndex(); |
|
192 if (index >= 0) { |
|
193 ErrorLibraryError p = (ErrorLibraryError)listCategories.getElementAt(index); |
|
194 if (p != null) |
|
195 browserCategoryDescription.setText(HtmlFormatter.formatHtmlStyle(textPanicSearch.getFont(), |
|
196 p.getDescription())); |
|
197 } |
|
198 |
|
199 // user selected from errors list |
|
200 } else if (event.getSource() == listErrors) { |
|
201 int index = listErrors.getList().getSelectionIndex(); |
|
202 if (index >= 0) { |
|
203 ErrorLibraryError p = (ErrorLibraryError)listErrors.getElementAt(index); |
|
204 if (p != null) |
|
205 browserErrorDescription.setText(HtmlFormatter.formatHtmlStyle(textPanicSearch.getFont(), |
|
206 p.getDescription())); |
|
207 } |
|
208 } |
|
209 } |
|
210 |
|
211 public void widgetDefaultSelected(SelectionEvent arg0) { |
|
212 // no implementation needed |
|
213 } |
|
214 |
|
215 public void widgetSelected(SelectionEvent event) { |
|
216 try { |
|
217 browserCategoryDescription.setUrl(event.text); |
|
218 } catch (Exception e) { |
|
219 e.printStackTrace(); |
|
220 } |
|
221 } |
|
222 |
|
223 /** |
|
224 * Creates panics tab page |
|
225 * @param tabFolder |
|
226 */ |
|
227 void createPanicsPage(TabFolder tabFolder) { |
|
228 TabItem panicsPage = new TabItem(tabFolder, SWT.NONE); |
|
229 panicsPage.setText("Panic Search"); |
|
230 |
|
231 Composite composite = getComposite(tabFolder); |
|
232 |
|
233 textPanicSearch = new Text(composite, SWT.BORDER | SWT.SINGLE); |
|
234 textPanicSearch.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
235 textPanicSearch.addModifyListener(this); |
|
236 |
|
237 listPanics = new ListViewer(composite, SWT.BORDER | SWT.V_SCROLL); |
|
238 listPanics.getList().setLayoutData(getListGridData()); |
|
239 listPanics.addSelectionChangedListener(this); |
|
240 listPanics.setSorter(new PanicsViewerSorter()); |
|
241 |
|
242 browserPanicDescription = new Browser(composite, SWT.BORDER); |
|
243 browserPanicDescription.setLayoutData(new GridData(GridData.FILL_BOTH)); |
|
244 browserPanicDescription.setText(""); |
|
245 |
|
246 panicsPage.setControl(composite); |
|
247 } |
|
248 |
|
249 /** |
|
250 * Creates categories tab page |
|
251 * @param tabFolder |
|
252 */ |
|
253 void createCategoriesPage(TabFolder tabFolder) { |
|
254 TabItem categoriesPage = new TabItem(tabFolder, SWT.NONE); |
|
255 categoriesPage.setText("Category Search"); |
|
256 |
|
257 Composite composite = getComposite(tabFolder); |
|
258 |
|
259 textCategorySearch = new Text(composite, SWT.BORDER | SWT.SINGLE); |
|
260 textCategorySearch.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
261 textCategorySearch.addModifyListener(this); |
|
262 |
|
263 listCategories = new ListViewer(composite, SWT.BORDER | SWT.V_SCROLL); |
|
264 listCategories.getList().setLayoutData(getListGridData()); |
|
265 listCategories.addSelectionChangedListener(this); |
|
266 listCategories.setSorter(new ViewerSorter()); |
|
267 |
|
268 browserCategoryDescription = new Browser(composite, SWT.BORDER); |
|
269 browserCategoryDescription.setLayoutData(new GridData(GridData.FILL_BOTH)); |
|
270 browserCategoryDescription.setText(""); |
|
271 |
|
272 categoriesPage.setControl(composite); |
|
273 } |
|
274 |
|
275 /** |
|
276 * Creates errors tab page |
|
277 * @param tabFolder |
|
278 */ |
|
279 void createErrorsPage(TabFolder tabFolder) { |
|
280 TabItem errorsPage = new TabItem(tabFolder, SWT.NONE); |
|
281 errorsPage.setText("Error Search"); |
|
282 |
|
283 Composite composite = getComposite(tabFolder); |
|
284 |
|
285 textErrorSearch = new Text(composite, SWT.BORDER | SWT.SINGLE); |
|
286 textErrorSearch.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
287 textErrorSearch.addModifyListener(this); |
|
288 |
|
289 listErrors = new ListViewer(composite, SWT.BORDER | SWT.V_SCROLL); |
|
290 listErrors.getList().setLayoutData(getListGridData()); |
|
291 listErrors.addSelectionChangedListener(this); |
|
292 listErrors.setSorter(new ErrorsViewerSorter()); |
|
293 |
|
294 browserErrorDescription = new Browser(composite, SWT.BORDER); |
|
295 browserErrorDescription.setLayoutData(new GridData(GridData.FILL_BOTH)); |
|
296 browserErrorDescription.setText(""); |
|
297 |
|
298 errorsPage.setControl(composite); |
|
299 } |
|
300 |
|
301 /** |
|
302 * Creates a composite which tab pages can utilize. |
|
303 * @param tabFolder |
|
304 * @return composite |
|
305 */ |
|
306 Composite getComposite(TabFolder tabFolder) { |
|
307 Composite composite = new Composite(tabFolder, SWT.NONE); |
|
308 composite.setLayout(new RowLayout()); |
|
309 GridLayout gdl = new GridLayout(1, false); |
|
310 GridData gd = new GridData(GridData.FILL_BOTH); |
|
311 composite.setLayout(gdl); |
|
312 composite.setLayoutData(gd); |
|
313 return composite; |
|
314 } |
|
315 |
|
316 /** |
|
317 * Creates a grid data object for lists |
|
318 * @return |
|
319 */ |
|
320 GridData getListGridData() { |
|
321 GridData listGd = new GridData(GridData.FILL_HORIZONTAL); |
|
322 listGd.heightHint = 100; |
|
323 return listGd; |
|
324 } |
|
325 |
|
326 /** |
|
327 * Sets context sensitive helps to all UI items. |
|
328 */ |
|
329 void setHelps() { |
|
330 PlatformUI.getWorkbench().getHelpSystem().setHelp(textPanicSearch, |
|
331 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
332 PlatformUI.getWorkbench().getHelpSystem().setHelp(textErrorSearch, |
|
333 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
334 PlatformUI.getWorkbench().getHelpSystem().setHelp(textCategorySearch, |
|
335 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
336 PlatformUI.getWorkbench().getHelpSystem().setHelp(listPanics.getControl(), |
|
337 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
338 PlatformUI.getWorkbench().getHelpSystem().setHelp(listCategories.getControl(), |
|
339 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
340 PlatformUI.getWorkbench().getHelpSystem().setHelp(listErrors.getControl(), |
|
341 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
342 PlatformUI.getWorkbench().getHelpSystem().setHelp(browserCategoryDescription, |
|
343 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
344 PlatformUI.getWorkbench().getHelpSystem().setHelp(browserErrorDescription, |
|
345 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
346 PlatformUI.getWorkbench().getHelpSystem().setHelp(browserPanicDescription, |
|
347 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
348 PlatformUI.getWorkbench().getHelpSystem().setHelp(linkMailTo, |
|
349 HelpContextIDs.CRASH_ANALYSER_HELP_ERROR_LIBRARY); |
|
350 } |
|
351 |
|
352 /** |
|
353 * Loads panics, categories and errors into lists asynchronously so that |
|
354 * dialog can be opened fast |
|
355 */ |
|
356 public void loadDataAsync() { |
|
357 Runnable refreshRunnable = new Runnable(){ |
|
358 public void run(){ |
|
359 // panics |
|
360 contentPanics = new ErrorLibraryContentProvider(ErrorLibraryContentProvider.ContentTypes.PANIC, errorLibrary); |
|
361 listPanics.setContentProvider(contentPanics); |
|
362 listPanics.setInput(contentPanics); |
|
363 |
|
364 // categories |
|
365 contentCategories = new ErrorLibraryContentProvider(ErrorLibraryContentProvider.ContentTypes.CATEGORY, errorLibrary); |
|
366 listCategories.setContentProvider(contentCategories); |
|
367 listCategories.setInput(contentCategories); |
|
368 |
|
369 // errors |
|
370 contentErrors = new ErrorLibraryContentProvider(ErrorLibraryContentProvider.ContentTypes.ERROR, errorLibrary); |
|
371 listErrors.setContentProvider(contentErrors); |
|
372 listErrors.setInput(contentErrors); |
|
373 } |
|
374 }; |
|
375 |
|
376 Display.getDefault().asyncExec(refreshRunnable); |
|
377 } |
|
378 } |