/* * Lilith - a log event viewer. * Copyright (C) 2007-2017 Joern Huxhorn * * 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 3 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, see <http://www.gnu.org/licenses/>. */ package de.huxhorn.lilith.swing.preferences; import de.huxhorn.lilith.swing.ApplicationPreferences; import de.huxhorn.lilith.swing.Icons; import de.huxhorn.lilith.swing.LilithActionId; import de.huxhorn.lilith.swing.TextPreprocessor; import de.huxhorn.lilith.swing.preferences.table.ConditionTableColumnModel; import de.huxhorn.lilith.swing.preferences.table.ConditionTableModel; import de.huxhorn.sulky.conditions.Condition; import de.huxhorn.sulky.swing.Windows; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.List; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.JToolBar; import javax.swing.ListSelectionModel; import javax.swing.border.EtchedBorder; import javax.swing.border.TitledBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ConditionsPanel extends JPanel { private static final long serialVersionUID = -2757940105037104853L; private final Logger logger = LoggerFactory.getLogger(ConditionsPanel.class); private PreferencesDialog preferencesDialog; private ApplicationPreferences applicationPreferences; private EditConditionDialog editConditionDialog; private List<SavedCondition> conditions; private JTable conditionTable; private ConditionTableModel conditionTableModel; private EditConditionAction editConditionAction; private RemoveConditionAction removeConditionAction; private JTextArea conditionTextArea; private MoveUpAction moveUpAction; private MoveDownAction moveDownAction; public ConditionsPanel(PreferencesDialog preferencesDialog) { this.preferencesDialog = preferencesDialog; applicationPreferences = preferencesDialog.getApplicationPreferences(); createUI(); } private void createUI() { setLayout(new BorderLayout()); editConditionDialog = new EditConditionDialog(preferencesDialog); conditionTableModel = new ConditionTableModel(null); conditionTable = new JTable(conditionTableModel); conditionTable.addMouseListener(new ConditionTableMouseListener()); // TODO: D&D? Probably not worth the effort... conditionTable.setColumnModel(new ConditionTableColumnModel()); conditionTextArea = new JTextArea(); conditionTextArea.setEditable(false); JScrollPane tableScrollPane = new JScrollPane(conditionTable); JScrollPane descriptionScrollPane = new JScrollPane(conditionTextArea); descriptionScrollPane.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED), "Details")); JPanel conditionsPanel = new JPanel(new GridLayout(2, 1)); conditionsPanel.add(tableScrollPane); conditionsPanel.add(descriptionScrollPane); JToolBar toolBar = new JToolBar(); toolBar.setFloatable(false); ListSelectionModel sourceNameRowSelectionModel = conditionTable.getSelectionModel(); sourceNameRowSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); sourceNameRowSelectionModel.addListSelectionListener(new ConditionTableRowSelectionListener()); //AddConditionAction addConditionAction = new AddConditionAction(); editConditionAction = new EditConditionAction(); removeConditionAction = new RemoveConditionAction(); moveUpAction = new MoveUpAction(); moveDownAction = new MoveDownAction(); JButton editConditionButton = new JButton(editConditionAction); JButton removeConditionButton = new JButton(removeConditionAction); JButton moveUpButton = new JButton(moveUpAction); JButton moveDownButton = new JButton(moveDownAction); toolBar.add(editConditionButton); toolBar.add(removeConditionButton); toolBar.add(moveUpButton); toolBar.add(moveDownButton); add(toolBar, BorderLayout.NORTH); add(conditionsPanel, BorderLayout.CENTER); } public void initUI() { conditions = applicationPreferences.getConditions(); if(logger.isDebugEnabled()) logger.debug("Conditions retrieved: {}", conditions); conditionTableModel.setData(conditions); updateConditions(); } public void updateConditions() { int selectedRow = conditionTable.getSelectedRow(); if(logger.isDebugEnabled()) logger.debug("selectedRow={}", selectedRow); // no need to call convert since we only want to know if selected or not. SavedCondition condition = null; int conditionCount = conditions.size(); if(selectedRow > -1 && selectedRow < conditionCount) { condition = conditions.get(selectedRow); } editConditionAction.setEnabled(condition != null); removeConditionAction.setEnabled(condition != null); moveUpAction.setEnabled(selectedRow > 0); moveDownAction.setEnabled(selectedRow > -1 && selectedRow < conditionCount - 1); String description = ""; if(condition != null) { description = TextPreprocessor.formatCondition(condition.getCondition()); } conditionTextArea.setText(description); } public void saveSettings() { if(logger.isInfoEnabled()) logger.info("Setting conditions to {}.", conditions); applicationPreferences.setConditions(conditions); } public void editCondition(Condition condition) { SavedCondition savedCondition = null; for(SavedCondition current : conditions) { if(condition.equals(current.getCondition())) { savedCondition = current; if(logger.isDebugEnabled()) logger.debug("Found saved condition {}.", savedCondition); break; } } boolean adding = false; if(savedCondition == null) { adding = true; savedCondition = new SavedCondition(condition); } try { savedCondition = savedCondition.clone(); } catch(CloneNotSupportedException e) { if(logger.isErrorEnabled()) logger.error("Couldn't clone saved condition!", e); } editConditionDialog.setSavedCondition(savedCondition); editConditionDialog.setAdding(adding); for(;;) { Windows.showWindow(editConditionDialog, preferencesDialog, true); if(editConditionDialog.isCanceled()) { break; } SavedCondition newCondition = editConditionDialog.getSavedCondition(); String newName = newCondition.getName(); Condition containedCondition = newCondition.getCondition(); int conditionIndex = -1; int nameIndex = -1; for(int i = 0; i < conditions.size(); i++) { if(containedCondition.equals(conditions.get(i).getCondition())) { conditionIndex = i; } if(newName.equals(conditions.get(i).getName())) { nameIndex = i; } } if(logger.isDebugEnabled()) logger.debug("conditionIndex={}, nameIndex={}", conditionIndex, nameIndex); boolean done = false; // check for duplicate name if(nameIndex >= 0 && nameIndex != conditionIndex) { // replace? String dialogTitle = "Duplicate condition name!"; String message = "A different confition with the same name does already exist!\nOverwrite that condition?"; int result = JOptionPane.showConfirmDialog(this, message, dialogTitle, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if(JOptionPane.OK_OPTION == result) { // yes, replace condition@nameIndex conditionTableModel.set(nameIndex, savedCondition); if(conditionIndex >= 0) { // remove other with same condition if it exists conditionTableModel.remove(conditionIndex); if(conditionIndex < nameIndex) { // correct name index nameIndex--; } } conditionIndex = nameIndex; done = true; } // no, leave done=false => editDialog will reopen } else if(conditionIndex < 0) { conditionIndex = conditionTableModel.add(savedCondition); done = true; } else { conditionTableModel.set(conditionIndex, savedCondition); done = true; } if(done) { conditionTable.setRowSelectionInterval(conditionIndex, conditionIndex); updateConditions(); break; } } } private class ConditionTableRowSelectionListener implements ListSelectionListener { public void valueChanged(ListSelectionEvent e) { updateConditions(); } } private class EditConditionAction extends AbstractAction { private static final long serialVersionUID = 95425194239658313L; EditConditionAction() { super("Edit"); putValue(Action.SMALL_ICON, Icons.ADD_16_ICON); putValue(Action.SHORT_DESCRIPTION, "Edit a Condition."); } public void actionPerformed(ActionEvent e) { if(logger.isDebugEnabled()) logger.debug("Edit"); int row = conditionTable.getSelectedRow(); if(row >= 0) { if(row < conditions.size()) { SavedCondition condition = conditions.get(row); editCondition(condition.getCondition()); updateConditions(); } } } } private class RemoveConditionAction extends AbstractAction { private static final long serialVersionUID = 4573645407508010450L; RemoveConditionAction() { super("Remove"); putValue(Action.SMALL_ICON, Icons.REMOVE_16_ICON); putValue(Action.SHORT_DESCRIPTION, "Remove the selected Condition."); } public void actionPerformed(ActionEvent e) { if(logger.isDebugEnabled()) logger.debug("Remove"); int row = conditionTable.getSelectedRow(); if(row >= 0) { conditionTableModel.remove(row); int rowCount = conditionTableModel.getRowCount(); if(row >= rowCount) { if(rowCount > 0) { row = rowCount - 1; } else { row = -1; } } if(row >= 0) { conditionTable.setRowSelectionInterval(row, row); } updateConditions(); } } } private class MoveUpAction extends AbstractAction { private static final long serialVersionUID = -5414336722079117405L; MoveUpAction() { super("Move up"); putValue(Action.SMALL_ICON, Icons.resolveMenuIcon(LilithActionId.FIND_PREVIOUS)); putValue(Action.SHORT_DESCRIPTION, "Move the selected Condition up."); } public void actionPerformed(ActionEvent e) { if(logger.isDebugEnabled()) logger.debug("MoveUp"); int row = conditionTable.getSelectedRow(); if(row >= 0) { int newRow = conditionTableModel.moveUp(row); if(newRow >= 0) { conditionTable.setRowSelectionInterval(newRow, newRow); } updateConditions(); } } } private class MoveDownAction extends AbstractAction { private static final long serialVersionUID = -1115999498183305487L; MoveDownAction() { super("Move down"); putValue(Action.SMALL_ICON, Icons.resolveMenuIcon(LilithActionId.FIND_NEXT)); putValue(Action.SHORT_DESCRIPTION, "Move the selected Condition down."); } public void actionPerformed(ActionEvent e) { if(logger.isDebugEnabled()) logger.debug("MoveDown"); int row = conditionTable.getSelectedRow(); if(row >= 0) { int newRow = conditionTableModel.moveDown(row); if(newRow >= 0) { conditionTable.setRowSelectionInterval(newRow, newRow); } updateConditions(); } } } private class ConditionTableMouseListener implements MouseListener { ConditionTableMouseListener() { } public void mouseClicked(MouseEvent evt) { if(evt.isPopupTrigger()) { showPopup(evt); } else if(evt.getButton() == MouseEvent.BUTTON1) { Point p = evt.getPoint(); int row = conditionTable.rowAtPoint(p); int col = conditionTable.columnAtPoint(p); if(row >= 0 && row < conditions.size()) { if(col == ConditionTableColumnModel.DEFAULT_COLUMN_INDEX_ACTIVE) { SavedCondition condition = conditions.get(row); condition.setActive(!condition.isActive()); conditionTableModel.set(row, condition); } else if(evt.getClickCount() >= 2) { SavedCondition condition = conditions.get(row); editCondition(condition.getCondition()); } } } } @SuppressWarnings({"UnusedDeclaration"}) private void showPopup(MouseEvent evt) { } public void mousePressed(MouseEvent evt) { if(evt.isPopupTrigger()) { showPopup(evt); } } public void mouseReleased(MouseEvent evt) { if(evt.isPopupTrigger()) { showPopup(evt); } } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } } }