/* * JFileSync * Copyright (C) 2002-2008, Jens Heidrich * * 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., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301, USA */ package jfs.gui; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import javax.swing.JPopupMenu; import javax.swing.JTable; import javax.swing.ListSelectionModel; import jfs.conf.JFSSyncMode.SyncAction; import jfs.conf.JFSSyncModes; import jfs.sync.JFSElement; import jfs.sync.JFSElement.ElementState; import jfs.sync.JFSTable; /** * This class is responsible for handling actions of the synchronization table. * * @author Jens Heidrich * @version $Id: JFSTableListener.java,v 1.4 2007/02/26 18:49:10 heidrich Exp $ */ public class JFSTableListener implements MouseListener, ActionListener { /** * The parent frame. */ private final Frame parent; /** * The corresponding JTable. */ private final JTable table; /** * Stores the names for the icons used for displaying actions. */ private final Map<SyncAction, String> actionIconNames; /** * Stores the current selection of JFS elements in the table. */ private final List<JFSElement> currentSelection = new ArrayList<>(); /** * The default constructor just performs some initialization work. * * @param parent * The parent frame. * @param table * The table to listen to. * @param actionIconNames * The action icon names. */ public JFSTableListener(Frame parent, JTable table, Map<SyncAction, String> actionIconNames) { this.parent = parent; this.table = table; this.actionIconNames = actionIconNames; } /** * @see MouseListener#mouseClicked(MouseEvent) */ @Override public void mouseClicked(MouseEvent e) { handlePopupMenu(e); } /** * @see MouseListener#mouseEntered(MouseEvent) */ @Override public void mouseEntered(MouseEvent e) { // empty default } /** * @see MouseListener#mouseExited(MouseEvent) */ @Override public void mouseExited(MouseEvent e) { // empty default } /** * @see MouseListener#mousePressed(MouseEvent) */ @Override public void mousePressed(MouseEvent e) { handlePopupMenu(e); } /** * @see MouseListener#mouseReleased(MouseEvent) */ @Override public void mouseReleased(MouseEvent e) { handlePopupMenu(e); } /** * Creates a popup menu for a certain mouse event on the table. * * @param e * The mouse event to deal with. */ private void handlePopupMenu(MouseEvent e) { // If appropriate, adjust the selection in response to a popup // trigger if (e.isPopupTrigger()) { int row = table.rowAtPoint(e.getPoint()); if (row==-1) { // The popup trigger was fired outside the // bounds of the table; ignore it return; } ListSelectionModel model = table.getSelectionModel(); if (!model.isSelectedIndex(row)) { // The popup trigger was fired within the // bounds of the table but outside of the // current selection; change the selection model.setSelectionInterval(row, row); } } if (e.isPopupTrigger()&&!table.getSelectionModel().isSelectionEmpty()) { // Updates the selection of JFS elements: updateSelection(); // Go through selection and add actions that are common for all // selected JFS elements: TreeMap<SyncAction, Integer> validActions = new TreeMap<SyncAction, Integer>(); for (JFSElement element : currentSelection) { // Skip pop-up if root element is part of selection: if (element.getState()==ElementState.IS_ROOT) { return; } for (SyncAction a : element.getValidActions()) { Integer i = validActions.get(a); if (i!=null) { validActions.put(a, i+1); } else { validActions.put(a, 1); } } } // Create menu: JPopupMenu popup = new JPopupMenu(); popup.add(JFSSupport.getMenuItem("compTable.menu.activate", "ACTIVATE", this)); popup.add(JFSSupport.getMenuItem("compTable.menu.deactivate", "DEACTIVATE", this)); popup.addSeparator(); // If the number of appearances in the hash map is equal to // the size of the selection, the action is valid: for (Entry<SyncAction, Integer> entry : validActions.entrySet()) { if (entry.getValue()==currentSelection.size()) { popup.add(JFSSupport.getMenuItem(entry.getKey().getName(), String.valueOf(entry.getKey()), this, actionIconNames.get(entry.getKey()))); } } if (currentSelection.size()>=1) { popup.addSeparator(); popup.add(JFSSupport.getMenuItem("general.reset", "general.reset", this)); } // Add properties field, if only one element is selected: if (currentSelection.size()==1) { popup.addSeparator(); popup.add(JFSSupport.getMenuItem("fileProps.title", "PROPERTIES", this)); } // Show menu: popup.show(e.getComponent(), e.getX(), e.getY()); } } /** * @see ActionListener#actionPerformed(ActionEvent) */ @Override public void actionPerformed(ActionEvent e) { if (table.getSelectionModel().isSelectionEmpty()) { return; } String cmd = e.getActionCommand(); for (JFSElement element : currentSelection) { // Set whether the action of the element is active: if ("ACTIVATE".equals(cmd)) { element.setActive(true); } if ("DEACTIVATE".equals(cmd)) { element.setActive(false); } // Change action based on command string: if ("general.reset".equals(cmd)) { element.setActive(true); element.setManuallySetAction(false); JFSSyncModes.getInstance().getCurrentMode().computeAction(element); } for (SyncAction a : SyncAction.values()) { if (cmd.equals(String.valueOf(a))) { element.setAction(a); element.setManuallySetAction(true); } } // Show properties for selected element: if ("PROPERTIES".equals(cmd)) { new JFSPropertiesView(parent, element); } } table.updateUI(); } /** * Updates the vector of selected JFS elements based on the selection model. */ private void updateSelection() { ListSelectionModel sm = table.getSelectionModel(); currentSelection.clear(); for (int i = sm.getMinSelectionIndex(); i<=sm.getMaxSelectionIndex(); i++) { if (sm.isSelectedIndex(i)) { currentSelection.add(JFSTable.getInstance().getViewElement(i)); } } } }