root/jface/Librarian.d

Revision 143:42c3056512ba, 31.1 kB (checked in by Frank Benoit <benoit@tionex.de>, 4 years ago)

redirect the jface examples to the new collection wrappers

Line 
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;
56 import dwtx.dwtxhelper.Collection;
57
58 version(JIVE) import jive.stacktrace;
59
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
336                 ModalContext.run( dgIRunnableWithProgress( &internalOpen, fileName ),
337                     true, getStatusLineManager().getProgressMonitor(), getShell().getDisplay());
338             } catch (InterruptedException e) {
339             } catch (InvocationTargetException e) {
340             } finally {
341                 // Enable actions
342                 enableActions(true);
343             }
344         }
345     }
346     private void internalOpen( IProgressMonitor progressMonitor,String filename ){
347         try {
348             progressMonitor.beginTask("Loading", IProgressMonitor.UNKNOWN);
349             library.load(filename);
350             progressMonitor.done();
351             viewer.setInput(library);
352             refreshView();
353         } catch (IOException e) {
354             showError( Format("Can't load file {}\r{}", filename, e.msg));
355         }
356     }
357     /**
358      * Creates a new file
359      */
360     public void newFile() {
361         if (checkOverwrite()) {
362         library = new Library();
363             viewer.setInput(library);
364         }
365     }
366
367     /**
368      * Saves the current file
369      */
370     public void saveFile() {
371         String fileName = library.getFileName();
372         if (fileName is null) {
373             fileName = (new SafeSaveDialog(getShell())).open();
374         }
375         if (fileName is null) {
376             return;
377         }
378         saveFileAs(fileName);
379     }
380
381     /**
382      * Saves the current file using the specified file name
383      *
384      * @param fileName the file name
385      */
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 {
390             auto pm = getStatusLineManager().getProgressMonitor();
391             auto disp = getShell().getDisplay();
392             // Launch the Save runnable
393             ModalContext.run( dgIRunnableWithProgress( &internalSave, fileName ), true, pm, disp);
394
395         } catch (InterruptedException e) {
396         } catch (InvocationTargetException e) {
397         } finally {
398             // Enable the actions
399             enableActions(true);
400         }
401     }
402
403     private void internalSave(IProgressMonitor progressMonitor,String filename ){
404         try {
405             progressMonitor.beginTask("Saving", IProgressMonitor.UNKNOWN );
406             library.save(filename);
407             progressMonitor.done();
408         } catch (IOException e) {
409             showError(Format("Can't save file {}\r{}", library.getFileName(), e.msg ));
410         }
411     }
412     /**
413      * Shows an error
414      *
415      * @param msg the error
416      */
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++) {
430             viewer.getTable().getColumn(i).pack();
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) {
578             Librarian.getApp().saveFileAs(fileName);
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
957     private LinkedList books;
958
959     // The dirty flag
960     private bool dirty;
961
962     /**
963     * Library constructor Note the signature :-)
964     */
965     public this() {
966         books = new LinkedList();
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 );
1000         foreach ( o; books ) {
1001             Book book = cast(Book)o;
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) {
1016         books.add(book);
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     */
1036     public LinkedList getBooks() {
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 }
Note: See TracBrowser for help on using the browser.