| 1 | package de.uka.ipd.sdq.sensorframework.visualisation.dialogs; |
| 2 | |
| 3 | import java.io.File; |
| 4 | |
| 5 | import org.eclipse.swt.widgets.Dialog; |
| 6 | import org.eclipse.swt.widgets.Display; |
| 7 | import org.eclipse.swt.widgets.FileDialog; |
| 8 | import org.eclipse.swt.widgets.MessageBox; |
| 9 | import org.eclipse.swt.widgets.Shell; |
| 10 | import org.eclipse.swt.widgets.Button; |
| 11 | import org.eclipse.swt.SWT; |
| 12 | import org.eclipse.swt.widgets.Combo; |
| 13 | import org.eclipse.swt.widgets.Label; |
| 14 | import org.eclipse.swt.widgets.Group; |
| 15 | import org.eclipse.swt.graphics.Point; |
| 16 | import org.eclipse.swt.events.SelectionAdapter; |
| 17 | import org.eclipse.swt.events.SelectionEvent; |
| 18 | import org.eclipse.ui.PlatformUI; |
| 19 | import de.uka.ipd.sdq.sensorframework.visualisation.dialogs.Separator; |
| 20 | |
| 21 | /** |
| 22 | * A dialog for the settings of the CSV data export. |
| 23 | * |
| 24 | * @author David Scherr |
| 25 | */ |
| 26 | public class CSVSettingsDialog extends Dialog { |
| 27 | |
| 28 | protected Object result; |
| 29 | protected Shell frmDialog; |
| 30 | |
| 31 | private String fileOrDirName = ""; |
| 32 | private String pathFileOrDir = ""; |
| 33 | private String pathParentDir = ""; |
| 34 | private Button btnSave; |
| 35 | private Button chkHeader; |
| 36 | private boolean isHeader = true; |
| 37 | private boolean isSettingsDialogCanceled = false; |
| 38 | private boolean isFileOrDirDialogCanceled = false; |
| 39 | private Combo cmbSeparator; |
| 40 | private String selectedSeparator = Separator.Semicolon.toString(); |
| 41 | private String[] separatorItems; |
| 42 | private Label lblHeader; |
| 43 | private String fileExtension = ""; |
| 44 | private DialogType dialogType; |
| 45 | |
| 46 | /** |
| 47 | * Create the dialog. |
| 48 | * |
| 49 | * @param pathParentDir |
| 50 | * Default path of the parent directory. |
| 51 | * @param fileOrDirName |
| 52 | * If the type is <code>FILE</code> then it means the default file name or if the |
| 53 | * type is <code>DIRECTORY</code> then it means the child directory name (but not a |
| 54 | * whole path). |
| 55 | * @param fileExtension |
| 56 | * Default file extension (only for type = <code>FILE</code>). |
| 57 | * @param type |
| 58 | * The type of the dialog either DialogType.DIRECTORY stands for SWT DirectoryDialog |
| 59 | * for choosing a directory path or DialogType.FILE stands for SWT FileDialog for |
| 60 | * choosing a file path. |
| 61 | */ |
| 62 | public CSVSettingsDialog(String pathParentDir, String fileOrDirName, String fileExtension, |
| 63 | DialogType type) { |
| 64 | |
| 65 | super(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), |
| 66 | SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM); |
| 67 | setText("SWT Dialog"); |
| 68 | |
| 69 | this.dialogType = type; |
| 70 | this.pathParentDir = pathParentDir; |
| 71 | this.fileOrDirName = fileOrDirName; |
| 72 | this.fileExtension = fileExtension; |
| 73 | |
| 74 | separatorItems = new String[3]; |
| 75 | int i = 0; |
| 76 | for (Separator sep : Separator.values()) { |
| 77 | separatorItems[i] = sep.toString(); |
| 78 | i++; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | /** |
| 83 | * Open the dialog while you cancel or click on the <em>Save As</em> Button. |
| 84 | * |
| 85 | * @return The result is not defined at the moment. |
| 86 | */ |
| 87 | public Object open() { |
| 88 | createContents(); |
| 89 | frmDialog.open(); |
| 90 | frmDialog.layout(); |
| 91 | Display display = getParent().getDisplay(); |
| 92 | while (!frmDialog.isDisposed()) { |
| 93 | if (!display.readAndDispatch()) { |
| 94 | display.sleep(); |
| 95 | } |
| 96 | } |
| 97 | return result; |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * @return {@link CSVSettingsDialog#isPathValid()} |
| 102 | */ |
| 103 | public boolean getValidPath() { |
| 104 | String pathDir = ""; |
| 105 | /* |
| 106 | * If the directory doesn't exist, then it will be created. If the directory exists, |
| 107 | * then a message box ask to overwrite it. |
| 108 | */ |
| 109 | while (!isSettingsDialogCanceled & getPath().equals("")) { |
| 110 | isFileOrDirDialogCanceled = false; |
| 111 | isSettingsDialogCanceled = false; |
| 112 | open(); |
| 113 | /* |
| 114 | * If the dialog type is DIRECTORY, then the file path (fileOrDirName) is the parent |
| 115 | * directory path + child directory name. |
| 116 | */ |
| 117 | if (isPathValid()) { |
| 118 | if (dialogType == DialogType.DIRECTORY) { |
| 119 | pathDir = getPath() + File.separatorChar + fileOrDirName; |
| 120 | createDirectory(pathDir); |
| 121 | } else if (dialogType == DialogType.FILE) { |
| 122 | // Do nothing special. |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | if (dialogType == DialogType.DIRECTORY) { |
| 127 | pathFileOrDir = pathDir; |
| 128 | } |
| 129 | dispose(); |
| 130 | return isPathValid(); |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * If the directory doesn't exist then a dialog ask to create one or not. |
| 135 | * |
| 136 | * @param pathDir |
| 137 | * The full path of the directory that you want to create. |
| 138 | */ |
| 139 | private void createDirectory(String pathDir) { |
| 140 | |
| 141 | File fileObject = new File(pathDir); |
| 142 | |
| 143 | if (fileObject.exists()) { |
| 144 | MessageBox box = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow() |
| 145 | .getShell(), SWT.OK | SWT.CANCEL); |
| 146 | box.setMessage("The directory already exists! Do you want to overwrite it?"); |
| 147 | int boxResult = box.open(); |
| 148 | |
| 149 | if (boxResult == SWT.OK) { |
| 150 | // Overwrite the existing directory. |
| 151 | deleteTree(fileObject); |
| 152 | fileObject.mkdirs(); |
| 153 | } else if (boxResult == SWT.CANCEL) { |
| 154 | // Don't overwrite the existing directory. |
| 155 | pathFileOrDir = ""; |
| 156 | } |
| 157 | } else { |
| 158 | // The directory doesn't exist. |
| 159 | fileObject.mkdirs(); |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | /** |
| 164 | * Delete directories in recursion. |
| 165 | */ |
| 166 | private void deleteTree(File path) { |
| 167 | for (File file : path.listFiles()) { |
| 168 | if (file.isDirectory()) { |
| 169 | deleteTree(file); |
| 170 | } else { |
| 171 | file.delete(); |
| 172 | } |
| 173 | } |
| 174 | path.delete(); |
| 175 | } |
| 176 | |
| 177 | /** |
| 178 | * Create contents of the dialog. |
| 179 | */ |
| 180 | private void createContents() { |
| 181 | frmDialog = new Shell(getParent(), SWT.DIALOG_TRIM); |
| 182 | frmDialog.setMinimumSize(new Point(100, 100)); |
| 183 | frmDialog.setSize(245, 220); |
| 184 | frmDialog.setText("CSV Settings"); |
| 185 | frmDialog.setLocation(300, 300); |
| 186 | { |
| 187 | Group grpSeparator = new Group(frmDialog, SWT.NONE); |
| 188 | grpSeparator.setBounds(10, 31, 218, 90); |
| 189 | { |
| 190 | cmbSeparator = new Combo(grpSeparator, SWT.NONE); |
| 191 | cmbSeparator.addSelectionListener(new SelectionAdapter() { |
| 192 | public void widgetSelected(SelectionEvent e) { |
| 193 | selectedSeparator = cmbSeparator.getItem(cmbSeparator.getSelectionIndex()); |
| 194 | } |
| 195 | }); |
| 196 | |
| 197 | cmbSeparator.setBounds(10, 20, 105, 23); |
| 198 | cmbSeparator.setItems(separatorItems); |
| 199 | // The default selection index must be consistent with the |
| 200 | // String value of the property separator. |
| 201 | cmbSeparator.select(0); |
| 202 | } |
| 203 | { |
| 204 | Label lblSeparator = new Label(grpSeparator, SWT.NONE); |
| 205 | lblSeparator.setBounds(143, 23, 65, 20); |
| 206 | lblSeparator.setText("Separator"); |
| 207 | } |
| 208 | { |
| 209 | chkHeader = new Button(grpSeparator, SWT.CHECK); |
| 210 | chkHeader.addSelectionListener(new SelectionAdapter() { |
| 211 | public void widgetSelected(SelectionEvent e) { |
| 212 | isHeader = chkHeader.getSelection(); |
| 213 | } |
| 214 | }); |
| 215 | chkHeader.setBounds(56, 61, 51, 23); |
| 216 | chkHeader.setSelection(isHeader); |
| 217 | } |
| 218 | { |
| 219 | lblHeader = new Label(grpSeparator, SWT.NONE); |
| 220 | lblHeader.setBounds(143, 64, 65, 20); |
| 221 | lblHeader.setText("Header"); |
| 222 | } |
| 223 | } |
| 224 | { |
| 225 | btnSave = new Button(frmDialog, SWT.NONE); |
| 226 | btnSave.addSelectionListener(new SelectionAdapter() { |
| 227 | public void widgetSelected(SelectionEvent e) { |
| 228 | if (dialogType == DialogType.FILE) { |
| 229 | saveAsCSVFileDialog(); |
| 230 | } else if (dialogType == DialogType.DIRECTORY) { |
| 231 | CSVDirectoryDialog dirDialog = new CSVDirectoryDialog(pathParentDir); |
| 232 | pathParentDir = dirDialog.getPathDir(); |
| 233 | pathFileOrDir = pathParentDir; |
| 234 | isFileOrDirDialogCanceled = dirDialog.isCanceled(); |
| 235 | } |
| 236 | frmDialog.close(); |
| 237 | } |
| 238 | }); |
| 239 | btnSave.setBounds(10, 152, 75, 25); |
| 240 | btnSave.setText("Save As"); |
| 241 | } |
| 242 | { |
| 243 | Button btnCancel = new Button(frmDialog, SWT.NONE); |
| 244 | btnCancel.addSelectionListener(new SelectionAdapter() { |
| 245 | public void widgetSelected(SelectionEvent e) { |
| 246 | pathFileOrDir = ""; |
| 247 | frmDialog.close(); |
| 248 | isSettingsDialogCanceled = true; |
| 249 | } |
| 250 | }); |
| 251 | btnCancel.setBounds(153, 152, 75, 25); |
| 252 | btnCancel.setText("Cancel"); |
| 253 | } |
| 254 | |
| 255 | } |
| 256 | |
| 257 | /** |
| 258 | * Open a Save File Dialog to select a target path for the CSV export. |
| 259 | */ |
| 260 | private void saveAsCSVFileDialog() { |
| 261 | |
| 262 | FileDialog dialog = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow() |
| 263 | .getShell(), SWT.SAVE); |
| 264 | |
| 265 | dialog.setFilterPath(pathParentDir); |
| 266 | dialog.setFileName(fileOrDirName); |
| 267 | dialog.setFilterExtensions(new String[] { fileExtension }); |
| 268 | dialog.setOverwrite(true); |
| 269 | |
| 270 | pathFileOrDir = dialog.open(); |
| 271 | |
| 272 | if (pathFileOrDir == null) { |
| 273 | // The dialog is canceled. |
| 274 | pathFileOrDir = ""; |
| 275 | isFileOrDirDialogCanceled = true; |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | /** |
| 280 | * @return The complete target path for the CSV export. |
| 281 | */ |
| 282 | public String getPath() { |
| 283 | return pathFileOrDir; |
| 284 | } |
| 285 | |
| 286 | /** |
| 287 | * @return <code>true</code>: Save CSV file with integrated header.<br> |
| 288 | * <code>false</code>: Save CSV file without any header. |
| 289 | */ |
| 290 | public boolean isHeader() { |
| 291 | // It can't return chkHeader.getEnabled() after the dialog is closed, so |
| 292 | // it is stored in an extra property. |
| 293 | return isHeader; |
| 294 | } |
| 295 | |
| 296 | /** |
| 297 | * @return The chosen separator which is one of the following characters:<br> |
| 298 | * <br> |
| 299 | * <ul> |
| 300 | * <li>Semicolon ";"</li> |
| 301 | * <li>Comma ","</li> |
| 302 | * <li>Tabulator "\t"</li> |
| 303 | * </ul> |
| 304 | */ |
| 305 | public String getSeparator() { |
| 306 | if (selectedSeparator.equals(Separator.Semicolon.toString())) { |
| 307 | return ";"; |
| 308 | } else if (selectedSeparator.equals(Separator.Comma.toString())) { |
| 309 | return ","; |
| 310 | } else if (selectedSeparator.equals(Separator.Tabulator.toString())) { |
| 311 | return "\t"; |
| 312 | } |
| 313 | return ";"; // Standard |
| 314 | } |
| 315 | |
| 316 | /** |
| 317 | * Dispose the resources of the dialog widgets. |
| 318 | */ |
| 319 | public void dispose() { |
| 320 | frmDialog.dispose(); |
| 321 | } |
| 322 | |
| 323 | /** |
| 324 | * @return <code>true</code> if a path is chosen and the both dialog are not canceled or<br> |
| 325 | * <code>false</code> if one of the dialogs is canceled or the path is an empty string. |
| 326 | */ |
| 327 | public boolean isPathValid() { |
| 328 | if (getPath().equals("") | isFileOrDirDialogCanceled | isSettingsDialogCanceled) { |
| 329 | return false; |
| 330 | } else { |
| 331 | return true; |
| 332 | } |
| 333 | } |
| 334 | } |