diff --git a/diylc/diylc-core/src/org/diylc/presenter/update.xml b/diylc/diylc-core/src/org/diylc/presenter/update.xml
index 25c68935..e9a3afdc 100644
--- a/diylc/diylc-core/src/org/diylc/presenter/update.xml
+++ b/diylc/diylc-core/src/org/diylc/presenter/update.xml
@@ -3430,6 +3430,10 @@
NEW_FEATURE
Scroll buttons added to the component toolbar that appear when needed
+
+ NEW_FEATURE
+ Toolbar drop down menu now contains options for managing favorites, keyboard shortcuts and selecting all components of type
+
IMPROVEMENT
Save last selected tab in the component toolbar and restore it in the next session
diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar
index 58c63323..b835fb11 100644
Binary files a/diylc/diylc-library/lib/diylc-core.jar and b/diylc/diylc-library/lib/diylc-core.jar differ
diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar
index 58c63323..b835fb11 100644
Binary files a/diylc/diylc-swing/lib/diylc-core.jar and b/diylc/diylc-swing/lib/diylc-core.jar differ
diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar
index 41964622..37eebdef 100644
Binary files a/diylc/diylc-swing/library/main.jar and b/diylc/diylc-swing/library/main.jar differ
diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/toolbox/ComponentTabbedPane.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/toolbox/ComponentTabbedPane.java
index ee7783f2..eb662573 100644
--- a/diylc/diylc-swing/src/org/diylc/swing/plugins/toolbox/ComponentTabbedPane.java
+++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/toolbox/ComponentTabbedPane.java
@@ -1,39 +1,42 @@
/*
+ *
+ * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
+ *
+ * This file is part of DIYLC.
+ *
+ * DIYLC 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 3 of the
+ * License, or (at your option) any later version.
+ *
+ * DIYLC 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 DIYLC. If not, see
+ * .
+ *
+ */
+package org.diylc.swing.plugins.toolbox;
- DIY Layout Creator (DIYLC).
- Copyright (c) 2009-2018 held jointly by the individual authors.
-
- This file is part of DIYLC.
-
- DIYLC 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 3 of the License, or
- (at your option) any later version.
-
- DIYLC 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 DIYLC. If not, see .
-
-*/
-package org.diylc.swing.plugins.toolbox;
-
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import javax.swing.BoxLayout;
+import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -51,71 +54,74 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.Template;
import org.diylc.lang.LangUtil;
import org.diylc.presenter.ComparatorFactory;
-import org.diylc.presenter.ComponentProcessor;
-
-/**
- * Tabbed pane that shows all available components categorized into tabs.
- *
- * @author Branislav Stojkovic
- */
-class ComponentTabbedPane extends JTabbedPane {
-
- private static final long serialVersionUID = 1L;
-
+import org.diylc.presenter.ComponentProcessor;
+import org.diylc.swing.images.IconLoader;
+import org.diylc.swing.plugins.tree.TreePanel;
+import org.diylc.swing.plugins.tree.TreePanel.SelectAllAction;
+
+/**
+ * Tabbed pane that shows all available components categorized into tabs.
+ *
+ * @author Branislav Stojkovic
+ */
+class ComponentTabbedPane extends JTabbedPane {
+
+ private static final long serialVersionUID = 1L;
+
private static final Logger LOG = Logger.getLogger(ComponentTabbedPane.class);
-
- public static String LAST_SELECTED_TAB = "lastSelectedTab";
-
- private final IPlugInPort plugInPort;
+
+ public static String LAST_SELECTED_TAB = "lastSelectedTab";
+
+ private final IPlugInPort plugInPort;
private Container recentToolbar;
private Container buildingBlocksToolbar;
private Container favoritesToolbar;
-
- private Map typesByClass;
-
+
+ private Map typesByClass;
+
private List favorites;
private List pendingRecentComponents = null;
- private List blocks;
+ private List blocks;
- public ComponentTabbedPane(IPlugInPort plugInPort) {
- super();
+ public ComponentTabbedPane(IPlugInPort plugInPort) {
+ super();
this.plugInPort = plugInPort;
-
+
initialize();
-
+
// layout UI
- addTab(LangUtil.translate("(Favorites)"), createFavoritesPanel());
+ addTab(LangUtil.translate("(Favorites)"), createFavoritesPanel());
addTab(LangUtil.translate("(Recently Used)"), createRecentComponentsPanel());
- addTab(LangUtil.translate("(Building Blocks)"), createBuildingBlocksPanel());
- Map> componentTypes = plugInPort.getComponentTypes();
- List categories = new ArrayList(componentTypes.keySet());
- Collections.sort(categories);
- for (String category : categories) {
- JPanel panel = createTab((componentTypes.get(category)));
- addTab(category, panel);
+ addTab(LangUtil.translate("(Building Blocks)"), createBuildingBlocksPanel());
+ Map> componentTypes = plugInPort.getComponentTypes();
+ List categories = new ArrayList(componentTypes.keySet());
+ Collections.sort(categories);
+ for (String category : categories) {
+ JPanel panel = createTab((componentTypes.get(category)));
+ addTab(category, panel);
}
-
+
// restore last selected tab
int lastSelectedTab = ConfigurationManager.getInstance().readInt(LAST_SELECTED_TAB, -1);
if (lastSelectedTab >= 0)
setSelectedIndex(lastSelectedTab);
-
- addChangeListener(new ChangeListener() {
-
- @Override
+
+ addChangeListener(new ChangeListener() {
+
+ @Override
public void stateChanged(ChangeEvent e) {
- ConfigurationManager.getInstance().writeValue(LAST_SELECTED_TAB, getSelectedIndex());
- ComponentTabbedPane.this.plugInPort.setNewComponentTypeSlot(null, null, false);
- // Refresh recent components if needed
- if (pendingRecentComponents != null) {
- refreshRecentComponentsToolbar(pendingRecentComponents);
- getRecentToolbar().invalidate();
- pendingRecentComponents = null;
- }
- }
+ ConfigurationManager.getInstance().writeValue(LAST_SELECTED_TAB, getSelectedIndex());
+ ComponentTabbedPane.this.plugInPort.setNewComponentTypeSlot(null, null, false);
+ // Refresh recent components if needed
+ if (pendingRecentComponents != null) {
+ refreshRecentComponentsToolbar(pendingRecentComponents);
+ getRecentToolbar().invalidate();
+ pendingRecentComponents = null;
+ }
+ }
});
-
-
+
+
}
@SuppressWarnings("unchecked")
@@ -125,7 +131,7 @@ class ComponentTabbedPane extends JTabbedPane {
for (Map.Entry> e : componentTypes.entrySet())
for (ComponentType c : e.getValue())
typesByClass.put(c.getInstanceClass().getCanonicalName(), c);
-
+
// load building blocks
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.BLOCKS_KEY,
new IConfigListener() {
@@ -139,14 +145,14 @@ class ComponentTabbedPane extends JTabbedPane {
Collections.sort(blockNames);
if (!blockNames.equals(ComponentTabbedPane.this.blocks)) {
LOG.info("Detected block change");
- ComponentTabbedPane.this.blocks = blockNames;
+ ComponentTabbedPane.this.blocks = blockNames;
refreshBuildingBlocksToolbar();
} else
LOG.info("Detected no block change");
} else
LOG.info("Detected no block change");
}
- });
+ });
Map>> newBlocks =
(Map>>) ConfigurationManager.getInstance()
.readObject(IPlugInPort.BLOCKS_KEY, null);
@@ -156,7 +162,7 @@ class ComponentTabbedPane extends JTabbedPane {
this.blocks = new ArrayList(newBlocks.keySet());
Collections.sort(this.blocks);
}
-
+
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.FAVORITES_KEY,
new IConfigListener() {
@@ -173,25 +179,25 @@ class ComponentTabbedPane extends JTabbedPane {
});
this.favorites = new ArrayList((List) ConfigurationManager.getInstance()
.readObject(IPlugInPort.FAVORITES_KEY, new ArrayList()));
- }
-
- private JPanel createTab(List componentTypes) {
- JPanel panel = new JPanel(new BorderLayout());
-
- panel.setOpaque(false);
- panel.add(createComponentPanel(componentTypes), BorderLayout.CENTER);
-
- return panel;
- }
-
- public Container getRecentToolbar() {
- if (recentToolbar == null) {
- recentToolbar = new Container();
- recentToolbar.setLayout(new BoxLayout(recentToolbar, BoxLayout.X_AXIS));
- }
- return recentToolbar;
}
-
+
+ private JPanel createTab(List componentTypes) {
+ JPanel panel = new JPanel(new BorderLayout());
+
+ panel.setOpaque(false);
+ panel.add(createComponentPanel(componentTypes), BorderLayout.CENTER);
+
+ return panel;
+ }
+
+ public Container getRecentToolbar() {
+ if (recentToolbar == null) {
+ recentToolbar = new Container();
+ recentToolbar.setLayout(new BoxLayout(recentToolbar, BoxLayout.X_AXIS));
+ }
+ return recentToolbar;
+ }
+
public Container getBuildingBlocksToolbar() {
if (buildingBlocksToolbar == null) {
buildingBlocksToolbar = new Container();
@@ -199,62 +205,64 @@ class ComponentTabbedPane extends JTabbedPane {
}
return buildingBlocksToolbar;
}
-
+
public Container getFavoritesToolbar() {
if (favoritesToolbar == null) {
favoritesToolbar = new Container();
favoritesToolbar.setLayout(new BoxLayout(favoritesToolbar, BoxLayout.X_AXIS));
}
return favoritesToolbar;
- }
-
- private Component createComponentPanel(List componentTypes) {
- Container toolbar = new Container();
- Collections.sort(componentTypes, ComparatorFactory.getInstance().getComponentTypeComparator());
- toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS));
- for (ComponentType componentType : componentTypes) {
- try {
- Component button = ComponentButtonFactory.create(plugInPort, componentType, createVariantPopup(componentType));
- toolbar.add(button);
- } catch (Exception e) {
- LOG.error("Could not create recent component button for " + componentType.getName(), e);
- }
- }
-
- return new ToolbarScrollPane(toolbar);
- }
-
- @SuppressWarnings("unchecked")
- private Component createRecentComponentsPanel() {
- final Container toolbar = getRecentToolbar();
- refreshRecentComponentsToolbar((List) ConfigurationManager.getInstance().readObject(IPlugInPort.RECENT_COMPONENTS_KEY,
- new ArrayList()));
- ConfigurationManager.getInstance().addConfigListener(IPlugInPort.RECENT_COMPONENTS_KEY, new IConfigListener() {
-
- @Override
- public void valueChanged(String key, Object value) {
- // Cache the new list, we'll refresh when there's a
- // chance
- pendingRecentComponents = (List) value;
- }
- });
-
- JPanel panel = new ToolbarScrollPane(toolbar);
-
- return panel;
}
-
-
+
+ private Component createComponentPanel(List componentTypes) {
+ Container toolbar = new Container();
+ Collections.sort(componentTypes, ComparatorFactory.getInstance().getComponentTypeComparator());
+ toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS));
+ for (ComponentType componentType : componentTypes) {
+ try {
+ Component button = ComponentButtonFactory.create(plugInPort, componentType,
+ createVariantPopup(componentType));
+ toolbar.add(button);
+ } catch (Exception e) {
+ LOG.error("Could not create recent component button for " + componentType.getName(), e);
+ }
+ }
+
+ return new ToolbarScrollPane(toolbar);
+ }
+
+ @SuppressWarnings("unchecked")
+ private Component createRecentComponentsPanel() {
+ final Container toolbar = getRecentToolbar();
+ refreshRecentComponentsToolbar((List) ConfigurationManager.getInstance()
+ .readObject(IPlugInPort.RECENT_COMPONENTS_KEY, new ArrayList()));
+ ConfigurationManager.getInstance().addConfigListener(IPlugInPort.RECENT_COMPONENTS_KEY,
+ new IConfigListener() {
+
+ @Override
+ public void valueChanged(String key, Object value) {
+ // Cache the new list, we'll refresh when there's a
+ // chance
+ pendingRecentComponents = (List) value;
+ }
+ });
+
+ JPanel panel = new ToolbarScrollPane(toolbar);
+
+ return panel;
+ }
+
+
private Component createBuildingBlocksPanel() {
final Container toolbar = getBuildingBlocksToolbar();
JPanel panel = new ToolbarScrollPane(toolbar);
-
+
refreshBuildingBlocksToolbar();
return panel;
}
-
+
private Component createFavoritesPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setOpaque(false);
@@ -262,31 +270,31 @@ class ComponentTabbedPane extends JTabbedPane {
final Container toolbar = getFavoritesToolbar();
panel.add(toolbar, BorderLayout.CENTER);
-
+
refreshFavoritesToolbar();
return panel;
}
-
-
- @SuppressWarnings("unchecked")
+
+
+ @SuppressWarnings("unchecked")
private void refreshRecentComponentsToolbar(List recentComponentClassList) {
- Container toolbar = getRecentToolbar();
- toolbar.removeAll();
- for (String componentClassName : recentComponentClassList) {
- ComponentType componentType;
- try {
- componentType =
- ComponentProcessor.getInstance().extractComponentTypeFrom(
- (Class extends IDIYComponent>>) Class.forName(componentClassName));
- Component button = ComponentButtonFactory.create(plugInPort, componentType, createVariantPopup(componentType));
- toolbar.add(button);
- } catch (Exception e) {
- LOG.error("Could not create recent component button for " + componentClassName, e);
- }
- }
+ Container toolbar = getRecentToolbar();
+ toolbar.removeAll();
+ for (String componentClassName : recentComponentClassList) {
+ ComponentType componentType;
+ try {
+ componentType = ComponentProcessor.getInstance().extractComponentTypeFrom(
+ (Class extends IDIYComponent>>) Class.forName(componentClassName));
+ Component button = ComponentButtonFactory.create(plugInPort, componentType,
+ createVariantPopup(componentType));
+ toolbar.add(button);
+ } catch (Exception e) {
+ LOG.error("Could not create recent component button for " + componentClassName, e);
+ }
+ }
}
-
+
private void refreshBuildingBlocksToolbar() {
Container toolbar = getBuildingBlocksToolbar();
toolbar.removeAll();
@@ -295,7 +303,7 @@ class ComponentTabbedPane extends JTabbedPane {
toolbar.add(button);
}
}
-
+
private void refreshFavoritesToolbar() {
Container toolbar = getFavoritesToolbar();
toolbar.removeAll();
@@ -305,39 +313,135 @@ class ComponentTabbedPane extends JTabbedPane {
button = ComponentButtonFactory.createBuildingBlockButton(plugInPort, fav.getName());
} else {
ComponentType componentType = this.typesByClass.get(fav.getName());
- button = ComponentButtonFactory.create(plugInPort, componentType, createVariantPopup(componentType));
+ button = ComponentButtonFactory.create(plugInPort, componentType,
+ createVariantPopup(componentType));
}
toolbar.add(button);
}
- }
-
- private JPopupMenu createVariantPopup(final ComponentType componentType) {
- final JPopupMenu variantPopup = new JPopupMenu();
- variantPopup.add("Loading...");
- variantPopup.addPopupMenuListener(new PopupMenuListener() {
-
- @Override
- public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
- variantPopup.removeAll();
- List variants = plugInPort.getVariantsFor(componentType);
- if (variants == null || variants.isEmpty()) {
- JMenuItem item = new JMenuItem("");
- item.setEnabled(false);
- variantPopup.add(item);
- } else {
- for (Template variant : variants) {
- JMenuItem item = ComponentButtonFactory.createVariantItem(plugInPort, variant, componentType);
- variantPopup.add(item);
- }
- }
- }
-
- @Override
- public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
-
- @Override
- public void popupMenuCanceled(PopupMenuEvent e) {}
- });
- return variantPopup;
- }
-}
+ }
+
+ private JPopupMenu createVariantPopup(final ComponentType componentType) {
+ final JPopupMenu variantPopup = new JPopupMenu();
+ variantPopup.add("Loading...");
+ variantPopup.addPopupMenuListener(new PopupMenuListener() {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+ variantPopup.removeAll();
+
+ final String identifier = componentType.getInstanceClass().getCanonicalName();
+
+ JMenu shortcutSubmenu = new JMenu("Assign Shortcut");
+ final JRadioButtonMenuItem noneItem = new JRadioButtonMenuItem ("None");
+ noneItem.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ HashMap map = (HashMap) ConfigurationManager
+ .getInstance().readObject(TreePanel.COMPONENT_SHORTCUT_KEY, null);
+ if (map == null)
+ map = new HashMap();
+
+ Iterator> it = map.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry item = it.next();
+ if (item.getValue().equals(identifier))
+ it.remove();
+ }
+
+ ConfigurationManager.getInstance().writeValue(TreePanel.COMPONENT_SHORTCUT_KEY, map);
+ }
+ });
+
+ HashMap map = (HashMap) ConfigurationManager
+ .getInstance().readObject(TreePanel.COMPONENT_SHORTCUT_KEY, null);
+ noneItem.setSelected(map == null);
+ shortcutSubmenu.add(noneItem);
+
+ for (int i = 1; i <= 12; i++) {
+ final JRadioButtonMenuItem item = new JRadioButtonMenuItem("F" + i);
+ item.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ HashMap map = (HashMap) ConfigurationManager
+ .getInstance().readObject(TreePanel.COMPONENT_SHORTCUT_KEY, null);
+ if (map == null)
+ map = new HashMap();
+
+ if (map.containsKey(item.getText()))
+ map.remove(item.getText());
+
+ Iterator> it = map.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry item = it.next();
+ if (item.getValue().equals(identifier))
+ it.remove();
+ }
+
+ map.put(item.getText(), identifier);
+
+ ConfigurationManager.getInstance().writeValue(TreePanel.COMPONENT_SHORTCUT_KEY, map);
+ }
+ });
+
+ boolean selected;
+
+ if (map == null)
+ selected = false;
+ else
+ selected = map.containsKey(item.getText()) && map.get(item.getText()).equals(identifier);
+
+ item.setSelected(selected);
+ shortcutSubmenu.add(item);
+ }
+
+ final Favorite fav =
+ new Favorite(FavoriteType.Component, componentType.getInstanceClass().getCanonicalName());
+ final boolean isFavorite = favorites != null && favorites.indexOf(fav) >= 0;
+ final JMenuItem favoritesItem =
+ new JMenuItem(isFavorite ? "Remove From Favorites" : "Add To Favorites",
+ isFavorite ? IconLoader.StarBlue.getIcon() : IconLoader.StarGrey.getIcon());
+ favoritesItem.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ List favorites = new ArrayList(ComponentTabbedPane.this.favorites);
+ if (isFavorite) {
+ favorites.remove(fav);
+ } else {
+ favorites.add(fav);
+ Collections.sort(favorites);
+ }
+ ConfigurationManager.getInstance().writeValue(IPlugInPort.FAVORITES_KEY, favorites);
+ }
+ });
+ variantPopup.add(favoritesItem);
+
+ variantPopup.add(new SelectAllAction(plugInPort, componentType));
+ variantPopup.add(shortcutSubmenu);
+
+ List variants = plugInPort.getVariantsFor(componentType);
+ if (variants == null || variants.isEmpty()) {
+ JMenuItem item = new JMenuItem("");
+ item.setEnabled(false);
+ variantPopup.add(item);
+ } else {
+ for (Template variant : variants) {
+ JMenuItem item =
+ ComponentButtonFactory.createVariantItem(plugInPort, variant, componentType);
+ variantPopup.add(item);
+ }
+ }
+ }
+
+ @Override
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
+
+ @Override
+ public void popupMenuCanceled(PopupMenuEvent e) {}
+ });
+ return variantPopup;
+ }
+}