/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander 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. * * muCommander 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, see <http://www.gnu.org/licenses/>. */ package com.mucommander.ui.dialog.file; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.regex.PatternSyntaxException; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mucommander.commons.file.filter.AndFileFilter; import com.mucommander.commons.file.filter.AttributeFileFilter; import com.mucommander.commons.file.filter.AttributeFileFilter.FileAttribute; import com.mucommander.commons.file.filter.ContainsFilenameFilter; import com.mucommander.commons.file.filter.EndsWithFilenameFilter; import com.mucommander.commons.file.filter.EqualsFilenameFilter; import com.mucommander.commons.file.filter.FileFilter; import com.mucommander.commons.file.filter.PassThroughFileFilter; import com.mucommander.commons.file.filter.RegexpFilenameFilter; import com.mucommander.commons.file.filter.StartsWithFilenameFilter; import com.mucommander.text.Translator; import com.mucommander.ui.dialog.DialogToolkit; import com.mucommander.ui.dialog.FocusDialog; import com.mucommander.ui.layout.YBoxPanel; import com.mucommander.ui.main.MainFrame; import com.mucommander.ui.main.table.FileTable; /** * This dialog allows the user to add (mark) or remove (unmark) files from the current selection, * based on a match criterium and string. * * @author Maxence Bernard */ public class FileSelectionDialog extends FocusDialog implements ActionListener { private static final Logger LOGGER = LoggerFactory.getLogger(FileSelectionDialog.class); /* Filename comparison criteria */ private final static int CONTAINS = 0; private final static int STARTS_WITH = 1; private final static int ENDS_WIDTH = 2; private final static int IS = 3; private final static int REGEXP = 4; /** Add to or remove from selection ? */ private boolean addToSelection; private JComboBox comparisonComboBox; private JTextField selectionField; private JCheckBox caseSensitiveCheckBox; private JCheckBox includeFoldersCheckBox; private JButton okButton; private MainFrame mainFrame; /** * Is selection case sensitive? (initially false) * <br>Note: this field is static so the value is kept after the dialog is OKed. */ private static boolean caseSensitive = false; /** * Does the selection include folders? (initially false) * <br>Note: this field is static so the value is kept after the dialog is OKed. */ private static boolean includeFolders = false; /** * Filename comparison: contains, starts with, ends with, is ? * <br>Note: this field is static so the value is kept after the dialog is OKed. */ private static int comparison = CONTAINS; /** * Keyword which has last been typed to mark or unmark files. * <br>Note: this field is static so the value is kept after the dialog is OKed. */ private static String keywordString = "*"; private final static Dimension MINIMUM_DIALOG_DIMENSION = new Dimension(320,0); private final static Dimension MAXIMUM_DIALOG_DIMENSION = new Dimension(400,10000); /** * Creates a new 'mark' or 'unmark' dialog. * * @param addToSelection if <true>, files matching */ public FileSelectionDialog(MainFrame mainFrame, boolean addToSelection) { super(mainFrame, Translator.get(addToSelection?"file_selection_dialog.mark":"file_selection_dialog.unmark"), mainFrame); this.mainFrame = mainFrame; this.addToSelection = addToSelection; Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); YBoxPanel northPanel = new YBoxPanel(5); JLabel label = new JLabel(Translator.get(addToSelection?"file_selection_dialog.mark_description":"file_selection_dialog.unmark_description")+" :"); northPanel.add(label); JPanel tempPanel = new JPanel(); tempPanel.setLayout(new BoxLayout(tempPanel, BoxLayout.X_AXIS)); comparisonComboBox = new JComboBox(); comparisonComboBox.addItem(Translator.get("file_selection_dialog.contains")); comparisonComboBox.addItem(Translator.get("file_selection_dialog.starts_with")); comparisonComboBox.addItem(Translator.get("file_selection_dialog.ends_with")); comparisonComboBox.addItem(Translator.get("file_selection_dialog.is")); comparisonComboBox.addItem(Translator.get("file_selection_dialog.matches_regexp")); comparisonComboBox.setSelectedIndex(comparison); tempPanel.add(comparisonComboBox); // selectionField is initialized with last textfield's value (if any) selectionField = new JTextField(keywordString); selectionField.addActionListener(this); selectionField.setSelectionStart(0); selectionField.setSelectionEnd(keywordString.length()); tempPanel.add(selectionField); northPanel.add(tempPanel); // Add some vertical space northPanel.addSpace(10); caseSensitiveCheckBox = new JCheckBox(Translator.get("file_selection_dialog.case_sensitive"), caseSensitive); northPanel.add(caseSensitiveCheckBox); includeFoldersCheckBox = new JCheckBox(Translator.get("file_selection_dialog.include_folders"), includeFolders); northPanel.add(includeFoldersCheckBox); northPanel.addSpace(10); northPanel.add(Box.createVerticalGlue()); contentPane.add(northPanel, BorderLayout.NORTH); okButton = new JButton(Translator.get(addToSelection?"file_selection_dialog.mark":"file_selection_dialog.unmark")); contentPane.add(DialogToolkit.createOKCancelPanel(okButton, new JButton(Translator.get("cancel")), getRootPane(), this), BorderLayout.SOUTH); // Selection field receives initial keyboard focus setInitialFocusComponent(selectionField); setMinimumSize(MINIMUM_DIALOG_DIMENSION); setMaximumSize(MAXIMUM_DIALOG_DIMENSION); } //////////////////////////// // ActionListener methods // //////////////////////////// public void actionPerformed(ActionEvent e) { Object source = e.getSource(); FileTable activeTable = mainFrame.getActiveTable(); // Action coming from the selection dialog if ((source==okButton || source==selectionField)) { // Save values for next time this dialog is invoked caseSensitive = caseSensitiveCheckBox.isSelected(); includeFolders = includeFoldersCheckBox.isSelected(); comparison = comparisonComboBox.getSelectedIndex(); String testString; keywordString = selectionField.getText(); if(comparison!=REGEXP) { // Remove '*' characters testString = keywordString.replace("*", ""); } else { testString = keywordString; } // Instantiate the main file filter FileFilter filter; switch (comparison) { case CONTAINS: filter = new ContainsFilenameFilter(testString, caseSensitive); break; case STARTS_WITH: filter = new StartsWithFilenameFilter(testString, caseSensitive); break; case ENDS_WIDTH: filter = new EndsWithFilenameFilter(testString, caseSensitive); break; case IS: filter = new EqualsFilenameFilter(testString, caseSensitive); break; case REGEXP: default: try { filter = new RegexpFilenameFilter(testString, caseSensitive); } catch(PatternSyntaxException ex) { // Todo: let the user know the regexp is invalid LOGGER.debug("Invalid regexp", ex); // This filter does match any file filter = new PassThroughFileFilter(false); } break; } // If folders are excluded, add a regular file filter and chain it with an AndFileFilter if(!includeFolders) { filter = new AndFileFilter( new AttributeFileFilter(FileAttribute.FILE), filter ); } // Mark/unmark the files using the filter activeTable.getFileTableModel().setFilesMarked(filter, addToSelection); // Notify registered listeners that currently marked files have changed on this FileTable activeTable.fireMarkedFilesChangedEvent(); activeTable.repaint(); } dispose(); } }