/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo 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.
*
* OpenFlexo 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 OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.components.tabularbrowser;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import org.openflexo.FlexoCst;
import org.openflexo.antar.binding.TypeUtils;
import org.openflexo.components.browser.BrowserFilter.BrowserFilterStatus;
import org.openflexo.components.browser.ElementTypeBrowserFilter;
import org.openflexo.foundation.FlexoEditor;
import org.openflexo.foundation.FlexoModelObject;
import org.openflexo.foundation.action.FlexoAction;
import org.openflexo.foundation.action.FlexoActionType;
import org.openflexo.icon.IconLibrary;
import org.openflexo.localization.FlexoLocalization;
public class TabularBrowserFooter extends JPanel {
protected static final Logger logger = Logger.getLogger(TabularBrowserFooter.class.getPackage().getName());
protected TabularBrowserView _tabularBrowserView;
protected JButton plusButton;
protected JButton minusButton;
protected JButton optionsButton;
protected JPopupMenu popupMenu = null;
public TabularBrowserFooter(TabularBrowserView tabularBrowserView) {
super();
_tabularBrowserView = tabularBrowserView;
setBorder(BorderFactory.createEmptyBorder());
setLayout(new BorderLayout());
// setPreferredSize(new Dimension(FlexoCst.MINIMUM_BROWSER_VIEW_WIDTH,FlexoCst.MINIMUM_BROWSER_CONTROL_PANEL_HEIGHT));
setPreferredSize(new Dimension(FlexoCst.MINIMUM_BROWSER_VIEW_WIDTH, 20));
JPanel plusMinusPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
plusMinusPanel.setBorder(BorderFactory.createEmptyBorder());
plusButton = new JButton(IconLibrary.BROWSER_PLUS_ICON);
plusButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!hasMultiplePlusActions()) {
TabularBrowserFooter.this.<FlexoAction, FlexoModelObject, FlexoModelObject> plusPressed(e);
plusButton.setIcon(IconLibrary.BROWSER_PLUS_ICON);
}
}
});
plusButton.setBorder(BorderFactory.createEmptyBorder());
plusButton.setDisabledIcon(IconLibrary.BROWSER_PLUS_DISABLED_ICON);
// plusButton.setSelectedIcon(FlexoCst.BROWSER_PLUS_SELECTED_ICON);
plusButton.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
if (plusButton.isEnabled()) {
plusButton.setIcon(IconLibrary.BROWSER_PLUS_SELECTED_ICON);
}
if (hasMultiplePlusActions()) {
getPlusActionMenu().show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY());
plusButton.setIcon(IconLibrary.BROWSER_PLUS_ICON);
}
}
@Override
public void mouseReleased(MouseEvent mouseEvent) {
if (plusButton.isEnabled()) {
plusButton.setIcon(IconLibrary.BROWSER_PLUS_ICON);
}
if (hasMultiplePlusActions()) {
getPlusActionMenu().show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY());
}
}
});
// FCH.setHelpItem(plusButton,"plus");
minusButton = new JButton(IconLibrary.BROWSER_MINUS_ICON);
minusButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// Multiple DELETE ACTION popup menu not implemented yet
// If you need it, do the same as for ADD ACTION
minusPressed(e);
minusButton.setIcon(IconLibrary.BROWSER_MINUS_ICON);
}
});
minusButton.setBorder(BorderFactory.createEmptyBorder());
minusButton.setDisabledIcon(IconLibrary.BROWSER_MINUS_DISABLED_ICON);
// minusButton.setSelectedIcon(FlexoCst.BROWSER_MINUS_SELECTED_ICON);
minusButton.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
if (minusButton.isEnabled()) {
minusButton.setIcon(IconLibrary.BROWSER_MINUS_SELECTED_ICON);
}
}
@Override
public void mouseReleased(MouseEvent mouseEvent) {
if (minusButton.isEnabled()) {
minusButton.setIcon(IconLibrary.BROWSER_MINUS_ICON);
}
}
});
// FCH.setHelpItem(minusButton,"minus");
plusMinusPanel.add(plusButton);
plusMinusPanel.add(minusButton);
add(plusMinusPanel, BorderLayout.WEST);
optionsButton = new JButton(IconLibrary.BROWSER_OPTIONS_ICON);
optionsButton.setBorder(BorderFactory.createEmptyBorder());
optionsButton.setDisabledIcon(IconLibrary.BROWSER_OPTIONS_DISABLED_ICON);
add(optionsButton, BorderLayout.EAST);
optionsButton.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
if (hasOptionalFilters()) {
optionsButton.setIcon(IconLibrary.BROWSER_OPTIONS_SELECTED_ICON);
getPopupMenu().show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY());
}
}
@Override
public void mouseReleased(MouseEvent mouseEvent) {
if (hasOptionalFilters()) {
getPopupMenu().show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY());
}
}
});
// if (browserView.getBrowser().getOptionalFilters().size() == 0)
optionsButton.setEnabled(hasOptionalFilters());
// FCH.setHelpItem(optionsButton,"options");
if (logger.isLoggable(Level.FINE)) {
logger.fine("Browser " + tabularBrowserView.getBrowser() + " has "
+ tabularBrowserView.getBrowser().getConfigurableElementTypeFilters().size() + " filters");
}
handleSelectionCleared();
// validate();
}
public void handleOptionalFilterAdded() {
optionsButton.setEnabled(hasOptionalFilters());
if (popupMenu != null) {
popupMenu.setVisible(false);
}
popupMenu = null;
}
protected boolean hasOptionalFilters() {
return _tabularBrowserView.getBrowser().getConfigurableElementTypeFilters().size() > 0;
}
protected JPopupMenu getPopupMenu() {
if (popupMenu == null) {
popupMenu = makePopupMenu();
}
return popupMenu;
}
private JPopupMenu makePopupMenu() {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Browser " + _tabularBrowserView.getBrowser() + " has now "
+ _tabularBrowserView.getBrowser().getConfigurableElementTypeFilters().size() + " filters");
}
JPopupMenu returned = new JPopupMenu() {
@Override
public void setVisible(boolean b) {
super.setVisible(b);
if (!b) {
optionsButton.setIcon(IconLibrary.BROWSER_OPTIONS_ICON);
}
}
@Override
public void menuSelectionChanged(boolean isIncluded) {
super.menuSelectionChanged(true);
}
};
// Make the popup menu
// popupMenu.add(new JCheckBoxMenuItem("coucou",FlexoCst.BROWSER_MINUS_ICON,true));
// popupMenu.add(new JCheckBoxMenuItem("coucou2",FlexoCst.BROWSER_MINUS_ICON,false));
for (Enumeration<ElementTypeBrowserFilter> e = _tabularBrowserView.getBrowser().getConfigurableElementTypeFilters().elements(); e
.hasMoreElements();) {
ElementTypeBrowserFilter filter = e.nextElement();
returned.add(new TabularBrowserFilterMenuItem(filter));
}
returned.addSeparator();
JMenuItem closeMenuItem = new JMenuItem(FlexoLocalization.localizedForKey("close"));
returned.add(closeMenuItem);
closeMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
popupMenu.setVisible(false);
}
});
return returned;
}
private FlexoEditor getEditor() {
return _tabularBrowserView.getEditor();
}
protected void handleSelectionChanged() {
FlexoModelObject focusedObject = getFocusedObject();
Vector<FlexoModelObject> globalSelection = buildGlobalSelection();
if (_tabularBrowserView.getEditor() == null) {
plusButton.setEnabled(false);
minusButton.setEnabled(false);
} else {
plusButton.setEnabled(focusedObject != null
&& this.<FlexoAction, FlexoModelObject, FlexoModelObject> getActionTypesWithAddType(focusedObject, globalSelection)
.size() > 0);
minusButton.setEnabled(focusedObject != null
&& this.<FlexoAction, FlexoModelObject, FlexoModelObject> getActionTypesWithDeleteType(focusedObject, globalSelection)
.size() > 0);
}
plusActionMenuNeedsRecomputed = true;
}
@SuppressWarnings("unchecked")
private <A extends FlexoAction<A, T1, T2>, T1 extends FlexoModelObject, T2 extends FlexoModelObject> List<FlexoActionType<A, T1, T2>> getActionTypesWithAddType(
FlexoModelObject focusedObject, Vector<? extends FlexoModelObject> globalSelection) {
List<FlexoActionType<A, T1, T2>> returned = new ArrayList<FlexoActionType<A, T1, T2>>();
for (FlexoActionType<?, ?, ?> actionType : focusedObject.getActionList()) {
if (TypeUtils.isAssignableTo(focusedObject, actionType.getFocusedObjectType())
&& (globalSelection == null || TypeUtils.isAssignableTo(globalSelection, actionType.getGlobalSelectionType()))) {
FlexoActionType<A, T1, T2> cast = (FlexoActionType<A, T1, T2>) actionType;
if (cast.getActionCategory() == FlexoActionType.ADD_ACTION_TYPE) {
if (getEditor().isActionVisible(cast, (T1) focusedObject, (Vector<T2>) globalSelection)) {
if (getEditor().isActionEnabled(cast, (T1) focusedObject, (Vector<T2>) globalSelection)) {
returned.add(cast);
}
}
}
}
}
return returned;
}
@SuppressWarnings("unchecked")
private <A extends FlexoAction<A, T1, T2>, T1 extends FlexoModelObject, T2 extends FlexoModelObject> List<FlexoActionType<A, T1, T2>> getActionTypesWithDeleteType(
FlexoModelObject focusedObject, Vector<? extends FlexoModelObject> globalSelection) {
List<FlexoActionType<A, T1, T2>> returned = new ArrayList<FlexoActionType<A, T1, T2>>();
for (FlexoActionType<?, ?, ?> actionType : focusedObject.getActionList()) {
if (TypeUtils.isAssignableTo(focusedObject, actionType.getFocusedObjectType())
&& (globalSelection == null || TypeUtils.isAssignableTo(globalSelection, actionType.getGlobalSelectionType()))) {
FlexoActionType<A, T1, T2> cast = (FlexoActionType<A, T1, T2>) actionType;
if (cast.getActionCategory() == FlexoActionType.DELETE_ACTION_TYPE) {
if (getEditor().isActionVisible(cast, (T1) focusedObject, (Vector<T2>) globalSelection)) {
if (getEditor().isActionEnabled(cast, (T1) focusedObject, (Vector<T2>) globalSelection)) {
returned.add(cast);
}
}
}
}
}
return returned;
}
protected void handleSelectionCleared() {
plusButton.setEnabled(false);
minusButton.setEnabled(false);
plusActionMenuNeedsRecomputed = true;
}
@SuppressWarnings("unchecked")
protected <A extends FlexoAction<A, T1, T2>, T1 extends FlexoModelObject, T2 extends FlexoModelObject> void plusPressed(ActionEvent e) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Pressed on plus");
}
FlexoActionType<A, T1, T2> actionType = this.<A, T1, T2> getActionTypesWithAddType(getFocusedObject(),
(Vector<FlexoModelObject>) null).get(0);
if (getEditor() != null) {
getEditor().performActionType(actionType, (T1) getFocusedObject(), (Vector<T2>) getGlobalSelection(), e);
} else if (logger.isLoggable(Level.WARNING)) {
logger.warning("No editor available. Ignoring action " + actionType);
}
}
protected boolean hasMultiplePlusActions() {
if (getFocusedObject() == null) {
return false;
}
return getActionTypesWithAddType(getFocusedObject(), (Vector) null).size() > 1;
}
private JPopupMenu plusActionMenu = null;
private boolean plusActionMenuNeedsRecomputed = true;
protected JPopupMenu getPlusActionMenu() {
if (plusActionMenuNeedsRecomputed) {
plusActionMenu = new JPopupMenu();
if (logger.isLoggable(Level.FINE)) {
logger.fine("Build plus menu");
}
for (final FlexoActionType<?, FlexoModelObject, FlexoModelObject> actionType : (List<FlexoActionType<?, FlexoModelObject, FlexoModelObject>>) getActionTypesWithAddType(
getFocusedObject(), (Vector) null)) {
JMenuItem menuItem = new JMenuItem(actionType.getLocalizedName());
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
getEditor().performActionType(actionType, getFocusedObject(), getGlobalSelection(), e);
}
});
plusActionMenu.add(menuItem);
}
plusActionMenuNeedsRecomputed = false;
}
return plusActionMenu;
}
protected void minusPressed(ActionEvent e) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Pressed on minus");
}
Vector globalSelection = buildGlobalSelection();
FlexoActionType<?, FlexoModelObject, FlexoModelObject> actionType = (FlexoActionType<?, FlexoModelObject, FlexoModelObject>) getActionTypesWithDeleteType(
getFocusedObject(), globalSelection).get(0);
if (getEditor() != null) {
getEditor().performActionType(actionType, getFocusedObject(), globalSelection, e);
} else if (logger.isLoggable(Level.WARNING)) {
logger.warning("No editor available. Ignoring action " + actionType);
}
}
/*private boolean hasMultipleMinusActions()
{
Vector globalSelection = buildGlobalSelection();
return getActionTypesWithDeleteType(getFocusedObject(),globalSelection).size() > 1;
}*/
/**
* Returns focused object, considering focused object is the last selected object. If none object are selected, return null.
*/
public FlexoModelObject getFocusedObject() {
return _tabularBrowserView.getSelectedObject();
}
public Vector<FlexoModelObject> getGlobalSelection() {
return buildGlobalSelection();
}
private Vector<FlexoModelObject> buildGlobalSelection() {
Vector<FlexoModelObject> returned = new Vector<FlexoModelObject>();
returned.addAll(_tabularBrowserView.getSelectedObjects());
return returned;
}
public class TabularBrowserFilterMenuItem extends JCheckBoxMenuItem implements ActionListener {
protected ElementTypeBrowserFilter _filter;
public TabularBrowserFilterMenuItem(ElementTypeBrowserFilter filter) {
super(filter.getLocalizedName(), filter.getIcon(), filter.getStatus() == BrowserFilterStatus.SHOW);
_filter = filter;
addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if (_filter != null) {
_filter.setStatus(isSelected() ? BrowserFilterStatus.SHOW : BrowserFilterStatus.HIDE);
if (_tabularBrowserView.getBrowser() != null) {
_tabularBrowserView.getBrowser().update();
}
_tabularBrowserView.getTreeTable().treeStructureChanged();
}
}
}
}