/* * Jajuk * Copyright (C) The Jajuk Team * http://jajuk.info * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.jajuk.ui.widgets; import static org.jajuk.ui.actions.JajukActions.CONFIGURE_AMBIENCES; import static org.jajuk.ui.actions.JajukActions.CONFIGURE_DJS; import static org.jajuk.ui.actions.JajukActions.CONTINUE_MODE; import static org.jajuk.ui.actions.JajukActions.CUSTOM_PROPERTIES_ADD; import static org.jajuk.ui.actions.JajukActions.CUSTOM_PROPERTIES_REMOVE; import static org.jajuk.ui.actions.JajukActions.EXTRA_TAGS_WIZARD; import static org.jajuk.ui.actions.JajukActions.HELP_REQUIRED; import static org.jajuk.ui.actions.JajukActions.INTRO_MODE; import static org.jajuk.ui.actions.JajukActions.OPTIONS; import static org.jajuk.ui.actions.JajukActions.QUALITY; import static org.jajuk.ui.actions.JajukActions.REPEAT_ALL_MODE; import static org.jajuk.ui.actions.JajukActions.REPEAT_MODE; import static org.jajuk.ui.actions.JajukActions.SHOW_ABOUT; import static org.jajuk.ui.actions.JajukActions.SHOW_DONATE; import static org.jajuk.ui.actions.JajukActions.SHOW_TRACES; import static org.jajuk.ui.actions.JajukActions.SHUFFLE_MODE; import static org.jajuk.ui.actions.JajukActions.SIMPLE_DEVICE_WIZARD; import static org.jajuk.ui.actions.JajukActions.TIP_OF_THE_DAY; import static org.jajuk.ui.actions.JajukActions.VIEW_RESTORE_DEFAULTS; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashSet; import java.util.Set; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.apache.commons.lang.StringUtils; import org.jajuk.events.JajukEvent; import org.jajuk.events.JajukEvents; import org.jajuk.events.ObservationManager; import org.jajuk.events.Observer; import org.jajuk.services.core.SessionService; import org.jajuk.ui.actions.ActionManager; import org.jajuk.ui.actions.ActionUtil; import org.jajuk.ui.actions.JajukActions; import org.jajuk.ui.perspectives.PerspectiveAdapter; import org.jajuk.ui.perspectives.PerspectiveManager; import org.jajuk.ui.views.IView; import org.jajuk.ui.views.ViewFactory; import org.jajuk.util.Conf; import org.jajuk.util.Const; import org.jajuk.util.IconLoader; import org.jajuk.util.JajukIcons; import org.jajuk.util.Messages; import org.jajuk.util.UpgradeManager; import org.jajuk.util.UtilSystem; import org.jajuk.util.log.Log; /** * Jajuk menu bar * <p> * Singleton. */ public final class JajukJMenuBar extends JMenuBar implements Observer { /** Generated serialVersionUID. */ private static final long serialVersionUID = 1L; /** The singleton. */ static JajukJMenuBar jjmb = new JajukJMenuBar(); JMenu file; JMenuItem jmiFileExit; JMenu views; JMenuItem jmiRestoreDefaultViews; JMenuItem jmiRestoreDefaultViewsAllPerpsectives; JMenu properties; JMenuItem jmiNewProperty; JMenuItem jmiRemoveProperty; JMenu mode; JCheckBoxMenuItem jcbShowPopups; JCheckBoxMenuItem jcbNoneInternetAccess; private final JCheckBoxMenuItem jcbmiRepeat; private final JCheckBoxMenuItem jcbmiShuffle; private final JCheckBoxMenuItem jcbmiContinue; private final JCheckBoxMenuItem jcbmiIntro; private final JCheckBoxMenuItem jcbmiKaraoke; JMenuBar mainmenu; JMenu smart; JMenuItem jmiShuffle; JMenuItem jmiBestof; JMenuItem jmiNovelties; JMenuItem jmiFinishAlbum; JMenu tools; JMenuItem jmiduplicateFinder; JMenuItem jmialarmClock; JMenuItem jmiprepareParty; JMenu configuration; JMenuItem jmiDJ; JMenuItem jmiAmbience; JMenuItem jmiWizard; JMenuItem jmiOptions; JCheckBoxMenuItem jmiUnmounted; JMenu help; JMenuItem jmiHelp; JMenuItem jmiTipOfTheDay; JMenuItem jmiQualityAgent; JMenuItem jmiTraces; JMenuItem jmiCheckforUpdates; JMenuItem jmiAbout; JLabel jlUpdate; JButton jbGC; JButton jbSlim; private JajukButton jbFull = null; private final JCheckBoxMenuItem jcbmiRepeatAll; /** The jmi activate tags. */ private JMenuItem jmiActivateTags; private JMenuItem jmiDonate; /** * Instantiates a new jajuk j menu bar. */ private JajukJMenuBar() { setAlignmentX(0.0f); // File menu file = new JMenu(Messages.getString("JajukJMenuBar.0")); jmiFileExit = new JMenuItem(ActionManager.getAction(JajukActions.EXIT)); file.add(jmiFileExit); // Properties menu properties = new JMenu(Messages.getString("JajukJMenuBar.5")); jmiNewProperty = new JMenuItem(ActionManager.getAction(CUSTOM_PROPERTIES_ADD)); jmiRemoveProperty = new JMenuItem(ActionManager.getAction(CUSTOM_PROPERTIES_REMOVE)); jmiActivateTags = new JMenuItem(ActionManager.getAction(EXTRA_TAGS_WIZARD)); properties.add(jmiNewProperty); properties.add(jmiRemoveProperty); properties.add(jmiActivateTags); // View menu views = new JMenu(Messages.getString("JajukJMenuBar.8")); jmiRestoreDefaultViews = new JMenuItem(ActionManager.getAction(VIEW_RESTORE_DEFAULTS)); jmiRestoreDefaultViewsAllPerpsectives = new JMenuItem( ActionManager.getAction(JajukActions.ALL_VIEW_RESTORE_DEFAULTS)); views.add(jmiRestoreDefaultViews); views.add(jmiRestoreDefaultViewsAllPerpsectives); views.addSeparator(); // Add the list of available views parsed in XML files at startup JMenu jmViews = new JMenu(Messages.getString("JajukJMenuBar.25")); for (final Class<? extends IView> view : ViewFactory.getKnownViews()) { JMenuItem jmi = null; try { jmi = new JMenuItem(view.newInstance().getDesc(), IconLoader.getIcon(JajukIcons.LOGO_FRAME)); } catch (Exception e1) { Log.error(e1); continue; } jmi.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // Simply add the new view in the current perspective PerspectiveAdapter current = (PerspectiveAdapter) PerspectiveManager .getCurrentPerspective(); IView newView = ViewFactory.createView(view, current, Math.abs(UtilSystem.getRandom().nextInt())); newView.initUI(); newView.setPopulated(); current.addDockable(newView); } }); jmViews.add(jmi); } views.add(jmViews); // Mode menu String modeText = Messages.getString("JajukJMenuBar.9"); mode = new JMenu(ActionUtil.strip(modeText)); jcbmiRepeat = new JCheckBoxMenuItem(ActionManager.getAction(REPEAT_MODE)); jcbmiRepeat.setSelected(Conf.getBoolean(Const.CONF_STATE_REPEAT)); jcbmiRepeatAll = new JCheckBoxMenuItem(ActionManager.getAction(REPEAT_ALL_MODE)); jcbmiRepeatAll.setSelected(Conf.getBoolean(Const.CONF_STATE_REPEAT_ALL)); jcbmiShuffle = new JCheckBoxMenuItem(ActionManager.getAction(SHUFFLE_MODE)); jcbmiShuffle.setSelected(Conf.getBoolean(Const.CONF_STATE_SHUFFLE)); jcbmiContinue = new JCheckBoxMenuItem(ActionManager.getAction(CONTINUE_MODE)); jcbmiContinue.setSelected(Conf.getBoolean(Const.CONF_STATE_CONTINUE)); jcbmiIntro = new JCheckBoxMenuItem(ActionManager.getAction(INTRO_MODE)); jcbmiIntro.setSelected(Conf.getBoolean(Const.CONF_STATE_INTRO)); jcbmiKaraoke = new JCheckBoxMenuItem(ActionManager.getAction(JajukActions.KARAOKE_MODE)); if (Conf.getBoolean(Const.CONF_BIT_PERFECT)) { jcbmiKaraoke.setEnabled(false); jcbmiKaraoke.setSelected(false); Conf.setProperty(Const.CONF_STATE_KARAOKE, Const.FALSE); } else { jcbmiKaraoke.setSelected(Conf.getBoolean(Const.CONF_STATE_KARAOKE)); } mode.add(jcbmiRepeat); mode.add(jcbmiRepeatAll); mode.add(jcbmiShuffle); mode.add(jcbmiContinue); mode.add(jcbmiIntro); mode.add(jcbmiKaraoke); // Smart Menu smart = new JMenu(Messages.getString("JajukJMenuBar.29")); jmiShuffle = new SizedJMenuItem(ActionManager.getAction(JajukActions.SHUFFLE_GLOBAL)); jmiBestof = new SizedJMenuItem(ActionManager.getAction(JajukActions.BEST_OF)); jmiNovelties = new SizedJMenuItem(ActionManager.getAction(JajukActions.NOVELTIES)); jmiFinishAlbum = new SizedJMenuItem(ActionManager.getAction(JajukActions.FINISH_ALBUM)); smart.add(jmiShuffle); smart.add(jmiBestof); smart.add(jmiNovelties); smart.add(jmiFinishAlbum); // Tools Menu tools = new JMenu(Messages.getString("JajukJMenuBar.28")); jmiduplicateFinder = new JMenuItem(ActionManager.getAction(JajukActions.FIND_DUPLICATE_FILES)); jmialarmClock = new JMenuItem(ActionManager.getAction(JajukActions.ALARM_CLOCK)); jmiprepareParty = new JMenuItem(ActionManager.getAction(JajukActions.PREPARE_PARTY)); tools.add(jmiduplicateFinder); tools.add(jmialarmClock); tools.add(jmiprepareParty); // tools.addSeparator(); // Configuration menu configuration = new JMenu(Messages.getString("JajukJMenuBar.21")); jmiDJ = new JMenuItem(ActionManager.getAction(CONFIGURE_DJS)); // Overwrite default icon jmiDJ.setIcon(IconLoader.getIcon(JajukIcons.DIGITAL_DJ_16X16)); jmiAmbience = new JMenuItem(ActionManager.getAction(CONFIGURE_AMBIENCES)); jmiWizard = new JMenuItem(ActionManager.getAction(SIMPLE_DEVICE_WIZARD)); jmiOptions = new JMenuItem(ActionManager.getAction(OPTIONS)); jmiUnmounted = new JCheckBoxMenuItem(ActionManager.getAction(JajukActions.UNMOUNTED)); jmiUnmounted.setSelected(Conf.getBoolean(Const.CONF_OPTIONS_HIDE_UNMOUNTED)); jmiUnmounted.putClientProperty(Const.DETAIL_ORIGIN, jmiUnmounted); jcbShowPopups = new JCheckBoxMenuItem(Messages.getString("ParameterView.228")); jcbShowPopups.setSelected(Conf.getBoolean(Const.CONF_SHOW_POPUPS)); jcbShowPopups.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Conf.setProperty(Const.CONF_SHOW_POPUPS, Boolean.toString(jcbShowPopups.isSelected())); // force parameter view to take this into account ObservationManager.notify(new JajukEvent(JajukEvents.PARAMETERS_CHANGE)); } }); jcbNoneInternetAccess = new JCheckBoxMenuItem(Messages.getString("ParameterView.264")); jcbNoneInternetAccess.setToolTipText(Messages.getString("ParameterView.265")); jcbNoneInternetAccess.setSelected(Conf.getBoolean(Const.CONF_NETWORK_NONE_INTERNET_ACCESS)); jcbNoneInternetAccess.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Conf.setProperty(Const.CONF_NETWORK_NONE_INTERNET_ACCESS, Boolean.toString(jcbNoneInternetAccess.isSelected())); // force parameter view to take this into account ObservationManager.notify(new JajukEvent(JajukEvents.PARAMETERS_CHANGE)); } }); configuration.add(jmiUnmounted); configuration.add(jcbShowPopups); configuration.add(jcbNoneInternetAccess); configuration.addSeparator(); configuration.add(jmiDJ); configuration.add(jmiAmbience); configuration.add(jmiWizard); configuration.add(jmiOptions); // Help menu String helpText = Messages.getString("JajukJMenuBar.14"); help = new JMenu(ActionUtil.strip(helpText)); jmiHelp = new JMenuItem(ActionManager.getAction(HELP_REQUIRED)); jmiDonate = new JMenuItem(ActionManager.getAction(SHOW_DONATE)); jmiAbout = new JMenuItem(ActionManager.getAction(SHOW_ABOUT)); jmiTraces = new JMenuItem(ActionManager.getAction(SHOW_TRACES)); jmiTraces = new JMenuItem(ActionManager.getAction(SHOW_TRACES)); jmiCheckforUpdates = new JMenuItem(ActionManager.getAction(JajukActions.CHECK_FOR_UPDATES)); jmiTipOfTheDay = new JMenuItem(ActionManager.getAction(TIP_OF_THE_DAY)); help.add(jmiHelp); help.add(jmiTipOfTheDay); // Install this action only if Desktop class is supported, it is used to // open default mail client if (UtilSystem.isBrowserSupported()) { jmiQualityAgent = new JMenuItem(ActionManager.getAction(QUALITY)); help.add(jmiQualityAgent); } help.add(jmiTraces); help.add(jmiCheckforUpdates); help.add(jmiDonate); help.add(jmiAbout); mainmenu = new JMenuBar(); mainmenu.add(file); mainmenu.add(views); mainmenu.add(properties); mainmenu.add(mode); mainmenu.add(smart); mainmenu.add(tools); mainmenu.add(configuration); mainmenu.add(help); // Apply mnemonics (Alt + first char of the menu keystroke) applyMnemonics(); if (SessionService.isTestMode()) { jbGC = new JajukButton(ActionManager.getAction(JajukActions.GC)); } jbSlim = new JajukButton(ActionManager.getAction(JajukActions.SLIM_JAJUK)); jbFull = new JajukButton(ActionManager.getAction(JajukActions.FULLSCREEN_JAJUK)); JMenuBar eastmenu = new JMenuBar(); // only show GC-button in test-mode if (SessionService.isTestMode()) { eastmenu.add(jbGC); } eastmenu.add(jbSlim); eastmenu.add(jbFull); setLayout(new BorderLayout()); add(mainmenu, BorderLayout.WEST); add(eastmenu, BorderLayout.EAST); // Check for new release and display the icon if a new release is available SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() { @Override public Void doInBackground() { UpgradeManager.checkForUpdate(); return null; } @Override public void done() { // add the new release label if required if (UpgradeManager.getNewVersionName() != null) { jlUpdate = new JLabel(" ", IconLoader.getIcon(JajukIcons.UPDATE_MANAGER), SwingConstants.RIGHT); String newRelease = UpgradeManager.getNewVersionName(); if (newRelease != null) { jlUpdate.setToolTipText(Messages.getString("UpdateManager.0") + newRelease + Messages.getString("UpdateManager.1")); } add(Box.createHorizontalGlue()); add(jlUpdate); } } }; // Search online for upgrade if the option is set and if the none Internet // access option is not set if (Conf.getBoolean(Const.CONF_CHECK_FOR_UPDATE) && !Conf.getBoolean(Const.CONF_NETWORK_NONE_INTERNET_ACCESS)) { sw.execute(); } ObservationManager.register(this); } /** * Gets the single instance of JajukJMenuBar. * * @return single instance of JajukJMenuBar */ public static JajukJMenuBar getInstance() { return jjmb; } /* * (non-Javadoc) * * @see org.jajuk.events.Observer#getRegistrationKeys() */ @Override public Set<JajukEvents> getRegistrationKeys() { Set<JajukEvents> eventSubjectSet = new HashSet<JajukEvents>(); eventSubjectSet.add(JajukEvents.PARAMETERS_CHANGE); eventSubjectSet.add(JajukEvents.SLIMBAR_VISIBILTY_CHANGED); eventSubjectSet.add(JajukEvents.MODE_STATUS_CHANGED); return eventSubjectSet; } /** * Apply all mnemonics for all menus (follow i18n). */ private void applyMnemonics() { for (int i = 0; i < mainmenu.getMenuCount(); i++) { JMenu menu = mainmenu.getMenu(i); if (menu != null && StringUtils.isNotBlank(menu.getText())) { String label = menu.getText(); int mnemonic = label.getBytes()[0]; menu.setMnemonic(mnemonic); } } } /* * (non-Javadoc) * * @see org.jajuk.ui.Observer#update(java.lang.String) */ @Override public void update(final JajukEvent event) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (JajukEvents.PARAMETERS_CHANGE.equals(event.getSubject()) || JajukEvents.SLIMBAR_VISIBILTY_CHANGED.equals(event.getSubject())) { jcbShowPopups.setSelected(Conf.getBoolean(Const.CONF_SHOW_POPUPS)); jmiUnmounted.setSelected(Conf.getBoolean(Const.CONF_OPTIONS_HIDE_UNMOUNTED)); jcbNoneInternetAccess.setSelected(Conf .getBoolean(Const.CONF_NETWORK_NONE_INTERNET_ACCESS)); // No karaoke mode and bit-perfect options are mutually exclusive if (Conf.getBoolean(Const.CONF_BIT_PERFECT)) { jcbmiKaraoke.setSelected(false); jcbmiKaraoke.setEnabled(false); Conf.setProperty(Const.CONF_STATE_KARAOKE, Const.FALSE); } else { jcbmiKaraoke.setEnabled(true); } } else if (JajukEvents.MODE_STATUS_CHANGED.equals(event.getSubject())) { updateModesGUIStatus(); } } }); } /** * Update mode buttons after a mode change */ private void updateModesGUIStatus() { this.jcbmiRepeat.setSelected(Conf.getBoolean(Const.CONF_STATE_REPEAT)); this.jcbmiRepeatAll.setSelected(Conf.getBoolean(Const.CONF_STATE_REPEAT_ALL)); this.jcbmiContinue.setSelected(Conf.getBoolean(Const.CONF_STATE_CONTINUE)); this.jcbmiShuffle.setSelected(Conf.getBoolean(Const.CONF_STATE_SHUFFLE)); this.jcbmiKaraoke.setSelected(Conf.getBoolean(Const.CONF_STATE_KARAOKE)); this.jcbmiIntro.setSelected(Conf.getBoolean(Const.CONF_STATE_INTRO)); } }