/*FreeMind - A Program for creating and viewing Mindmaps *Copyright (C) 2000-2001 Joerg Mueller <joergmueller@bigfoot.com> *See COPYING for Details * *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 (at your option) 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. */ /*$Id: MenuBar.java,v 1.24.14.17.2.22 2008/11/12 21:44:33 christianfoltin Exp $*/ package freemind.controller; import java.awt.Color; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import javax.swing.Action; import javax.swing.ButtonGroup; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JRadioButtonMenuItem; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import freemind.main.FreeMind; import freemind.modes.ModeController; import freemind.view.MapModule; /** * This is the menu bar for FreeMind. Actions are defined in MenuListener. * Moreover, the StructuredMenuHolder of all menus are hold here. * */ public class MenuBar extends JMenuBar { private static java.util.logging.Logger logger; public static final String MENU_BAR_PREFIX = "menu_bar/"; public static final String GENERAL_POPUP_PREFIX = "popup/"; public static final String POPUP_MENU = GENERAL_POPUP_PREFIX + "popup/"; public static final String INSERT_MENU = MENU_BAR_PREFIX + "insert/"; public static final String NAVIGATE_MENU = MENU_BAR_PREFIX + "navigate/"; public static final String VIEW_MENU = MENU_BAR_PREFIX + "view/"; public static final String HELP_MENU = MENU_BAR_PREFIX + "help/"; public static final String MINDMAP_MENU = MENU_BAR_PREFIX + "mindmaps/"; private static final String MENU_MINDMAP_CATEGORY = MINDMAP_MENU + "mindmaps"; public static final String MODES_MENU = MINDMAP_MENU; // public static final String MODES_MENU = MENU_BAR_PREFIX+"modes/"; public static final String EDIT_MENU = MENU_BAR_PREFIX + "edit/"; public static final String FILE_MENU = MENU_BAR_PREFIX + "file/"; public static final String FORMAT_MENU = MENU_BAR_PREFIX + "format/"; public static final String EXTRAS_MENU = MENU_BAR_PREFIX + "extras/"; private StructuredMenuHolder menuHolder; JPopupMenu mapsPopupMenu; private JMenu filemenu; private JMenu editmenu; private JMenu mapsmenu; Controller c; ActionListener mapsMenuActionListener = new MapsMenuActionListener(); private JMenu formatmenu; public MenuBar(Controller controller) { this.c = controller; if (logger == null) { logger = controller.getFrame().getLogger(this.getClass().getName()); } // updateMenus(); }// Constructor /** * This is the only public method. It restores all menus. * * @param newModeController */ public void updateMenus(ModeController newModeController) { this.removeAll(); menuHolder = new StructuredMenuHolder(); // filemenu filemenu = menuHolder.addMenu(new JMenu(c.getResourceString("file")), FILE_MENU + "."); // filemenu.setMnemonic(KeyEvent.VK_F); menuHolder.addCategory(FILE_MENU + "open"); menuHolder.addCategory(FILE_MENU + "close"); menuHolder.addSeparator(FILE_MENU); menuHolder.addCategory(FILE_MENU + "export"); menuHolder.addSeparator(FILE_MENU); menuHolder.addCategory(FILE_MENU + "import"); menuHolder.addSeparator(FILE_MENU); menuHolder.addCategory(FILE_MENU + "print"); menuHolder.addSeparator(FILE_MENU); menuHolder.addCategory(FILE_MENU + "last"); menuHolder.addSeparator(FILE_MENU); menuHolder.addCategory(FILE_MENU + "quit"); // editmenu editmenu = menuHolder.addMenu(new JMenu(c.getResourceString("edit")), EDIT_MENU + "."); menuHolder.addCategory(EDIT_MENU + "undo"); menuHolder.addSeparator(EDIT_MENU); menuHolder.addCategory(EDIT_MENU + "select"); menuHolder.addSeparator(EDIT_MENU); menuHolder.addCategory(EDIT_MENU + "paste"); menuHolder.addSeparator(EDIT_MENU); menuHolder.addCategory(EDIT_MENU + "edit"); menuHolder.addSeparator(EDIT_MENU); menuHolder.addCategory(EDIT_MENU + "find"); // view menu menuHolder.addMenu(new JMenu(c.getResourceString("menu_view")), VIEW_MENU + "."); // insert menu menuHolder.addMenu(new JMenu(c.getResourceString("menu_insert")), INSERT_MENU + "."); menuHolder.addCategory(INSERT_MENU + "nodes"); menuHolder.addSeparator(INSERT_MENU); menuHolder.addCategory(INSERT_MENU + "icons"); menuHolder.addSeparator(INSERT_MENU); // format menu formatmenu = menuHolder.addMenu( new JMenu(c.getResourceString("menu_format")), FORMAT_MENU + "."); // navigate menu menuHolder.addMenu(new JMenu(c.getResourceString("menu_navigate")), NAVIGATE_MENU + "."); // extras menu menuHolder.addMenu(new JMenu(c.getResourceString("menu_extras")), EXTRAS_MENU + "."); menuHolder.addCategory(EXTRAS_MENU + "first"); // Mapsmenu mapsmenu = menuHolder.addMenu( new JMenu(c.getResourceString("mindmaps")), MINDMAP_MENU + "."); // mapsmenu.setMnemonic(KeyEvent.VK_M); menuHolder.addCategory(MINDMAP_MENU + "navigate"); menuHolder.addSeparator(MINDMAP_MENU); menuHolder.addCategory(MENU_MINDMAP_CATEGORY); menuHolder.addSeparator(MINDMAP_MENU); // Modesmenu menuHolder.addCategory(MODES_MENU); // maps popup menu mapsPopupMenu = new FreeMindPopupMenu(); mapsPopupMenu.setName(c.getResourceString("mindmaps")); menuHolder.addCategory(POPUP_MENU + "navigate"); // menuHolder.addSeparator(POPUP_MENU); // formerly, the modes menu was an own menu, but to need less place for // the menus, // we integrated it into the maps menu. // JMenu modesmenu = menuHolder.addMenu(new // JMenu(c.getResourceString("modes")), MODES_MENU+"."); menuHolder.addMenu(new JMenu(c.getResourceString("help")), HELP_MENU + "."); menuHolder.addAction(c.documentation, HELP_MENU + "doc/documentation"); menuHolder.addAction(c.freemindUrl, HELP_MENU + "doc/freemind"); menuHolder.addAction(c.faq, HELP_MENU + "doc/faq"); menuHolder.addAction(c.keyDocumentation, HELP_MENU + "doc/keyDocumentation"); menuHolder.addSeparator(HELP_MENU); menuHolder.addCategory(HELP_MENU + "bugs"); menuHolder.addSeparator(HELP_MENU); menuHolder.addAction(c.license, HELP_MENU + "about/license"); menuHolder.addAction(c.about, HELP_MENU + "about/about"); updateFileMenu(); updateViewMenu(); updateEditMenu(); updateModeMenu(); updateMapsMenu(menuHolder, MENU_MINDMAP_CATEGORY + "/"); updateMapsMenu(menuHolder, POPUP_MENU); addAdditionalPopupActions(); // the modes: newModeController.updateMenus(menuHolder); menuHolder.updateMenus(this, MENU_BAR_PREFIX); menuHolder.updateMenus(mapsPopupMenu, GENERAL_POPUP_PREFIX); } private void updateModeMenu() { ButtonGroup group = new ButtonGroup(); ActionListener modesMenuActionListener = new ModesMenuActionListener(); List keys = new LinkedList(c.getModes()); for (ListIterator i = keys.listIterator(); i.hasNext();) { String key = (String) i.next(); JRadioButtonMenuItem item = new JRadioButtonMenuItem( c.getResourceString("mode_" + key)); item.setActionCommand(key); JRadioButtonMenuItem newItem = (JRadioButtonMenuItem) menuHolder .addMenuItem(item, MODES_MENU + key); group.add(newItem); if (c.getMode() != null) { newItem.setSelected(c.getMode().toString().equals(key)); } else { newItem.setSelected(false); } String keystroke = c.getFrame().getAdjustableProperty( "keystroke_mode_" + key); if (keystroke != null) { newItem.setAccelerator(KeyStroke.getKeyStroke(keystroke)); } newItem.addActionListener(modesMenuActionListener); } } private void addAdditionalPopupActions() { menuHolder.addSeparator(POPUP_MENU); JMenuItem newPopupItem; if (c.getFrame().isApplet()) { // We have enabled hiding of menubar only in applets. It it because // when we hide menubar in application, the key accelerators from // menubar do not work. newPopupItem = menuHolder.addAction(c.toggleMenubar, POPUP_MENU + "toggleMenubar"); newPopupItem.setForeground(new Color(100, 80, 80)); } newPopupItem = menuHolder.addAction(c.toggleToolbar, POPUP_MENU + "toggleToolbar"); newPopupItem.setForeground(new Color(100, 80, 80)); newPopupItem = menuHolder.addAction(c.toggleLeftToolbar, POPUP_MENU + "toggleLeftToolbar"); newPopupItem.setForeground(new Color(100, 80, 80)); } private void updateMapsMenu(StructuredMenuHolder holder, String basicKey) { MapModuleManager mapModuleManager = c.getMapModuleManager(); List mapModuleVector = mapModuleManager.getMapModuleVector(); if (mapModuleVector == null) { return; } ButtonGroup group = new ButtonGroup(); for (Iterator iterator = mapModuleVector.iterator(); iterator.hasNext();) { MapModule mapModule = (MapModule) iterator.next(); String displayName = mapModule.getDisplayName(); JRadioButtonMenuItem newItem = new JRadioButtonMenuItem(displayName); newItem.setSelected(false); group.add(newItem); newItem.addActionListener(mapsMenuActionListener); newItem.setMnemonic(displayName.charAt(0)); MapModule currentMapModule = mapModuleManager.getMapModule(); if (currentMapModule != null) { if (mapModule == currentMapModule) { newItem.setSelected(true); } } holder.addMenuItem(newItem, basicKey + displayName); } } private void updateFileMenu() { menuHolder.addAction(c.page, FILE_MENU + "print/pageSetup"); JMenuItem print = menuHolder.addAction(c.print, FILE_MENU + "print/print"); print.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_print"))); JMenuItem printPreview = menuHolder.addAction(c.printPreview, FILE_MENU + "print/printPreview"); printPreview.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_print_preview"))); JMenuItem close = menuHolder.addAction(c.close, FILE_MENU + "close/close"); close.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_close"))); JMenuItem quit = menuHolder.addAction(c.quit, FILE_MENU + "quit/quit"); quit.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_quit"))); updateLastOpenedList(); } private void updateLastOpenedList() { menuHolder.addMenu(new JMenu(c.getResourceString("most_recent_files")), FILE_MENU + "last/."); boolean firstElement = true; LastOpenedList lst = c.getLastOpenedList(); for (ListIterator it = lst.listIterator(); it.hasNext();) { String key = (String) it.next(); JMenuItem item = new JMenuItem(key); if (firstElement) { firstElement = false; item.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty( "keystroke_open_first_in_history"))); } item.addActionListener(new LastOpenedActionListener(key)); menuHolder.addMenuItem(item, FILE_MENU + "last/" + (key.replace('/', '_'))); } } private void updateEditMenu() { JMenuItem moveToRoot = menuHolder.addAction(c.moveToRoot, NAVIGATE_MENU + "nodes/moveToRoot"); moveToRoot.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_moveToRoot"))); JMenuItem previousMap = menuHolder.addAction(c.navigationPreviousMap, MINDMAP_MENU + "navigate/navigationPreviousMap"); previousMap.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty(FreeMind.KEYSTROKE_PREVIOUS_MAP))); JMenuItem nextMap = menuHolder.addAction(c.navigationNextMap, MINDMAP_MENU + "navigate/navigationNextMap"); nextMap.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty(FreeMind.KEYSTROKE_NEXT_MAP))); JMenuItem MoveMapLeft = menuHolder.addAction( c.navigationMoveMapLeftAction, MINDMAP_MENU + "navigate/navigationMoveMapLeft"); MoveMapLeft.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty(FreeMind.KEYSTROKE_MOVE_MAP_LEFT))); JMenuItem MoveMapRight = menuHolder.addAction( c.navigationMoveMapRightAction, MINDMAP_MENU + "navigate/navigationMoveMapRight"); MoveMapRight.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty(FreeMind.KEYSTROKE_MOVE_MAP_RIGHT))); // option menu item moved to mindmap_menus.xml // if (false) { // preferences.add(c.background); // // Background is disabled from preferences, because it has no real // function. // // To complete the function, one would either make sure that the // color is // // saved and read from auto.properties or think about storing the // background // // color into map (just like <map backgroud="#eeeee0">). // } } private void updateViewMenu() { JMenuItem toggleToolbar = menuHolder.addAction(c.toggleToolbar, VIEW_MENU + "toolbars/toggleToolbar"); JMenuItem toggleLeftToolbar = menuHolder.addAction(c.toggleLeftToolbar, VIEW_MENU + "toolbars/toggleLeftToolbar"); menuHolder.addSeparator(VIEW_MENU); JMenuItem showSelectionAsRectangle = menuHolder.addAction( c.showSelectionAsRectangle, VIEW_MENU + "general/selectionAsRectangle"); JMenuItem zoomIn = menuHolder.addAction(c.zoomIn, VIEW_MENU + "zoom/zoomIn"); zoomIn.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_zoom_in"))); JMenuItem zoomOut = menuHolder.addAction(c.zoomOut, VIEW_MENU + "zoom/zoomOut"); zoomOut.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_zoom_out"))); menuHolder.addSeparator(VIEW_MENU); menuHolder.addCategory(VIEW_MENU + "note_window"); menuHolder.addSeparator(VIEW_MENU); JMenu attributes = menuHolder.addMenu( new JMenu(c.getResourceString("menu_attributes")), VIEW_MENU + "attributes/."); ButtonGroup buttonGroup = new ButtonGroup(); JRadioButtonMenuItem itemShowAll = (JRadioButtonMenuItem) menuHolder .addMenuItem(new JRadioButtonMenuItem(c.showAllAttributes), VIEW_MENU + "attributes/showAllAttributes"); itemShowAll.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_show_all_attributes"))); buttonGroup.add(itemShowAll); JRadioButtonMenuItem itemShowSelected = (JRadioButtonMenuItem) menuHolder .addMenuItem( new JRadioButtonMenuItem(c.showSelectedAttributes), VIEW_MENU + "attributes/showSelectedAttributes"); itemShowSelected.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_show_selected_attributes"))); buttonGroup.add(itemShowSelected); JRadioButtonMenuItem itemHideAll = (JRadioButtonMenuItem) menuHolder .addMenuItem(new JRadioButtonMenuItem(c.hideAllAttributes), VIEW_MENU + "attributes/hideAllAttributes"); itemHideAll.setAccelerator(KeyStroke.getKeyStroke(c.getFrame() .getAdjustableProperty("keystroke_hide_all_attributes"))); buttonGroup.add(itemHideAll); } private void addOptionSet(Action action, String[] textIDs, JMenu menu, String selectedTextID) { ButtonGroup group = new ButtonGroup(); for (int optionIdx = 0; optionIdx < textIDs.length; optionIdx++) { JRadioButtonMenuItem item = new JRadioButtonMenuItem(action); item.setText(c.getResourceString(textIDs[optionIdx])); item.setActionCommand(textIDs[optionIdx]); group.add(item); menu.add(item); if (selectedTextID != null) { item.setSelected(selectedTextID.equals(textIDs[optionIdx])); } // keystroke present? String keystroke = c.getFrame().getAdjustableProperty( "keystroke_" + textIDs[optionIdx]); if (keystroke != null) item.setAccelerator(KeyStroke.getKeyStroke(keystroke)); } } JPopupMenu getMapsPopupMenu() { // visible only in controller package return mapsPopupMenu; } /** * This method simpy copy's all elements of the source Menu to the end of * the second menu. */ private void copyMenuItems(JMenu source, JMenu dest) { Component[] items = source.getMenuComponents(); for (int i = 0; i < items.length; i++) { dest.add(items[i]); } } private class MapsMenuActionListener implements ActionListener { public void actionPerformed(final ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { c.getMapModuleManager().changeToMapModule( e.getActionCommand()); } }); } } private class LastOpenedActionListener implements ActionListener { private String mKey; public LastOpenedActionListener(String pKey) { mKey = pKey; } public void actionPerformed(ActionEvent e) { String restoreable = mKey; try { c.getLastOpenedList().open(restoreable); } catch (Exception ex) { c.errorMessage("An error occured on opening the file: " + restoreable + "."); freemind.main.Resources.getInstance().logException(ex); } } } private class ModesMenuActionListener implements ActionListener { public void actionPerformed(final ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { c.createNewMode(e.getActionCommand()); } }); } } /** */ public StructuredMenuHolder getMenuHolder() { return menuHolder; } /* * (non-Javadoc) * * @see javax.swing.JMenuBar#processKeyBinding(javax.swing.KeyStroke, * java.awt.event.KeyEvent, int, boolean) */ public boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { return super.processKeyBinding(ks, e, condition, pressed); } }