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 *******************************************************************************/ 11package org.eclipse.test.internal.performance.results.ui; 12 13import java.io.File; 14import java.util.Arrays; 15import java.util.Iterator; 16 17import org.osgi.service.prefs.BackingStoreException; 18 19import org.eclipse.test.internal.performance.PerformanceTestPlugin; 20import org.eclipse.test.internal.performance.results.db.DB_Results; 21import org.eclipse.test.internal.performance.results.utils.IPerformancesConstants; 22import org.eclipse.test.internal.performance.results.utils.Util; 23import org.eclipse.test.performance.ui.UiPlugin; 24 25import org.eclipse.swt.SWT; 26import org.eclipse.swt.custom.CCombo; 27import org.eclipse.swt.events.ModifyEvent; 28import org.eclipse.swt.events.ModifyListener; 29import org.eclipse.swt.events.SelectionEvent; 30import org.eclipse.swt.events.SelectionListener; 31import org.eclipse.swt.layout.GridData; 32import org.eclipse.swt.layout.GridLayout; 33import org.eclipse.swt.widgets.Button; 34import org.eclipse.swt.widgets.Composite; 35import org.eclipse.swt.widgets.Control; 36import org.eclipse.swt.widgets.DirectoryDialog; 37import org.eclipse.swt.widgets.Display; 38import org.eclipse.swt.widgets.Group; 39import org.eclipse.swt.widgets.Label; 40import org.eclipse.swt.widgets.List; 41import org.eclipse.swt.widgets.Text; 42 43import org.eclipse.core.runtime.preferences.IEclipsePreferences; 44import org.eclipse.core.runtime.preferences.InstanceScope; 45 46import org.eclipse.jface.dialogs.MessageDialog; 47import org.eclipse.jface.preference.IPreferenceStore; 48import org.eclipse.jface.preference.PreferencePage; 49 50import org.eclipse.ui.IWorkbench; 51import org.eclipse.ui.IWorkbenchPreferencePage; 52 53/** 54 * Defines the 'Performances' preferences page. 55 */ 56public 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 */ 101private 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 */ 119private 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 */ 143private 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 */ 163protected 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 */ 295private 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 */ 316private 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 */ 333private 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 */ 356private 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 */ 379private 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 * 395private 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 */ 413private 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 */ 431protected IPreferenceStore doGetPreferenceStore() { 432 return UiPlugin.getDefault().getPreferenceStore(); 433} 434 435/** 436 * @return The dialog title 437 */ 438String 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 */ 456private 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 */ 474public void init(IWorkbench workbench) { 475 // do nothing 476} 477 478/* 479 * Init he contents of the dimensions list controls. 480 */ 481void 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 */ 495private 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 */ 508private 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 */ 572private 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 */ 667private 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 */ 721public 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 */ 897void 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 */ 904protected void performDefaults() { 905 super.performDefaults(); 906 initializeDefaults(); 907} 908 909/* 910 * (non-Javadoc) Method declared on PreferencePage 911 */ 912public 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 */ 931private 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 */ 1064public void widgetDefaultSelected(SelectionEvent event) { 1065} 1066 1067/** 1068 * (non-Javadoc) Method declared on SelectionListener 1069 */ 1070public 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 */ 1169void 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 */ 1176void 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 */ 1193void 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