Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/virtuosotechnologies/asaph/standardgui/StandardGuiPlugin.java


1   /*
2   ================================================================================
3   
4     FILE:  StandardGuiPlugin.java
5     
6     PROJECT:
7     
8       Asaph
9     
10    CONTENTS:
11    
12      Plugin for the standard song viewer and editor
13    
14    PROGRAMMERS:
15    
16      Daniel Azuma (DA)  <dazuma@kagi.com>
17    
18    COPYRIGHT:
19    
20      Copyright (C) 2003  Daniel Azuma  (dazuma@kagi.com)
21      
22      This program is free software; you can redistribute it and/or
23      modify it under the terms of the GNU General Public License as
24      published by the Free Software Foundation; either version 2
25      of the License, or (at your option) any later version.
26      
27      This program is distributed in the hope that it will be useful,
28      but WITHOUT ANY WARRANTY; without even the implied warranty of
29      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30      GNU General Public License for more details.
31      
32      You should have received a copy of the GNU General Public
33      License along with this program; if not, write to
34        Free Software Foundation, Inc.
35        59 Temple Place, Suite 330
36        Boston, MA 02111-1307 USA
37  
38  ================================================================================
39  */
40  
41  
42  package com.virtuosotechnologies.asaph.standardgui;
43  
44  
45  import java.awt.print.PrinterJob;
46  import java.awt.print.PrinterException;
47  import javax.print.attribute.PrintRequestAttributeSet;
48  import javax.print.attribute.HashPrintRequestAttributeSet;
49  import java.util.Set;
50  import java.util.HashSet;
51  import java.util.Collection;
52  import java.util.Iterator;
53  import java.util.logging.Logger;
54  import java.util.logging.Level;
55  import javax.swing.JOptionPane;
56  
57  import com.virtuosotechnologies.lib.command.CommandEvent;
58  import com.virtuosotechnologies.lib.basiccommand.BasicCommandNode;
59  import com.virtuosotechnologies.lib.basiccommand.BasicItemCommandNode;
60  import com.virtuosotechnologies.lib.util.ExceptionUtils;
61  import com.virtuosotechnologies.lib.util.EventAbortedException;
62  import com.virtuosotechnologies.lib.asyncjob.AsyncJobRunner;
63  import com.virtuosotechnologies.lib.asyncjob.AsyncJobListener;
64  import com.virtuosotechnologies.lib.asyncjob.ThreadWorkerAsyncJobRunner;
65  import com.virtuosotechnologies.lib.asyncjob.BasicAsyncJobListener;
66  import com.virtuosotechnologies.lib.asyncjob.AsyncJobFailedEvent;
67  import com.virtuosotechnologies.lib.asyncjob.AsyncJobException;
68  import com.virtuosotechnologies.lib.asyncjob.AsyncJob;
69  import com.virtuosotechnologies.lib.asyncjob.AbstractAsyncJob;
70  import com.virtuosotechnologies.lib.asyncjob.AsyncJobProgressReporter;
71  import com.virtuosotechnologies.lib.swing.SwingUtils;
72  import com.virtuosotechnologies.lib.swing.DetailedMessageDialog;
73  import com.virtuosotechnologies.lib.plugin.PluginLinker;
74  import com.virtuosotechnologies.lib.plugin.PluginInitializer;
75  import com.virtuosotechnologies.lib.plugin.PluginInitializerException;
76  
77  import com.virtuosotechnologies.asaph.model.SongDatabase;
78  import com.virtuosotechnologies.asaph.model.SongID;
79  import com.virtuosotechnologies.asaph.model.SongDeletedException;
80  import com.virtuosotechnologies.asaph.model.SongDatabaseFailedException;
81  import com.virtuosotechnologies.asaph.maingui.CommandManager;
82  import com.virtuosotechnologies.asaph.maingui.DatabaseManager;
83  import com.virtuosotechnologies.asaph.maingui.PrefsWindowManager;
84  import com.virtuosotechnologies.asaph.maingui.GuiEnvironmentManager;
85  import com.virtuosotechnologies.asaph.maingui.ListUpdateManager;
86  import com.virtuosotechnologies.asaph.maingui.PaneManager;
87  import com.virtuosotechnologies.asaph.maingui.SelectionManager;
88  import com.virtuosotechnologies.asaph.maingui.SelectionListener;
89  import com.virtuosotechnologies.asaph.maingui.DatabaseListener;
90  import com.virtuosotechnologies.asaph.maingui.DatabaseSelectionEvent;
91  import com.virtuosotechnologies.asaph.maingui.SongSelectionEvent;
92  import com.virtuosotechnologies.asaph.maingui.DatabaseEvent;
93  import com.virtuosotechnologies.asaph.modelutils.SongUtils;
94  import com.virtuosotechnologies.asaph.modelutils.DataTransferUtils;
95  import com.virtuosotechnologies.asaph.notationmanager.NotationManager;
96  
97  
98  /**
99   * Plugin for the standard song viewer and editor
100  */
101 public class StandardGuiPlugin
102 implements PluginInitializer
103 {
104   private static final String STR_dialog_ErrorTitle =
105     ResourceAccess.Strings.buildString("dialog_ErrorTitle");
106   private static final String STR_dialog_ErrorsHeader =
107     ResourceAccess.Strings.buildString("dialog_ErrorsHeader");
108   private static final String STR_dialog_FirstExceptionTemplate =
109     ResourceAccess.Strings.buildString("dialog_FirstExceptionTemplate");
110   private static final String STR_dialog_NextExceptionTemplate =
111     ResourceAccess.Strings.buildString("dialog_NextExceptionTemplate");
112   private static final String STR_message_SongRemovedOnOpen =
113     ResourceAccess.Strings.buildString("message_SongRemovedOnOpen");
114   private static final String STR_message_LoadSongError =
115     ResourceAccess.Strings.buildString("message_LoadSongError");
116   private static final String STR_message_PrinterError =
117     ResourceAccess.Strings.buildString("message_PrinterError");
118   private static final String STR_message_InternalError =
119     ResourceAccess.Strings.buildString("message_InternalError");
120   
121   private static final String STR_StandardGuiPlugin_OpenSongJobName =
122     ResourceAccess.Strings.buildString("StandardGuiPlugin_OpenSongJobName");
123   
124   private static final int DEFAULT_SONG_COMMAND_PRIORITY = 1;
125   
126   
127   private Logger logger_;
128   
129   private CommandManager commandManager_;
130   private DatabaseManager databaseManager_;
131   private GuiEnvironmentManager guiEnvironmentManager_;
132   private ListUpdateManager listUpdateManager_;
133   private PaneManager paneManager_;
134   private SelectionManager selectionManager_;
135   private SongUtils songUtils_;
136   private DataTransferUtils dataTransferUtils_;
137   private NotationManager notationManager_;
138   
139   private EditorPrefs editorPrefs_;
140   
141   private AsyncJobRunner jobRunner_;
142   private AsyncJobListener jobListener_;
143   
144   private BasicCommandNode openCommand_;
145   
146   private SongID curSong_;
147   private Set windows_;
148   
149   private PrinterJob printJob_;
150   private PrintRequestAttributeSet printAttributes_;
151   
152   private SelectionListener selectionListener_;
153   private DatabaseListener databaseListener_;
154   
155   
156   /**
157    * Perform first initialization of the plugin. This is called after the plugin
158    * is instantiated, but before it is asked to provide any of its API implementations.
159    * Any APIs the plugin declared it needed for initialization will be available
160    * through the linker when this method is called.
161    * <p>
162    * Plugins should perform any time-consuming initialization in this method, rather
163    * than in the constructor or static initializers, and should use this method to
164    * report any fatal errors during initialization.
165    *
166    * @param linker the linker for this plugin.
167    * @exception PluginInitializerException thrown if the plugin could not
168    *    initialize itself.
169    */
170   public void initialize(
171     PluginLinker linker)
172   throws
173     PluginInitializerException
174   {
175     logger_ = Logger.getLogger("com.virtuosotechnologies.asaph.standardgui");
176     
177     commandManager_ = (CommandManager)
178       linker.getAPI(CommandManager.API_NAME).getImplementation();
179     databaseManager_ = (DatabaseManager)
180       linker.getAPI(DatabaseManager.API_NAME).getImplementation();
181     guiEnvironmentManager_ = (GuiEnvironmentManager)
182       linker.getAPI(GuiEnvironmentManager.API_NAME).getImplementation();
183     listUpdateManager_ = (ListUpdateManager)
184       linker.getAPI(ListUpdateManager.API_NAME).getImplementation();
185     paneManager_ = (PaneManager)
186       linker.getAPI(PaneManager.API_NAME).getImplementation();
187     selectionManager_ = (SelectionManager)
188       linker.getAPI(SelectionManager.API_NAME).getImplementation();
189     songUtils_ = (SongUtils)
190       linker.getAPI(SongUtils.API_NAME).getImplementation();
191     dataTransferUtils_ = (DataTransferUtils)
192       linker.getAPI(DataTransferUtils.API_NAME).getImplementation();
193     notationManager_ = (NotationManager)
194       linker.getAPI(NotationManager.API_NAME).getImplementation();
195     PrefsWindowManager prefsMgr = (PrefsWindowManager)
196       linker.getAPI(PrefsWindowManager.API_NAME).getImplementation();
197     
198     editorPrefs_ = new EditorPrefs();
199     prefsMgr.registerPrefsPaneProvider(editorPrefs_,
200       ResourceAccess.Strings.buildString("EditorPrefs_Title"),
201       ResourceAccess.Strings.buildString("EditorPrefs_Description"));
202     
203     curSong_ = null;
204     windows_ = new HashSet();
205     
206     printJob_ = PrinterJob.getPrinterJob();
207     if (printJob_ == null)
208     {
209       logger_.log(Level.WARNING, "Unable to create PrinterJob");
210       throw new PluginInitializerException(ResourceAccess.Strings.buildString("err_PrinterInitFailed"));
211     }
212     printAttributes_ = new HashPrintRequestAttributeSet();
213     
214     openCommand_ = new BasicItemCommandNode()
215     {
216       public void commandInvoked(
217         CommandEvent ev)
218       {
219         doOpenSong();
220       }
221     };
222     openCommand_.setNameProperty(ResourceAccess.Strings.buildString("menu_MainSong_OpenSong"));
223     openCommand_.setDisabledProperty(true);
224     
225     SwingUtils.invokeOnSwingThread(
226       new Runnable()
227       {
228         public void run()
229         {
230           commandManager_.setDefaultSongCommand(openCommand_, DEFAULT_SONG_COMMAND_PRIORITY);
231         }
232       });
233     
234     jobRunner_ = new ThreadWorkerAsyncJobRunner(1);
235     guiEnvironmentManager_.registerAsyncJobRunner(jobRunner_);
236     jobRunner_.addAsyncJobListener(
237       jobListener_ = new BasicAsyncJobListener()
238       {
239         public void jobFailed(
240           final AsyncJobFailedEvent ev)
241         {
242           SwingUtils.invokeOnSwingThread(
243             new Runnable()
244             {
245               public void run()
246               {
247                 AsyncJobException ex = ev.getException();
248                 Throwable cause = ex.getCause();
249                 if (cause instanceof SongDeletedException)
250                 {
251                   JOptionPane.showMessageDialog(guiEnvironmentManager_.getDialogParent(),
252                     STR_message_SongRemovedOnOpen, STR_dialog_ErrorTitle,
253                     JOptionPane.ERROR_MESSAGE);
254                 }
255                 else if (cause instanceof SongDatabaseFailedException)
256                 {
257                   DetailedMessageDialog dialog = DetailedMessageDialog.create(
258                     guiEnvironmentManager_.getDialogParent(), STR_dialog_ErrorTitle,
259                     STR_message_LoadSongError, STR_dialog_ErrorsHeader,
260                     ExceptionUtils.getDescriptionFor(cause,
261                       STR_dialog_FirstExceptionTemplate, STR_dialog_NextExceptionTemplate),
262                     null);
263                   dialog.show();
264                 }
265                 else if (cause instanceof PrinterException)
266                 {
267                   DetailedMessageDialog dialog = DetailedMessageDialog.create(
268                     guiEnvironmentManager_.getDialogParent(), STR_dialog_ErrorTitle,
269                     STR_message_PrinterError, STR_dialog_ErrorsHeader,
270                     ExceptionUtils.getDescriptionFor(cause,
271                       STR_dialog_FirstExceptionTemplate, STR_dialog_NextExceptionTemplate),
272                     null);
273                   dialog.show();
274                 }
275                 else
276                 {
277                   DetailedMessageDialog dialog = DetailedMessageDialog.create(
278                     guiEnvironmentManager_.getDialogParent(), STR_dialog_ErrorTitle,
279                     STR_message_InternalError, STR_dialog_ErrorsHeader,
280                     ExceptionUtils.getDescriptionFor(cause,
281                       STR_dialog_FirstExceptionTemplate, STR_dialog_NextExceptionTemplate),
282                     null);
283                   dialog.show();
284                 }
285               }
286             });
287         }
288       });
289     
290     selectionManager_.addSelectionListener(
291       selectionListener_ = new SelectionListener()
292       {
293         public void databaseSelectionChanged(
294           DatabaseSelectionEvent ev)
295         {
296         }
297         
298         public void songSelectionChanged(
299           SongSelectionEvent ev)
300         {
301           handleSongSelected(ev);
302         }
303       });
304     
305     databaseManager_.addDatabaseListener(
306       databaseListener_ = new DatabaseListener()
307       {
308         public void databaseDirtyChanged(
309           DatabaseEvent ev)
310         {
311         }
312         
313         public void databaseClosing(
314           DatabaseEvent ev)
315         throws
316           EventAbortedException
317         {
318           handleDatabaseClosing(ev);
319         }
320         
321         public void databaseOpened(
322           DatabaseEvent ev)
323         {
324         }
325         
326         public void databaseClosed(
327           DatabaseEvent ev)
328         {
329         }
330       });
331     
332     RenderControls.initFonts();
333   }
334   
335   
336   /**
337    * A plugin must implement this method to provide the implementations of the APIs
338    * that it provides. This method is called after the initialize() method.
339    * Any APIs the plugin declared it needed in to implement this API will be available
340    * through the linker when this method is called.
341    * <p>
342    * Plugins should perform any time-consuming initialization in this method, rather
343    * than in the constructor or static initializers, and should use this method to
344    * report any fatal errors during initialization.
345    *
346    * @param apiName the name of the API to implement
347    * @param linker the linker for this plugin.
348    * @return an object implementing the API.
349    * @exception PluginInitializerException thrown if the plugin could not implement the API.
350    */
351   public Object getAPIImplementation(
352     String apiName,
353     PluginLinker linker)
354   throws
355     PluginInitializerException
356   {
357     throw new PluginInitializerException();
358   }
359   
360   
361   /**
362    * Get PrinterJob
363    */
364   /*package*/ PrinterJob getPrinterJob()
365   {
366     return printJob_;
367   }
368   
369   
370   /**
371    * Get PrintRequestAttributeSet
372    */
373   /*package*/ PrintRequestAttributeSet getPrintAttributes()
374   {
375     return printAttributes_;
376   }
377   
378   
379   /**
380    * Register a pane
381    */
382   /*package*/ void registerWindow(
383     SongWindow window)
384   {
385     windows_.add(window);
386   }
387   
388   
389   /**
390    * Unregister a pane
391    */
392   /*package*/ void unregisterWindow(
393     SongWindow window)
394   {
395     windows_.remove(window);
396   }
397   
398   
399   /**
400    * Database closing
401    */
402   private void handleDatabaseClosing(
403     DatabaseEvent ev)
404   throws
405     EventAbortedException
406   {
407     SongDatabase database = ev.getSongDatabase();
408     for (Iterator iter = windows_.iterator(); iter.hasNext(); )
409     {
410       SongWindow window = (SongWindow)iter.next();
411       if (!window.databaseClosing(database))
412       {
413         throw new EventAbortedException();
414       }
415     }
416   }
417   
418   
419   /**
420    * Song selection changed
421    */
422   private void handleSongSelected(
423     SongSelectionEvent ev)
424   {
425     Collection selection = ev.getNewSelection();
426     if (selection.size() == 1)
427     {
428       openCommand_.setDisabledProperty(false);
429       curSong_ = (SongID)selection.iterator().next();
430     }
431     else
432     {
433       openCommand_.setDisabledProperty(true);
434       curSong_ = null;
435     }
436   }
437   
438   
439   private void doOpenSong()
440   {
441     if (curSong_ == null)
442     {
443       return;
444     }
445     final SongID selectedSong = curSong_;
446     jobRunner_.startJob(
447       new AbstractAsyncJob(STR_StandardGuiPlugin_OpenSongJobName, false, AsyncJob.INDETERMINATE_PROGRESS, null)
448       {
449         public Object run(
450           AsyncJobProgressReporter reporter)
451         throws
452           AsyncJobException
453         {
454           try
455           {
456             new SongWindow(StandardGuiPlugin.this, selectedSong, editorPrefs_,
457               databaseManager_, guiEnvironmentManager_, listUpdateManager_, paneManager_,
458               songUtils_, dataTransferUtils_, notationManager_, jobRunner_);
459           }
460           catch (SongDeletedException ex)
461           {
462             throw new AsyncJobException(ex);
463           }
464           catch (SongDatabaseFailedException ex)
465           {
466             throw new AsyncJobException(ex);
467           }
468           return null;
469         }
470       });
471   }
472 }