1 package com.melloware.jukes.gui.tool;
2
3 import java.awt.Component;
4 import java.awt.Cursor;
5 import java.awt.Desktop;
6 import java.awt.EventQueue;
7 import java.awt.Frame;
8 import java.awt.GridLayout;
9 import java.awt.event.ActionEvent;
10 import java.io.File;
11 import java.io.FileInputStream;
12 import java.io.FileOutputStream;
13 import java.io.IOException;
14 import java.net.URI;
15 import java.net.URL;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.prefs.Preferences;
22
23 import javax.swing.JComboBox;
24 import javax.swing.JComponent;
25 import javax.swing.JFileChooser;
26 import javax.swing.JLabel;
27 import javax.swing.JList;
28 import javax.swing.JOptionPane;
29 import javax.swing.JPanel;
30 import javax.swing.JTable;
31 import javax.swing.JTextArea;
32 import javax.swing.JToggleButton;
33 import javax.swing.JTree;
34 import javax.swing.UIManager;
35 import javax.swing.filechooser.FileFilter;
36 import javax.swing.text.JTextComponent;
37 import javax.swing.tree.TreePath;
38
39 import javazoom.jlgui.basicplayer.BasicPlayer;
40 import net.sf.jasperreports.engine.JRException;
41 import net.sf.jasperreports.engine.JasperFillManager;
42 import net.sf.jasperreports.engine.JasperPrint;
43 import net.sf.jasperreports.view.JasperViewer;
44
45 import org.apache.commons.io.FileUtils;
46 import org.apache.commons.lang.StringUtils;
47 import org.apache.commons.lang.SystemUtils;
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.hibernate.HibernateException;
51 import org.hibernate.exception.JDBCConnectionException;
52
53 import com.jgoodies.uif.application.Application;
54 import com.jgoodies.uif.util.ResourceUtils;
55 import com.jgoodies.uifextras.convenience.DefaultAboutDialog;
56 import com.jgoodies.uifextras.convenience.SetupManager;
57 import com.jgoodies.uifextras.convenience.TipOfTheDayDialog;
58 import com.l2fprod.common.swing.JDirectoryChooser;
59 import com.melloware.jukes.db.Database;
60 import com.melloware.jukes.db.HibernateDao;
61 import com.melloware.jukes.db.HibernateUtil;
62 import com.melloware.jukes.db.orm.Artist;
63 import com.melloware.jukes.db.orm.Disc;
64 import com.melloware.jukes.db.orm.Track;
65 import com.melloware.jukes.exception.InfrastructureException;
66 import com.melloware.jukes.file.Disclist;
67 import com.melloware.jukes.file.FileUtil;
68 import com.melloware.jukes.file.MusicDirectory;
69 import com.melloware.jukes.file.Playlist;
70 import com.melloware.jukes.file.filter.FilterFactory;
71 import com.melloware.jukes.gui.view.DisclistPanel;
72 import com.melloware.jukes.gui.view.FilterPanel;
73 import com.melloware.jukes.gui.view.MainFrame;
74 import com.melloware.jukes.gui.view.PlaylistPanel;
75 import com.melloware.jukes.gui.view.component.AlbumImage;
76 import com.melloware.jukes.gui.view.dialogs.DifferenceToolDialog;
77 import com.melloware.jukes.gui.view.dialogs.DiscAddDialog;
78 import com.melloware.jukes.gui.view.dialogs.DiscFindDialog;
79 import com.melloware.jukes.gui.view.dialogs.DiscRemoveDialog;
80 import com.melloware.jukes.gui.view.dialogs.DiscTableModel;
81 import com.melloware.jukes.gui.view.dialogs.GenresToolDialog;
82 import com.melloware.jukes.gui.view.dialogs.LocationChangeDialog;
83 import com.melloware.jukes.gui.view.dialogs.MemoryDialog;
84 import com.melloware.jukes.gui.view.dialogs.SearchDialog;
85 import com.melloware.jukes.gui.view.dialogs.SearchTableModel;
86 import com.melloware.jukes.gui.view.dialogs.StatisticsDialog;
87 import com.melloware.jukes.gui.view.dialogs.TrackAddDialog;
88 import com.melloware.jukes.gui.view.dialogs.XMLExportDialog;
89 import com.melloware.jukes.gui.view.dialogs.XMLImportDialog;
90 import com.melloware.jukes.gui.view.editor.AbstractEditor;
91 import com.melloware.jukes.gui.view.node.AbstractTreeNode;
92 import com.melloware.jukes.gui.view.node.ArtistNode;
93 import com.melloware.jukes.gui.view.preferences.PreferencesDialog;
94 import com.melloware.jukes.util.GuiUtil;
95 import com.melloware.jukes.util.JukesValidationMessage;
96 import com.melloware.jukes.util.MessageUtil;
97
98
99
100
101
102
103
104
105
106
107 public final class MainController {
108
109 private static final Log LOG = LogFactory.getLog(MainController.class);
110 private static final String LINE_BREAK = "\n\n";
111 private static final String ERROR_WRITING_FILE = Resources.getString("label.Errorwritingfile");
112 private static final String ERROR_URL = Resources.getString("label.Enterurl");
113
114
115
116
117
118
119 private final MainModule mainModule;
120
121
122
123
124
125
126
127
128
129 public MainController(final MainModule mainModule) {
130 this.mainModule = mainModule;
131
132 }
133
134
135
136
137
138
139 @SuppressWarnings("deprecation")
140 public void backupTool(final ActionEvent aEvent) {
141 LOG.debug("Backup Database");
142 if (MessageUtil.confirmBackup(getDefaultParentFrame())) {
143 final File zip = MainModule.SETTINGS.getFileBackup();
144 getMainFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
145
146
147
148 Database.backupDatabase(HibernateUtil.getSession().connection(), zip.getAbsolutePath());
149 getMainFrame().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
150
151
152
153
154 MessageUtil.showTaskCompleted(getDefaultParentFrame());
155 }
156
157 }
158
159
160
161
162
163
164
165
166
167 public void checkForOpenTipOfTheDayDialog() {
168 if ((SetupManager.usageCount() > 1) && (TipOfTheDayDialog.isShowingTips())) {
169 EventQueue.invokeLater(new Runnable() {
170 public void run() {
171 openTipOfTheDayDialog();
172 }
173 });
174 }
175 }
176
177
178
179
180
181
182 public void chooseDirectory(final ActionEvent aEvent) {
183 final JComponent button = (JComponent) aEvent.getSource();
184 final JTextComponent text = (JTextComponent) button.getClientProperty(Resources.TEXT_COMPONENT);
185 final JDirectoryChooser chooser = new JDirectoryChooser();
186 final JTextArea accessory = new JTextArea(Resources.getString("label.SelectDirectory"));
187 chooser.setSelectedFile(new File(text.getText()));
188 accessory.setLineWrap(true);
189 accessory.setWrapStyleWord(true);
190 accessory.setEditable(false);
191 accessory.setOpaque(false);
192 accessory.setFont(UIManager.getFont("Tree.font"));
193 chooser.setAccessory(accessory);
194 chooser.setMultiSelectionEnabled(false);
195
196 final int choice = chooser.showOpenDialog(button);
197 if (choice == JDirectoryChooser.APPROVE_OPTION) {
198 final File dir = chooser.getSelectedFile();
199 LOG.debug("Directory selected: " + dir.getAbsolutePath());
200 text.setText(dir.getAbsolutePath());
201 }
202 }
203
204
205
206
207
208
209 public void chooseFile(final ActionEvent aEvent) {
210 final JComponent button = (JComponent) aEvent.getSource();
211 final JTextComponent text = (JTextComponent) button.getClientProperty(Resources.TEXT_COMPONENT);
212 final JFileChooser chooser = new JFileChooser();
213 chooser.setDialogTitle((String) button.getClientProperty(Resources.FILE_CHOOSER_TITLE));
214 chooser.setFileFilter((FileFilter) button.getClientProperty(Resources.FILE_CHOOSER_FILTER));
215 chooser.setMultiSelectionEnabled(false);
216 chooser.setFileHidingEnabled(true);
217 final int returnVal = chooser.showOpenDialog(this.getDefaultParentFrame());
218 if (returnVal != JFileChooser.APPROVE_OPTION) {
219 return;
220 }
221 final File file = chooser.getSelectedFile();
222 text.setText(file.getAbsolutePath());
223 if (LOG.isDebugEnabled()) {
224 LOG.debug(file.getAbsolutePath());
225
226 }
227 }
228
229
230
231
232
233
234 public void commit(final ActionEvent aEvent) {
235 LOG.debug("Commit Changes");
236 final JComponent button = (JComponent) aEvent.getSource();
237 final AbstractEditor editor = (AbstractEditor) button.getClientProperty(Resources.EDITOR_COMPONENT);
238 editor.commit();
239 }
240
241
242
243
244
245
246 @SuppressWarnings("deprecation")
247 public void connect(final ActionEvent aEvent) {
248 LOG.debug("Connecting to database.");
249 final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
250 try {
251
252 HibernateUtil.shutdown();
253 Database.shutdown();
254
255
256 String dbLocation = MainModule.SETTINGS.getDatabaseLocation().getAbsolutePath();
257 dbLocation = dbLocation + SystemUtils.FILE_SEPARATOR + Resources.APPLICATION_LOCATION;
258
259
260 Database.startup(dbLocation, Resources.APPLICATION_LOCATION);
261
262
263 HibernateUtil.initialize();
264 HibernateUtil.getSession().clear();
265
266
267 Database.setWriteDelay(HibernateUtil.getSession().connection(), "FALSE");
268
269
270 getMainModule().refreshTree();
271 } catch (JDBCConnectionException ex) {
272 final String errorMessage = ResourceUtils.getString("messages.NotValidConnection");
273 MessageUtil.showError(mainFrame, errorMessage);
274 LOG.error(errorMessage);
275 } catch (Exception ex) {
276 final String errorMessage = ResourceUtils.getString("messages.ErrorConnect");
277 MessageUtil.showError(mainFrame, errorMessage);
278 LOG.error(errorMessage, ex);
279 System.exit(1);
280 }
281 }
282
283
284
285
286
287
288 public void contactUs(final ActionEvent aEvent) {
289 LOG.debug("Contact Us");
290 try {
291 if (Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
292 Desktop.getDesktop().browse(new URI(Resources.APPLICATION_URL));
293 }
294 } catch (UnsupportedOperationException ex) {
295 LOG.warn(ex.getMessage() + LINE_BREAK + ERROR_URL + Resources.APPLICATION_URL);
296 } catch (Exception ex) {
297 LOG.warn(ex.getMessage() + LINE_BREAK + ERROR_URL + Resources.APPLICATION_URL);
298 }
299 }
300
301
302
303
304
305
306
307 public void delete(final ActionEvent aEvent) {
308 LOG.debug("Delete Item");
309 final JComponent source = (JComponent) aEvent.getSource();
310 final Object editor = source.getClientProperty(Resources.EDITOR_COMPONENT);
311 if (editor == null) {
312 return;
313 }
314
315 if (editor instanceof AbstractEditor) {
316 ((AbstractEditor) editor).delete();
317 } else if (editor instanceof JTree) {
318 final JTree tree = (JTree) editor;
319 final TreePath path = tree.getSelectionPath();
320
321
322 if (path.getLastPathComponent() instanceof AbstractTreeNode) {
323 LOG.debug("Tree Node Delete");
324 ((AbstractTreeNode) path.getLastPathComponent()).delete();
325 }
326 }
327
328 }
329
330
331
332
333
334
335 public void differenceTool(final ActionEvent aEvent) {
336 LOG.debug("Difference Tool Dialog");
337 new DifferenceToolDialog(getDefaultParentFrame(), MainModule.SETTINGS).open();
338
339 }
340
341
342
343
344
345
346 public void genresTool(final ActionEvent aEvent) {
347 LOG.debug("Genres Check Dialog");
348 new GenresToolDialog(getDefaultParentFrame(), MainModule.SETTINGS).open();
349 }
350
351
352
353
354
355
356 public void discAdd(final ActionEvent aEvent) {
357 LOG.debug("Add New Disc");
358 final JFileChooser openDialog = new JFileChooser();
359 final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
360 openDialog.setDialogTitle(Resources.getString("label.AddNewDisc"));
361 final File currentDir = MainModule.SETTINGS.getStartInDirectory();
362 openDialog.setCurrentDirectory(currentDir);
363 openDialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
364 openDialog.setAcceptAllFileFilterUsed(false);
365
366 openDialog.setMultiSelectionEnabled(false);
367 openDialog.setSelectedFile(null);
368 final int returnVal = openDialog.showOpenDialog(this.getDefaultParentFrame());
369 if (returnVal != JFileChooser.APPROVE_OPTION) {
370 return;
371 }
372 final File dir = openDialog.getSelectedFile();
373
374
375
376 final Collection files = MusicDirectory.findMusicFiles(dir);
377 if (files.isEmpty()) {
378 String message = Resources.getString("messages.NoMusicFilesFound");
379 MessageUtil.showError(mainFrame, message);
380 return;
381 } else {
382 File file = (File) files.toArray()[0];
383 LOG.debug(file.getAbsolutePath());
384
385 new DiscAddDialog(getDefaultParentFrame(), MainModule.SETTINGS, file).open();
386 }
387 }
388
389
390
391
392
393
394 public void trackAdd(final ActionEvent aEvent) {
395 LOG.debug("Add Single Track");
396 final JFileChooser openDialog = new JFileChooser();
397 openDialog.setDialogTitle(Resources.getString("label.AddNewTrack"));
398 final File currentDir = MainModule.SETTINGS.getStartInDirectory();
399 openDialog.setCurrentDirectory(currentDir);
400 openDialog.setFileFilter(FilterFactory.musicFileFilter());
401 openDialog.setMultiSelectionEnabled(false);
402 openDialog.setSelectedFile(null);
403 final int returnVal = openDialog.showOpenDialog(this.getDefaultParentFrame());
404 if (returnVal != JFileChooser.APPROVE_OPTION) {
405 return;
406 }
407 final File file = openDialog.getSelectedFile();
408
409 LOG.debug(file.getAbsolutePath());
410
411 new TrackAddDialog(getDefaultParentFrame(), MainModule.SETTINGS, file).open();
412 }
413
414
415
416
417
418
419 public void freeDB(final ActionEvent aEvent) {
420 LOG.debug("Search FreeDB");
421 final JComponent button = (JComponent) aEvent.getSource();
422 final Object editor = button.getClientProperty(Resources.EDITOR_COMPONENT);
423 if (editor != null) {
424 if (editor instanceof AbstractEditor) {
425 ((AbstractEditor) editor).freeDBSearch();
426 } else if (editor instanceof DiscAddDialog) {
427 ((DiscAddDialog) editor).freeDBSearch();
428 }
429 }
430 }
431
432
433
434
435
436
437 public void discAddComments(final ActionEvent aEvent) {
438 LOG.debug("Update comments all at once.");
439 final JComponent button = (JComponent) aEvent.getSource();
440 final Object editor = button.getClientProperty(Resources.EDITOR_COMPONENT);
441 if ((editor != null) && (editor instanceof DiscAddDialog)) {
442 ((DiscAddDialog) editor).updateComments();
443 }
444 }
445
446
447
448
449
450
451 public void discAddResetFromFilename(final ActionEvent aEvent) {
452 LOG.debug("Reset Titles from filenames.");
453 final JComponent button = (JComponent) aEvent.getSource();
454 final Object editor = button.getClientProperty(Resources.EDITOR_COMPONENT);
455 if ((editor != null) && (editor instanceof DiscAddDialog)) {
456 ((DiscAddDialog) editor).resetFromFilenames();
457 }
458 }
459
460
461
462
463
464
465 public void discAddResetTrackNumbers(final ActionEvent aEvent) {
466 LOG.debug("Reset Track Numbers.");
467 final JComponent button = (JComponent) aEvent.getSource();
468 final Object editor = button.getClientProperty(Resources.EDITOR_COMPONENT);
469 if ((editor != null) && (editor instanceof DiscAddDialog)) {
470 ((DiscAddDialog) editor).resetTrackNumbers();
471 }
472 }
473
474
475
476
477
478
479 public void discAddTitleCase(final ActionEvent aEvent) {
480 LOG.debug("Title case all tracks.");
481 final JComponent button = (JComponent) aEvent.getSource();
482 final Object editor = button.getClientProperty(Resources.EDITOR_COMPONENT);
483 if ((editor != null) && (editor instanceof DiscAddDialog)) {
484 ((DiscAddDialog) editor).titleCase();
485 }
486 }
487
488
489
490
491
492
493 public void discCoverImage(final ActionEvent aEvent) {
494 LOG.debug("Finding new cover image");
495 final JComponent button = (JComponent) aEvent.getSource();
496
497 final Object editor = button.getClientProperty(Resources.EDITOR_COMPONENT);
498 LOG.debug(editor);
499 if (editor != null) {
500 if (editor instanceof AbstractEditor) {
501 ((AbstractEditor) editor).findCover();
502 } else if (editor instanceof DiscAddDialog) {
503 ((DiscAddDialog) editor).findCover();
504 }
505 }
506 }
507
508
509
510
511
512
513 public void discFinder(final ActionEvent aEvent) {
514 LOG.debug("Disc Finder Dialog");
515 new DiscFindDialog(getDefaultParentFrame(), MainModule.SETTINGS).open();
516 }
517
518
519
520
521
522
523 public void discRemover(final ActionEvent aEvent) {
524 LOG.debug("Disc Remover Dialog");
525 new DiscRemoveDialog(getDefaultParentFrame()).open();
526 }
527
528
529
530
531
532
533 public void discWebSearch(final ActionEvent aEvent) {
534 LOG.debug("Web Search");
535 final JComponent button = (JComponent) aEvent.getSource();
536 final Object editor = button.getClientProperty(Resources.EDITOR_COMPONENT);
537 if (editor != null) {
538 if (editor instanceof AbstractEditor) {
539 ((AbstractEditor) editor).webSearch();
540 } else if (editor instanceof DiscAddDialog) {
541 ((DiscAddDialog) editor).webSearch();
542 }
543 }
544 }
545
546
547
548
549 public void donate() {
550 try {
551 if (Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
552 Desktop.getDesktop().browse(new URL(Resources.APPLICATION_DONATE_URL).toURI());
553 }
554 } catch (UnsupportedOperationException ex) {
555 LOG.warn(ex.getMessage() + LINE_BREAK + ERROR_URL + Resources.APPLICATION_DONATE_URL);
556 } catch (Exception ex) {
557 LOG.warn(ex.getMessage() + LINE_BREAK + ERROR_URL + Resources.APPLICATION_DONATE_URL);
558 }
559 }
560
561
562
563
564
565
566 @SuppressWarnings("unchecked")
567 public void exportCatalog(final ActionEvent aEvent) {
568 LOG.debug("Export Catalog");
569 final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
570 final JFileChooser chooser = new JFileChooser();
571 chooser.setDialogTitle(Resources.getString("label.ExportCatalog"));
572 chooser.setFileFilter(FilterFactory.textFileFilter());
573 chooser.setMultiSelectionEnabled(false);
574 chooser.setFileHidingEnabled(true);
575 final int returnVal = chooser.showSaveDialog(this.getDefaultParentFrame());
576 if (returnVal != JFileChooser.APPROVE_OPTION) {
577 return;
578 }
579 File file = chooser.getSelectedFile();
580 if (LOG.isDebugEnabled()) {
581 LOG.debug(file.getAbsolutePath());
582 }
583
584 file = FilterFactory.forceTextExtension(file);
585
586 try {
587
588 final ArrayList results = new ArrayList();
589 final Collection discs = HibernateDao.findByQuery(Resources.getString("hql.export.catalog"));
590
591 for (final Iterator iter = discs.iterator(); iter.hasNext();) {
592 final Object[] disc = (Object[]) iter.next();
593 results.add(disc[0] + Resources.TAB + disc[1] + Resources.TAB + disc[2] + Resources.TAB + disc[3]
594 + Resources.TAB + disc[4] + Resources.TAB + disc[5]);
595 }
596 FileUtils.writeLines(file, "UTF-8", results);
597
598 MessageUtil.showInformation(getDefaultParentFrame(), Resources
599 .getString("messages.Catalogexportedsuccessfully"));
600 } catch (IOException ex) {
601 MessageUtil.showError(mainFrame, ERROR_WRITING_FILE + LINE_BREAK + ex.getMessage());
602 LOG.error(ERROR_WRITING_FILE + LINE_BREAK + ex.getMessage(), ex);
603 } catch (InfrastructureException ex) {
604 MessageUtil.showError(mainFrame, "Infrastructure Exception: " + LINE_BREAK + ex.getMessage());
605 LOG.error(ERROR_WRITING_FILE + LINE_BREAK + ex.getMessage(), ex);
606 } catch (Exception ex) {
607 MessageUtil.showError(mainFrame, ERROR_WRITING_FILE + LINE_BREAK + ex.getMessage());
608 LOG.error("Unexpected error writing file.", ex);
609 }
610 }
611
612
613
614
615
616
617 public void fileRename(final ActionEvent aEvent) {
618 LOG.debug("Renaming File");
619 final JComponent button = (JComponent) aEvent.getSource();
620 final Object editor = button.getClientProperty(Resources.EDITOR_COMPONENT);
621 if (editor != null) {
622 if (editor instanceof AbstractEditor) {
623 ((AbstractEditor) editor).renameFiles();
624 } else if (editor instanceof DiscAddDialog) {
625 ((DiscAddDialog) editor).renameFiles();
626 }
627 }
628 }
629
630
631
632
633
634
635 public void filter(final ActionEvent aEvent) {
636 LOG.debug("Filter applied.");
637 final JToggleButton button = (JToggleButton) aEvent.getSource();
638 final FilterPanel editor = (FilterPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
639 if (button.isSelected()) {
640 LOG.debug("Button Selected");
641 editor.applyFilter();
642 } else {
643 LOG.debug("Button Deselected");
644 editor.removeFilter();
645 }
646 }
647
648
649
650
651
652
653 public void filterClear(final ActionEvent aEvent) {
654 LOG.debug("Filter cleared.");
655 final JComponent button = (JComponent) aEvent.getSource();
656 final FilterPanel editor = (FilterPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
657 editor.clearFilter();
658
659 }
660
661
662
663
664
665
666 public void filterClose(final ActionEvent aEvent) {
667 LOG.debug("Close Filter.");
668 getMainFrame().getMainPageBuilder().setFilterVisible(false);
669 }
670
671
672
673
674
675
676 public void filterDisplay(final ActionEvent aEvent) {
677 LOG.debug("Filter displayed/hidden.");
678 final boolean visible = !getMainFrame().getMainPageBuilder().isFilterVisible();
679 getMainFrame().getMainPageBuilder().setFilterVisible(visible);
680 }
681
682
683
684
685 public void forums() {
686 try {
687 if (Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
688 Desktop.getDesktop().browse(new URI(Resources.APPLICATION_FORUMS_URL));
689 }
690 } catch (UnsupportedOperationException ex) {
691 LOG.warn(ex.getMessage() + LINE_BREAK + ERROR_URL + Resources.APPLICATION_FORUMS_URL);
692 } catch (Exception ex) {
693 LOG.warn(ex.getMessage() + LINE_BREAK + ERROR_URL + Resources.APPLICATION_FORUMS_URL);
694 }
695 }
696
697
698
699
700 public void hideMainWindow() {
701 if (SystemUtils.IS_OS_WINDOWS) {
702 final MainFrame mainframe = (MainFrame) getDefaultParentFrame();
703 mainframe.getTrayIcon().hideWindow();
704 }
705 }
706
707
708
709
710
711
712
713 public void language(final ActionEvent aEvent, final String aLanguage) {
714 LOG.debug("Language change to " + aLanguage);
715
716
717 MainModule.SETTINGS.setLocale(aLanguage);
718 getMainModule().storeState();
719 MessageUtil.showInformation(getDefaultParentFrame(), Resources.getString("messages.update.language"));
720 }
721
722
723
724
725
726
727 public void locationTool(final ActionEvent aEvent) {
728 LOG.debug("Location Tool Dialog");
729 new LocationChangeDialog(getDefaultParentFrame(), MainModule.SETTINGS).open();
730 }
731
732
733
734
735
736
737 public void memory(final ActionEvent aEvent) {
738 LOG.debug("Memory Dialog");
739 new MemoryDialog(getDefaultParentFrame()).open();
740
741 }
742
743
744
745
746
747
748 public void playerNext(final ActionEvent aEvent) {
749 LOG.debug("Player Next");
750 final Runnable update = new Runnable() {
751 public void run() {
752 final Playlist playlist = getMainFrame().getPlaylist();
753 if (playlist.hasNext()) {
754 final Track track = (Track) playlist.getNext();
755 if (track.isValid()) {
756 getMainFrame().getPlayer().play(track.getTrackUrl());
757 }
758
759 }
760 }
761 };
762 EventQueue.invokeLater(update);
763 }
764
765
766
767
768
769
770 public void playerPause(final ActionEvent aEvent) {
771 LOG.debug("Player Pause/Resume");
772 final Runnable update = new Runnable() {
773 public void run() {
774 final MainFrame mainFrame = (MainFrame) getDefaultParentFrame();
775 mainFrame.getPlayer().pause();
776 }
777 };
778 EventQueue.invokeLater(update);
779 }
780
781
782
783
784
785
786 public void playerPlay(final ActionEvent aEvent) {
787 LOG.debug("Player Play");
788 final Runnable update = new Runnable() {
789 public void run() {
790 final MainFrame mainFrame = (MainFrame) getDefaultParentFrame();
791 LOG.debug("Status: " + mainFrame.getPlayer().getStatus());
792 if (mainFrame.getPlayer().getStatus() == -1) {
793 playerNext(null);
794 } else {
795 mainFrame.getPlayer().play();
796 }
797 }
798 };
799 EventQueue.invokeLater(update);
800
801 }
802
803
804
805
806
807
808 public void playerPrevious(final ActionEvent aEvent) {
809 LOG.debug("Player Previous");
810 final Runnable update = new Runnable() {
811 public void run() {
812 final Playlist playlist = getMainFrame().getPlaylist();
813 if (playlist.hasPrevious()) {
814 final Track trackCurrent = (Track) playlist.getPrevious();
815
816
817 if (getMainFrame().getPlayer().getElapsedTime() > 2000) {
818 LOG.debug("Player Previous: REPLAY current song");
819 playerNext(null);
820 } else {
821 final Track trackPrevious = (Track) playlist.getPrevious();
822 if ((trackPrevious != null) && (trackPrevious.isValid())) {
823 LOG.debug("Player Previous: PLAY previous song in playlist");
824 playerNext(null);
825 } else if ((trackCurrent != null) && (trackCurrent.isValid())) {
826 playerNext(null);
827 }
828 }
829 }
830 }
831 };
832 EventQueue.invokeLater(update);
833
834 }
835
836
837
838
839
840
841 public void playerStop(final ActionEvent aEvent) {
842 LOG.debug("Player Stop");
843 final Runnable update = new Runnable() {
844 public void run() {
845 MainFrame mainFrame = (MainFrame) getDefaultParentFrame();
846 mainFrame.getPlayer().stop();
847 }
848 };
849 EventQueue.invokeLater(update);
850 }
851
852
853
854
855
856
857 public void playImmediately(final ActionEvent aEvent) {
858 LOG.debug("Play Immediately");
859 final JComponent source = (JComponent) aEvent.getSource();
860 final Object editor = source.getClientProperty(Resources.EDITOR_COMPONENT);
861 final Runnable update = new Runnable() {
862 public void run() {
863
864 if (editor != null) {
865 final Player player = getMainFrame().getPlayer();
866 final Playlist playlist = getMainFrame().getPlaylist();
867
868 if (editor instanceof JTree) {
869 final JTree tree = (JTree) editor;
870 for (int i = 0; i < tree.getSelectionPaths().length; i++) {
871 final TreePath path = tree.getSelectionPaths()[i];
872 if (path.getLastPathComponent() instanceof AbstractTreeNode) {
873 final AbstractTreeNode node = (AbstractTreeNode) path.getLastPathComponent();
874
875 if (node instanceof ArtistNode) {
876 final int nodeCount = node.getChildCount();
877 if (nodeCount > 0) {
878 for (int ii = 0; ii < node.getChildCount(); ii++) {
879 final AbstractTreeNode childNode = (AbstractTreeNode) node.getChildAt(ii);
880 playlist.addNext(childNode.getModel());
881 }
882 }
883 } else {
884 playlist.addNext(node.getModel());
885 }
886 }
887 }
888 }
889
890 if (editor instanceof JList) {
891 final JList list = (JList) editor;
892 final Object[] selections = list.getSelectedValues();
893 for (int i = selections.length - 1; i >= 0; i--) {
894 Track track = null;
895 if (selections[i] instanceof JukesValidationMessage) {
896 final JukesValidationMessage message = (JukesValidationMessage) selections[i];
897 track = (Track) message.getDomainObject();
898 playlist.addNext(track);
899 } else if (selections[i] instanceof Track) {
900 track = (Track) selections[i];
901 playlist.addNext(track);
902 }
903 }
904 }
905 if (editor instanceof JTable) {
906 final JTable table = (JTable) editor;
907 final int[] selections = table.getSelectedRows();
908 final SearchTableModel model = (SearchTableModel) table.getModel();
909 for (int i = 0; i < selections.length; i++) {
910 int selectedRow = selections[i];
911 selectedRow = table.getRowSorter().convertRowIndexToModel(selectedRow);
912 Track track = (Track) model.getData()[selectedRow];
913 playlist.addNext(track);
914 }
915 }
916 if (editor instanceof AlbumImage) {
917 final AlbumImage image = (AlbumImage) editor;
918 if (image.getDisc() != null) {
919 playlist.addNext(image.getDisc());
920 }
921 }
922 final Track next = (Track) playlist.getNextImmediate();
923 if (next != null) {
924 player.play(next.getTrackUrl());
925 }
926
927 }
928 }
929 };
930 EventQueue.invokeLater(update);
931 }
932
933
934
935
936
937
938 public void playlistClose(final ActionEvent aEvent) {
939 LOG.debug("Close Playlist.");
940 getMainFrame().getMainPageBuilder().setPlaylistVisible(false);
941
942 }
943
944
945
946
947
948
949 public void playlistDisplay(final ActionEvent aEvent) {
950 LOG.debug("Playlist displayed/hidden.");
951 String currentPanel = getMainFrame().getMainPageBuilder().panelVisible();
952 boolean visible;
953 if (currentPanel == "playlistPanel") {
954 visible = false;
955 } else {
956 visible = true;
957 }
958 getMainFrame().getMainPageBuilder().setPlaylistVisible(visible);
959
960 }
961
962
963
964
965
966
967 public void playlistGoto(final ActionEvent aEvent) {
968 LOG.debug("Playlist goto.");
969 final Track selection;
970 final JComponent button = (JComponent) aEvent.getSource();
971 final JList editor = (JList) button.getClientProperty(Resources.EDITOR_COMPONENT);
972 try {
973 GuiUtil.setBusyCursor(getDefaultParentFrame(), true);
974 if (editor.getSelectedValue() != null) {
975
976 selection = (Track) editor.getSelectedValue();
977 String query = " and upper(disc.name) = '"
978 + selection.getDisc().getName().toUpperCase().replaceAll("'", "''") + "'";
979 String filter = MainModule.SETTINGS.getFilter();
980 if (!(MainModule.SETTINGS.isShowDefaultTree() && !StringUtils.isNotBlank(filter))) {
981 filter = query;
982 }
983 MainModule.SETTINGS.setFilter(filter);
984 getMainModule().refreshTree();
985 getMainModule().selectNodeInTree(editor.getSelectedValue());
986 } else {
987 MessageUtil.showInformation(Application.getDefaultParentFrame(), ResourceUtils
988 .getString("messages.SelectSomethingToGoTo"));
989 }
990 } finally {
991 GuiUtil.setBusyCursor(getDefaultParentFrame(), false);
992 }
993 }
994
995
996
997
998
999
1000 public void playlistLoad(final ActionEvent aEvent) {
1001 LOG.debug("Load Playlist");
1002 final JComponent button = (JComponent) aEvent.getSource();
1003 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1004 editor.load();
1005 }
1006
1007
1008
1009
1010
1011
1012 public void playlistMoveDown(final ActionEvent aEvent) {
1013 LOG.debug("Move down playlist");
1014 final JComponent button = (JComponent) aEvent.getSource();
1015 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1016 editor.moveDown();
1017
1018 }
1019
1020
1021
1022
1023
1024
1025 public void playlistMoveOver(final ActionEvent aEvent) {
1026 LOG.debug("Move over playlist");
1027 final JComponent button = (JComponent) aEvent.getSource();
1028 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1029 editor.moveOver();
1030
1031 }
1032
1033
1034
1035
1036
1037
1038 public void playlistMoveUp(final ActionEvent aEvent) {
1039 LOG.debug("Move up playlist");
1040 final JComponent button = (JComponent) aEvent.getSource();
1041 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1042 editor.moveUp();
1043 }
1044
1045
1046
1047
1048
1049
1050 public void playlistRemoveTracks(final ActionEvent aEvent) {
1051 LOG.debug("Remove tracks from playlist");
1052 final JComponent button = (JComponent) aEvent.getSource();
1053 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1054 editor.removeTracks();
1055 editor.repaint();
1056
1057 }
1058
1059
1060
1061
1062
1063
1064 public void playlistClear(ActionEvent aEvent) {
1065 LOG.debug("Clear tracks from playlist");
1066 final JComponent button = (JComponent) aEvent.getSource();
1067 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1068 editor.removeAllTracks();
1069 editor.repaint();
1070
1071
1072 }
1073
1074
1075
1076
1077
1078
1079 public void playlistSave(final ActionEvent aEvent) {
1080 LOG.debug("Save playlist.");
1081 final JComponent button = (JComponent) aEvent.getSource();
1082 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1083 editor.save();
1084 }
1085
1086
1087
1088
1089
1090
1091 public void playlistShuffleCatalog(final ActionEvent aEvent) {
1092 LOG.debug("Shuffle catalog.");
1093 final JToggleButton button = (JToggleButton) aEvent.getSource();
1094 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1095 editor.shuffleCatalog(button.isSelected());
1096
1097 if (button.isSelected()) {
1098 final Player player = getMainFrame().getPlayer();
1099
1100 if ((player.getStatus() == BasicPlayer.STOPPED) || (player.getStatus() == BasicPlayer.UNKNOWN)) {
1101 playerNext(null);
1102 }
1103 }
1104 }
1105
1106
1107
1108
1109
1110
1111 public void playlistShuffleList(final ActionEvent aEvent) {
1112 LOG.debug("Shuffle playlist.");
1113 final JToggleButton button = (JToggleButton) aEvent.getSource();
1114 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1115 editor.shufflePlaylist(button.isSelected());
1116 }
1117
1118
1119
1120
1121
1122
1123 public void playlistToggle(final ActionEvent aEvent) {
1124 LOG.debug("Toggle playlist.");
1125 final JToggleButton button = (JToggleButton) aEvent.getSource();
1126 final PlaylistPanel editor = (PlaylistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1127 editor.toggle(!button.isSelected());
1128 }
1129
1130
1131
1132
1133
1134
1135 public void preferencesExport(final ActionEvent aEvent) {
1136 LOG.debug("Export Preferences");
1137 final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
1138 final JFileChooser chooser = new JFileChooser();
1139 chooser.setDialogTitle(Resources.getString("label.ExportPreferences"));
1140 chooser.setFileFilter(FilterFactory.xmlFileFilter());
1141 chooser.setMultiSelectionEnabled(false);
1142 chooser.setFileHidingEnabled(true);
1143 final int returnVal = chooser.showSaveDialog(this.getDefaultParentFrame());
1144 if (returnVal != JFileChooser.APPROVE_OPTION) {
1145 return;
1146 }
1147 File file = chooser.getSelectedFile();
1148 if (LOG.isDebugEnabled()) {
1149 LOG.debug(file.getAbsolutePath());
1150 }
1151
1152
1153 file = FilterFactory.forceXmlExtension(file);
1154
1155
1156 try {
1157 final Preferences prefs = Application.getUserPreferences();
1158 final FileOutputStream stream = new FileOutputStream(file);
1159 prefs.exportSubtree(stream);
1160
1161 MessageUtil.showInformation(getDefaultParentFrame(), Resources
1162 .getString("messages.Preferencesexportedsuccessfully"));
1163 } catch (IOException ex) {
1164 MessageUtil.showError(mainFrame, ERROR_WRITING_FILE + LINE_BREAK + ex.getMessage());
1165 LOG.error(ERROR_WRITING_FILE + LINE_BREAK + ex, ex);
1166 } catch (Exception ex) {
1167 MessageUtil.showError(mainFrame, ERROR_WRITING_FILE);
1168 LOG.error("Unexpected error writing file.", ex);
1169 }
1170 }
1171
1172
1173
1174
1175
1176
1177 public void preferencesImport(final ActionEvent aEvent) {
1178 LOG.debug("Import Preferences");
1179 final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
1180 final JFileChooser chooser = new JFileChooser();
1181 chooser.setDialogTitle(Resources.getString("label.ImportPreferences"));
1182 chooser.setFileFilter(FilterFactory.xmlFileFilter());
1183 chooser.setMultiSelectionEnabled(false);
1184 chooser.setFileHidingEnabled(true);
1185 final int returnVal = chooser.showOpenDialog(this.getDefaultParentFrame());
1186 if (returnVal != JFileChooser.APPROVE_OPTION) {
1187 return;
1188 }
1189 final File file = chooser.getSelectedFile();
1190 if (LOG.isDebugEnabled()) {
1191 LOG.debug(file.getAbsolutePath());
1192 }
1193
1194
1195 try {
1196 final FileInputStream stream = new FileInputStream(file);
1197 Preferences.importPreferences(stream);
1198
1199 MainModule.SETTINGS.restoreFrom(Application.getUserPreferences());
1200
1201 MessageUtil.showInformation(getDefaultParentFrame(), Resources
1202 .getString("messages.Preferencesimportedsuccessfully"));
1203 } catch (IOException ex) {
1204 MessageUtil.showError(mainFrame, ERROR_WRITING_FILE + LINE_BREAK + ex.getMessage());
1205 LOG.error(ERROR_WRITING_FILE + LINE_BREAK + ex.getMessage(), ex);
1206 } catch (Exception ex) {
1207 MessageUtil.showError(mainFrame, ERROR_WRITING_FILE);
1208 LOG.error("Unexpected error writing file.", ex);
1209 }
1210 }
1211
1212
1213
1214
1215
1216
1217 public void queue(final ActionEvent aEvent) {
1218 LOG.debug("Queue");
1219 final JComponent source = (JComponent) aEvent.getSource();
1220 final Component editor = (Component) source.getClientProperty(Resources.EDITOR_COMPONENT);
1221 if (editor != null) {
1222 final Playlist playlist = getMainFrame().getPlaylist();
1223
1224
1225
1226
1227 if (editor instanceof JTree) {
1228 final JTree tree = (JTree) editor;
1229 for (int i = 0; i < tree.getSelectionPaths().length; i++) {
1230 final TreePath path = tree.getSelectionPaths()[i];
1231 if (path.getLastPathComponent() instanceof AbstractTreeNode) {
1232 final AbstractTreeNode node = (AbstractTreeNode) path.getLastPathComponent();
1233
1234 if (node instanceof ArtistNode) {
1235 final int nodeCount = node.getChildCount();
1236 if (nodeCount > 0) {
1237 for (int ii = 0; ii < node.getChildCount(); ii++) {
1238 final AbstractTreeNode childNode = (AbstractTreeNode) node.getChildAt(ii);
1239 playlist.add(childNode.getModel());
1240 }
1241 }
1242 } else {
1243 playlist.add(node.getModel());
1244 }
1245 }
1246 }
1247 }
1248
1249 if (editor instanceof JList) {
1250 final JList list = (JList) editor;
1251 final Object[] selections = list.getSelectedValues();
1252 for (int i = 0; i < selections.length; i++) {
1253 final JukesValidationMessage message = (JukesValidationMessage) selections[i];
1254 playlist.add(message.getDomainObject());
1255 }
1256 }
1257
1258 if (editor instanceof JTable) {
1259 final JTable table = (JTable) editor;
1260 final int[] selections = table.getSelectedRows();
1261 if (table.getModel() instanceof DiscTableModel) {
1262
1263
1264
1265 final DiscTableModel model = (DiscTableModel) table.getModel();
1266 for (int i = 0; i < selections.length; i++) {
1267 int selectedRow = selections[i];
1268 selectedRow = table.getRowSorter().convertRowIndexToModel(selectedRow);
1269 playlist.add(model.getData()[selectedRow]);
1270 }
1271 } else {
1272 final SearchTableModel model = (SearchTableModel) table.getModel();
1273 for (int i = 0; i < selections.length; i++) {
1274 int selectedRow = selections[i];
1275 selectedRow = table.getRowSorter().convertRowIndexToModel(selectedRow);
1276 playlist.add(model.getData()[selectedRow]);
1277 }
1278 }
1279 }
1280 if (editor instanceof AlbumImage) {
1281 final AlbumImage image = (AlbumImage) editor;
1282 if (image.getDisc() != null) {
1283 playlist.add(image.getDisc());
1284 }
1285 }
1286
1287 getMainFrame().getMainPageBuilder().refreshUI();
1288 }
1289 }
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302 public void queueNext(final ActionEvent aEvent) {
1303 LOG.debug("Queue Next");
1304 final JComponent source = (JComponent) aEvent.getSource();
1305 final Component editor = (Component) source.getClientProperty(Resources.EDITOR_COMPONENT);
1306 if (editor != null) {
1307 final Playlist playlist = getMainFrame().getPlaylist();
1308
1309 if (editor instanceof JTree) {
1310 final JTree tree = (JTree) editor;
1311 for (int i = tree.getSelectionPaths().length - 1; i >= 0; i--) {
1312 final TreePath path = tree.getSelectionPaths()[i];
1313 if (path.getLastPathComponent() instanceof AbstractTreeNode) {
1314 final AbstractTreeNode node = (AbstractTreeNode) path.getLastPathComponent();
1315
1316 if (node instanceof ArtistNode) {
1317 final int nodeCount = node.getChildCount();
1318 if (nodeCount > 0) {
1319 for (int ii = 0; ii < node.getChildCount(); ii++) {
1320 final AbstractTreeNode childNode = (AbstractTreeNode) node.getChildAt(ii);
1321 playlist.addNext(childNode.getModel());
1322 }
1323 }
1324 } else {
1325 playlist.addNext(node.getModel());
1326 }
1327 }
1328 }
1329 }
1330
1331 if (editor instanceof JList) {
1332 final JList list = (JList) editor;
1333 final Object[] selections = list.getSelectedValues();
1334 for (int i = selections.length - 1; i >= 0; i--) {
1335 final JukesValidationMessage message = (JukesValidationMessage) selections[i];
1336 playlist.addNext(message.getDomainObject());
1337 }
1338 }
1339
1340 if (editor instanceof JTable) {
1341 final JTable table = (JTable) editor;
1342 final int[] selections = table.getSelectedRows();
1343 if (table.getModel() instanceof DiscTableModel) {
1344
1345
1346
1347 final DiscTableModel model = (DiscTableModel) table.getModel();
1348 for (int i = 0; i < selections.length; i++) {
1349 int selectedRow = selections[i];
1350 selectedRow = table.getRowSorter().convertRowIndexToModel(selectedRow);
1351 playlist.addNext(model.getData()[selectedRow]);
1352 }
1353 } else {
1354 final SearchTableModel model = (SearchTableModel) table.getModel();
1355 for (int i = 0; i < selections.length; i++) {
1356 int selectedRow = selections[i];
1357 selectedRow = table.getRowSorter().convertRowIndexToModel(selectedRow);
1358 playlist.addNext(model.getData()[selectedRow]);
1359 }
1360 }
1361 }
1362
1363 if (editor instanceof AlbumImage) {
1364 final AlbumImage image = (AlbumImage) editor;
1365 if (image.getDisc() != null) {
1366 playlist.addNext(image.getDisc());
1367 }
1368 }
1369
1370 getMainFrame().getMainPageBuilder().refreshUI();
1371 }
1372 }
1373
1374
1375
1376
1377
1378
1379 public void refresh(final ActionEvent aEvent) {
1380 LOG.debug("Refreshing Data.");
1381 GuiUtil.setBusyCursor(getDefaultParentFrame(), true);
1382
1383
1384
1385
1386 getMainModule().refreshTree();
1387 GuiUtil.setBusyCursor(getDefaultParentFrame(), false);
1388 }
1389
1390
1391
1392
1393
1394
1395 public void rollback(final ActionEvent aEvent) {
1396 LOG.debug("Rollback Changes");
1397 final JComponent button = (JComponent) aEvent.getSource();
1398 final AbstractEditor editor = (AbstractEditor) button.getClientProperty(Resources.EDITOR_COMPONENT);
1399 editor.rollback();
1400 }
1401
1402
1403
1404
1405
1406
1407 public void search(final ActionEvent aEvent) {
1408 LOG.debug("Search");
1409 final SearchDialog dialog = new SearchDialog(getDefaultParentFrame(), MainModule.SETTINGS);
1410 dialog.open();
1411
1412 if (!dialog.hasBeenCanceled()) {
1413 try {
1414 GuiUtil.setBusyCursor(getDefaultParentFrame(), true);
1415 getMainModule().selectNodeInTree(dialog.getSelection());
1416 } finally {
1417 GuiUtil.setBusyCursor(getDefaultParentFrame(), false);
1418 }
1419 }
1420
1421 }
1422
1423
1424
1425
1426 public void showMainWindow() {
1427 if (SystemUtils.IS_OS_WINDOWS) {
1428 final MainFrame mainframe = (MainFrame) getDefaultParentFrame();
1429 mainframe.getTrayIcon().showWindow();
1430 }
1431 }
1432
1433
1434
1435
1436
1437
1438 public void statistics(final ActionEvent aEvent) {
1439 LOG.debug("Statistics Dialog");
1440 final MainFrame mainframe = (MainFrame) getDefaultParentFrame();
1441
1442 GuiUtil.setBusyCursor(mainframe, true);
1443 new StatisticsDialog(getDefaultParentFrame()).open();
1444 GuiUtil.setBusyCursor(mainframe, false);
1445 }
1446
1447
1448
1449
1450
1451
1452 public void titleCase(final ActionEvent aEvent) {
1453 final JComponent button = (JComponent) aEvent.getSource();
1454 final JTextComponent text = (JTextComponent) button.getClientProperty(Resources.TEXT_COMPONENT);
1455 if (LOG.isDebugEnabled()) {
1456 LOG.debug("Capitalizing '" + text.getText() + "'");
1457 }
1458 text.setText(FileUtil.capitalize(text.getText()));
1459 }
1460
1461
1462
1463
1464
1465
1466 public void unlock(final ActionEvent aEvent) {
1467 LOG.debug("Unlock item for editing");
1468 final JComponent button = (JComponent) aEvent.getSource();
1469 final AbstractEditor editor = (AbstractEditor) button.getClientProperty(Resources.EDITOR_COMPONENT);
1470 editor.unlock();
1471 }
1472
1473
1474
1475
1476
1477
1478 public void reportNoCoverArt(ActionEvent aEvent) {
1479 LOG.debug("Report: Albums Without Cover Artwork");
1480 runReport("/reports/nocoverart.jasper", new HashMap());
1481 }
1482
1483
1484
1485
1486
1487
1488 public void reportCatalog(ActionEvent aEvent) {
1489 LOG.debug("Report: Catalog");
1490 runReport("/reports/catalog.jasper", new HashMap());
1491 }
1492
1493
1494
1495
1496
1497
1498 public void reportAlbumsForArtist(ActionEvent aEvent) {
1499 LOG.debug("Report: Albums for Artist");
1500
1501 final HashMap<String, String> map = new HashMap<String, String>();
1502
1503 GuiUtil.setBusyCursor(getDefaultParentFrame(), true);
1504 final String hql = ResourceUtils.getString("hql.artist.all.sorted");
1505 final List artistsList = HibernateDao.findByQuery(hql);
1506 final List artistNames = new ArrayList();
1507 Artist artist;
1508 String artistName;
1509 final Object[] artists;
1510 for (int i = 0; i < artistsList.size(); i++) {
1511 artist = (Artist) artistsList.get(i);
1512 artistName = artist.getName();
1513 if (artistName.length() > 40) {
1514 artistName = artistName.substring(0, 40);
1515 }
1516 artistNames.add(artistName);
1517 }
1518 artists = artistNames.toArray();
1519 JComboBox artistField = new JComboBox(artists);
1520 JPanel panel = new JPanel();
1521 panel.add(new JLabel(Resources.getString("label.SelectArtistName")));
1522 panel.add(artistField);
1523 Integer response = JOptionPane.showConfirmDialog(null, panel, Resources.getString("label.AlbumsforArtistReport"),
1524 JOptionPane.OK_CANCEL_OPTION);
1525 final String selectedArtistName = artistField.getSelectedItem().toString();
1526 GuiUtil.setBusyCursor(getDefaultParentFrame(), false);
1527 if (response == 0) {
1528 if (StringUtils.isNotEmpty(selectedArtistName)) {
1529 map.put("selectedartist", selectedArtistName);
1530 runReport("/reports/albumsforartist.jasper", map);
1531 }
1532 }
1533 }
1534
1535
1536
1537
1538
1539
1540
1541 public void reportCatalogByGenres(ActionEvent aEvent) {
1542 LOG.debug("Report: Catalog By Genres");
1543 runReport("/reports/catalogbygenres.jasper", new HashMap());
1544 }
1545
1546
1547
1548
1549
1550
1551 public void reportBitrate(ActionEvent aEvent) {
1552 LOG.debug("Report: Bitrate");
1553 final HashMap<String, Integer> map = new HashMap<String, Integer>();
1554 JComboBox bitrateFromField = new JComboBox(Resources.BITRATES);
1555 JComboBox bitrateToField = new JComboBox(Resources.BITRATES);
1556
1557 JPanel panel = new JPanel();
1558 panel.add(new JLabel(Resources.getString("label.bitrateFrom")));
1559 panel.add(bitrateFromField);
1560 panel.add(new JLabel(Resources.getString("label.bitrateTo")));
1561 panel.add(bitrateToField);
1562 GridLayout grid = new GridLayout();
1563 grid.setVgap(10);
1564 grid.setColumns(2);
1565 grid.setRows(2);
1566 panel.setLayout(grid);
1567
1568 Integer response = JOptionPane.showConfirmDialog(null, panel, Resources.getString("label.BitrateReport"),
1569 JOptionPane.OK_CANCEL_OPTION);
1570 if (response == 0) {
1571 int bitrateFrom = Integer.parseInt(bitrateFromField.getSelectedItem().toString());
1572 int bitrateTo = Integer.parseInt(bitrateToField.getSelectedItem().toString());
1573 if (bitrateFrom > bitrateTo) {
1574 MessageUtil.showError(null, Resources.getString("messages.BitrateError"));
1575 } else {
1576 map.put("bitratefrom", bitrateFrom);
1577 map.put("bitrateto", bitrateTo);
1578 runReport("/reports/bitrate.jasper", map);
1579 }
1580 }
1581 }
1582
1583
1584
1585
1586
1587
1588 public void reportGenres(ActionEvent aEvent) {
1589 LOG.debug("Report: Genres");
1590 final HashMap<String, Integer> map = new HashMap<String, Integer>();
1591 runReport("/reports/genres.jasper", map);
1592 }
1593
1594
1595
1596
1597
1598
1599
1600 void aboutToExitApplication() {
1601 ((MainFrame) getDefaultParentFrame()).aboutToExitApplication();
1602 }
1603
1604
1605
1606
1607 void helpAbout() {
1608 new DefaultAboutDialog(getDefaultParentFrame()).open();
1609 }
1610
1611
1612
1613
1614 void openTipOfTheDayDialog() {
1615 final String tipIndexPath = Application.getConfiguration().getTipIndexPath();
1616 new TipOfTheDayDialog(getDefaultParentFrame(), tipIndexPath).open();
1617 }
1618
1619
1620
1621
1622 void preferences() {
1623 new PreferencesDialog(getDefaultParentFrame(), MainModule.SETTINGS).open();
1624 }
1625
1626
1627
1628
1629
1630
1631 private Frame getDefaultParentFrame() {
1632 return Application.getDefaultParentFrame();
1633 }
1634
1635
1636
1637
1638
1639
1640 private MainFrame getMainFrame() {
1641 return (MainFrame) getDefaultParentFrame();
1642 }
1643
1644
1645
1646
1647
1648
1649 private MainModule getMainModule() {
1650 return mainModule;
1651 }
1652
1653
1654
1655
1656
1657
1658
1659 @SuppressWarnings("deprecation")
1660 private void runReport(String aReport, HashMap aParameters) {
1661 try {
1662 GuiUtil.setBusyCursor(getDefaultParentFrame(), true);
1663 final JasperPrint print = JasperFillManager.fillReport(MainController.class.getResourceAsStream(aReport),
1664 aParameters, HibernateUtil.getSession().connection());
1665 GuiUtil.setBusyCursor(getDefaultParentFrame(), false);
1666 JasperViewer.viewReport(print, false);
1667 } catch (HibernateException ex) {
1668 LOG.error("HibernateException", ex);
1669 } catch (InfrastructureException ex) {
1670 LOG.error("InfrastructureException", ex);
1671 } catch (JRException ex) {
1672 LOG.error("JRException", ex);
1673 }
1674 }
1675
1676
1677
1678
1679
1680
1681 public void disclistClose(final ActionEvent aEvent) {
1682 LOG.debug("Close Disclist.");
1683 getMainFrame().getMainPageBuilder().setDisclistVisible(false);
1684 }
1685
1686
1687
1688
1689
1690
1691 public void disclistGoto(final ActionEvent aEvent) {
1692 LOG.debug("Disclist goto.");
1693 final Disc selection;
1694 final JComponent button = (JComponent) aEvent.getSource();
1695 final JList editor = (JList) button.getClientProperty(Resources.EDITOR_COMPONENT);
1696 try {
1697 GuiUtil.setBusyCursor(getDefaultParentFrame(), true);
1698 if (editor.getSelectedValue() != null) {
1699
1700 selection = (Disc) editor.getSelectedValue();
1701 String query = " and upper(disc.name) = '" + selection.getName().toUpperCase().replaceAll("'", "''") + "'";
1702 String filter = MainModule.SETTINGS.getFilter();
1703 if (!(MainModule.SETTINGS.isShowDefaultTree() && !StringUtils.isNotBlank(filter))) {
1704 filter = query;
1705 }
1706 MainModule.SETTINGS.setFilter(filter);
1707 getMainModule().refreshTree();
1708 getMainModule().selectNodeInTree(editor.getSelectedValue());
1709 } else {
1710 MessageUtil.showInformation(Application.getDefaultParentFrame(), ResourceUtils
1711 .getString("messages.SelectSomethingToGoTo"));
1712 }
1713 } finally {
1714 GuiUtil.setBusyCursor(getDefaultParentFrame(), false);
1715 }
1716 }
1717
1718
1719
1720
1721
1722
1723 public void disclistLoad(final ActionEvent aEvent) {
1724 LOG.debug("Load Disclist");
1725 final JComponent button = (JComponent) aEvent.getSource();
1726 final DisclistPanel editor = (DisclistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1727 editor.load();
1728 }
1729
1730
1731
1732
1733
1734
1735 public void disclistMoveDown(final ActionEvent aEvent) {
1736 LOG.debug("Move down disclist");
1737 final JComponent button = (JComponent) aEvent.getSource();
1738 final DisclistPanel editor = (DisclistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1739 editor.moveDown();
1740 }
1741
1742
1743
1744
1745
1746
1747 public void disclistMoveUp(final ActionEvent aEvent) {
1748 LOG.debug("Move up disclist");
1749 final JComponent button = (JComponent) aEvent.getSource();
1750 final DisclistPanel editor = (DisclistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1751 editor.moveUp();
1752 }
1753
1754
1755
1756
1757
1758
1759 public void disclistRemoveTracks(final ActionEvent aEvent) {
1760 LOG.debug("Remove discs from disclist");
1761 final JComponent button = (JComponent) aEvent.getSource();
1762 final DisclistPanel editor = (DisclistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1763 editor.removeDisc();
1764 editor.repaint();
1765
1766 }
1767
1768
1769
1770
1771
1772
1773 public void disclistClear(ActionEvent aEvent) {
1774 LOG.debug("Clear discs from disclist");
1775 final JComponent button = (JComponent) aEvent.getSource();
1776 final DisclistPanel editor = (DisclistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1777 editor.removeAllDiscs();
1778 editor.repaint();
1779 }
1780
1781
1782
1783
1784
1785
1786 public void disclistSave(final ActionEvent aEvent) {
1787 LOG.debug("Save disclist.");
1788 final JComponent button = (JComponent) aEvent.getSource();
1789 final DisclistPanel editor = (DisclistPanel) button.getClientProperty(Resources.EDITOR_COMPONENT);
1790 editor.save();
1791 }
1792
1793
1794
1795
1796
1797
1798 public void disclistDisplay(final ActionEvent aEvent) {
1799 LOG.debug("Disclist displayed/hidden.");
1800 String currentPanel = getMainFrame().getMainPageBuilder().panelVisible();
1801 boolean visible;
1802 if (currentPanel == "disclistPanel") {
1803 visible = false;
1804 } else {
1805 visible = true;
1806 }
1807 getMainFrame().getMainPageBuilder().setDisclistVisible(visible);
1808
1809 }
1810
1811
1812
1813
1814
1815
1816 public void addToDisclist(final ActionEvent aEvent) {
1817 LOG.debug("Add to disclist");
1818 final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
1819 final JComponent source = (JComponent) aEvent.getSource();
1820 final Component editor = (Component) source.getClientProperty(Resources.EDITOR_COMPONENT);
1821 if (editor != null) {
1822
1823 final Disclist disclist = getMainFrame().getDisclist();
1824 if (editor instanceof JTree) {
1825 final JTree tree = (JTree) editor;
1826 for (int i = 0; i < tree.getSelectionPaths().length; i++) {
1827 final TreePath path = tree.getSelectionPaths()[i];
1828 if (path.getLastPathComponent() instanceof AbstractTreeNode) {
1829 final AbstractTreeNode node = (AbstractTreeNode) path.getLastPathComponent();
1830
1831 if (node instanceof ArtistNode) {
1832 final int nodeCount = node.getChildCount();
1833 if (nodeCount > 0) {
1834 for (int ii = 0; ii < node.getChildCount(); ii++) {
1835 final AbstractTreeNode childNode = (AbstractTreeNode) node.getChildAt(ii);
1836 disclist.add(childNode.getModel());
1837 }
1838 }
1839 } else {
1840 disclist.add(node.getModel());
1841 }
1842 }
1843 }
1844 }
1845
1846 if (editor instanceof JList) {
1847 final JList list = (JList) editor;
1848 final Object[] selections = list.getSelectedValues();
1849 for (int i = 0; i < selections.length; i++) {
1850 final JukesValidationMessage message = (JukesValidationMessage) selections[i];
1851 disclist.add(message.getDomainObject());
1852 }
1853 }
1854 if (editor instanceof JTable) {
1855 final JTable table = (JTable) editor;
1856 final int[] selections = table.getSelectedRows();
1857 if (selections.length == 0) {
1858 MessageUtil.showMessage(mainFrame, Resources.getString("messages.SelectDisc"));
1859 ;
1860 }
1861 if (table.getModel() instanceof DiscTableModel) {
1862
1863
1864
1865 final DiscTableModel model = (DiscTableModel) table.getModel();
1866 for (int i = 0; i < selections.length; i++) {
1867 int selectedRow = selections[i];
1868 selectedRow = table.getRowSorter().convertRowIndexToModel(selectedRow);
1869 disclist.add(model.getData()[selectedRow]);
1870 }
1871 } else {
1872 final SearchTableModel model = (SearchTableModel) table.getModel();
1873 for (int i = 0; i < selections.length; i++) {
1874 int selectedRow = selections[i];
1875 selectedRow = table.getRowSorter().convertRowIndexToModel(selectedRow);
1876 disclist.add(model.getData()[selectedRow]);
1877 }
1878 }
1879 }
1880 if (editor instanceof AlbumImage) {
1881 final AlbumImage image = (AlbumImage) editor;
1882 if (image.getDisc() != null) {
1883 disclist.add(image.getDisc());
1884 }
1885 }
1886 getMainFrame().getMainPageBuilder().refreshUI();
1887 }
1888 }
1889
1890
1891
1892
1893
1894
1895 public void setCurrent(final ActionEvent aEvent) {
1896 LOG.debug("Set disc as current");
1897 final Disclist disclist = getMainFrame().getDisclist();
1898 Disc currentDisc = disclist.getCurrentDisc();
1899 final JComponent source = (JComponent) aEvent.getSource();
1900 final Component editor = (Component) source.getClientProperty(Resources.EDITOR_COMPONENT);
1901 if (editor instanceof JList) {
1902 final JList list = (JList) editor;
1903 final Object[] selections = list.getSelectedValues();
1904 if (selections.length != 0) {
1905 currentDisc = (Disc) selections[0];
1906 disclist.setCurrentDisc(currentDisc);
1907 disclist.updateState();
1908 }
1909 }
1910 }
1911
1912
1913
1914
1915
1916
1917 public void xmlExport(final ActionEvent aEvent) {
1918 LOG.debug("XML Export Dialog");
1919
1920 final JFileChooser chooser = new JFileChooser();
1921 chooser.setDialogTitle(Resources.getString("label.ExportCatalog"));
1922 chooser.setFileFilter(FilterFactory.xmlFileFilter());
1923 chooser.setMultiSelectionEnabled(false);
1924 chooser.setFileHidingEnabled(true);
1925 final int returnVal = chooser.showSaveDialog(this.getDefaultParentFrame());
1926 if (returnVal != JFileChooser.APPROVE_OPTION) {
1927 return;
1928 }
1929 File file = chooser.getSelectedFile();
1930
1931 file = FilterFactory.forceXmlExtension(file);
1932
1933
1934 new XMLExportDialog(getDefaultParentFrame(), MainModule.SETTINGS, file).open();
1935 }
1936
1937
1938
1939
1940
1941
1942 public void xmlImport(final ActionEvent aEvent) {
1943 LOG.debug("XML Import Dialog");
1944
1945 final JFileChooser chooser = new JFileChooser();
1946 chooser.setDialogTitle(Resources.getString("label.ImportCatalog"));
1947 chooser.setFileFilter(FilterFactory.xmlFileFilter());
1948 chooser.setMultiSelectionEnabled(false);
1949 chooser.setFileHidingEnabled(true);
1950 final int returnVal = chooser.showOpenDialog(this.getDefaultParentFrame());
1951 if (returnVal != JFileChooser.APPROVE_OPTION) {
1952 return;
1953 }
1954 File file = chooser.getSelectedFile();
1955
1956 file = FilterFactory.forceXmlExtension(file);
1957
1958
1959 new XMLImportDialog(getDefaultParentFrame(), MainModule.SETTINGS, file).open();
1960 }
1961
1962 }