Mercurial > projects > dwt-samples
annotate jface/Librarian.d @ 143:42c3056512ba
redirect the jface examples to the new collection wrappers
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 07 Aug 2008 22:21:50 +0200 |
parents | 9ff9b8f7284b |
children |
rev | line source |
---|---|
66 | 1 module jface.Librarian; |
2 | |
3 import dwtx.core.runtime.IProgressMonitor; | |
4 import dwtx.jface.action.MenuManager; | |
5 import dwtx.jface.action.StatusLineManager; | |
6 import dwtx.jface.action.ToolBarManager; | |
7 import dwtx.jface.action.CoolBarManager; | |
8 import dwtx.jface.action.Action; | |
9 import dwtx.jface.action.IAction; | |
10 import dwtx.jface.dialogs.MessageDialog; | |
11 import dwtx.jface.operation.IRunnableWithProgress; | |
12 import dwtx.jface.operation.ModalContext; | |
13 import dwtx.jface.util.IPropertyChangeListener; | |
14 import dwtx.jface.util.PropertyChangeEvent; | |
15 import dwtx.jface.viewers.TableViewer; | |
16 import dwtx.jface.viewers.Viewer; | |
17 import dwtx.jface.viewers.ITableLabelProvider; | |
18 import dwtx.jface.viewers.IStructuredContentProvider; | |
19 import dwtx.jface.viewers.ICellModifier; | |
20 import dwtx.jface.viewers.ILabelProviderListener; | |
21 import dwtx.jface.viewers.TextCellEditor; | |
22 import dwtx.jface.viewers.CellEditor; | |
23 import dwtx.jface.viewers.CheckboxCellEditor; | |
24 import dwtx.jface.action.Separator; | |
25 import dwtx.jface.viewers.IStructuredSelection; | |
26 import dwtx.jface.window.ApplicationWindow; | |
27 import dwtx.jface.resource.ImageDescriptor; | |
28 | |
29 import dwt.DWT; | |
30 | |
31 import dwt.graphics.Image; | |
32 import dwt.graphics.ImageData; | |
33 import dwt.layout.GridData; | |
34 import dwt.layout.GridLayout; | |
35 import dwt.widgets.Display; | |
36 import dwt.widgets.FileDialog; | |
37 import dwt.widgets.MessageBox; | |
38 import dwt.widgets.Shell; | |
39 import dwt.widgets.Table; | |
40 import dwt.widgets.TableColumn; | |
41 import dwt.widgets.Control; | |
42 import dwt.widgets.Composite; | |
43 import dwt.widgets.Item; | |
44 | |
45 import dwt.dwthelper.utils; | |
46 import dwt.dwthelper.ByteArrayInputStream; | |
47 | |
48 import tango.text.convert.Format; | |
49 import tango.io.FilePath; | |
50 import tango.io.File; | |
51 import tango.io.Print; | |
52 import tango.io.stream.FileStream; | |
53 import tango.text.Util; | |
54 import tango.text.stream.LineIterator; | |
55 import tango.util.log.Trace; | |
143
42c3056512ba
redirect the jface examples to the new collection wrappers
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
56 import dwtx.dwtxhelper.Collection; |
66 | 57 |
67 | 58 version(JIVE) import jive.stacktrace; |
59 | |
66 | 60 /** |
61 * The application entry point | |
62 * | |
63 * @param args the command line arguments | |
64 */ | |
65 void main() { | |
66 (new Librarian()).run(); | |
67 } | |
68 | |
69 | |
70 /** | |
71 * This class keeps track of you library, and who you've loaned books to | |
72 */ | |
73 public class Librarian : ApplicationWindow { | |
74 // A static instance to the running application | |
75 private static Librarian APP; | |
76 | |
77 // Table column names/properties | |
78 public static const String TITLE = "Title"; | |
79 public static const String CHECKED_OUT = "?"; | |
80 public static const String WHO = "By Whom"; | |
81 public static const String[] PROPS = [ TITLE, CHECKED_OUT, WHO ]; | |
82 | |
83 // The viewer | |
84 private TableViewer viewer; | |
85 | |
86 // The current library | |
87 private Library library; | |
88 | |
89 // The actions | |
90 private NewAction newAction; | |
91 private OpenAction openAction; | |
92 private SaveAction saveAction; | |
93 private SaveAsAction saveAsAction; | |
94 private ExitAction exitAction; | |
95 private AddBookAction addBookAction; | |
96 private RemoveBookAction removeBookAction; | |
97 private AboutAction aboutAction; | |
98 private ShowBookCountAction showBookCountAction; | |
99 | |
100 /** | |
101 * Gets the running application | |
102 */ | |
103 public static Librarian getApp() { | |
104 return APP; | |
105 } | |
106 | |
107 /** | |
108 * Librarian constructor | |
109 */ | |
110 public this() { | |
111 super(null); | |
112 | |
113 APP = this; | |
114 | |
115 // Create the data model | |
116 library = new Library(); | |
117 | |
118 // Create the actions | |
119 newAction = new NewAction(); | |
120 openAction = new OpenAction(); | |
121 saveAction = new SaveAction(); | |
122 saveAsAction = new SaveAsAction(); | |
123 exitAction = new ExitAction(); | |
124 addBookAction = new AddBookAction(); | |
125 removeBookAction = new RemoveBookAction(); | |
126 aboutAction = new AboutAction(); | |
127 showBookCountAction = new ShowBookCountAction(); | |
128 | |
129 addMenuBar(); | |
130 //addCoolBar(DWT.NONE); | |
131 addToolBar(DWT.FLAT); | |
132 addStatusLine(); | |
133 } | |
134 | |
135 /** | |
136 * Runs the application | |
137 */ | |
138 public void run() { | |
139 // Don't return from open() until window closes | |
140 setBlockOnOpen(true); | |
141 | |
142 // Open the main window | |
143 open(); | |
144 | |
145 // Dispose the display | |
146 Display.getCurrent().dispose(); | |
147 } | |
148 | |
149 /** | |
150 * Configures the shell | |
151 * | |
152 * @param shell the shell | |
153 */ | |
154 protected void configureShell(Shell shell) { | |
155 super.configureShell(shell); | |
156 | |
157 // Set the title bar text | |
158 shell.setText("Librarian"); | |
159 } | |
160 | |
161 /** | |
162 * Creates the main window's contents | |
163 * | |
164 * @param parent the main window | |
165 * @return Control | |
166 */ | |
167 protected Control createContents(Composite parent) { | |
168 Composite composite = new Composite(parent, DWT.NONE); | |
169 composite.setLayout(new GridLayout(1, false)); | |
170 | |
171 viewer = new TableViewer(composite, DWT.FULL_SELECTION | DWT.BORDER); | |
172 Table table = viewer.getTable(); | |
173 table.setLayoutData(new GridData(GridData.FILL_BOTH)); | |
174 | |
175 // Set up the viewer | |
176 viewer.setContentProvider(new LibraryContentProvider()); | |
177 viewer.setLabelProvider(new LibraryLabelProvider()); | |
178 viewer.setInput(library); | |
179 viewer.setColumnProperties(PROPS); | |
180 viewer.setCellEditors( [ cast(CellEditor) new TextCellEditor(table), | |
181 new CheckboxCellEditor(table), new TextCellEditor(table)]); | |
182 viewer.setCellModifier(new LibraryCellModifier()); | |
183 | |
184 // Set up the table | |
185 for (int i = 0, n = PROPS.length; i < n; i++) | |
186 (new TableColumn(table, DWT.LEFT)).setText(PROPS[i]); | |
187 table.setHeaderVisible(true); | |
188 table.setLinesVisible(true); | |
189 | |
190 // Add code to hide or display the book count based on the action | |
191 showBookCountAction.addPropertyChangeListener(new class IPropertyChangeListener { | |
192 public void propertyChange(PropertyChangeEvent event) { | |
193 // The value has changed; refresh the view | |
194 refreshView(); | |
195 } | |
196 }); | |
197 | |
198 // Rfresh the view to get the columns right-sized | |
199 refreshView(); | |
200 | |
201 return composite; | |
202 } | |
203 | |
204 /** | |
205 * Creates the menu for the application | |
206 * | |
207 * @return MenuManager | |
208 */ | |
209 protected MenuManager createMenuManager() { | |
210 // Create the main menu | |
211 MenuManager mm = new MenuManager(); | |
212 | |
213 // Create the File menu | |
214 MenuManager fileMenu = new MenuManager("File"); | |
215 mm.add(fileMenu); | |
216 | |
217 // Add the actions to the File menu | |
218 fileMenu.add(newAction); | |
219 fileMenu.add(openAction); | |
220 fileMenu.add(saveAction); | |
221 fileMenu.add(saveAsAction); | |
222 fileMenu.add(new Separator()); | |
223 fileMenu.add(exitAction); | |
224 | |
225 // Create the Book menu | |
226 MenuManager bookMenu = new MenuManager("Book"); | |
227 mm.add(bookMenu); | |
228 | |
229 // Add the actions to the Book menu | |
230 bookMenu.add(addBookAction); | |
231 bookMenu.add(removeBookAction); | |
232 | |
233 // Create the View menu | |
234 MenuManager viewMenu = new MenuManager("View"); | |
235 mm.add(viewMenu); | |
236 | |
237 // Add the actions to the View menu | |
238 viewMenu.add(showBookCountAction); | |
239 | |
240 // Create the Help menu | |
241 MenuManager helpMenu = new MenuManager("Help"); | |
242 mm.add(helpMenu); | |
243 | |
244 // Add the actions to the Help menu | |
245 helpMenu.add(aboutAction); | |
246 | |
247 return mm; | |
248 } | |
249 | |
250 /** | |
251 * Creates the toolbar for the application | |
252 */ | |
253 protected ToolBarManager createToolBarManager(int style) { | |
254 // Create the toolbar manager | |
255 ToolBarManager tbm = new ToolBarManager(style); | |
256 | |
257 // Add the file actions | |
258 tbm.add(newAction); | |
259 tbm.add(openAction); | |
260 tbm.add(saveAction); | |
261 tbm.add(saveAsAction); | |
262 | |
263 // Add a separator | |
264 tbm.add(new Separator()); | |
265 | |
266 // Add the book actions | |
267 tbm.add(addBookAction); | |
268 tbm.add(removeBookAction); | |
269 | |
270 // Add a separator | |
271 tbm.add(new Separator()); | |
272 | |
273 // Add the show book count, which will appear as a toggle button | |
274 tbm.add(showBookCountAction); | |
275 | |
276 // Add a separator | |
277 tbm.add(new Separator()); | |
278 | |
279 // Add the about action | |
280 tbm.add(aboutAction); | |
281 | |
282 return tbm; | |
283 } | |
284 /+ | |
285 /** | |
286 * Creates the coolbar for the application | |
287 */ | |
288 protected CoolBarManager createCoolBarManager(int style) { | |
289 // Create the coolbar manager | |
290 CoolBarManager cbm = new CoolBarManager(style); | |
291 | |
292 // Add the toolbar | |
293 cbm.add(createToolBarManager(DWT.FLAT)); | |
294 | |
295 return cbm; | |
296 } | |
297 +/ | |
298 /** | |
299 * Creates the status line manager | |
300 */ | |
301 protected StatusLineManager createStatusLineManager() { | |
302 return new StatusLineManager(); | |
303 } | |
304 | |
305 /** | |
306 * Adds a book | |
307 */ | |
308 public void addBook() { | |
309 library.add(new Book("[Enter Title]")); | |
310 refreshView(); | |
311 } | |
312 | |
313 /** | |
314 * Removes the selected book | |
315 */ | |
316 public void removeSelectedBook() { | |
317 Book book = cast(Book) (cast(IStructuredSelection) viewer.getSelection()) | |
318 .getFirstElement(); | |
319 if (book !is null) library.remove(book); | |
320 refreshView(); | |
321 } | |
322 | |
323 /** | |
324 * Opens a file | |
325 * | |
326 * @param fileName the file name | |
327 */ | |
328 public void openFile(String fileName) { | |
329 if (checkOverwrite()) { | |
330 // Disable the actions, so user can't change library while loading | |
331 enableActions(false); | |
332 | |
333 library = new Library(); | |
334 try { | |
335 // Launch the Open runnable | |
72
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
336 ModalContext.run( dgIRunnableWithProgress( &internalOpen, fileName ), |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
337 true, getStatusLineManager().getProgressMonitor(), getShell().getDisplay()); |
66 | 338 } catch (InterruptedException e) { |
339 } catch (InvocationTargetException e) { | |
340 } finally { | |
341 // Enable actions | |
342 enableActions(true); | |
343 } | |
344 } | |
345 } | |
72
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
346 private void internalOpen( IProgressMonitor progressMonitor,String filename ){ |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
347 try { |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
348 progressMonitor.beginTask("Loading", IProgressMonitor.UNKNOWN); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
349 library.load(filename); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
350 progressMonitor.done(); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
351 viewer.setInput(library); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
352 refreshView(); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
353 } catch (IOException e) { |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
354 showError( Format("Can't load file {}\r{}", filename, e.msg)); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
355 } |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
356 } |
66 | 357 /** |
73
9ff9b8f7284b
FileTreeViewer now work on windows without error dialog.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
358 * Creates a new file |
9ff9b8f7284b
FileTreeViewer now work on windows without error dialog.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
359 */ |
66 | 360 public void newFile() { |
361 if (checkOverwrite()) { | |
362 library = new Library(); | |
72
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
363 viewer.setInput(library); |
66 | 364 } |
365 } | |
366 | |
367 /** | |
73
9ff9b8f7284b
FileTreeViewer now work on windows without error dialog.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
368 * Saves the current file |
9ff9b8f7284b
FileTreeViewer now work on windows without error dialog.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
369 */ |
66 | 370 public void saveFile() { |
371 String fileName = library.getFileName(); | |
372 if (fileName is null) { | |
373 fileName = (new SafeSaveDialog(getShell())).open(); | |
374 } | |
72
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
375 if (fileName is null) { |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
376 return; |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
377 } |
66 | 378 saveFileAs(fileName); |
379 } | |
380 | |
381 /** | |
73
9ff9b8f7284b
FileTreeViewer now work on windows without error dialog.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
382 * Saves the current file using the specified file name |
9ff9b8f7284b
FileTreeViewer now work on windows without error dialog.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
383 * |
9ff9b8f7284b
FileTreeViewer now work on windows without error dialog.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
384 * @param fileName the file name |
9ff9b8f7284b
FileTreeViewer now work on windows without error dialog.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
385 */ |
66 | 386 public void saveFileAs(String fileName) { |
387 // Disable the actions, so user can't change file while it's saving | |
388 enableActions(false); | |
389 try { | |
71 | 390 auto pm = getStatusLineManager().getProgressMonitor(); |
391 auto disp = getShell().getDisplay(); | |
72
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
392 // Launch the Save runnable |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
393 ModalContext.run( dgIRunnableWithProgress( &internalSave, fileName ), true, pm, disp); |
71 | 394 |
66 | 395 } catch (InterruptedException e) { |
396 } catch (InvocationTargetException e) { | |
397 } finally { | |
398 // Enable the actions | |
399 enableActions(true); | |
400 } | |
401 } | |
402 | |
72
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
403 private void internalSave(IProgressMonitor progressMonitor,String filename ){ |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
404 try { |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
405 progressMonitor.beginTask("Saving", IProgressMonitor.UNKNOWN ); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
406 library.save(filename); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
407 progressMonitor.done(); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
408 } catch (IOException e) { |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
409 showError(Format("Can't save file {}\r{}", library.getFileName(), e.msg )); |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
410 } |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
411 } |
66 | 412 /** |
72
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
413 * Shows an error |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
414 * |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
415 * @param msg the error |
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
416 */ |
66 | 417 public void showError(String msg) { |
418 MessageDialog.openError(getShell(), "Error", msg); | |
419 } | |
420 | |
421 /** | |
422 * Refreshes the view | |
423 */ | |
424 public void refreshView() { | |
425 // Refresh the view | |
426 viewer.refresh(); | |
427 | |
428 // Repack the columns | |
429 for (int i = 0, n = viewer.getTable().getColumnCount(); i < n; i++) { | |
73
9ff9b8f7284b
FileTreeViewer now work on windows without error dialog.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
430 viewer.getTable().getColumn(i).pack(); |
66 | 431 } |
432 | |
433 getStatusLineManager().setMessage( | |
434 showBookCountAction.isChecked() ? Format( "Book Count: {}", | |
435 library.getBooks().size()) : ""); | |
436 } | |
437 | |
438 /** | |
439 * Checks the current file for unsaved changes. If it has unsaved changes, | |
440 * confirms that user wants to overwrite | |
441 * | |
442 * @return bool | |
443 */ | |
444 public bool checkOverwrite() { | |
445 bool proceed = true; | |
446 if (library.isDirty()) { | |
447 proceed = MessageDialog.openConfirm(getShell(), "Are you sure?", | |
448 "You have unsaved changes--are you sure you want to lose them?"); | |
449 } | |
450 return proceed; | |
451 } | |
452 | |
453 /** | |
454 * Sets the current library dirty | |
455 */ | |
456 public void setLibraryDirty() { | |
457 library.setDirty(); | |
458 } | |
459 | |
460 /** | |
461 * Closes the application | |
462 */ | |
463 public bool close() { | |
464 if (checkOverwrite()) return super.close(); | |
465 return false; | |
466 } | |
467 | |
468 /** | |
469 * Enables or disables the actions | |
470 * | |
471 * @param enable true to enable, false to disable | |
472 */ | |
473 private void enableActions(bool enable) { | |
474 newAction.setEnabled(enable); | |
475 openAction.setEnabled(enable); | |
476 saveAction.setEnabled(enable); | |
477 saveAsAction.setEnabled(enable); | |
478 exitAction.setEnabled(enable); | |
479 addBookAction.setEnabled(enable); | |
480 removeBookAction.setEnabled(enable); | |
481 aboutAction.setEnabled(enable); | |
482 showBookCountAction.setEnabled(enable); | |
483 } | |
484 } | |
485 | |
486 | |
487 /** | |
488 * This action class responds to requests to save a file | |
489 */ | |
490 public class SaveAction : Action { | |
491 /** | |
492 * SaveAction constructor | |
493 */ | |
494 public this() { | |
495 super("&Save@Ctrl+S", ImageDescriptor.createFromFile( getImportData!("jface.librarian.save.gif"))); | |
496 setDisabledImageDescriptor(ImageDescriptor.createFromFile(getImportData!("jface.librarian.disabledSave.gif"))); | |
497 setToolTipText("Save"); | |
498 } | |
499 | |
500 /** | |
501 * Saves the file | |
502 */ | |
503 public void run() { | |
504 Librarian.getApp().saveFile(); | |
505 } | |
506 } | |
507 | |
508 | |
509 | |
510 | |
511 /** | |
512 * This action class responds to requests open a file | |
513 */ | |
514 public class OpenAction : Action { | |
515 /** | |
516 * OpenAction constructor | |
517 */ | |
518 public this() { | |
519 super("&Open...@Ctrl+O", ImageDescriptor.createFromFile(getImportData!("jface.librarian.open.gif"))); | |
520 setDisabledImageDescriptor(ImageDescriptor.createFromFile(getImportData!("jface.librarian.disabledOpen.gif"))); | |
521 setToolTipText("Open"); | |
522 } | |
523 | |
524 /** | |
525 * Opens an existing file | |
526 */ | |
527 public void run() { | |
528 // Use the file dialog | |
529 FileDialog dlg = new FileDialog(Librarian.getApp().getShell(), DWT.OPEN); | |
530 String fileName = dlg.open(); | |
531 if (fileName !is null) { | |
532 Librarian.getApp().openFile(fileName); | |
533 } | |
534 } | |
535 } | |
536 | |
537 /** | |
538 * This action class reponds to requests for a new file | |
539 */ | |
540 public class NewAction : Action { | |
541 /** | |
542 * NewAction constructor | |
543 */ | |
544 public this() { | |
545 super("&New@Ctrl+N", ImageDescriptor.createFromFile(getImportData!("jface.librarian.new.gif"))); | |
546 setDisabledImageDescriptor(ImageDescriptor.createFromFile(getImportData!("jface.librarian.disabledNew.gif"))); | |
547 setToolTipText("New"); | |
548 } | |
549 | |
550 /** | |
551 * Creates a new file | |
552 */ | |
553 public void run() { | |
554 Librarian.getApp().newFile(); | |
555 } | |
556 } | |
557 | |
558 /** | |
559 * This action class responds to requests to save a file as . . . | |
560 */ | |
561 public class SaveAsAction : Action { | |
562 /** | |
563 * SaveAsAction constructor | |
564 */ | |
565 public this() { | |
566 super("Save As...", ImageDescriptor.createFromFile(getImportData!("jface.librarian.saveAs.gif"))); | |
567 setDisabledImageDescriptor(ImageDescriptor.createFromFile(getImportData!("jface.librarian.disabledSaveAs.gif"))); | |
568 setToolTipText("Save As"); | |
569 } | |
570 | |
571 /** | |
572 * Saves the file | |
573 */ | |
574 public void run() { | |
575 SafeSaveDialog dlg = new SafeSaveDialog(Librarian.getApp().getShell()); | |
576 String fileName = dlg.open(); | |
577 if (fileName !is null) { | |
72
fc7a8f537871
Open/Save with experimental runner factory.
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
578 Librarian.getApp().saveFileAs(fileName); |
66 | 579 } |
580 } | |
581 } | |
582 | |
583 | |
584 /** | |
585 * This action class deletes a book | |
586 */ | |
587 public class RemoveBookAction : Action { | |
588 /** | |
589 * RemoveBookAction constructor | |
590 */ | |
591 public this() { | |
592 super("&Remove Book@Ctrl+X", ImageDescriptor.createFromFile(getImportData!("jface.librarian.removeBook.gif"))); | |
593 setDisabledImageDescriptor(ImageDescriptor.createFromFile(getImportData!("jface.librarian.disabledRemoveBook.gif"))); | |
594 setToolTipText("Remove"); | |
595 } | |
596 | |
597 /** | |
598 * Removes the selected book after confirming | |
599 */ | |
600 public void run() { | |
601 if (MessageDialog.openConfirm(Librarian.getApp().getShell(), "Are you sure?", | |
602 "Are you sure you want to remove the selected book?")) { | |
603 Librarian.getApp().removeSelectedBook(); | |
604 } | |
605 } | |
606 } | |
607 | |
608 | |
609 /** | |
610 * This action class adds a book | |
611 */ | |
612 public class AddBookAction : Action { | |
613 /** | |
614 * AddBookAction constructor | |
615 */ | |
616 public this() { | |
617 super("&Add Book@Ctrl+B", ImageDescriptor.createFromFile(getImportData!("jface.librarian.addBook.gif"))); | |
618 setDisabledImageDescriptor(ImageDescriptor.createFromFile(getImportData!("jface.librarian.disabledAddBook.gif"))); | |
619 setToolTipText("Add"); | |
620 } | |
621 | |
622 /** | |
623 * Adds a book to the current library | |
624 */ | |
625 public void run() { | |
626 Librarian.getApp().addBook(); | |
627 } | |
628 } | |
629 | |
630 /** | |
631 * This action class exits the application | |
632 */ | |
633 public class ExitAction : Action { | |
634 /** | |
635 * ExitAction constructor | |
636 */ | |
637 public this() { | |
638 super("E&xit@Alt+F4"); | |
639 setToolTipText("Exit"); | |
640 } | |
641 | |
642 /** | |
643 * Exits the application | |
644 */ | |
645 public void run() { | |
646 Librarian.getApp().close(); | |
647 } | |
648 } | |
649 | |
650 /** | |
651 * This action class shows an About box | |
652 */ | |
653 public class AboutAction : Action { | |
654 /** | |
655 * AboutAction constructor | |
656 */ | |
657 public this() { | |
658 super("&About@Ctrl+A", ImageDescriptor.createFromFile(getImportData!("jface.librarian.about.gif"))); | |
659 setDisabledImageDescriptor(ImageDescriptor.createFromFile(getImportData!("jface.librarian.disabledAbout.gif"))); | |
660 setToolTipText("About"); | |
661 } | |
662 | |
663 /** | |
664 * Shows an about box | |
665 */ | |
666 public void run() { | |
667 MessageDialog.openInformation(Librarian.getApp().getShell(), "About", | |
668 "Librarian--to manage your books"); | |
669 } | |
670 } | |
671 | |
672 | |
673 | |
674 /** | |
675 * This action class determines whether to show the book count | |
676 */ | |
677 public class ShowBookCountAction : Action { | |
678 public this() { | |
679 super("&Show Book Count@Ctrl+C", IAction.AS_CHECK_BOX); | |
680 setChecked(true); | |
681 setImageDescriptor(ImageDescriptor.createFromFile(getImportData!("jface.librarian.count.gif"))); | |
682 setDisabledImageDescriptor(ImageDescriptor.createFromFile(getImportData!("jface.librarian.disabledCount.gif"))); | |
683 } | |
684 } | |
685 | |
686 /** | |
687 * This class represents a book | |
688 */ | |
689 public class Book { | |
690 private String title; | |
691 private String checkedOutTo; | |
692 | |
693 /** | |
694 * Book constructor | |
695 * @param title the title | |
696 */ | |
697 public this(String title) { | |
698 setTitle(title); | |
699 } | |
700 | |
701 /** | |
702 * Sets the title | |
703 * @param title the title | |
704 */ | |
705 public void setTitle(String title) { | |
706 this.title = title; | |
707 } | |
708 | |
709 /** | |
710 * Gets the title | |
711 * @return String | |
712 */ | |
713 public String getTitle() { | |
714 return title; | |
715 } | |
716 | |
717 /** | |
718 * Check out | |
719 * @param who the person checking this book out | |
720 */ | |
721 public void checkOut(String who) { | |
722 checkedOutTo = who; | |
723 if (checkedOutTo.length is 0) checkedOutTo = null; | |
724 } | |
725 | |
726 public bool isCheckedOut() { | |
727 return checkedOutTo !is null && checkedOutTo.length > 0; | |
728 } | |
729 | |
730 public void checkIn() { | |
731 checkedOutTo = null; | |
732 } | |
733 | |
734 /** | |
735 * Gets who this book is checked out to | |
736 * @return String | |
737 */ | |
738 public String getCheckedOutTo() { | |
739 return checkedOutTo; | |
740 } | |
741 } | |
742 | |
743 | |
744 /** | |
745 * This class provides a facade for the "save" | |
746 * FileDialog class. If the selected file already | |
747 * exists, the user is asked to confirm before | |
748 * overwriting. | |
749 */ | |
750 public class SafeSaveDialog | |
751 { | |
752 // The wrapped FileDialog | |
753 private FileDialog dlg; | |
754 | |
755 /** | |
756 * SafeSaveDialog constructor | |
757 * @param shell the parent shell | |
758 */ | |
759 public this(Shell shell) | |
760 { | |
761 dlg = new FileDialog(shell, DWT.SAVE); | |
762 } | |
763 | |
764 public String open() | |
765 { | |
766 // We store the selected file name in fileName | |
767 String fileName = null; | |
768 | |
769 // The user has finished when one of the | |
770 // following happens: | |
771 // 1) The user dismisses the dialog by pressing Cancel | |
772 // 2) The selected file name does not exist | |
773 // 3) The user agrees to overwrite existing file | |
774 bool done = false; | |
775 | |
776 while (!done) | |
777 { | |
778 // Open the File Dialog | |
779 fileName = dlg.open(); | |
780 if (fileName is null) | |
781 { | |
782 // User has cancelled, so quit and return | |
783 done = true; | |
784 } | |
785 else | |
786 { | |
787 // User has selected a file; see if it already exists | |
788 FilePath file = new FilePath(fileName); | |
789 if (file.exists()) | |
790 { | |
791 // The file already exists; asks for confirmation | |
792 MessageBox mb = new MessageBox(dlg.getParent(), | |
793 DWT.ICON_WARNING | DWT.YES | DWT.NO); | |
794 | |
795 // We really should read this string from a | |
796 // resource bundle | |
797 mb.setMessage(fileName ~ " already exists. Do you want to replace it?"); | |
798 | |
799 // If they click Yes, we're done and we drop out. If | |
800 // they click No, we redisplay the File Dialog | |
801 done = mb.open() is DWT.YES; | |
802 } | |
803 else | |
804 { | |
805 // File does not exist, so drop out | |
806 done = true; | |
807 } | |
808 } | |
809 } | |
810 return fileName; | |
811 } | |
812 | |
813 public String getFileName() | |
814 { | |
815 return dlg.getFileName(); | |
816 } | |
817 | |
818 public String[] getFileNames() | |
819 { | |
820 return dlg.getFileNames(); | |
821 } | |
822 | |
823 public String[] getFilterExtensions() | |
824 { | |
825 return dlg.getFilterExtensions(); | |
826 } | |
827 | |
828 public String[] getFilterNames() | |
829 { | |
830 return dlg.getFilterNames(); | |
831 } | |
832 | |
833 public String getFilterPath() | |
834 { | |
835 return dlg.getFilterPath(); | |
836 } | |
837 | |
838 public void setFileName(String string) | |
839 { | |
840 dlg.setFileName(string); | |
841 } | |
842 | |
843 public void setFilterExtensions(String[] extensions) | |
844 { | |
845 dlg.setFilterExtensions(extensions); | |
846 } | |
847 | |
848 public void setFilterNames(String[] names) | |
849 { | |
850 dlg.setFilterNames(names); | |
851 } | |
852 | |
853 public void setFilterPath(String string) | |
854 { | |
855 dlg.setFilterPath(string); | |
856 } | |
857 | |
858 public Shell getParent() | |
859 { | |
860 return dlg.getParent(); | |
861 } | |
862 | |
863 public int getStyle() | |
864 { | |
865 return dlg.getStyle(); | |
866 } | |
867 | |
868 public String getText() | |
869 { | |
870 return dlg.getText(); | |
871 } | |
872 | |
873 public void setText(String string) | |
874 { | |
875 dlg.setText(string); | |
876 } | |
877 } | |
878 | |
879 | |
880 /** | |
881 * This class is the cell modifier for the Librarian program | |
882 */ | |
883 public class LibraryCellModifier : ICellModifier { | |
884 /** | |
885 * Gets whether the specified property can be modified | |
886 * | |
887 * @param element the book | |
888 * @param property the property | |
889 * @return bool | |
890 */ | |
891 public bool canModify(Object element, String property) { | |
892 return true; | |
893 } | |
894 | |
895 /** | |
896 * Gets the value for the property | |
897 * | |
898 * @param element the book | |
899 * @param property the property | |
900 * @return Object | |
901 */ | |
902 public Object getValue(Object element, String property) { | |
903 Book book = cast(Book) element; | |
904 if (Librarian.TITLE.equals(property)) | |
905 return stringcast(book.getTitle()); | |
906 else if (Librarian.CHECKED_OUT.equals(property)) | |
907 return Boolean.valueOf(book.isCheckedOut()); | |
908 else if (Librarian.WHO.equals(property)) | |
909 return stringcast( book.getCheckedOutTo() is null ? "" : book.getCheckedOutTo()); | |
910 else | |
911 return null; | |
912 } | |
913 | |
914 /** | |
915 * Modifies the element | |
916 * | |
917 * @param element the book | |
918 * @param property the property | |
919 * @param value the new value | |
920 */ | |
921 public void modify(Object element, String property, Object value) { | |
922 if ( auto item = cast(Item)element ){ | |
923 element = item.getData(); | |
924 } | |
925 | |
926 Book book = cast(Book) element; | |
927 if (Librarian.TITLE.equals(property)) | |
928 book.setTitle(stringcast(value)); | |
929 else if (Librarian.CHECKED_OUT.equals(property)) { | |
930 bool b = (cast(Boolean) value).booleanValue(); | |
931 if (b) | |
932 book.checkOut("[Enter Name]"); | |
933 else | |
934 book.checkIn(); | |
935 } else if (Librarian.WHO.equals(property)) | |
936 book.checkOut(stringcast(value)); | |
937 | |
938 // Refresh the view | |
939 Librarian.getApp().refreshView(); | |
940 | |
941 // Set the library dirty | |
942 Librarian.getApp().setLibraryDirty(); | |
943 } | |
944 } | |
945 | |
946 /** | |
947 * This class holds all the books in a library. It also handles loading from and | |
948 * saving to disk | |
949 */ | |
950 public class Library { | |
951 private static const String SEP = "|"; | |
952 | |
953 // The filename | |
954 private String filename; | |
955 | |
956 // The books | |
143
42c3056512ba
redirect the jface examples to the new collection wrappers
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
957 private LinkedList books; |
66 | 958 |
959 // The dirty flag | |
960 private bool dirty; | |
961 | |
962 /** | |
963 * Library constructor Note the signature :-) | |
964 */ | |
965 public this() { | |
143
42c3056512ba
redirect the jface examples to the new collection wrappers
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
966 books = new LinkedList(); |
66 | 967 } |
968 | |
969 /** | |
970 * Loads the library from a file | |
971 * | |
972 * @param filename the filename | |
973 * @throws IOException | |
974 */ | |
975 public void load(String filename) { | |
976 auto istr = (new FileInput(filename)).input; | |
977 auto lines = new LineIterator!(char)(istr); | |
978 String line; | |
979 foreach (line; lines ) { | |
980 auto tokens = tango.text.Util.delimit(line, SEP); | |
981 Book book = null; | |
982 if ( tokens.length > 0 ) book = new Book( tokens[0].dup ); | |
983 if (tokens.length > 1) book.checkOut(tokens[1].dup ); | |
984 if (book !is null) add(book); | |
985 } | |
986 istr.close(); | |
987 this.filename = filename; | |
988 dirty = false; | |
989 } | |
990 | |
991 /** | |
992 * Saves the library to a file | |
993 * | |
994 * @param filename the filename | |
995 * @throws IOException | |
996 */ | |
997 public void save(String filename) { | |
998 scope ostr = (new FileOutput(filename)).output; | |
999 scope printer = new Print!(char)( Format, ostr ); | |
143
42c3056512ba
redirect the jface examples to the new collection wrappers
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
1000 foreach ( o; books ) { |
42c3056512ba
redirect the jface examples to the new collection wrappers
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
1001 Book book = cast(Book)o; |
66 | 1002 printer.formatln( "{}|{}",book.getTitle(), (book.getCheckedOutTo() is null ? "" : book.getCheckedOutTo())); |
1003 } | |
1004 ostr.close(); | |
1005 this.filename = filename; | |
1006 dirty = false; | |
1007 } | |
1008 | |
1009 /** | |
1010 * Adds a book | |
1011 * | |
1012 * @param book the book to add | |
1013 * @return bool | |
1014 */ | |
1015 public bool add(Book book) { | |
143
42c3056512ba
redirect the jface examples to the new collection wrappers
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
1016 books.add(book); |
66 | 1017 setDirty(); |
1018 return true; | |
1019 } | |
1020 | |
1021 /** | |
1022 * Removes a book | |
1023 * | |
1024 * @param book the book to remove | |
1025 */ | |
1026 public void remove(Book book) { | |
1027 books.remove(book); | |
1028 setDirty(); | |
1029 } | |
1030 | |
1031 /** | |
1032 * Gets the books | |
1033 * | |
1034 * @return Collection | |
1035 */ | |
143
42c3056512ba
redirect the jface examples to the new collection wrappers
Frank Benoit <benoit@tionex.de>
parents:
73
diff
changeset
|
1036 public LinkedList getBooks() { |
66 | 1037 return books; |
1038 } | |
1039 | |
1040 /** | |
1041 * Gets the file name | |
1042 * | |
1043 * @return String | |
1044 */ | |
1045 public String getFileName() { | |
1046 return filename; | |
1047 } | |
1048 | |
1049 /** | |
1050 * Gets whether this file is dirty | |
1051 * | |
1052 * @return bool | |
1053 */ | |
1054 public bool isDirty() { | |
1055 return dirty; | |
1056 } | |
1057 | |
1058 /** | |
1059 * Sets this file as dirty | |
1060 */ | |
1061 public void setDirty() { | |
1062 dirty = true; | |
1063 } | |
1064 } | |
1065 | |
1066 | |
1067 /** | |
1068 * This class provides the content for the library table | |
1069 */ | |
1070 public class LibraryContentProvider : IStructuredContentProvider { | |
1071 /** | |
1072 * Gets the books | |
1073 * | |
1074 * @param inputElement the library | |
1075 * @return Object[] | |
1076 */ | |
1077 public Object[] getElements(Object inputElement) { | |
1078 return (cast(Library) inputElement).getBooks().toArray(); | |
1079 } | |
1080 | |
1081 /** | |
1082 * Disposes any resources | |
1083 */ | |
1084 public void dispose() { | |
1085 // Do nothing | |
1086 } | |
1087 | |
1088 /** | |
1089 * Called when the input changes | |
1090 * | |
1091 * @param viewer the viewer | |
1092 * @param oldInput the old library | |
1093 * @param newInput the new library | |
1094 */ | |
1095 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { | |
1096 // Ignore | |
1097 } | |
1098 } | |
1099 | |
1100 | |
1101 /** | |
1102 * This class provides the labels for the library table | |
1103 */ | |
1104 public class LibraryLabelProvider : ITableLabelProvider { | |
1105 private Image checked; | |
1106 private Image unchecked; | |
1107 | |
1108 /** | |
1109 * LibraryLabelProvider constructor | |
1110 */ | |
1111 public this() { | |
1112 // Create the check mark images | |
1113 checked = new Image(null, new ImageData( new ByteArrayInputStream( cast(byte[])import("jface.librarian.checked.gif")))); | |
1114 unchecked = new Image(null,new ImageData( new ByteArrayInputStream( cast(byte[])import("jface.librarian.unchecked.gif")))); | |
1115 } | |
1116 | |
1117 /** | |
1118 * Gets the column image | |
1119 * | |
1120 * @param element the book | |
1121 * @param columnIndex the column index | |
1122 * @return Image | |
1123 */ | |
1124 public Image getColumnImage(Object element, int columnIndex) { | |
1125 // For the "Checked Out" column, return the check mark | |
1126 // if the book is checked out | |
1127 if (columnIndex is 1) | |
1128 return (cast(Book) element).isCheckedOut() ? checked : unchecked; | |
1129 return null; | |
1130 } | |
1131 | |
1132 /** | |
1133 * Gets the column text | |
1134 * | |
1135 * @param element the book | |
1136 * @param columnIndex the column index | |
1137 * @return String | |
1138 */ | |
1139 public String getColumnText(Object element, int columnIndex) { | |
1140 Book book = cast(Book) element; | |
1141 String text = null; | |
1142 switch (columnIndex) { | |
1143 case 0: | |
1144 text = book.getTitle(); | |
1145 break; | |
1146 case 2: | |
1147 text = book.getCheckedOutTo(); | |
1148 break; | |
1149 default: | |
1150 } | |
1151 return text is null ? "" : text; | |
1152 } | |
1153 | |
1154 /** | |
1155 * Adds a listener | |
1156 */ | |
1157 public void addListener(ILabelProviderListener listener) { | |
1158 // Ignore | |
1159 } | |
1160 | |
1161 /** | |
1162 * Disposes any resources | |
1163 */ | |
1164 public void dispose() { | |
1165 if (checked !is null) checked.dispose(); | |
1166 if (unchecked !is null) unchecked.dispose(); | |
1167 } | |
1168 | |
1169 /** | |
1170 * Gets whether this is a label property | |
1171 * | |
1172 * @param element the book | |
1173 * @param property the property | |
1174 * @return bool | |
1175 */ | |
1176 public bool isLabelProperty(Object element, String property) { | |
1177 return false; | |
1178 } | |
1179 | |
1180 /** | |
1181 * Removes a listener | |
1182 * | |
1183 * @param listener the listener | |
1184 */ | |
1185 public void removeListener(ILabelProviderListener listener) { | |
1186 // Ignore | |
1187 } | |
1188 } | |
1189 | |
1190 | |
1191 | |
1192 | |
1193 | |
1194 |