001/***************************************************************************** 002 * Copyright by The HDF Group. * 003 * Copyright by the Board of Trustees of the University of Illinois. * 004 * All rights reserved. * 005 * * 006 * This file is part of the HDF Java Products distribution. * 007 * The full copyright notice, including terms governing use, modification, * 008 * and redistribution, is contained in the files COPYING and Copyright.html. * 009 * COPYING can be found at the root of the source code distribution tree. * 010 * Or, see https://support.hdfgroup.org/products/licenses.html * 011 * If you do not have access to either file, you may request a copy from * 012 * help@hdfgroup.org. * 013 ****************************************************************************/ 014 015package hdf.view.dialog; 016 017import java.awt.GraphicsEnvironment; 018import java.io.File; 019 020import org.eclipse.swt.SWT; 021import org.eclipse.swt.events.SelectionAdapter; 022import org.eclipse.swt.events.SelectionEvent; 023import org.eclipse.swt.graphics.Font; 024import org.eclipse.swt.layout.GridData; 025import org.eclipse.swt.layout.GridLayout; 026import org.eclipse.swt.widgets.Button; 027import org.eclipse.swt.widgets.Combo; 028import org.eclipse.swt.widgets.Composite; 029import org.eclipse.swt.widgets.Control; 030import org.eclipse.swt.widgets.DirectoryDialog; 031import org.eclipse.swt.widgets.Display; 032import org.eclipse.swt.widgets.FileDialog; 033import org.eclipse.swt.widgets.Label; 034import org.eclipse.swt.widgets.Text; 035 036import hdf.view.Tools; 037import hdf.view.ViewProperties; 038 039/** 040 * UserOptionsGeneralPage.java - Configuration page for general application settings. 041 */ 042public class UserOptionsGeneralPage extends UserOptionsDefaultPage { 043 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UserOptionsGeneralPage.class); 044 045 private Text UGField, workField, maxMemberField, startMemberField; 046 047 private Combo fontSizeChoice, fontTypeChoice, delimiterChoice, imageOriginChoice, indexBaseChoice; 048 049 private Button checkCurrentUserDir, checkAutoContrast, checkShowValues; 050 private Button currentDirButton, rwButton, helpButton; 051 private Button checkReadOnly, checkReadAll; 052 053 private boolean isFontChanged; 054 private boolean isUserGuideChanged; 055 private boolean isWorkDirChanged; 056 057 private String workDir; 058 059 private static String fontname; 060 061 public UserOptionsGeneralPage() { 062 super("General Settings"); 063 isFontChanged = false; 064 isUserGuideChanged = false; 065 isWorkDirChanged = false; 066 } 067 068 /** 069 * Performs special processing when this page's Defaults button has been pressed. 070 */ 071 @Override 072 public void performDefaults() { 073 super.performDefaults(); 074 } 075 076 /** 077 * Notifies that the OK button of this page's container has been pressed. 078 * 079 * @return <code>false</code> to abort the container's OK processing and 080 * <code>true</code> to allow the OK to happen 081 */ 082 @Override 083 public boolean performOk() { 084 getPreferenceStore(); 085 086 if (UGField != null) { 087 String UGPath = UGField.getText(); 088 if ((UGPath != null) && (UGPath.length() > 0)) { 089 UGPath = UGPath.trim(); 090 isUserGuideChanged = !UGPath.equals(ViewProperties.getUsersGuide()); 091 ViewProperties.setUsersGuide(UGPath); 092 } 093 } 094 095 if (workField != null) { 096 String workPath = workField.getText(); 097 if (checkCurrentUserDir.getSelection()) 098 workPath = System.getProperty("user.home"); 099 100 if ((workPath != null) && (workPath.length() > 0)) { 101 workPath = workPath.trim(); 102 isWorkDirChanged = !workPath.equals(ViewProperties.getWorkDir()); 103 ViewProperties.setWorkDir(workPath); 104 } 105 } 106 107 // set font size and type 108 try { 109 if (fontTypeChoice != null) { 110 String ftype = fontTypeChoice.getItem(fontTypeChoice.getSelectionIndex()); 111 int fsize = Integer.parseInt(fontSizeChoice.getItem(fontSizeChoice.getSelectionIndex())); 112 log.trace("performOk: save font options {} - {}", ftype, fsize); 113 114 if (ViewProperties.getFontSize() != fsize) { 115 ViewProperties.setFontSize(fsize); 116 isFontChanged = true; 117 log.trace("performOk: props font size {}", ViewProperties.getFontSize()); 118 } 119 120 if (!ftype.equalsIgnoreCase(ViewProperties.getFontType())) { 121 ViewProperties.setFontType(ftype); 122 isFontChanged = true; 123 log.trace("performOk: props font {}", ViewProperties.getFontType()); 124 } 125 } 126 } 127 catch (Exception ex) { 128 isFontChanged = false; 129 } 130 131 // set file access 132 if (checkReadOnly != null) { 133 if (checkReadOnly.getSelection()) 134 ViewProperties.setReadOnly(true); 135 else 136 ViewProperties.setReadOnly(false); 137 } 138 139 // set data delimiter 140 if (delimiterChoice != null) 141 ViewProperties.setDataDelimiter(delimiterChoice.getItem(delimiterChoice.getSelectionIndex())); 142 if (imageOriginChoice != null) 143 ViewProperties.setImageOrigin(imageOriginChoice.getItem(imageOriginChoice.getSelectionIndex())); 144 145 if (checkReadAll != null) { 146 if (checkReadAll.getSelection()) { 147 ViewProperties.setStartMembers(0); 148 ViewProperties.setMaxMembers(-1); 149 } 150 else { 151 try { 152 int maxsize = Integer.parseInt(maxMemberField.getText()); 153 ViewProperties.setMaxMembers(maxsize); 154 } 155 catch (Exception ex) { 156 } 157 158 try { 159 int startsize = Integer.parseInt(startMemberField.getText()); 160 ViewProperties.setStartMembers(startsize); 161 } 162 catch (Exception ex) { 163 } 164 } 165 } 166 167 if (checkAutoContrast != null) 168 ViewProperties.setAutoContrast(checkAutoContrast.getSelection()); 169 if (checkShowValues != null) 170 ViewProperties.setShowImageValue(checkShowValues.getSelection()); 171 172 if (indexBaseChoice != null) { 173 if (indexBaseChoice.getSelectionIndex() == 0) 174 ViewProperties.setIndexBase1(false); 175 else 176 ViewProperties.setIndexBase1(true); 177 } 178 179 return true; 180 } 181 182 public boolean isFontChanged() { 183 return isFontChanged; 184 } 185 186 public boolean isUserGuideChanged() { 187 return isUserGuideChanged; 188 } 189 190 public boolean isWorkDirChanged() { 191 return isWorkDirChanged; 192 } 193 194 /** 195 * Loads all stored values in the <code>FieldEditor</code>s. 196 */ 197 protected void load() { 198 getPreferenceStore(); 199 200 try { 201 curFont = new Font( 202 Display.getCurrent(), 203 ViewProperties.getFontType(), 204 ViewProperties.getFontSize(), 205 SWT.NORMAL); 206 } 207 catch (Exception ex) { 208 curFont = null; 209 } 210 211 workDir = ViewProperties.getWorkDir(); 212 if (workDir == null) 213 workDir = rootDir; 214 215 workField.setText(workDir); 216 217 if (workDir.equals(System.getProperty("user.home"))) { 218 checkCurrentUserDir.setSelection(true); 219 workField.setEnabled(false); 220 } 221 222 log.trace("UserOptionsGeneralPage: workDir={}", workDir); 223 224 UGField.setText(ViewProperties.getUsersGuide()); 225 226 checkReadOnly.setSelection(ViewProperties.isReadOnly()); 227 228 rwButton.setSelection(!ViewProperties.isReadOnly()); 229 230 String fontsize = String.valueOf(ViewProperties.getFontSize()); 231 log.trace("performOk: load General options fontsize={}", fontsize); 232 try { 233 int selectionIndex = fontSizeChoice.indexOf(fontsize); 234 fontSizeChoice.select(selectionIndex); 235 } 236 catch (Exception ex) { 237 fontSizeChoice.select(0); 238 } 239 240 fontname = ViewProperties.getFontType(); 241 log.trace("performOk: load General options fontname={}", fontname); 242 try { 243 int selectionIndex = fontTypeChoice.indexOf(fontname); 244 fontTypeChoice.select(selectionIndex); 245 } 246 catch (Exception ex) { 247 String sysFontName = Display.getDefault().getSystemFont().getFontData()[0].getName(); 248 249 try { 250 int selectionIndex = fontTypeChoice.indexOf(sysFontName); 251 fontTypeChoice.select(selectionIndex); 252 } 253 catch (Exception ex2) { 254 fontTypeChoice.select(0); 255 } 256 } 257 258 checkAutoContrast.setSelection(ViewProperties.isAutoContrast()); 259 260 checkShowValues.setSelection(ViewProperties.showImageValues()); 261 262 String[] imageOriginChoices = { ViewProperties.ORIGIN_UL, ViewProperties.ORIGIN_LL, ViewProperties.ORIGIN_UR, 263 ViewProperties.ORIGIN_LR }; 264 imageOriginChoice.setItems(imageOriginChoices); 265 266 try { 267 int selectionIndex = imageOriginChoice.indexOf(ViewProperties.getImageOrigin()); 268 imageOriginChoice.select(selectionIndex); 269 } 270 catch (Exception ex) { 271 imageOriginChoice.select(0); 272 } 273 274 // helpButton.setImage(ViewProperties.getHelpIcon()); 275 276 if (ViewProperties.isIndexBase1()) 277 indexBaseChoice.select(1); 278 else 279 indexBaseChoice.select(0); 280 281 String[] delimiterChoices = { ViewProperties.DELIMITER_TAB, ViewProperties.DELIMITER_COMMA, 282 ViewProperties.DELIMITER_SPACE, ViewProperties.DELIMITER_COLON, ViewProperties.DELIMITER_SEMI_COLON }; 283 delimiterChoice.setItems(delimiterChoices); 284 285 try { 286 int selectionIndex = delimiterChoice.indexOf(ViewProperties.getDataDelimiter()); 287 delimiterChoice.select(selectionIndex); 288 } 289 catch (Exception ex) { 290 delimiterChoice.select(0); 291 } 292 293 int nMax = ViewProperties.getMaxMembers(); 294 checkReadAll.setSelection((nMax<=0) || (nMax==Integer.MAX_VALUE)); 295 296 startMemberField.setText(String.valueOf(ViewProperties.getStartMembers())); 297 298 maxMemberField.setText(String.valueOf(ViewProperties.getMaxMembers())); 299 } 300 301 /** 302 * Creates and returns the SWT control for the customized body of this 303 * preference page under the given parent composite. 304 * 305 * @param parent the parent composite 306 * @return the new control 307 */ 308 @Override 309 protected Control createContents(Composite parent) { 310 shell = parent.getShell(); 311 Composite composite = new Composite(parent, SWT.NONE); 312 composite.setLayout(new GridLayout()); 313 314 org.eclipse.swt.widgets.Group workingDirectoryGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE); 315 workingDirectoryGroup.setLayout(new GridLayout(3, false)); 316 workingDirectoryGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 317 workingDirectoryGroup.setFont(curFont); 318 workingDirectoryGroup.setText("Default Working Directory"); 319 320 checkCurrentUserDir = new Button(workingDirectoryGroup, SWT.CHECK); 321 checkCurrentUserDir.setFont(curFont); 322 checkCurrentUserDir.setText("\"Current Working Directory\" or"); 323 checkCurrentUserDir.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 324 checkCurrentUserDir.addSelectionListener(new SelectionAdapter() { 325 @Override 326 public void widgetSelected(SelectionEvent e) { 327 boolean isCheckCurrentUserDirSelected = checkCurrentUserDir.getSelection(); 328 workField.setEnabled(!isCheckCurrentUserDirSelected); 329 currentDirButton.setEnabled(!isCheckCurrentUserDirSelected); 330 } 331 }); 332 333 workField = new Text(workingDirectoryGroup, SWT.SINGLE | SWT.BORDER); 334 workField.setFont(curFont); 335 workField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 336 337 currentDirButton = new Button(workingDirectoryGroup, SWT.PUSH); 338 currentDirButton.setFont(curFont); 339 currentDirButton.setText("Browse..."); 340 currentDirButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 341 currentDirButton.addSelectionListener(new SelectionAdapter() { 342 @Override 343 public void widgetSelected(SelectionEvent e) { 344 final DirectoryDialog dChooser = new DirectoryDialog(shell); 345 dChooser.setFilterPath(workDir); 346 dChooser.setText("Select a Directory"); 347 348 String dir = dChooser.open(); 349 350 if(dir == null) return; 351 352 workField.setText(dir); 353 } 354 }); 355 356 org.eclipse.swt.widgets.Group helpDocumentGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE); 357 helpDocumentGroup.setLayout(new GridLayout(3, false)); 358 helpDocumentGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 359 helpDocumentGroup.setFont(curFont); 360 helpDocumentGroup.setText("Help Document"); 361 362 Label label = new Label(helpDocumentGroup, SWT.RIGHT); 363 label.setFont(curFont); 364 label.setText("User's Guide: "); 365 366 UGField = new Text(helpDocumentGroup, SWT.SINGLE | SWT.BORDER); 367 UGField.setFont(curFont); 368 UGField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); 369 370 Button browseButton = new Button(helpDocumentGroup, SWT.PUSH); 371 browseButton.setFont(curFont); 372 browseButton.setText("Browse..."); 373 browseButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 374 browseButton.addSelectionListener(new SelectionAdapter() { 375 @Override 376 public void widgetSelected(SelectionEvent e) { 377 final FileDialog fChooser = new FileDialog(shell, SWT.OPEN); 378 fChooser.setFilterPath(rootDir); 379 fChooser.setFilterExtensions(new String[] {"*"}); 380 fChooser.setFilterNames(new String[] {"All Files"}); 381 fChooser.setFilterIndex(0); 382 383 if(fChooser.open() == null) { 384 return; 385 } 386 387 File chosenFile = new File(fChooser.getFilterPath() + File.separator + fChooser.getFileName()); 388 389 if(!chosenFile.exists()) { 390 // Give an error 391 return; 392 } 393 394 UGField.setText(chosenFile.getAbsolutePath()); 395 } 396 }); 397 398 org.eclipse.swt.widgets.Group fileAccessModeGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE); 399 fileAccessModeGroup.setLayout(new GridLayout(2, true)); 400 fileAccessModeGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 401 fileAccessModeGroup.setFont(curFont); 402 fileAccessModeGroup.setText("Default File Access Mode"); 403 404 checkReadOnly = new Button(fileAccessModeGroup, SWT.RADIO); 405 checkReadOnly.setFont(curFont); 406 checkReadOnly.setText("Read Only"); 407 checkReadOnly.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, false)); 408 409 rwButton = new Button(fileAccessModeGroup, SWT.RADIO); 410 rwButton.setFont(curFont); 411 rwButton.setText("Read/Write"); 412 rwButton.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, false, false)); 413 414 org.eclipse.swt.widgets.Group textFontGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE); 415 textFontGroup.setLayout(new GridLayout(4, false)); 416 textFontGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 417 textFontGroup.setFont(curFont); 418 textFontGroup.setText("Text Font"); 419 420 label = new Label(textFontGroup, SWT.RIGHT); 421 label.setFont(curFont); 422 label.setText("Font Size: "); 423 424 String[] fontSizeChoices = { "8", "10", "12", "14", "16", "18", "20", "22", "24", "26", "28", "30", "32", "34", "36", "48" }; 425 fontSizeChoice = new Combo(textFontGroup, SWT.SINGLE | SWT.READ_ONLY); 426 fontSizeChoice.setFont(curFont); 427 fontSizeChoice.setItems(fontSizeChoices); 428 fontSizeChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 429 430 label = new Label(textFontGroup, SWT.RIGHT); 431 label.setFont(curFont); 432 label.setText("Font Type: "); 433 434 String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); 435 436 fontTypeChoice = new Combo(textFontGroup, SWT.SINGLE | SWT.READ_ONLY); 437 fontTypeChoice.setFont(curFont); 438 fontTypeChoice.setItems(fontNames); 439 fontTypeChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 440 441 org.eclipse.swt.widgets.Group imageGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE); 442 imageGroup.setLayout(new GridLayout(5, false)); 443 imageGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 444 imageGroup.setFont(curFont); 445 imageGroup.setText("Image"); 446 447 helpButton = new Button(imageGroup, SWT.PUSH); 448 helpButton.setImage(ViewProperties.getHelpIcon()); 449 helpButton.setToolTipText("Help on Auto Contrast"); 450 helpButton.addSelectionListener(new SelectionAdapter() { 451 @Override 452 public void widgetSelected(SelectionEvent e) { 453 final String msg = "Auto Contrast does the following to compute a gain/bias \n" 454 + "that will stretch the pixels in the image to fit the pixel \n" 455 + "values of the graphics system. For example, it stretches unsigned\n" 456 + "short data to fit the full range of an unsigned short. Later \n" 457 + "code simply takes the high order byte and passes it to the graphics\n" 458 + "system (which expects 0-255). It uses some statistics on the pixels \n" 459 + "to prevent outliers from throwing off the gain/bias calculations much.\n\n" 460 + "To compute the gain/bias we... \n" 461 + "Find the mean and std. deviation of the pixels in the image \n" + "min = mean - 3 * std.dev. \n" 462 + "max = mean + 3 * std.dev. \n" + "small fudge factor because this tends to overshoot a bit \n" 463 + "Stretch to 0-USHRT_MAX \n" + " gain = USHRT_MAX / (max-min) \n" 464 + " bias = -min \n" + "\n" + "To apply the gain/bias to a pixel, use the formula \n" 465 + "data[i] = (data[i] + bias) * gain \n" + "\n" 466 // + 467 // "Finally, for auto-ranging the sliders for gain/bias, we do the following \n" 468 // + "gain_min = 0 \n" 469 // + "gain_max = gain * 3.0 \n" 470 // + "bias_min = -fabs(bias) * 3.0 \n" 471 // + "bias_max = fabs(bias) * 3.0 \n" 472 + "\n\n"; 473 474 Tools.showInformation(getShell(), "Help", msg); 475 } 476 }); 477 478 checkAutoContrast = new Button(imageGroup, SWT.CHECK); 479 checkAutoContrast.setFont(curFont); 480 checkAutoContrast.setText("Autogain Image Contrast"); 481 checkAutoContrast.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 482 483 checkShowValues = new Button(imageGroup, SWT.CHECK); 484 checkShowValues.setFont(curFont); 485 checkShowValues.setText("Show Values"); 486 checkShowValues.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 487 488 label = new Label(imageGroup, SWT.RIGHT); 489 label.setFont(curFont); 490 label.setText("Image Origin: "); 491 492 imageOriginChoice = new Combo(imageGroup, SWT.SINGLE | SWT.READ_ONLY); 493 imageOriginChoice.setFont(curFont); 494 imageOriginChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 495 496 org.eclipse.swt.widgets.Group dataGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE); 497 dataGroup.setLayout(new GridLayout(4, false)); 498 dataGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 499 dataGroup.setFont(curFont); 500 dataGroup.setText("Data"); 501 502 label = new Label(dataGroup, SWT.RIGHT); 503 label.setFont(curFont); 504 label.setText("Index Base: "); 505 506 String[] indexBaseChoices = { "0-based", "1-based" }; 507 indexBaseChoice = new Combo(dataGroup, SWT.SINGLE | SWT.READ_ONLY); 508 indexBaseChoice.setFont(curFont); 509 indexBaseChoice.setItems(indexBaseChoices); 510 indexBaseChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 511 512 Label delimLabel = new Label(dataGroup, SWT.RIGHT); 513 delimLabel.setFont(curFont); 514 delimLabel.setText("Data Delimiter: "); 515 delimLabel.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); 516 517 delimiterChoice = new Combo(dataGroup, SWT.SINGLE | SWT.READ_ONLY); 518 delimiterChoice.setFont(curFont); 519 delimiterChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 520 521 org.eclipse.swt.widgets.Group objectsGroup = new org.eclipse.swt.widgets.Group(composite, SWT.NONE); 522 objectsGroup.setLayout(new GridLayout(5, true)); 523 objectsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 524 objectsGroup.setFont(curFont); 525 objectsGroup.setText("Objects to Open"); 526 527 checkReadAll = new Button(objectsGroup, SWT.CHECK); 528 checkReadAll.setFont(curFont); 529 checkReadAll.setText("Open All"); 530 checkReadAll.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 531 checkReadAll.addSelectionListener(new SelectionAdapter() { 532 @Override 533 public void widgetSelected(SelectionEvent e) { 534 startMemberField.setEnabled(!checkReadAll.getSelection()); 535 maxMemberField.setEnabled(!checkReadAll.getSelection()); 536 } 537 }); 538 539 label = new Label(objectsGroup, SWT.RIGHT); 540 label.setFont(curFont); 541 label.setText("Start Member: "); 542 543 startMemberField = new Text(objectsGroup, SWT.SINGLE | SWT.BORDER); 544 startMemberField.setFont(curFont); 545 startMemberField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 546 547 label = new Label(objectsGroup, SWT.RIGHT); 548 label.setFont(curFont); 549 label.setText("Member Count: "); 550 551 maxMemberField = new Text(objectsGroup, SWT.SINGLE | SWT.BORDER); 552 maxMemberField.setFont(curFont); 553 maxMemberField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); 554 555 startMemberField.setEnabled(!checkReadAll.getSelection()); 556 maxMemberField.setEnabled(!checkReadAll.getSelection()); 557 558 load(); 559 // return scroller; 560 return composite; 561 } 562}