1 /*******************************************************************************
2 * Copyright (c) 2000, 2009 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 *******************************************************************************/
11 package org.eclipse.test.internal.performance.results.ui;
12
13 import java.io.File;
14 import java.util.Arrays;
15 import java.util.Iterator;
16
17 import org.osgi.service.prefs.BackingStoreException;
18
19 import org.eclipse.test.internal.performance.PerformanceTestPlugin;
20 import org.eclipse.test.internal.performance.results.db.DB_Results;
21 import org.eclipse.test.internal.performance.results.utils.IPerformancesConstants;
22 import org.eclipse.test.internal.performance.results.utils.Util;
23 import org.eclipse.test.performance.ui.UiPlugin;
24
25 import org.eclipse.swt.SWT;
26 import org.eclipse.swt.custom.CCombo;
27 import org.eclipse.swt.events.ModifyEvent;
28 import org.eclipse.swt.events.ModifyListener;
29 import org.eclipse.swt.events.SelectionEvent;
30 import org.eclipse.swt.events.SelectionListener;
31 import org.eclipse.swt.layout.GridData;
32 import org.eclipse.swt.layout.GridLayout;
33 import org.eclipse.swt.widgets.Button;
34 import org.eclipse.swt.widgets.Composite;
35 import org.eclipse.swt.widgets.Control;
36 import org.eclipse.swt.widgets.DirectoryDialog;
37 import org.eclipse.swt.widgets.Display;
38 import org.eclipse.swt.widgets.Group;
39 import org.eclipse.swt.widgets.Label;
40 import org.eclipse.swt.widgets.List;
41 import org.eclipse.swt.widgets.Text;
42
43 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
44 import org.eclipse.core.runtime.preferences.InstanceScope;
45
46 import org.eclipse.jface.dialogs.MessageDialog;
47 import org.eclipse.jface.preference.IPreferenceStore;
48 import org.eclipse.jface.preference.PreferencePage;
49
50 import org.eclipse.ui.IWorkbench;
51 import org.eclipse.ui.IWorkbenchPreferencePage;
52
53 /**
54 * Defines the 'Performances' preferences page.
55 */
56 public class PerformanceResultsPreferencePage extends PreferencePage
57 implements IWorkbenchPreferencePage, SelectionListener, ModifyListener, IPerformancesConstants {
58
59 private Button mVersionRadioButton;
60 private Button dVersionRadionButton;
61 private CCombo databaseLocationCombo;
62 private Button dbConnectionCheckBox;
63 private Button dbLocalBrowseButton;
64 private Button dbRelengRadioButton;
65 private Button dbLocalRadioButton;
66 private CCombo defaultDimensionCombo;
67 private CCombo lastBuildCombo;
68 private List resultsDimensionsList;
69 private CCombo milestonesCombo;
70 private Label dbLocationLabel;
71
72 // Status SWT objects
73 private Button statusValuesCheckBox;
74 private Button statusErrorNoneRadioButton;
75 private Button statusErrorNoticeableRadioButton;
76 private Button statusErrorSuspiciousRadioButton;
77 private Button statusErrorWeirdRadioButton;
78 private Button statusErrorInvalidRadioButton;
79 private Button statusSmallBuildValueCheckBox;
80 private Button statusSmallDeltaValueCheckBox;
81 private Button statusStatisticNoneRadioButton;
82 private Button statusStatisticErraticRadioButton;
83 private Button statusStatisticUnstableRadioButton;
84 private Text statusBuildsToConfirm;
85
86 // TODO See whether config descriptors need to be set as preferences or not...
87 // private Table configDescriptorsTable;
88
89 private BuildsView buildsView;
90
91 /**
92 * Utility method that creates a push button instance and sets the default
93 * layout data.
94 *
95 * @param parent
96 * the parent for the new button
97 * @param label
98 * the label for the new button
99 * @return the newly-created button
100 */
createCheckBox(Composite parent, String label)101 private Button createCheckBox(Composite parent, String label) {
102 Button button = new Button(parent, SWT.CHECK);
103 button.setText(label);
104 button.addSelectionListener(this);
105 GridData data = new GridData();
106 data.horizontalAlignment = GridData.FILL;
107 data.horizontalSpan = 5;
108 button.setLayoutData(data);
109 return button;
110 }
111
112 /**
113 * Create a text field specific for this application
114 *
115 * @param parent
116 * the parent of the new text field
117 * @return the new text field
118 */
createCombo(Composite parent)119 private CCombo createCombo(Composite parent) {
120 CCombo combo= new CCombo(parent, SWT.BORDER);
121 combo.addModifyListener(this);
122 GridData data = new GridData();
123 data.horizontalSpan = 3;
124 data.horizontalAlignment = GridData.FILL;
125 data.grabExcessHorizontalSpace = true;
126 data.verticalAlignment = GridData.CENTER;
127 data.grabExcessVerticalSpace = false;
128 combo.setLayoutData(data);
129 return combo;
130 }
131
132
133 /**
134 * Creates composite control and sets the default layout data.
135 *
136 * @param parent
137 * the parent of the new composite
138 * @param numColumns
139 * the number of columns for the new composite
140 * @param hSpan TODO
141 * @return the newly-created coposite
142 */
createComposite(Composite parent, int numColumns, int hSpan)143 private Composite createComposite(Composite parent, int numColumns, int hSpan) {
144 Composite composite = new Composite(parent, SWT.NULL);
145
146 // GridLayout
147 GridLayout layout = new GridLayout();
148 layout.numColumns = numColumns;
149 composite.setLayout(layout);
150
151 // GridData
152 GridData data = new GridData();
153 data.verticalAlignment = GridData.FILL;
154 data.horizontalAlignment = GridData.FILL;
155 data.horizontalSpan = hSpan;
156 composite.setLayoutData(data);
157 return composite;
158 }
159
160 /**
161 * (non-Javadoc) Method declared on PreferencePage
162 */
createContents(Composite parent)163 protected Control createContents(Composite parent) {
164
165 this.buildsView = (BuildsView) PerformancesView.getWorkbenchView("org.eclipse.test.internal.performance.results.ui.BuildsView");
166 if (this.buildsView == null) {
167 Label errorLabel = createLabel(parent, "No performances preferences can be set because the build view has not been created yet!", false);
168 errorLabel.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
169 } else {
170 // Eclipse version choice
171 Composite composite_eclipseVersion = createComposite(parent, 5, 1);
172 createLabel(composite_eclipseVersion, "Eclipse version", false);
173 Composite composite_versionChoice = createComposite(composite_eclipseVersion, 5, 1);
174 this.mVersionRadioButton = createRadioButton(composite_versionChoice, "v"+ECLIPSE_MAINTENANCE_VERSION);
175 this.dVersionRadionButton = createRadioButton(composite_versionChoice, "v"+ECLIPSE_DEVELOPMENT_VERSION);
176
177 // Database location
178 Composite compositeDatabase = createComposite(parent, 5, 1);
179 Group databaseGroup = createGroup(compositeDatabase, "Database", 5);
180 Composite compositeDatabaseConnection = createComposite(databaseGroup, 3, 5);
181 this.dbConnectionCheckBox = createCheckBox(compositeDatabaseConnection, "Connected");
182 this.dbRelengRadioButton = createRadioButton(compositeDatabaseConnection, "Releng");
183 this.dbLocalRadioButton = createRadioButton(compositeDatabaseConnection, "Local");
184 this.dbLocationLabel = createLabel(databaseGroup, "Location", false);
185 this.databaseLocationCombo = createCombo(databaseGroup);
186 this.databaseLocationCombo.setEditable(false);
187 this.dbLocalBrowseButton = createPushButton(databaseGroup, "Browse");
188
189 // Status
190 Composite compositeStatus = createComposite(parent, 1, 3);
191 Group statusGroup = createGroup(compositeStatus, "Status", 1);
192 this.statusValuesCheckBox = createCheckBox(statusGroup, "Values");
193 this.statusValuesCheckBox.setToolTipText("Include numbers while writing status");
194 Group statusErrorGroup = createGroup(statusGroup, "Error level", 5);
195 statusErrorGroup.setToolTipText("Exclude from the written status failures depending on their build result error...");
196 this.statusErrorNoneRadioButton = createRadioButton(statusErrorGroup, "None");
197 this.statusErrorNoneRadioButton.setToolTipText("Do not exclude failures if they have a noticeable error");
198 this.statusErrorInvalidRadioButton = createRadioButton(statusErrorGroup, "Invalid");
199 this.statusErrorInvalidRadioButton.setToolTipText("Exclude all invalid failures (i.e. result error is over 100%)");
200 this.statusErrorWeirdRadioButton = createRadioButton(statusErrorGroup, "Weird");
201 this.statusErrorWeirdRadioButton.setToolTipText("Exclude all weird failures (i.e. result error is over 50%)");
202 this.statusErrorSuspiciousRadioButton = createRadioButton(statusErrorGroup, "Suspicious");
203 this.statusErrorSuspiciousRadioButton.setToolTipText("Exclude all suspicious failures (i.e. result error is over 25%)");
204 this.statusErrorNoticeableRadioButton = createRadioButton(statusErrorGroup, "Noticeable");
205 this.statusErrorNoticeableRadioButton.setToolTipText("Exclude all failures which have a noticeable error (i.e result error is over 3%)");
206 Group statusSmallGroup = createGroup(statusGroup, "Small value", 5);
207 statusErrorGroup.setToolTipText("Exclude from the written status failures depending on their value");
208 this.statusSmallBuildValueCheckBox = createCheckBox(statusSmallGroup, "Build value");
209 this.statusSmallBuildValueCheckBox.setToolTipText("Exclude all failures which have a build result value smaller than 100ms");
210 this.statusSmallDeltaValueCheckBox = createCheckBox(statusSmallGroup, "Delta value");
211 this.statusSmallDeltaValueCheckBox.setToolTipText("Exclude all failures which have a delta result value smaller than 100ms");
212 Group statusStatisticsGroup = createGroup(statusGroup, "Statistics", 5);
213 statusStatisticsGroup.setToolTipText("Exclude from the written status failures depending on build results statistics...");
214 this.statusStatisticNoneRadioButton = createRadioButton(statusStatisticsGroup, "None");
215 this.statusStatisticNoneRadioButton.setToolTipText("Do not exclude failures which have bad baseline results statistics (i.e. variation is over 10%)");
216 this.statusStatisticUnstableRadioButton = createRadioButton(statusStatisticsGroup, "Unstable");
217 this.statusStatisticUnstableRadioButton.setToolTipText("Exclude all failures which have unstable baseline results statistics (i.e. variation is between 10% and 20%)");
218 this.statusStatisticErraticRadioButton = createRadioButton(statusStatisticsGroup, "Erratic");
219 this.statusStatisticErraticRadioButton.setToolTipText("Exclude all failures which have erratic baseline results statistics (i.e. variation is over 20%)");
220 createLabel(statusGroup, "Builds to confirm:", false);
221 this.statusBuildsToConfirm = createTextField(statusGroup);
222 this.statusBuildsToConfirm.setToolTipText("The number of previous builds to take into account to confirm a regression");
223
224 // Milestones
225 Composite compositeMilestones = createComposite(parent, 3, 1);
226 createLabel(compositeMilestones, "Milestones", false);
227 this.milestonesCombo = createCombo(compositeMilestones);
228 this.milestonesCombo.setToolTipText("Enter the date of the milestone as yyyymmddHHMM");
229
230 // Last build
231 StringBuffer tooltip = new StringBuffer("Select the last build to display performance results\n");
232 tooltip.append("If set then performance results won't be displayed for any build after this date...");
233 String tooltipText = tooltip.toString();
234 Composite compositeLastBuild = createComposite(parent, 3, 1);
235 // this.lastBuildCheckBox = createCheckBox(compositeLastBuild, "Until last build");
236 createLabel(compositeLastBuild, "Last build: ", false);
237 this.lastBuildCombo = createCombo(compositeLastBuild);
238 this.lastBuildCombo.setEditable(false);
239 this.lastBuildCombo.setToolTipText(tooltipText);
240 this.lastBuildCombo.add("");
241 initBuildsList();
242
243 // Default dimension layout
244 tooltip = new StringBuffer("Select the default dimension which will be used for performance results\n");
245 tooltip.append("When changed, the new selected dimension is automatically added to the dimensions list below...");
246 tooltipText = tooltip.toString();
247 Composite compositeDefaultDimension = createComposite(parent, 3, 1);
248 createLabel(compositeDefaultDimension, "Default dimension: ", false);
249 this.defaultDimensionCombo = createCombo(compositeDefaultDimension);
250 this.defaultDimensionCombo.setEditable(false);
251 this.defaultDimensionCombo.setToolTipText(tooltipText);
252
253 // Results dimensions layout
254 tooltip = new StringBuffer("Select the dimensions which will be used while generating performance results\n");
255 tooltip.append("When changed, the default dimension above is automatically added to the new list...");
256 tooltipText = tooltip.toString();
257 Composite compositeResultsDimensions = createComposite(parent, 3, 1);
258 createLabel(compositeResultsDimensions, "Results dimensions: ", true/*beginning*/);
259 this.resultsDimensionsList = createList(compositeResultsDimensions);
260 this.resultsDimensionsList.setToolTipText(tooltipText);
261
262 // Config descriptors layout
263 /* TODO See whether config descriptors need to be set as preferences or not...
264 Composite compositeConfigDescriptors = createComposite(parent, 3);
265 createLabel(compositeConfigDescriptors, "Config descriptors: ", false);
266 this.configDescriptorsTable = createTable(compositeConfigDescriptors);
267 TableColumn firstColumn = new TableColumn(this.configDescriptorsTable, SWT.LEFT);
268 firstColumn.setText ("Name");
269 firstColumn.setWidth(50);
270 TableColumn secondColumn = new TableColumn(this.configDescriptorsTable, SWT.FILL | SWT.LEFT);
271 secondColumn.setText ("Description");
272 secondColumn.setWidth(300);
273 */
274
275 // init values
276 initializeValues();
277 }
278
279 // font = null;
280 Composite contents = new Composite(parent, SWT.NULL);
281 contents.pack(true);
282 return contents;
283 }
284
285 /**
286 * Utility method that creates a label instance and sets the default layout
287 * data.
288 *
289 * @param parent
290 * the parent for the new label
291 * @param text
292 * the text for the new label
293 * @return the new label
294 */
createGroup(Composite parent, String text, int columns)295 private Group createGroup(Composite parent, String text, int columns) {
296 Group group = new Group(parent, SWT.NONE);
297 group.setLayout(new GridLayout(columns, false));
298 group.setText(text);
299 GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
300 // data.horizontalSpan = 1;
301 group.setLayoutData(data);
302 return group;
303 }
304
305 /**
306 * Utility method that creates a label instance and sets the default layout
307 * data.
308 *
309 * @param parent
310 * the parent for the new label
311 * @param text
312 * the text for the new label
313 * @param beginning TODO
314 * @return the new label
315 */
createLabel(Composite parent, String text, boolean beginning)316 private Label createLabel(Composite parent, String text, boolean beginning) {
317 Label label = new Label(parent, SWT.BEGINNING|SWT.LEFT);
318 label.setText(text);
319 GridData data = new GridData();
320 data.horizontalAlignment = GridData.FILL;
321 data.verticalAlignment = beginning ? GridData.BEGINNING : GridData.CENTER;
322 label.setLayoutData(data);
323 return label;
324 }
325
326 /**
327 * Create a text field specific for this application
328 *
329 * @param parent
330 * the parent of the new text field
331 * @return the new text field
332 */
createList(Composite parent)333 private List createList(Composite parent) {
334 List list = new List(parent, SWT.MULTI | SWT.BORDER);
335 list.addSelectionListener(this);
336 GridData data = new GridData();
337 data.horizontalSpan = 2;
338 data.horizontalAlignment = GridData.FILL;
339 data.grabExcessHorizontalSpace = true;
340 data.verticalAlignment = GridData.CENTER;
341 data.grabExcessVerticalSpace = false;
342 list.setLayoutData(data);
343 return list;
344 }
345
346 /**
347 * Utility method that creates a push button instance and sets the default
348 * layout data.
349 *
350 * @param parent
351 * the parent for the new button
352 * @param label
353 * the label for the new button
354 * @return the newly-created button
355 */
createPushButton(Composite parent, String label)356 private Button createPushButton(Composite parent, String label) {
357 Button button = new Button(parent, SWT.PUSH);
358 button.setText(label);
359 button.addSelectionListener(this);
360 GridData data = new GridData();
361 data.horizontalAlignment = SWT.LEFT;
362 data.grabExcessHorizontalSpace = true;
363 // data.horizontalSpan = 2;
364 data.minimumWidth = 100;
365 button.setLayoutData(data);
366 return button;
367 }
368
369 /**
370 * Utility method that creates a radio button instance and sets the default
371 * layout data.
372 *
373 * @param parent
374 * the parent for the new button
375 * @param label
376 * the label for the new button
377 * @return the newly-created button
378 */
createRadioButton(Composite parent, String label)379 private Button createRadioButton(Composite parent, String label) {
380 Button button = new Button(parent, SWT.RADIO | SWT.LEFT);
381 button.setText(label);
382 button.addSelectionListener(this);
383 GridData data = new GridData();
384 button.setLayoutData(data);
385 return button;
386 }
387
388 /*
389 * Create a text field specific for this application
390 *
391 * @param parent
392 * the parent of the new text field
393 * @return the new text field
394 *
395 private Table createTable(Composite parent) {
396 Table table = new Table(parent, SWT.BORDER);
397 table.setLinesVisible (true);
398 table.setHeaderVisible (true);
399 GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
400 gridData.heightHint = 150;
401 table.setLayoutData(gridData);
402 return table;
403 }
404 */
405
406 /*
407 * Create a text field specific for this application
408 *
409 * @param parent
410 * the parent of the new text field
411 * @return the new text field
412 */
createTextField(Composite parent)413 private Text createTextField(Composite parent) {
414 Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
415 text.addModifyListener(this);
416 GridData data = new GridData();
417 data.horizontalAlignment = GridData.FILL;
418 data.grabExcessHorizontalSpace = true;
419 data.verticalAlignment = GridData.CENTER;
420 data.grabExcessVerticalSpace = false;
421 text.setLayoutData(data);
422 return text;
423 }
424
425 /**
426 * The <code>ReadmePreferencePage</code> implementation of this
427 * <code>PreferencePage</code> method returns preference store that belongs to
428 * the our plugin. This is important because we want to store our preferences
429 * separately from the workbench.
430 */
doGetPreferenceStore()431 protected IPreferenceStore doGetPreferenceStore() {
432 return UiPlugin.getDefault().getPreferenceStore();
433 }
434
435 /**
436 * @return The dialog title
437 */
getDialogTitle()438 String getDialogTitle() {
439 String title = DB_Results.getDbTitle();
440 if (title == null) {
441 // DB is not connected
442 int version;
443 if (this.mVersionRadioButton.getSelection()) {
444 version = ECLIPSE_MAINTENANCE_VERSION;
445 } else {
446 version = ECLIPSE_DEVELOPMENT_VERSION;
447 }
448 title = "Eclipse " + version + " - DB not connected";
449 }
450 return title;
451 }
452
453 /*
454 * Get the directory path using the given location as default.
455 */
getDirectoryPath(String location)456 private String getDirectoryPath(String location) {
457 DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.OPEN);
458 dialog.setText(getDialogTitle());
459 dialog.setMessage("Select local database directory:");
460 dialog.setFilterPath(location);
461 String path = dialog.open();
462 if (path != null) {
463 File dir = new File(path);
464 if (dir.exists() && dir.isDirectory()) {
465 return dir.getAbsolutePath();
466 }
467 }
468 return null;
469 }
470
471 /*
472 * (non-Javadoc) Method declared on IWorkbenchPreferencePage
473 */
init(IWorkbench workbench)474 public void init(IWorkbench workbench) {
475 // do nothing
476 }
477
478 /*
479 * Init he contents of the dimensions list controls.
480 */
initDimensionsLists()481 void initDimensionsLists() {
482 // Dimensions lists
483 java.util.List dimensions = PerformanceTestPlugin.getDimensions();
484 Iterator names = dimensions.iterator();
485 while (names.hasNext()) {
486 String name = (String) names.next();
487 this.defaultDimensionCombo.add(name);
488 this.resultsDimensionsList.add(name);
489 }
490 }
491
492 /*
493 * Init he contents of the dimensions list controls.
494 */
initBuildsList()495 private void initBuildsList() {
496 String[] builds = DB_Results.getBuilds();
497 Arrays.sort(builds, Util.BUILD_DATE_COMPARATOR);
498 int length = builds.length;
499 for (int i=length-1; i>=0; i--) {
500 this.lastBuildCombo.add(builds[i]);
501 }
502 }
503
504 /**
505 * Initializes states of the controls using default values in the preference
506 * store.
507 */
initializeDefaults()508 private void initializeDefaults() {
509 IPreferenceStore store = getPreferenceStore();
510
511 // Init default database values
512 this.dbConnectionCheckBox.setSelection(store.getDefaultBoolean(PRE_DATABASE_CONNECTION));
513 this.dbRelengRadioButton.setSelection(false);
514 this.dbLocalRadioButton.setSelection(false);
515 final boolean dbLocal = store.getDefaultBoolean(PRE_DATABASE_LOCAL);
516 if (dbLocal) {
517 this.dbLocalRadioButton.setSelection(true);
518 } else {
519 this.dbRelengRadioButton.setSelection(true);
520 }
521 this.databaseLocationCombo.removeAll();
522 this.databaseLocationCombo.setText(store.getDefaultString(PRE_DATABASE_LOCATION));
523 updateDatabaseGroup();
524
525 // Init default status values
526 int writeStatus = store.getDefaultInt(PRE_WRITE_STATUS);
527 initStatusValues(writeStatus);
528
529 // Init eclipse version
530 this.mVersionRadioButton.setSelection(false);
531 this.dVersionRadionButton.setSelection(false);
532 int version = store.getDefaultInt(PRE_ECLIPSE_VERSION);
533 if (version == ECLIPSE_MAINTENANCE_VERSION) {
534 this.mVersionRadioButton.setSelection(true);
535 } else {
536 this.dVersionRadionButton.setSelection(true);
537 }
538 updateBrowseButtonToolTip(version);
539
540 // Milestones
541 this.milestonesCombo.removeAll();
542 String prefix = PRE_MILESTONE_BUILDS + "." + version;
543 String milestone = store.getDefaultString(prefix + "0");
544 int index = 0;
545 while (milestone != null && milestone.length() > 0) {
546 this.milestonesCombo.add(milestone);
547 milestone = store.getDefaultString(prefix + ++index);
548 }
549
550 // Init last build
551 String lastBuild = store.getDefaultString(PRE_LAST_BUILD);
552 // if (lastBuild.length() == 0) {
553 // this.lastBuildCheckBox.setSelection(false);
554 // this.lastBuildCombo.setEnabled(false);
555 // } else {
556 // this.lastBuildCombo.setEnabled(true);
557 // }
558 this.lastBuildCombo.setText(lastBuild);
559
560 // Init default default dimension
561 String defaultDimension = store.getDefaultString(PRE_DEFAULT_DIMENSION);
562 this.defaultDimensionCombo.setText(defaultDimension);
563
564 // Init default generated dimensions
565 this.resultsDimensionsList.add(store.getDefaultString(PRE_RESULTS_DIMENSION+".0"));
566 this.resultsDimensionsList.add(store.getDefaultString(PRE_RESULTS_DIMENSION+".1"));
567 }
568
569 /**
570 * Initializes states of the controls from the preference store.
571 */
initializeValues()572 private void initializeValues() {
573 IPreferenceStore store = getPreferenceStore();
574
575 // Init database info
576 this.dbConnectionCheckBox.setSelection(store.getBoolean(PRE_DATABASE_CONNECTION));
577 final boolean dbLocal = store.getBoolean(PRE_DATABASE_LOCAL);
578 if (dbLocal) {
579 this.dbLocalRadioButton.setSelection(true);
580 this.dbRelengRadioButton.setToolTipText("");
581 } else {
582 this.dbRelengRadioButton.setSelection(true);
583 this.dbRelengRadioButton.setToolTipText(NETWORK_DATABASE_LOCATION);
584 }
585 this.databaseLocationCombo.removeAll();
586 this.databaseLocationCombo.setText(store.getString(PRE_DATABASE_LOCATION));
587 for (int i = 0; i < 3; i++) {
588 String history = store.getString(PRE_DATABASE_LOCATION + "." + i);
589 if (history.length() == 0)
590 break;
591 this.databaseLocationCombo.add(history);
592 }
593 updateDatabaseGroup();
594
595 // Init status values
596 int writeStatus = store.getInt(PRE_WRITE_STATUS);
597 initStatusValues(writeStatus);
598
599 // Init eclipse version
600 int version = store.getInt(PRE_ECLIPSE_VERSION);
601 if (version == ECLIPSE_MAINTENANCE_VERSION) {
602 this.mVersionRadioButton.setSelection(true);
603 } else {
604 this.dVersionRadionButton.setSelection(true);
605 }
606 updateBrowseButtonToolTip(version);
607
608 // Milestones
609 String prefix = PRE_MILESTONE_BUILDS + "." + version;
610 int index = 0;
611 String milestone = store.getString(prefix + index);
612 while (milestone != null && milestone.length() > 0) {
613 this.milestonesCombo.add(milestone);
614 milestone = store.getString(prefix + ++index);
615 }
616
617 // Init last build
618 String lastBuild = store.getString(PRE_LAST_BUILD);
619 // if (lastBuild.length() == 0) {
620 // this.lastBuildCheckBox.setSelection(false);
621 // this.lastBuildCombo.setEnabled(false);
622 // } else {
623 // this.lastBuildCombo.setEnabled(true);
624 // }
625 this.lastBuildCombo.setText(lastBuild);
626
627 // Init composite lists
628 initDimensionsLists();
629
630 // Init default dimension
631 String defaultDimension = store.getString(PRE_DEFAULT_DIMENSION);
632 this.defaultDimensionCombo.setText(defaultDimension);
633
634 // Init generated dimensions
635 int count = this.resultsDimensionsList.getItemCount();
636 int[] indices = new int[count];
637 int n = 0;
638 String resultsDimension = store.getString(PRE_RESULTS_DIMENSION + "." + n);
639 while (resultsDimension.length() > 0) {
640 indices[n++] = this.resultsDimensionsList.indexOf(resultsDimension);
641 resultsDimension = store.getString(PRE_RESULTS_DIMENSION + "." + n);
642 }
643 if (n < count) {
644 System.arraycopy(indices, 0, indices = new int[n], 0, n);
645 }
646 this.resultsDimensionsList.select(indices);
647
648 // Init config descriptors
649 /* TODO See whether config descriptors need to be set as preferences or not...
650 this.configDescriptorsTable.clearAll();
651 int d = 0;
652 String descriptorName = store.getString(PRE_CONFIG_DESCRIPTOR_NAME + "." + d);
653 String descriptorDescription = store.getString(PRE_CONFIG_DESCRIPTOR_DESCRIPTION + "." + d++);
654 while (descriptorName.length() > 0) {
655 TableItem tableItem = new TableItem (this.configDescriptorsTable, SWT.NONE);
656 tableItem.setText (0, descriptorName);
657 tableItem.setText (1, descriptorDescription);
658 descriptorName = store.getString(PRE_CONFIG_DESCRIPTOR_NAME + "." + d);
659 descriptorDescription = store.getString(PRE_CONFIG_DESCRIPTOR_DESCRIPTION + "." + d++);
660 }
661 */
662 }
663
664 /**
665 * @param writeStatus The observed status to write
666 */
initStatusValues(int writeStatus)667 private void initStatusValues(int writeStatus) {
668 this.statusValuesCheckBox.setSelection((writeStatus & STATUS_VALUES) != 0);
669 this.statusErrorNoneRadioButton.setSelection(false);
670 this.statusErrorNoticeableRadioButton.setSelection(false);
671 this.statusErrorSuspiciousRadioButton.setSelection(false);
672 this.statusErrorWeirdRadioButton.setSelection(false);
673 this.statusErrorInvalidRadioButton.setSelection(false);
674 switch (writeStatus & STATUS_ERROR_LEVEL_MASK) {
675 case STATUS_ERROR_NONE:
676 this.statusErrorNoneRadioButton.setSelection(true);
677 break;
678 case STATUS_ERROR_NOTICEABLE:
679 this.statusErrorNoticeableRadioButton.setSelection(true);
680 break;
681 case STATUS_ERROR_SUSPICIOUS:
682 this.statusErrorSuspiciousRadioButton.setSelection(true);
683 break;
684 case STATUS_ERROR_WEIRD:
685 this.statusErrorWeirdRadioButton.setSelection(true);
686 break;
687 case STATUS_ERROR_INVALID:
688 this.statusErrorInvalidRadioButton.setSelection(true);
689 break;
690 }
691 this.statusSmallBuildValueCheckBox.setSelection(false);
692 this.statusSmallDeltaValueCheckBox.setSelection(false);
693 switch (writeStatus & STATUS_SMALL_VALUE_MASK) {
694 case STATUS_SMALL_VALUE_BUILD:
695 this.statusSmallBuildValueCheckBox.setSelection(true);
696 break;
697 case STATUS_SMALL_VALUE_DELTA:
698 this.statusSmallDeltaValueCheckBox.setSelection(true);
699 break;
700 }
701 this.statusStatisticNoneRadioButton.setSelection(false);
702 this.statusStatisticErraticRadioButton.setSelection(false);
703 this.statusStatisticUnstableRadioButton.setSelection(false);
704 switch (writeStatus & STATUS_STATISTICS_MASK) {
705 case 0:
706 this.statusStatisticNoneRadioButton.setSelection(true);
707 break;
708 case STATUS_STATISTICS_ERRATIC:
709 this.statusStatisticErraticRadioButton.setSelection(true);
710 break;
711 case STATUS_STATISTICS_UNSTABLE:
712 this.statusStatisticUnstableRadioButton.setSelection(true);
713 break;
714 }
715 this.statusBuildsToConfirm.setText(String.valueOf(writeStatus & STATUS_BUILDS_NUMBER_MASK));
716 }
717
718 /**
719 * (non-Javadoc) Method declared on ModifyListener
720 */
modifyText(ModifyEvent event)721 public void modifyText(ModifyEvent event) {
722
723 // Add default dimension to results if necessary
724 if (event.getSource() == this.defaultDimensionCombo) {
725 String[] resultsDimensions = this.resultsDimensionsList.getSelection();
726 int length = resultsDimensions.length;
727 String defaultDimension = this.defaultDimensionCombo.getText();
728 for (int i = 0; i < length; i++) {
729 if (resultsDimensions[i].equals(defaultDimension)) {
730 // Default dim is already set as a results dimension, hence nothing has to be done
731 return;
732 }
733 }
734 System.arraycopy(resultsDimensions, 0, resultsDimensions = new String[length + 1], 0, length);
735 resultsDimensions[length] = defaultDimension;
736 this.resultsDimensionsList.setSelection(resultsDimensions);
737 }
738
739 // Add default dimension to results if necessary
740 if (event.getSource() == this.milestonesCombo) {
741
742 // Verify the only digits are entered
743 String milestoneDate = this.milestonesCombo.getText();
744 final int mLength = milestoneDate.length();
745 if (mLength > 0) {
746 for (int i=0; i<mLength; i++) {
747 if (!Character.isDigit(milestoneDate.charAt(i))) {
748 String[] items = this.milestonesCombo.getItems();
749 int length = items.length;
750 for (int j=0; j<length; j++) {
751 if (items[j].equals(milestoneDate)) {
752 // already existing milestone, leave silently
753 if (MessageDialog.openQuestion(getShell(), getDialogTitle(), "Do you want to select milestone "+milestoneDate+" as the last build?")) {
754 String builds[] = this.lastBuildCombo.getItems();
755 int bLength = builds.length;
756 String milestone = milestoneDate.substring(milestoneDate.indexOf('-')+1);
757 for (int b=0; b<bLength; b++) {
758 if (builds[b].length() > 0 && Util.getBuildDate(builds[b]).equals(milestone)) {
759 this.lastBuildCombo.select(b);
760 break;
761 }
762 }
763 }
764 return;
765 }
766 }
767 openMilestoneErrorMessage(milestoneDate);
768 return;
769 }
770 }
771 }
772
773 // Do not verify further until a complete milestone date is entered
774 if (mLength < 12) return;
775
776 // Verify the digits
777 try {
778 String str = milestoneDate.substring(0, 4);
779 int year = Integer.parseInt(str);
780 if (year < 2009 || year > 2020) { // 2020 should be enough!
781 MessageDialog.openError(getShell(), getDialogTitle(), milestoneDate+": "+str+" is an invalid year, only value between 2009 and 2020 is accepted!");
782 return;
783 }
784 str = milestoneDate.substring(4, 6);
785 int month = Integer.parseInt(str);
786 if (month <= 0 || month > 12) {
787 MessageDialog.openError(getShell(), getDialogTitle(), milestoneDate+": "+str+" is an invalid month, it should be only from 01 to 12!");
788 return;
789 }
790 str = milestoneDate.substring(6, 8);
791 int day = Integer.parseInt(str);
792 if (day <= 0 || day > 31) {
793 // TODO improve this verification
794 MessageDialog.openError(getShell(), getDialogTitle(), milestoneDate+": "+str+" is an invalid day, it should be only from 01 to 31!");
795 return;
796 }
797 str = milestoneDate.substring(8, 10);
798 int hour = Integer.parseInt(str);
799 if (hour < 0 || hour > 23) {
800 MessageDialog.openError(getShell(), getDialogTitle(), milestoneDate+": "+str+" is an invalid hour, it should be only from 00 to 23!");
801 return;
802 }
803 str = milestoneDate.substring(10, 12);
804 int min = Integer.parseInt(str);
805 if (min < 0 || min > 59) {
806 MessageDialog.openError(getShell(), getDialogTitle(), milestoneDate+": "+str+" is invalid minutes, it should be only from 00 to 59!");
807 return;
808 }
809 }
810 catch (NumberFormatException nfe) {
811 openMilestoneErrorMessage(milestoneDate);
812 }
813
814 // Get combo info
815 String[] milestones = this.milestonesCombo.getItems();
816 int length = milestones.length;
817 String lastMilestone = length == 0 ? null : milestones[length-1];
818
819 // Verify that the added milestone is valid
820 final String databaseLocation = this.databaseLocationCombo.getText();
821 char version = databaseLocation.charAt(databaseLocation.length()-1);
822
823 // Verify that the milestone follow the last one
824 String milestoneName;
825 if (lastMilestone == null) {
826 // No previous last milestone
827 milestoneName = "M1";
828 } else {
829 // Compare with last milestone
830 if (lastMilestone.charAt(0) == 'M') {
831 char digit = lastMilestone.charAt(1);
832 if (digit == '6') {
833 // M6 is the last dvpt milestone
834 milestoneName = "RC1";
835 } else {
836 milestoneName = "M" +((char)(digit+1));
837 }
838 } else if (lastMilestone.startsWith("RC")) {
839 char digit = lastMilestone.charAt(2);
840 if (digit == '4') {
841 // RC4 is the last release candidate milestone
842 milestoneName = "R3_"+version;
843 } else {
844 milestoneName = "RC" +((char)(digit+1));
845 }
846 } else if (lastMilestone.startsWith("R3_"+version+"-")) {
847 milestoneName = "R3_" + version + "_1";
848 } else if (lastMilestone.startsWith("R3_"+version+"_")) {
849 char digit = lastMilestone.charAt(5);
850 milestoneName = "R3_" + version + "_" + ((char)(digit+1));
851 } else {
852 MessageDialog.openError(getShell(), getDialogTitle(), "Unexpected last milestone name: "+lastMilestone+"!");
853 return;
854 }
855
856 // Verify the date of the new milestone
857 int lastMilestoneDash = lastMilestone.indexOf('-');
858 final String lastMilestoneDate = lastMilestone.substring(lastMilestoneDash+1);
859 if (milestoneDate.compareTo(lastMilestoneDate) <= 0) {
860 // TODO improve this verification
861 MessageDialog.openError(getShell(), getDialogTitle(), "Milestone "+milestoneDate+" should be after the last milestone: "+lastMilestoneDate+"!");
862 return;
863 }
864 }
865
866 // Verification are ok, ask to add the milestone
867 final String milestone = milestoneName + "-" + milestoneDate;
868 if (MessageDialog.openConfirm(getShell(), getDialogTitle(), milestoneDate+" is a valid milestone date.\n\nDo you want to add the milestone '"+milestone+"' to the preferences?")) {
869 this.milestonesCombo.add(milestone);
870 this.milestonesCombo.setText("");
871 }
872 }
873
874 // Verify the 'builds to confirm' number
875 if (event.getSource() == this.statusBuildsToConfirm) {
876 try {
877 int number = Integer.parseInt(this.statusBuildsToConfirm.getText());
878 if (number < 1 ) {
879 this.statusBuildsToConfirm.setText("1");
880 } else {
881 int buildsNumber = DB_Results.getBuildsNumber();
882 if (number > buildsNumber) {
883 this.statusBuildsToConfirm.setText(String.valueOf(buildsNumber));
884 }
885 }
886 }
887 catch (NumberFormatException nfe) {
888 this.statusBuildsToConfirm.setText("1");
889 }
890 }
891 }
892
893
894 /**
895 * @param milestone
896 */
openMilestoneErrorMessage(String milestone)897 void openMilestoneErrorMessage(String milestone) {
898 MessageDialog.openError(getShell(), getDialogTitle(), milestone+" is an invalid milestone date. Only 'yyyymmddHHMM' format is accepted!");
899 }
900
901 /*
902 * (non-Javadoc) Method declared on PreferencePage
903 */
performDefaults()904 protected void performDefaults() {
905 super.performDefaults();
906 initializeDefaults();
907 }
908
909 /*
910 * (non-Javadoc) Method declared on PreferencePage
911 */
performOk()912 public boolean performOk() {
913 final boolean hasBuildsView = this.buildsView != null;
914 if (hasBuildsView) {
915 storeValues();
916 try {
917 IEclipsePreferences preferences = new InstanceScope().getNode(PLUGIN_ID);
918 preferences.flush();
919 this.buildsView.resetView();
920 } catch (BackingStoreException e) {
921 e.printStackTrace();
922 return false;
923 }
924 }
925 return true;
926 }
927
928 /**
929 * Stores the values of the controls back to the preference store.
930 */
storeValues()931 private void storeValues() {
932 IPreferenceStore store = getPreferenceStore();
933
934 // Set version
935 int version;
936 if (this.mVersionRadioButton.getSelection()) {
937 version = ECLIPSE_MAINTENANCE_VERSION;
938 } else {
939 version = ECLIPSE_DEVELOPMENT_VERSION;
940 }
941 store.setValue(PRE_ECLIPSE_VERSION, version);
942
943 // Set database values
944 store.setValue(PRE_DATABASE_CONNECTION, this.dbConnectionCheckBox.getSelection());
945 final boolean dbLocal = this.dbLocalRadioButton.getSelection();
946 store.setValue(PRE_DATABASE_LOCAL, dbLocal);
947 String location = this.databaseLocationCombo.getText();
948 if (dbLocal) {
949 store.setValue(PRE_DATABASE_LOCATION, location);
950 } else {
951 store.setValue(PRE_DATABASE_LOCATION, NETWORK_DATABASE_LOCATION);
952 }
953 int count = this.databaseLocationCombo.getItemCount();
954 for (int i=0; i<count; i++) {
955 String item = this.databaseLocationCombo.getItem(i);
956 if (item.equals(location)) {
957 this.databaseLocationCombo.remove(i);
958 break;
959 }
960 }
961 if (dbLocal) {
962 this.databaseLocationCombo.add(location, 0);
963 }
964 int i=0;
965 for (; i<count; i++) {
966 String item = this.databaseLocationCombo.getItem(i);
967 if (item.length() == 0) break;
968 store.setValue(PRE_DATABASE_LOCATION+"."+i, item);
969 }
970 while (store.getString(PRE_DATABASE_LOCATION+"."+i).length() > 0) {
971 store.setToDefault(PRE_DATABASE_LOCATION+"."+i);
972 i++;
973 }
974
975 // Set status values
976 int writeStatus = 0;
977 if (this.statusValuesCheckBox.getSelection()) {
978 writeStatus |= STATUS_VALUES;
979 }
980 if (this.statusErrorNoneRadioButton.getSelection()) {
981 writeStatus |= STATUS_ERROR_NONE;
982 } else if (this.statusErrorNoticeableRadioButton.getSelection()) {
983 writeStatus |= STATUS_ERROR_NOTICEABLE;
984 } else if (this.statusErrorSuspiciousRadioButton.getSelection()) {
985 writeStatus |= STATUS_ERROR_SUSPICIOUS;
986 } else if (this.statusErrorWeirdRadioButton.getSelection()) {
987 writeStatus |= STATUS_ERROR_WEIRD;
988 } else if (this.statusErrorInvalidRadioButton.getSelection()) {
989 writeStatus |= STATUS_ERROR_INVALID;
990 }
991 if (this.statusSmallBuildValueCheckBox.getSelection()) {
992 writeStatus |= STATUS_SMALL_VALUE_BUILD;
993 }
994 if (this.statusSmallDeltaValueCheckBox.getSelection()) {
995 writeStatus |= STATUS_SMALL_VALUE_DELTA;
996 }
997 if (this.statusStatisticNoneRadioButton.getSelection()) {
998 writeStatus &= ~STATUS_STATISTICS_MASK;
999 } else if (this.statusStatisticErraticRadioButton.getSelection()) {
1000 writeStatus |= STATUS_STATISTICS_ERRATIC;
1001 } else if (this.statusStatisticUnstableRadioButton.getSelection()) {
1002 writeStatus |= STATUS_STATISTICS_UNSTABLE;
1003 }
1004 writeStatus += Integer.parseInt(this.statusBuildsToConfirm.getText());
1005 store.setValue(PRE_WRITE_STATUS, writeStatus);
1006
1007 // Set milestones
1008 String prefix = PRE_MILESTONE_BUILDS + "." + version;
1009 count = this.milestonesCombo.getItemCount();
1010 for (i=0; i<count; i++) {
1011 store.putValue(prefix + i, this.milestonesCombo.getItem(i));
1012 }
1013 Util.setMilestones(this.milestonesCombo.getItems());
1014
1015 // Unset previous additional milestones
1016 String milestone = store.getString(prefix + count);
1017 while (milestone != null && milestone.length() > 0) {
1018 store.putValue(prefix + count++, "");
1019 milestone = store.getString(prefix + count);
1020 }
1021
1022 // Set last build
1023 String lastBuild = this.lastBuildCombo.getText();
1024 store.putValue(PRE_LAST_BUILD, lastBuild);
1025
1026 // Set default dimension
1027 String defaultDimension = this.defaultDimensionCombo.getText();
1028 store.putValue(PRE_DEFAULT_DIMENSION, defaultDimension);
1029 DB_Results.setDefaultDimension(defaultDimension);
1030
1031 // Set generated dimensions
1032 int[] indices = this.resultsDimensionsList.getSelectionIndices();
1033 int length = indices.length;
1034 String[] dimensions = new String[length];
1035 if (length > 0) {
1036 for (i = 0; i < indices.length; i++) {
1037 dimensions[i] = this.resultsDimensionsList.getItem(indices[i]);
1038 store.putValue(PRE_RESULTS_DIMENSION + "." + i, dimensions[i]);
1039 }
1040 }
1041 int currentLength = DB_Results.getResultsDimensions().length;
1042 if (currentLength > length) {
1043 for (i = currentLength - 1; i >= length; i--) {
1044 store.putValue(PRE_RESULTS_DIMENSION + "." + i, ""); // reset extra dimensions
1045 }
1046 }
1047 DB_Results.setResultsDimensions(dimensions);
1048
1049 // Set config descriptors
1050 /* TODO See whether config descriptors need to be set as preferences or not...
1051 TableItem[] items = this.configDescriptorsTable.getItems();
1052 length = items.length;
1053 for (int i = 0; i < length; i++) {
1054 TableItem item = items[i];
1055 store.putValue(PRE_CONFIG_DESCRIPTOR_NAME + "." + i, item.getText(0));
1056 store.putValue(PRE_CONFIG_DESCRIPTOR_DESCRIPTION + "." + i, item.getText(1));
1057 }
1058 */
1059 }
1060
1061 /**
1062 * (non-Javadoc) Method declared on SelectionListener
1063 */
widgetDefaultSelected(SelectionEvent event)1064 public void widgetDefaultSelected(SelectionEvent event) {
1065 }
1066
1067 /**
1068 * (non-Javadoc) Method declared on SelectionListener
1069 */
widgetSelected(SelectionEvent event)1070 public void widgetSelected(SelectionEvent event) {
1071
1072 // As for directory when 'Local' button is pushed
1073 final Object source = event.getSource();
1074 if (source == this.dbLocalBrowseButton) {
1075 String location = this.databaseLocationCombo.getText();
1076 String path = getDirectoryPath(location);
1077 if (path != null) {
1078 // First verify that the selected dir was correct
1079 int version;
1080 if (this.mVersionRadioButton.getSelection()) {
1081 version = ECLIPSE_MAINTENANCE_VERSION;
1082 } else {
1083 version = ECLIPSE_DEVELOPMENT_VERSION;
1084 }
1085 File dbDir = new File(path, "perfDb"+version);
1086 if (!dbDir.exists() || !dbDir.isDirectory()) {
1087 StringBuffer message = new StringBuffer("Invalid performance database directory\n");
1088 message.append(path+" should contain 'perfDb");
1089 message.append(version);
1090 message.append("' directory and none was found!");
1091 MessageDialog.openError(getShell(), getDialogTitle(), message.toString());
1092 return;
1093 }
1094
1095 // Look for selected dir in combo box list
1096 int count = this.databaseLocationCombo.getItemCount();
1097 int index = -1;
1098 for (int i = 0; i < count; i++) {
1099 String item = this.databaseLocationCombo.getItem(i);
1100 if (item.length() == 0) { // nothing in the combo-box list
1101 break;
1102 }
1103 if (item.equals(path)) {
1104 index = i;
1105 break;
1106 }
1107 }
1108 // Set the selected dir the more recent in the previous dirs list
1109 if (index != 0) {
1110 if (index > 0) {
1111 // the dir was used before, but not recently => remove it from previous dirs list
1112 this.databaseLocationCombo.remove(index);
1113 }
1114 // add the selected dir on the top of the previous dirs list
1115 this.databaseLocationCombo.add(path, 0);
1116 }
1117 // Set combo box text
1118 this.databaseLocationCombo.setText(path);
1119 updateLocalDb();
1120 }
1121 }
1122
1123 // Reset dabase location when 'Releng' button is pushed
1124 if (source == this.dbConnectionCheckBox) {
1125 updateDatabaseGroup();
1126 }
1127
1128 // Reset dabase location when 'Releng' check-box is checked
1129 if (source == this.dbLocalRadioButton) {
1130 updateLocalDb();
1131 }
1132
1133 // Add default dimension to results if necessary
1134 if (source == this.resultsDimensionsList) {
1135 String[] resultsDimensions = this.resultsDimensionsList.getSelection();
1136 int length = resultsDimensions.length;
1137 String defaultDimension = this.defaultDimensionCombo.getText();
1138 for (int i = 0; i < length; i++) {
1139 if (resultsDimensions[i].equals(defaultDimension)) {
1140 // Default dim is already set as a results dimension, hence nothing has to be done
1141 return;
1142 }
1143 }
1144 System.arraycopy(resultsDimensions, 0, resultsDimensions = new String[length + 1], 0, length);
1145 resultsDimensions[length] = defaultDimension;
1146 this.resultsDimensionsList.setSelection(resultsDimensions);
1147 }
1148
1149 // if (source == this.lastBuildCheckBox) {
1150 // this.lastBuildCombo.setEnabled(this.lastBuildCheckBox.getSelection());
1151 // }
1152
1153 if (source == this.mVersionRadioButton) {
1154 if (this.mVersionRadioButton.getSelection()) {
1155 updateBrowseButtonToolTip(ECLIPSE_MAINTENANCE_VERSION);
1156 }
1157 }
1158
1159 if (source == this.dVersionRadionButton) {
1160 if (this.dVersionRadionButton.getSelection()) {
1161 updateBrowseButtonToolTip(ECLIPSE_DEVELOPMENT_VERSION);
1162 }
1163 }
1164 }
1165
1166 /*
1167 * Update browse tooltip
1168 */
updateBrowseButtonToolTip(int version)1169 void updateBrowseButtonToolTip(int version) {
1170 this.dbLocalBrowseButton.setToolTipText("Select the directory where the database was unzipped\n(i.e. should contain the perfDb"+version+" subdirectory)");
1171 }
1172
1173 /*
1174 * Update database group controls.
1175 */
updateDatabaseGroup()1176 void updateDatabaseGroup() {
1177 if (this.dbConnectionCheckBox.getSelection()) {
1178 this.dbRelengRadioButton.setEnabled(true);
1179 this.dbLocalRadioButton.setEnabled(true);
1180 updateLocalDb();
1181 } else {
1182 this.dbRelengRadioButton.setEnabled(false);
1183 this.dbLocalRadioButton.setEnabled(false);
1184 this.databaseLocationCombo.setEnabled(false);
1185 this.dbLocalBrowseButton.setEnabled(false);
1186 setValid(true);
1187 }
1188 }
1189
1190 /*
1191 * Update database location controls.
1192 */
updateLocalDb()1193 void updateLocalDb() {
1194 if (this.dbLocalRadioButton.getSelection()) {
1195 this.databaseLocationCombo.setEnabled(true);
1196 this.dbLocalBrowseButton.setEnabled(true);
1197 if (this.databaseLocationCombo.getItemCount() == 0) {
1198 this.databaseLocationCombo.setText("");
1199 setValid(false);
1200 } else {
1201 this.databaseLocationCombo.select(0);
1202 setValid(true);
1203 }
1204 this.dbRelengRadioButton.setToolTipText("");
1205 this.dbLocationLabel.setEnabled(true);
1206 } else {
1207 this.dbRelengRadioButton.setToolTipText(NETWORK_DATABASE_LOCATION);
1208 this.databaseLocationCombo.setText("");
1209 this.databaseLocationCombo.setEnabled(false);
1210 this.dbLocalBrowseButton.setEnabled(false);
1211 setValid(true);
1212 this.dbLocationLabel.setEnabled(false);
1213 }
1214 }
1215
1216 }
1217