/*FreeMind - A Program for creating and viewing Mindmaps
*Copyright (C) 2000-2005 Joerg Mueller, Daniel Polansky, Christian Foltin and others.
*
*See COPYING for Details
*
*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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Created on 04.02.2005
*/
package accessories.plugins.time;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.EventListener;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import java.util.regex.Pattern;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import freemind.controller.MapModuleManager.MapModuleChangeObserver;
import freemind.controller.MenuItemSelectedListener;
import freemind.controller.StructuredMenuHolder;
import freemind.controller.actions.generated.instance.TimeWindowColumnSetting;
import freemind.controller.actions.generated.instance.TimeWindowConfigurationStorage;
import freemind.controller.actions.generated.instance.WindowConfigurationStorage;
import freemind.main.HtmlTools;
import freemind.main.Tools;
import freemind.modes.MindIcon;
import freemind.modes.MindMap;
import freemind.modes.MindMapNode;
import freemind.modes.Mode;
import freemind.modes.ModeController;
import freemind.modes.common.plugins.ReminderHookBase;
import freemind.modes.mindmapmode.MindMapController;
import freemind.modes.mindmapmode.hooks.MindMapHookAdapter;
import freemind.view.MapModule;
import freemind.view.mindmapview.MultipleImage;
/**
* @author foltin
*
* TODO: - Extract HTML from nodes and notes.
*/
public class TimeList extends MindMapHookAdapter implements
MapModuleChangeObserver {
private static final int TYPE_DELAY_TIME = 500;
private static String COLUMN_MODIFIED = "Modified";
private static String COLUMN_CREATED = "Created";
private static String COLUMN_ICONS = "Icons";
private static String COLUMN_TEXT = "Text";
private static String COLUMN_DATE = "Date";
private static String COLUMN_NOTES = "Notes";
private static final int DATE_COLUMN = 0;
public static final int NODE_TEXT_COLUMN = 1;
protected static final int NODE_ICON_COLUMN = 2;
protected static final int NODE_CREATED_COLUMN = 3;
protected static final int NODE_MODIFIED_COLUMN = 4;
protected static final int NODE_NOTES_COLUMN = 5;
private JDialog dialog;
private JPanel timePanel;
private JTable timeTable;
private DefaultTableModel timeTableModel;
private accessories.plugins.time.TableSorter sorter;
private DateRenderer dateRenderer;
private NodeRenderer nodeRenderer;
private IconsRenderer iconsRenderer;
private boolean showAllNodes = false;
private static final String WINDOW_PREFERENCE_STORAGE_PROPERTY = TimeList.class
.getName() + "_properties";
private FlatNodeTableFilterModel mFlatNodeTableFilterModel;
private JTextField mFilterTextSearchField;
private JTextField mFilterTextReplaceField;
private NotesRenderer notesRenderer;
private JLabel mTreeLabel;
private MindMapController mMyMindMapController;
private boolean mViewFoldedNodes = true;
public void startupMapHook() {
super.startupMapHook();
mMyMindMapController = super.getMindMapController();
getMindMapController().getController().getMapModuleManager()
.addListener(this);
// get strings from resources:
COLUMN_MODIFIED = getResourceString("plugins/TimeList.xml_Modified");
COLUMN_CREATED = getResourceString("plugins/TimeList.xml_Created");
COLUMN_ICONS = getResourceString("plugins/TimeList.xml_Icons");
COLUMN_TEXT = getResourceString("plugins/TimeList.xml_Text");
COLUMN_DATE = getResourceString("plugins/TimeList.xml_Date");
COLUMN_NOTES = getResourceString("plugins/TimeList.xml_Notes");
showAllNodes = Tools.xmlToBoolean(getResourceString("show_all_nodes"));
dialog = new JDialog(getController().getFrame().getJFrame(), false /* unmodal */);
String windowTitle;
if (showAllNodes) {
windowTitle = "plugins/TimeManagement.xml_WindowTitle_All_Nodes";
} else {
windowTitle = "plugins/TimeManagement.xml_WindowTitle";
}
dialog.setTitle(getResourceString(windowTitle));
dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
disposeDialog();
}
});
Tools.addEscapeActionToDialog(dialog, new AbstractAction() {
public void actionPerformed(ActionEvent arg0) {
disposeDialog();
}
});
Container contentPane = dialog.getContentPane();
GridBagLayout gbl = new GridBagLayout();
gbl.columnWeights = new double[] { 1.0f };
gbl.rowWeights = new double[] { 1.0f };
contentPane.setLayout(gbl);
contentPane.add(new JLabel(
getResourceString("plugins/TimeManagement.xml_Find")),
new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
mFilterTextSearchField = new JTextField();
mFilterTextSearchField.getDocument().addDocumentListener(
new FilterTextDocumentListener());
mFilterTextSearchField.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent pEvent) {
// logger.info("Key event:" + pEvent.getKeyCode());
if (pEvent.getKeyCode() == KeyEvent.VK_DOWN) {
logger.info("Set Focus to replace fields");
mFilterTextReplaceField.requestFocusInWindow();
}
}
});
contentPane.add(/* new JScrollPane */(mFilterTextSearchField),
new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
contentPane.add(new JLabel(
getResourceString("plugins/TimeManagement.xml_Replace")),
new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
mFilterTextReplaceField = new JTextField();
contentPane.add(/* new JScrollPane */(mFilterTextReplaceField),
new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
mFilterTextReplaceField.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent pEvent) {
if (pEvent.getKeyCode() == KeyEvent.VK_DOWN) {
logger.info("Set Focus to table");
timeTable.requestFocusInWindow();
} else if (pEvent.getKeyCode() == KeyEvent.VK_UP) {
logger.info("Set Focus to table");
mFilterTextSearchField.requestFocusInWindow();
}
}
});
dateRenderer = new DateRenderer();
nodeRenderer = new NodeRenderer();
notesRenderer = new NotesRenderer();
iconsRenderer = new IconsRenderer(getController());
timeTable = new FlatNodeTable();
timeTable.addKeyListener(new FlatNodeTableKeyListener());
// double click = goto.
timeTable.addMouseListener(new FlatNodeTableMouseAdapter());
// disable moving:
timeTable.getTableHeader().setReorderingAllowed(false);
updateModel();
sorter.setTableHeader(timeTable.getTableHeader());
sorter.setColumnComparator(Date.class,
TableSorter.COMPARABLE_COMAPRATOR);
sorter.setColumnComparator(NodeHolder.class,
TableSorter.LEXICAL_COMPARATOR);
sorter.setColumnComparator(NotesHolder.class,
TableSorter.LEXICAL_COMPARATOR);
sorter.setColumnComparator(IconsHolder.class,
TableSorter.COMPARABLE_COMAPRATOR);
// Sort by default by date.
sorter.setSortingStatus(DATE_COLUMN, TableSorter.ASCENDING);
JScrollPane pane = new JScrollPane(timeTable);
contentPane.add(pane, new GridBagConstraints(0, 4, 1, 1, 1.0, 10.0,
GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0,
0, 0, 0), 0, 0));
mTreeLabel = new JLabel();
contentPane.add(new JScrollPane(mTreeLabel), new GridBagConstraints(0,
5, 1, 1, 1.0, 1.0, GridBagConstraints.WEST,
GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
// button bar
AbstractAction selectAction = new AbstractAction(
getResourceString("plugins/TimeManagement.xml_Select")) {
public void actionPerformed(ActionEvent arg0) {
selectSelectedRows();
}
};
AbstractAction exportAction = new AbstractAction(
getResourceString("plugins/TimeManagement.xml_Export")) {
public void actionPerformed(ActionEvent arg0) {
exportSelectedRowsAndClose();
}
};
AbstractAction replaceAllAction = new AbstractAction(
getResourceString("plugins/TimeManagement.xml_Replace_All")) {
public void actionPerformed(ActionEvent arg0) {
replace(new ReplaceAllInfo());
}
};
AbstractAction replaceSelectedAction = new AbstractAction(
getResourceString("plugins/TimeManagement.xml_Replace_Selected")) {
public void actionPerformed(ActionEvent arg0) {
replace(new ReplaceSelectedInfo());
}
};
AbstractAction gotoAction = new AbstractAction(
getResourceString("plugins/TimeManagement.xml_Goto")) {
public void actionPerformed(ActionEvent arg0) {
selectSelectedRows();
disposeDialog();
}
};
AbstractAction disposeAction = new AbstractAction(
getResourceString("plugins/TimeManagement.xml_Cancel")) {
public void actionPerformed(ActionEvent arg0) {
disposeDialog();
}
};
AbstractAction toggleViewFoldedNodesAction = new ToggleViewFoldedNodesAction(
getResourceString("plugins/TimeManagement.xml_ToggleViewFoldedNodesAction"));
/** Menu **/
StructuredMenuHolder menuHolder = new StructuredMenuHolder();
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu(
getResourceString("plugins/TimeManagement.xml_menu_actions"));
menuHolder.addMenu(menu, "main/actions/.");
final JMenuItem selectMenuItem = addAccelerator(
menuHolder.addAction(selectAction, "main/actions/select"),
"keystroke_plugins/TimeList_select");
final JMenuItem gotoMenuItem = addAccelerator(
menuHolder.addAction(gotoAction, "main/actions/goto"),
"keystroke_plugins/TimeList_goto");
final JMenuItem replaceSelectedMenuItem = addAccelerator(
menuHolder.addAction(replaceSelectedAction,
"main/actions/replaceSelected"),
"keystroke_plugins/TimeList_replaceSelected");
final JMenuItem replaceAllMenuItem = addAccelerator(
menuHolder.addAction(replaceAllAction,
"main/actions/replaceAll"),
"keystroke_plugins/TimeList_replaceAll");
final JMenuItem exportMenuItem = addAccelerator(
menuHolder.addAction(exportAction, "main/actions/export"),
"keystroke_plugins/TimeList_export");
addAccelerator(
menuHolder.addAction(disposeAction, "main/actions/dispose"),
"keystroke_plugins/TimeList_dispose");
JMenu viewMenu = new JMenu(
getResourceString("plugins/TimeManagement.xml_menu_view"));
menuHolder.addMenu(viewMenu, "main/view/.");
addAccelerator(menuHolder.addAction(toggleViewFoldedNodesAction,
"main/view/showFoldedNodes"),
"keystroke_plugins/TimeList_showFoldedNodes");
menuHolder.updateMenus(menuBar, "main/");
dialog.setJMenuBar(menuBar);
/* Initial State */
selectMenuItem.setEnabled(false);
gotoMenuItem.setEnabled(false);
exportMenuItem.setEnabled(false);
replaceSelectedMenuItem.setEnabled(false);
// table selection listeners to enable/disable menu actions:
ListSelectionModel rowSM = timeTable.getSelectionModel();
rowSM.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
// Ignore extra messages.
if (e.getValueIsAdjusting())
return;
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
boolean enable = !(lsm.isSelectionEmpty());
replaceSelectedMenuItem.setEnabled(enable);
selectMenuItem.setEnabled(enable);
gotoMenuItem.setEnabled(enable);
exportMenuItem.setEnabled(enable);
}
});
// table selection listener to display the history of the selected nodes
rowSM.addListSelectionListener(new ListSelectionListener() {
String getNodeText(MindMapNode node) {
return Tools.getNodeTextHierarchy(node, getMindMapController());
}
public void valueChanged(ListSelectionEvent e) {
// Ignore extra messages.
if (e.getValueIsAdjusting())
return;
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
if (lsm.isSelectionEmpty()) {
mTreeLabel.setText("");
return;
}
int selectedRow = lsm.getLeadSelectionIndex();
MindMapNode mindMapNode = getMindMapNode(selectedRow);
mTreeLabel.setText(getNodeText(mindMapNode));
}
});
// restore preferences:
// Retrieve window size and column positions.
WindowConfigurationStorage storage = getMindMapController()
.decorateDialog(dialog, WINDOW_PREFERENCE_STORAGE_PROPERTY);
if (storage != null) {
setTableConfiguration(storage);
}
dialog.setVisible(true);
}
protected void setTableConfiguration(WindowConfigurationStorage storage) {
// Disable auto resizing
timeTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
final TimeWindowConfigurationStorage timeStorage = (TimeWindowConfigurationStorage) storage;
if(mViewFoldedNodes != timeStorage.getViewFoldedNodes()) {
toggleViewFoldedNodes();
}
int column = 0;
for (Iterator i = timeStorage
.getListTimeWindowColumnSettingList().iterator(); i
.hasNext();) {
TimeWindowColumnSetting setting = (TimeWindowColumnSetting) i
.next();
timeTable.getColumnModel().getColumn(column)
.setPreferredWidth(setting.getColumnWidth());
sorter.setSortingStatus(column, setting.getColumnSorting());
column++;
}
}
/**
*
*/
protected void toggleViewFoldedNodes() {
mViewFoldedNodes = ! mViewFoldedNodes;
updateModel();
}
protected void decorateButtonAndAction(String stringProperty,
final AbstractAction selectAction, JButton selectButton) {
String resourceString = getResourceString(stringProperty);
selectAction.putValue(AbstractAction.NAME,
resourceString.replaceAll("&", ""));
Tools.setLabelAndMnemonic(selectButton, resourceString);
}
protected void exportSelectedRowsAndClose() {
int[] selectedRows = timeTable.getSelectedRows();
Vector selectedNodes = new Vector();
for (int i = 0; i < selectedRows.length; i++) {
int row = selectedRows[i];
selectedNodes.add(getMindMapNode(row));
}
// create new map:
MindMap newMap = getMindMapController().newMap();
MindMapController newMindMapController = (MindMapController) newMap
.getModeController();
// Tools.BooleanHolder booleanHolder = new Tools.BooleanHolder();
// booleanHolder.setValue(false);
for (Iterator iter = selectedNodes.iterator(); iter.hasNext();) {
MindMapNode node = (MindMapNode) iter.next();
// MindMapNode newNode = newMindMapController.addNewNode(
// newMap.getRootNode(), 0, booleanHolder);
// // copy style:
// freemind.controller.actions.generated.instance.Pattern pattern =
// StylePatternFactory.createPatternFromNode(node);
// newMindMapController.applyPattern(newNode, pattern);
// // copy text:
// newMindMapController.setNodeText(newNode, node.getText());
MindMapNode copy = node.shallowCopy();
if (copy != null) {
newMindMapController.insertNodeInto(copy, newMap.getRootNode());
}
}
disposeDialog();
}
/**
* @author foltin
* @date 25.04.2012
*/
private final class MindmapTableModel extends DefaultTableModel {
/*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#getColumnClass(int)
*/
public Class getColumnClass(int arg0) {
switch (arg0) {
case DATE_COLUMN:
case NODE_CREATED_COLUMN:
case NODE_MODIFIED_COLUMN:
return Date.class;
case NODE_TEXT_COLUMN:
return NodeHolder.class;
case NODE_ICON_COLUMN:
return IconsHolder.class;
case NODE_NOTES_COLUMN:
return NotesHolder.class;
default:
return Object.class;
}
}
}
/**
* @author foltin
* @date 25.04.2012
*/
private final class ToggleViewFoldedNodesAction extends AbstractAction implements MenuItemSelectedListener {
/**
* @param pName
*/
private ToggleViewFoldedNodesAction(String pName) {
super(pName);
}
public void actionPerformed(ActionEvent arg0) {
toggleViewFoldedNodes();
}
/* (non-Javadoc)
* @see freemind.controller.MenuItemSelectedListener#isSelected(javax.swing.JMenuItem, javax.swing.Action)
*/
public boolean isSelected(JMenuItem pCheckItem, Action pAction) {
return mViewFoldedNodes;
}
}
public interface IReplaceInputInformation {
int getLength();
NodeHolder getNodeHolderAt(int i);
void changeString(NodeHolder holder, String newText);
}
private void replace(IReplaceInputInformation info) {
try {
String searchString = getText(mFilterTextSearchField.getDocument());
String replaceString = getText(mFilterTextReplaceField
.getDocument());
replace(info, searchString, replaceString);
timeTableModel.fireTableDataChanged();
mFlatNodeTableFilterModel.resetFilter();
mFilterTextSearchField.setText("");
} catch (BadLocationException e) {
freemind.main.Resources.getInstance().logException(e);
}
}
public static void replace(IReplaceInputInformation info,
String searchString, String replaceString) {
String regExp = "(" + (searchString) + ")";
Pattern p = Pattern.compile(regExp, Pattern.CASE_INSENSITIVE);
// String replacement = getPureRegularExpression(replaceString);
String replacement = (replaceString);
int length = info.getLength();
for (int i = 0; i < length; i++) {
NodeHolder nodeHolder = info.getNodeHolderAt(i);
String text = nodeHolder.node.getText();
String replaceResult = HtmlTools.getInstance().getReplaceResult(p,
replacement, text);
if (!Tools.safeEquals(text, replaceResult)) {
// set new node text only, if different.
info.changeString(nodeHolder, replaceResult);
}
}
}
private class ReplaceAllInfo implements IReplaceInputInformation {
public int getLength() {
return mFlatNodeTableFilterModel.getRowCount();
}
public NodeHolder getNodeHolderAt(int i) {
return (NodeHolder) mFlatNodeTableFilterModel.getValueAt(i,
NODE_TEXT_COLUMN);
}
public void changeString(NodeHolder nodeHolder, String newText) {
getMindMapController().setNodeText(nodeHolder.node, newText);
}
}
private class ReplaceSelectedInfo implements IReplaceInputInformation {
public int getLength() {
return timeTable.getSelectedRowCount();
}
public NodeHolder getNodeHolderAt(int i) {
return (NodeHolder) sorter.getValueAt(
timeTable.getSelectedRows()[i], NODE_TEXT_COLUMN);
}
public void changeString(NodeHolder nodeHolder, String newText) {
getMindMapController().setNodeText(nodeHolder.node, newText);
}
}
private void selectSelectedRows() {
selectNodes(timeTable.getSelectedRow(), timeTable.getSelectedRows());
}
private void gotoNodesAndClose(int focussedRow, int[] selectedRows) {
selectNodes(focussedRow, selectedRows);
disposeDialog();
}
private void selectNodes(int focussedRow, int[] selectedRows) {
if (focussedRow >= 0) {
MindMapNode focussedNode = getMindMapNode(focussedRow);
// getController().centerNode(focussedNode);
Vector selectedNodes = new Vector();
for (int i = 0; i < selectedRows.length; i++) {
int row = selectedRows[i];
selectedNodes.add(getMindMapNode(row));
}
getMindMapController().select(focussedNode, selectedNodes);
}
}
/**
*/
private MindMapNode getMindMapNode(int focussedRow) {
MindMapNode selectedNode = ((NodeHolder) timeTable.getModel()
.getValueAt(focussedRow, NODE_TEXT_COLUMN)).node;
return selectedNode;
}
/**
* Creates a table model for the new table and returns it.
*/
private DefaultTableModel updateModel() {
TimeWindowConfigurationStorage storage = null;
// if not first call, get configuration
if(sorter != null) {
storage = getTableConfiguration();
}
DefaultTableModel model = new MindmapTableModel();
model.addColumn(COLUMN_DATE);
model.addColumn(COLUMN_TEXT);
model.addColumn(COLUMN_ICONS);
model.addColumn(COLUMN_CREATED);
model.addColumn(COLUMN_MODIFIED);
model.addColumn(COLUMN_NOTES);
MindMapNode node = getMindMapController().getMap().getRootNode();
updateModel(model, node);
timeTableModel = model;
mFlatNodeTableFilterModel = new FlatNodeTableFilterModel(
timeTableModel, NODE_TEXT_COLUMN, NODE_NOTES_COLUMN);
if(sorter == null) {
sorter = new TableSorter(mFlatNodeTableFilterModel);
timeTable.setModel(sorter);
} else {
sorter.setTableModel(mFlatNodeTableFilterModel);
}
if(storage != null) {
setTableConfiguration(storage);
}
try {
String text = getRegularExpression(getText(mFilterTextSearchField
.getDocument()));
mFlatNodeTableFilterModel.setFilter(text);
} catch (BadLocationException e) {
freemind.main.Resources.getInstance().logException(e);
}
return model;
}
private void updateModel(DefaultTableModel model, MindMapNode node) {
ReminderHookBase hook = TimeManagementOrganizer.getHook(node);
// show all nodes or only those with reminder:
if (showAllNodes || hook != null) {
Date date = null;
if (hook != null) {
date = new Date(hook.getRemindUserAt());
}
model.addRow(new Object[] { date, new NodeHolder(node),
new IconsHolder(node),
node.getHistoryInformation().getCreatedAt(),
node.getHistoryInformation().getLastModifiedAt(),
new NotesHolder(node) });
}
if((!mViewFoldedNodes) && node.isFolded()) {
// no recursion, if folded nodes should be hidden.
return;
}
for (Iterator i = node.childrenUnfolded(); i.hasNext();) {
MindMapNode child = (MindMapNode) i.next();
updateModel(model, child);
}
}
/**
*/
private JPanel getTimePanel() {
if (timePanel == null) {
timePanel = new JPanel();
timePanel.setLayout(new GridBagLayout());
// {
// GridBagConstraints gb2 = new GridBagConstraints();
// gb2.gridx = 0;
// gb2.gridy = 0;
// gb2.fill = GridBagConstraints.HORIZONTAL;
// timePanel.add(new JLabel(
// getResourceString("plugins/TimeManagement.xml_hour")),
// gb2);
// }
}
return timePanel;
}
/**
*
*/
private void disposeDialog() {
// store window positions:
TimeWindowConfigurationStorage storage = getTableConfiguration();
getMindMapController().storeDialogPositions(dialog, storage,
WINDOW_PREFERENCE_STORAGE_PROPERTY);
getMindMapController().getController().getMapModuleManager()
.removeListener(this);
dialog.setVisible(false);
dialog.dispose();
}
protected TimeWindowConfigurationStorage getTableConfiguration() {
TimeWindowConfigurationStorage storage = new TimeWindowConfigurationStorage();
storage.setViewFoldedNodes(mViewFoldedNodes);
for (int i = 0; i < timeTable.getColumnCount(); i++) {
TimeWindowColumnSetting setting = new TimeWindowColumnSetting();
setting.setColumnWidth(timeTable.getColumnModel().getColumn(i)
.getWidth());
setting.setColumnSorting(sorter.getSortingStatus(i));
storage.addTimeWindowColumnSetting(setting);
}
return storage;
}
public static String getRegularExpression(String text)
throws BadLocationException {
text = ".*(" + text + ").*";
return text;
}
/**
* @throws BadLocationException
*/
private String getText(Document document) throws BadLocationException {
String text = document.getText(0, document.getLength());
return text;
}
/**
* Removes all regular expression stuff with exception of "*", which is
* replaced by ".*".
*/
public static String getPureRegularExpression(String text) {
// remove regexp:
text = text.replaceAll("([().\\[\\]^$|])", "\\\\$1");
text = text.replaceAll("\\*", ".*");
return text;
}
private final class FilterTextDocumentListener implements DocumentListener {
private Timer mTypeDelayTimer = null;
private synchronized void change(DocumentEvent event) {
// stop old timer, if present:
if (mTypeDelayTimer != null) {
mTypeDelayTimer.cancel();
mTypeDelayTimer = null;
}
mTypeDelayTimer = new Timer();
mTypeDelayTimer.schedule(new DelayedTextEntry(event),
TYPE_DELAY_TIME);
}
public void insertUpdate(DocumentEvent event) {
change(event);
}
public void removeUpdate(DocumentEvent event) {
change(event);
}
public void changedUpdate(DocumentEvent event) {
change(event);
}
protected class DelayedTextEntry extends TimerTask {
private final DocumentEvent event;
DelayedTextEntry(DocumentEvent event) {
this.event = event;
}
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
Document document = event.getDocument();
String text = getRegularExpression(getText(document));
mFlatNodeTableFilterModel.setFilter(text);
} catch (BadLocationException e) {
freemind.main.Resources.getInstance().logException(
e);
mFlatNodeTableFilterModel.resetFilter();
}
}
});
}
}
}
private final class FlatNodeTableMouseAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
Point p = e.getPoint();
int row = timeTable.rowAtPoint(p);
gotoNodesAndClose(row, new int[] { row });
}
}
}
private final class FlatNodeTableKeyListener implements KeyListener {
public void keyTyped(KeyEvent arg0) {
}
public void keyPressed(KeyEvent arg0) {
}
public void keyReleased(KeyEvent arg0) {
if (arg0.getKeyCode() == KeyEvent.VK_ESCAPE) {
disposeDialog();
}
if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {
selectSelectedRows();
disposeDialog();
}
}
}
private final class FlatNodeTable extends JTable {
public TableCellRenderer getCellRenderer(int row, int column) {
Object object = getModel().getValueAt(row, column);
if (object instanceof Date)
return dateRenderer;
if (object instanceof NodeHolder)
return nodeRenderer;
if (object instanceof NotesHolder)
return notesRenderer;
if (object instanceof IconsHolder)
return iconsRenderer;
return super.getCellRenderer(row, column);
}
public boolean isCellEditable(int rowIndex, int vColIndex) {
return false;
}
protected void processKeyEvent(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
EventListener[] el = super.getListeners(KeyListener.class);
if (e.getID() != KeyEvent.KEY_RELEASED)
return;
for (int i = 0; i < el.length; i++) {
KeyListener kl = (KeyListener) el[i];
kl.keyReleased(e);
}
return;
}
super.processKeyEvent(e);
}
}
static class DateRenderer extends DefaultTableCellRenderer {
DateFormat formatter;
public DateRenderer() {
super();
}
public void setValue(Object value) {
if (formatter == null) {
formatter = DateFormat.getDateTimeInstance();
}
setText((value == null) ? "" : formatter.format(value));
}
}
static class NodeRenderer extends DefaultTableCellRenderer {
public NodeRenderer() {
super();
}
public void setValue(Object value) {
setText((value == null) ? "" : ((NodeHolder) value)
.getUntaggedNodeText());
}
}
static class NotesRenderer extends DefaultTableCellRenderer {
public NotesRenderer() {
super();
}
public void setValue(Object value) {
setText((value == null) ? "" : ((NotesHolder) value)
.getUntaggedNotesText());
}
}
/** removes html in nodes before comparison. */
public static class NodeHolder implements Comparable {
private final MindMapNode node;
private String untaggedNodeText = null;
/**
* Holds the original node content to cache the untaggedNodeText and to
* see whether or not the cache is dirty.
*/
private String originalNodeText = null;
/**
*
*/
public NodeHolder(MindMapNode node) {
this.node = node;
}
public int compareTo(Object compareToObject) {
return toString().compareTo(compareToObject.toString());
}
public String toString() {
return getUntaggedNodeText();
}
public String getUntaggedNodeText() {
String nodeText = node.getText();
// cache empty or dirty?:
if (untaggedNodeText == null
|| (originalNodeText != null && !originalNodeText
.equals(nodeText))) {
originalNodeText = nodeText;
// remove tags:
untaggedNodeText = HtmlTools.htmlToPlain(nodeText)
.replaceAll("\\s+", " ");
}
return untaggedNodeText;
}
}
/** removes html in notes before comparison. */
public static class NotesHolder implements Comparable {
private final MindMapNode node;
private String untaggedNotesText = null;
private String originalNotesText = null;
/**
*
*/
public NotesHolder(MindMapNode node) {
this.node = node;
}
public int compareTo(Object compareToObject) {
return toString().compareTo(compareToObject.toString());
}
public String toString() {
return getUntaggedNotesText();
}
public String getUntaggedNotesText() {
String notesText = node.getNoteText();
if (notesText == null)
return "";
if (untaggedNotesText == null
|| (originalNotesText != null && !originalNotesText
.equals(notesText))) {
originalNotesText = notesText;
// remove tags:
untaggedNotesText = HtmlTools.removeHtmlTagsFromString(
notesText).replaceAll("\\s+", " ");
}
return untaggedNotesText;
}
}
static class IconsHolder implements Comparable {
Vector icons = new Vector();
private Vector iconNames;
public IconsHolder(MindMapNode node) {
icons.addAll(node.getIcons());
// sorting the output.
iconNames = new Vector();
for (Iterator i = icons.iterator(); i.hasNext();) {
MindIcon icon = (MindIcon) i.next();
iconNames.add(icon.getName());
}
Collections.sort(iconNames);
}
public int compareTo(Object compareToObject) {
return toString().compareTo(compareToObject.toString());
}
public Vector getIcons() {
return icons;
}
/** Returns a sorted list of icon names. */
public String toString() {
String result = "";
for (Iterator i = iconNames.iterator(); i.hasNext();) {
String name = (String) i.next();
result += name + " ";
}
return result;
}
}
static class IconsRenderer extends DefaultTableCellRenderer {
private final ModeController modeController;
public IconsRenderer(ModeController controller) {
super();
modeController = controller;
}
public void setValue(Object value) {
if (value instanceof IconsHolder) {
IconsHolder iconsHolder = (IconsHolder) value;
MultipleImage iconImages = new MultipleImage(1.0f);
for (Iterator i = iconsHolder.getIcons().iterator(); i
.hasNext();) {
MindIcon icon = (MindIcon) i.next();
iconImages.addImage(icon.getIcon());
}
if (iconImages.getImageCount() > 0) {
setIcon(iconImages);
} else {
setIcon(null);
}
}
}
}
/**
* Overwritten, as this dialog is not modal, but after the plugin has
* terminated, the dialog is still present and needs the controller to store
* its values.
* */
public MindMapController getMindMapController() {
return mMyMindMapController;
}
/*
* (non-Javadoc)
*
* @see freemind.controller.MapModuleManager.MapModuleChangeObserver#
* isMapModuleChangeAllowed(freemind.view.MapModule, freemind.modes.Mode,
* freemind.view.MapModule, freemind.modes.Mode)
*/
public boolean isMapModuleChangeAllowed(MapModule pOldMapModule,
Mode pOldMode, MapModule pNewMapModule, Mode pNewMode) {
return true;
}
/*
* (non-Javadoc)
*
* @see freemind.controller.MapModuleManager.MapModuleChangeObserver#
* beforeMapModuleChange(freemind.view.MapModule, freemind.modes.Mode,
* freemind.view.MapModule, freemind.modes.Mode)
*/
public void beforeMapModuleChange(MapModule pOldMapModule, Mode pOldMode,
MapModule pNewMapModule, Mode pNewMode) {
}
/*
* (non-Javadoc)
*
* @see
* freemind.controller.MapModuleManager.MapModuleChangeObserver#afterMapClose
* (freemind.view.MapModule, freemind.modes.Mode)
*/
public void afterMapClose(MapModule pOldMapModule, Mode pOldMode) {
disposeDialog();
}
/*
* (non-Javadoc)
*
* @see freemind.controller.MapModuleManager.MapModuleChangeObserver#
* afterMapModuleChange(freemind.view.MapModule, freemind.modes.Mode,
* freemind.view.MapModule, freemind.modes.Mode)
*/
public void afterMapModuleChange(MapModule pOldMapModule, Mode pOldMode,
MapModule pNewMapModule, Mode pNewMode) {
disposeDialog();
}
/*
* (non-Javadoc)
*
* @see freemind.controller.MapModuleManager.MapModuleChangeObserver#
* numberOfOpenMapInformation(int, int)
*/
public void numberOfOpenMapInformation(int pNumber, int pIndex) {
}
}