Source code: com/virtuosotechnologies/asaph/standardgui/SongViewer.java
1 /*
2 ================================================================================
3
4 FILE: SongViewer.java
5
6 PROJECT:
7
8 Asaph
9
10 CONTENTS:
11
12 Song viewer pane implementation
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.Component;
46 import java.io.File;
47 import java.io.OutputStream;
48 import java.io.FileOutputStream;
49 import java.io.InputStream;
50 import java.io.BufferedInputStream;
51 import java.io.FileInputStream;
52 import java.io.IOException;
53 import java.util.logging.Logger;
54 import java.util.prefs.BackingStoreException;
55 import java.util.prefs.InvalidPreferencesFormatException;
56 import javax.swing.JComponent;
57 import javax.swing.JSplitPane;
58 import javax.swing.JFileChooser;
59 import javax.swing.filechooser.FileFilter;
60
61 import com.virtuosotechnologies.lib.command.CommandNode;
62 import com.virtuosotechnologies.lib.command.CommandEvent;
63 import com.virtuosotechnologies.lib.basiccommand.BasicCommandNode;
64 import com.virtuosotechnologies.lib.basiccommand.BasicContainerCommandNode;
65 import com.virtuosotechnologies.lib.basiccommand.BasicItemCommandNode;
66 import com.virtuosotechnologies.lib.basiccommand.BasicSeparatorCommandNode;
67 import com.virtuosotechnologies.lib.basiccommand.BasicGroupCommandNode;
68 import com.virtuosotechnologies.lib.util.ExceptionUtils;
69 import com.virtuosotechnologies.lib.swing.DetailedMessageDialog;
70 import com.virtuosotechnologies.lib.asyncjob.AsyncJobRunner;
71
72 import com.virtuosotechnologies.asaph.model.SongID;
73 import com.virtuosotechnologies.asaph.model.Song;
74 import com.virtuosotechnologies.asaph.maingui.GuiEnvironmentManager;
75 import com.virtuosotechnologies.asaph.modelutils.SongUtils;
76
77
78 /**
79 * Song viewer pane implementation
80 */
81 /*package*/ class SongViewer
82 {
83 private static final String STR_menu_ViewTitle =
84 ResourceAccess.Strings.buildString("menu_ViewTitle");
85 private static final String STR_menu_View_PrintItem =
86 ResourceAccess.Strings.buildString("menu_View_PrintItem");
87 private static final String STR_menu_View_ExportItem =
88 ResourceAccess.Strings.buildString("menu_View_ExportItem");
89 private static final String STR_menu_View_SaveLayoutItem =
90 ResourceAccess.Strings.buildString("menu_View_SaveLayoutItem");
91 private static final String STR_menu_View_LoadLayoutItem =
92 ResourceAccess.Strings.buildString("menu_View_LoadLayoutItem");
93 private static final String STR_menu_View_SetDefaultLayoutItem =
94 ResourceAccess.Strings.buildString("menu_View_SetDefaultLayoutItem");
95
96 private static final String STR_dialog_ErrorTitle =
97 ResourceAccess.Strings.buildString("dialog_ErrorTitle");
98 private static final String STR_message_SaveLayoutError =
99 ResourceAccess.Strings.buildString("message_SaveLayoutError");
100 private static final String STR_dialog_ErrorsHeader =
101 ResourceAccess.Strings.buildString("dialog_ErrorsHeader");
102 private static final String STR_dialog_FirstExceptionTemplate =
103 ResourceAccess.Strings.buildString("dialog_FirstExceptionTemplate");
104 private static final String STR_dialog_NextExceptionTemplate =
105 ResourceAccess.Strings.buildString("dialog_NextExceptionTemplate");
106 private static final String STR_message_LoadLayoutError =
107 ResourceAccess.Strings.buildString("message_LoadLayoutError");
108
109 private static final String STR_SongViewer_SavedLayoutFileFilter =
110 ResourceAccess.Strings.buildString("SongViewer_SavedLayoutFileFilter");
111
112
113 private static final String SAVED_LAYOUT_EXTENSION = ".asly";
114
115
116 private Logger logger_;
117
118 private SongWindow window_;
119 private GuiEnvironmentManager guiEnvironment_;
120 private AsyncJobRunner jobRunner_;
121
122 private SongID songID_;
123 private Song song_;
124
125 private BasicCommandNode commandGroup_;
126 private JComponent component_;
127
128
129 /**
130 * Constructor
131 */
132 /*package*/ SongViewer(
133 SongWindow window,
134 SongUtils songUtils,
135 GuiEnvironmentManager guiEnvironment,
136 AsyncJobRunner jobRunner,
137 SongID songID,
138 Song song,
139 final RenderSettings renderSettings)
140 {
141 logger_ = Logger.getLogger("com.virtuosotechnologies.asaph.standardgui");
142
143 window_ = window;
144 guiEnvironment_ = guiEnvironment;
145 jobRunner_ = jobRunner;
146 songID_ = songID;
147 song_ = song;
148
149 final RenderPane renderPane = new RenderPane(song_, renderSettings, songUtils);
150 final RenderControls renderControls = new RenderControls(song_, renderPane, renderSettings,
151 window.getNotationManager().getNotationFactoryForLocale(song_.getLocale()));
152 InfoPane infoPane = new InfoPane(song_, songUtils);
153 BasicCommandNode node;
154
155 // Create view menu
156 BasicCommandNode viewMenu = new BasicContainerCommandNode();
157 viewMenu.setNameProperty(STR_menu_ViewTitle);
158
159 node = new BasicItemCommandNode()
160 {
161 public void commandInvoked(
162 CommandEvent ev)
163 {
164 doPrint(renderPane);
165 }
166 };
167 node.setNameProperty(STR_menu_View_PrintItem);
168 viewMenu.addChild(node);
169
170 node = new BasicItemCommandNode()
171 {
172 public void commandInvoked(
173 CommandEvent ev)
174 {
175 renderPane.doExportText();
176 }
177 };
178 node.setNameProperty(STR_menu_View_ExportItem);
179 viewMenu.addChild(node);
180
181 viewMenu.addChild(BasicSeparatorCommandNode.getInstance());
182
183 node = new BasicItemCommandNode()
184 {
185 public void commandInvoked(
186 CommandEvent ev)
187 {
188 doSaveLayout(renderSettings);
189 }
190 };
191 node.setNameProperty(STR_menu_View_SaveLayoutItem);
192 viewMenu.addChild(node);
193
194 node = new BasicItemCommandNode()
195 {
196 public void commandInvoked(
197 CommandEvent ev)
198 {
199 doLoadLayout(renderSettings, renderPane, renderControls);
200 }
201 };
202 node.setNameProperty(STR_menu_View_LoadLayoutItem);
203 viewMenu.addChild(node);
204
205 node = new BasicItemCommandNode()
206 {
207 public void commandInvoked(
208 CommandEvent ev)
209 {
210 renderSettings.saveAsDefaults();
211 }
212 };
213 node.setNameProperty(STR_menu_View_SetDefaultLayoutItem);
214 viewMenu.addChild(node);
215
216 // Set up pane
217 JSplitPane splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, false,
218 infoPane.getJComponent(), renderPane.getJComponent());
219 splitter.setDividerSize(6);
220 commandGroup_ = new BasicGroupCommandNode();
221 commandGroup_.addChild(viewMenu);
222 commandGroup_.addChild(renderControls.getToplevelCommandNode());
223 splitter.setDividerLocation(infoPane.getJComponent().getPreferredSize().width);
224 component_ = splitter;
225 }
226
227
228 /**
229 * Dispose the viewer
230 */
231 /*package*/ void dispose()
232 {
233 }
234
235
236 /**
237 * Get the component
238 */
239 /*package*/ JComponent getJComponent()
240 {
241 return component_;
242 }
243
244
245 /**
246 * Get the toplevel command node
247 */
248 /*package*/ CommandNode getCommandNode()
249 {
250 return commandGroup_;
251 }
252
253
254 /**
255 * Print
256 */
257 private void doPrint(
258 RenderPane renderPane)
259 {
260 PrintHandler printer = PrintHandler.create(window_.getPrinterJob(),
261 window_.getPrintAttributes(), renderPane.getCurRenderHelper(),
262 guiEnvironment_.getDialogParent(), jobRunner_);
263 if (printer != null)
264 {
265 printer.doPrint();
266 }
267 }
268
269
270 /**
271 * Save the layout
272 */
273 private void doSaveLayout(
274 RenderSettings renderSettings)
275 {
276 Component dialogParent = guiEnvironment_.getDialogParent();
277 JFileChooser chooser = new JFileChooser(guiEnvironment_.getFileChooserDirectory());
278 int returnVal = chooser.showSaveDialog(dialogParent);
279 guiEnvironment_.setFileChooserDirectory(chooser.getCurrentDirectory());
280 if (returnVal == JFileChooser.APPROVE_OPTION)
281 {
282 File file = chooser.getSelectedFile();
283 String path = file.getPath();
284 if (!path.endsWith(SAVED_LAYOUT_EXTENSION))
285 {
286 file = new File(path + SAVED_LAYOUT_EXTENSION);
287 }
288 OutputStream stream = null;
289 try
290 {
291 stream = new FileOutputStream(file);
292 renderSettings.saveToStream(stream);
293 }
294 catch (IOException ex)
295 {
296 DetailedMessageDialog dialog = DetailedMessageDialog.create(
297 dialogParent, STR_dialog_ErrorTitle,
298 STR_message_SaveLayoutError, STR_dialog_ErrorsHeader,
299 ExceptionUtils.getDescriptionFor(ex,
300 STR_dialog_FirstExceptionTemplate, STR_dialog_NextExceptionTemplate),
301 null);
302 dialog.show();
303 }
304 catch (BackingStoreException ex)
305 {
306 DetailedMessageDialog dialog = DetailedMessageDialog.create(
307 dialogParent, STR_dialog_ErrorTitle,
308 STR_message_SaveLayoutError, STR_dialog_ErrorsHeader,
309 ExceptionUtils.getDescriptionFor(ex,
310 STR_dialog_FirstExceptionTemplate, STR_dialog_NextExceptionTemplate),
311 null);
312 dialog.show();
313 }
314 finally
315 {
316 if (stream != null)
317 {
318 try
319 {
320 stream.close();
321 }
322 catch (IOException ex)
323 {
324 }
325 }
326 }
327 }
328 }
329
330
331 /**
332 * Load the layout
333 */
334 private void doLoadLayout(
335 RenderSettings renderSettings,
336 RenderPane renderPane,
337 RenderControls renderControls)
338 {
339 Component dialogParent = guiEnvironment_.getDialogParent();
340 JFileChooser chooser = new JFileChooser(guiEnvironment_.getFileChooserDirectory());
341 chooser.setFileFilter(
342 new FileFilter()
343 {
344 public boolean accept(
345 File f)
346 {
347 return f.isDirectory() ||
348 f.getPath().endsWith(SAVED_LAYOUT_EXTENSION);
349 }
350
351 public String getDescription()
352 {
353 return STR_SongViewer_SavedLayoutFileFilter;
354 }
355 });
356 chooser.setAcceptAllFileFilterUsed(false);
357 int returnVal = chooser.showOpenDialog(dialogParent);
358 guiEnvironment_.setFileChooserDirectory(chooser.getCurrentDirectory());
359 if (returnVal == JFileChooser.APPROVE_OPTION)
360 {
361 File file = chooser.getSelectedFile();
362 InputStream stream = null;
363 try
364 {
365 stream = new BufferedInputStream(new FileInputStream(file));
366 renderSettings.loadFromStream(stream);
367 renderPane.updateDisplay();
368 renderControls.settingsChanged();
369 }
370 catch (IOException ex)
371 {
372 DetailedMessageDialog dialog = DetailedMessageDialog.create(
373 dialogParent, STR_dialog_ErrorTitle,
374 STR_message_LoadLayoutError, STR_dialog_ErrorsHeader,
375 ExceptionUtils.getDescriptionFor(ex,
376 STR_dialog_FirstExceptionTemplate, STR_dialog_NextExceptionTemplate),
377 null);
378 dialog.show();
379 }
380 catch (InvalidPreferencesFormatException ex)
381 {
382 DetailedMessageDialog dialog = DetailedMessageDialog.create(
383 dialogParent, STR_dialog_ErrorTitle,
384 STR_message_LoadLayoutError, STR_dialog_ErrorsHeader,
385 ExceptionUtils.getDescriptionFor(ex,
386 STR_dialog_FirstExceptionTemplate, STR_dialog_NextExceptionTemplate),
387 null);
388 dialog.show();
389 }
390 finally
391 {
392 if (stream != null)
393 {
394 try
395 {
396 stream.close();
397 }
398 catch (IOException ex)
399 {
400 }
401 }
402 }
403 }
404 }
405 }