001: /*
002:
003: The contents of this file are subject to the Mozilla Public License Version 1.1
004: (the "License") you may not use this file except in compliance with the License.
005:
006: You may obtain a copy of the License at http://www.mozilla.org/MPL/
007:
008: Software distributed under the License is distributed on an "AS IS" basis,
009: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: for the specific language governing rights and limitations under the License.
011:
012: The Original Code is "BshInterpreter plugin for The Columba Project"
013:
014: The Initial Developer of the Original Code is Celso Pinto
015: Portions created by Celso Pinto are Copyright (C) 2005.
016: Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
017:
018: All Rights Reserved.
019:
020: */
021: package org.columba.core.gui.scripting;
022:
023: import java.awt.BorderLayout;
024: import java.awt.Color;
025: import java.awt.Dimension;
026: import java.awt.FlowLayout;
027: import java.awt.Frame;
028: import java.awt.GridLayout;
029: import java.awt.event.ActionEvent;
030: import java.awt.event.ActionListener;
031: import java.util.logging.Logger;
032:
033: import javax.swing.BorderFactory;
034: import javax.swing.JButton;
035: import javax.swing.JDialog;
036: import javax.swing.JOptionPane;
037: import javax.swing.JPanel;
038: import javax.swing.JScrollPane;
039: import javax.swing.JTabbedPane;
040: import javax.swing.JTable;
041: import javax.swing.ListSelectionModel;
042: import javax.swing.SwingConstants;
043: import javax.swing.SwingUtilities;
044: import javax.swing.event.ListSelectionEvent;
045: import javax.swing.event.ListSelectionListener;
046: import javax.swing.table.DefaultTableCellRenderer;
047: import javax.swing.table.TableColumnModel;
048: import javax.swing.table.TableModel;
049:
050: import org.columba.core.gui.base.ButtonWithMnemonic;
051: import org.columba.core.gui.base.SingleSideEtchedBorder;
052: import org.columba.core.scripting.ScriptLogger;
053: import org.columba.core.scripting.model.ColumbaScript;
054:
055: /**
056: @author Celso Pinto (cpinto@yimports.com)
057: */
058: public class ScriptManager extends JDialog implements ActionListener {
059:
060: private static final Logger LOG = Logger
061: .getLogger(ScriptManager.class.getName());
062:
063: /*TODO move resources to a resource file */
064: private static final String RES_WINDOW_TITLE = "Macros",
065: RES_EDIT_BUTTON = "&Edit",
066: RES_REFRESH_BUTTON = "&Refresh",
067: RES_REMOVE_BUTTON = "Re&move",
068: RES_CLOSE_BUTTON = "&Close",
069: RES_LOG_DETAILS_BUTTON = "&Details...",
070: RES_CLEAR_LOG_BUTTON = "C&lear",
071: RES_TAB_SCRIPTS = "Scripts",
072: RES_TAB_LOG = "Log",
073: RES_REMOVE_MESSAGE = "The selected scripts will be removed from disk.\nContinue?",
074: RES_WARNING_DIALOG_TITLE = "Remove scripts";
075:
076: private static final String EDIT_SCRIPT_ACTION = "edit",
077: REMOVE_SCRIPT_ACTION = "remove",
078: REFRESH_LIST_ACTION = "refresh", CLOSE_ACTION = "close",
079: LOG_DETAILS_ACTION = "log_details",
080: CLEAR_LOG_ACTION = "clear_log";
081:
082: private JTable scriptsList, logList;
083:
084: private JButton editScriptButton, removeScriptButton,
085: refreshListButton, logDetailsButton, clearLogButton;
086:
087: private ScriptManagerDocument document;
088:
089: public ScriptManager(Frame parent, ScriptManagerDocument doc) {
090: super (parent, RES_WINDOW_TITLE, true);
091: document = doc;
092:
093: initGui();
094: setLocationRelativeTo(getParent());
095:
096: }
097:
098: private void initGui() {
099:
100: JPanel bottomPanel = new JPanel(
101: new FlowLayout(FlowLayout.RIGHT));
102: bottomPanel.setBorder(new SingleSideEtchedBorder(
103: SwingConstants.TOP));
104: bottomPanel.add(createDialogActionsPanel());
105:
106: getContentPane().setLayout(new BorderLayout());
107: JTabbedPane tabs = new JTabbedPane();
108: tabs.add(RES_TAB_SCRIPTS, createScriptsPanel());
109: tabs.add(RES_TAB_LOG, createLogPanel());
110: getContentPane().add(tabs, BorderLayout.CENTER);
111: getContentPane().add(bottomPanel, BorderLayout.SOUTH);
112:
113: setButtonStatus();
114:
115: pack();
116:
117: }
118:
119: private JPanel createLogPanel() {
120: JPanel panel = new JPanel(new BorderLayout(10, 0));
121: panel
122: .setBorder(BorderFactory.createEmptyBorder(10, 10, 10,
123: 10));
124: panel.add(createLogList(), BorderLayout.CENTER);
125: panel.add(createLogListActionsPanel(), BorderLayout.EAST);
126: return panel;
127: }
128:
129: private JPanel createLogListActionsPanel() {
130: JPanel panel = new JPanel(new GridLayout(2, 1, 0, 5));
131:
132: logDetailsButton = new ButtonWithMnemonic(
133: RES_LOG_DETAILS_BUTTON);
134: clearLogButton = new ButtonWithMnemonic(RES_CLEAR_LOG_BUTTON);
135:
136: logDetailsButton.setActionCommand(LOG_DETAILS_ACTION);
137: clearLogButton.setActionCommand(CLEAR_LOG_ACTION);
138:
139: logDetailsButton.addActionListener(this );
140: clearLogButton.addActionListener(this );
141:
142: panel.add(logDetailsButton);
143: panel.add(clearLogButton);
144:
145: JPanel container = new JPanel(new BorderLayout());
146: container.add(panel, BorderLayout.NORTH);
147: return container;
148:
149: }
150:
151: private JPanel createLogList() {
152: JPanel panel = new JPanel(new BorderLayout());
153:
154: logList = new JTable(new ScriptLogTableModel());
155:
156: logList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
157: logList.setShowGrid(true);
158: logList.sizeColumnsToFit(JTable.AUTO_RESIZE_ALL_COLUMNS);
159:
160: logList.getSelectionModel().addListSelectionListener(
161: new ListSelectionListener() {
162: public void valueChanged(ListSelectionEvent e) {
163: if (e.getValueIsAdjusting())
164: return;
165:
166: setButtonStatus();
167: }
168:
169: });
170:
171: TableColumnModel tcm = logList.getColumnModel();
172: tcm.getColumn(ScriptLogTableModel.MESSAGE_COLUMN)
173: .setPreferredWidth(400);
174: tcm.getColumn(ScriptLogTableModel.MESSAGE_COLUMN)
175: .setCellRenderer(new DefaultTableCellRenderer() {
176: protected void setValue(Object value) {
177: setText(((ScriptLogger.LogEntry) value)
178: .getMessage());
179: }
180: });
181:
182: JScrollPane scrollPane = new JScrollPane(logList);
183: scrollPane.setPreferredSize(new Dimension(450, 200));
184: scrollPane.getViewport().setBackground(Color.white);
185: panel.add(scrollPane, BorderLayout.CENTER);
186:
187: return panel;
188: }
189:
190: private JPanel createScriptsPanel() {
191:
192: JPanel panel = new JPanel(new BorderLayout(10, 0));
193: panel
194: .setBorder(BorderFactory.createEmptyBorder(10, 10, 10,
195: 10));
196: panel.add(createScriptList(), BorderLayout.CENTER);
197: panel.add(createScriptActionsPanel(), BorderLayout.EAST);
198:
199: return panel;
200:
201: }
202:
203: private JPanel createScriptList() {
204: JPanel panel = new JPanel(new BorderLayout());
205:
206: scriptsList = new JTable(new ScriptsTableModel(document));
207:
208: scriptsList
209: .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
210: scriptsList.setShowGrid(false);
211: scriptsList.sizeColumnsToFit(JTable.AUTO_RESIZE_NEXT_COLUMN);
212:
213: scriptsList.getSelectionModel().addListSelectionListener(
214: new ListSelectionListener() {
215: public void valueChanged(ListSelectionEvent e) {
216: if (e.getValueIsAdjusting())
217: return;
218:
219: setButtonStatus();
220: }
221: });
222:
223: TableColumnModel tcm = scriptsList.getColumnModel();
224: tcm.getColumn(ScriptsTableModel.NAME_COLUMN).setPreferredWidth(
225: 100);
226: tcm.getColumn(ScriptsTableModel.NAME_COLUMN).setCellRenderer(
227: new DefaultTableCellRenderer() {
228: protected void setValue(Object value) {
229: setText(((ColumbaScript) value).getName());
230: }
231: });
232:
233: tcm.getColumn(ScriptsTableModel.AUTHOR_COLUMN)
234: .setPreferredWidth(100);
235: tcm.getColumn(ScriptsTableModel.DESCRIPTION_COLUMN)
236: .setPreferredWidth(250);
237:
238: JScrollPane scrollPane = new JScrollPane(scriptsList);
239: scrollPane.setPreferredSize(new Dimension(450, 200));
240: scrollPane.getViewport().setBackground(Color.white);
241: panel.add(scrollPane, BorderLayout.CENTER);
242:
243: return panel;
244: }
245:
246: private JPanel createScriptActionsPanel() {
247:
248: JPanel scriptActionsPanel = new JPanel(new GridLayout(3, 1, 0,
249: 5));
250:
251: editScriptButton = new ButtonWithMnemonic(RES_EDIT_BUTTON);
252: removeScriptButton = new ButtonWithMnemonic(RES_REMOVE_BUTTON);
253: refreshListButton = new ButtonWithMnemonic(RES_REFRESH_BUTTON);
254:
255: editScriptButton.setActionCommand(EDIT_SCRIPT_ACTION);
256: removeScriptButton.setActionCommand(REMOVE_SCRIPT_ACTION);
257: refreshListButton.setActionCommand(REFRESH_LIST_ACTION);
258:
259: editScriptButton.addActionListener(this );
260: removeScriptButton.addActionListener(this );
261: refreshListButton.addActionListener(this );
262:
263: scriptActionsPanel.add(editScriptButton);
264: scriptActionsPanel.add(removeScriptButton);
265: scriptActionsPanel.add(refreshListButton);
266:
267: JPanel container = new JPanel(new BorderLayout());
268: container.add(scriptActionsPanel, BorderLayout.NORTH);
269:
270: return container;
271: }
272:
273: private void setButtonStatus() {
274: SwingUtilities.invokeLater(new Runnable() {
275: public void run() {
276:
277: boolean scriptSelected = scriptsList
278: .getSelectedRowCount() > 0, hasLogMessages = logList
279: .getRowCount() > 0, logMessageSelected = logList
280: .getSelectedRow() > -1;
281:
282: editScriptButton.setEnabled(scriptSelected);
283: removeScriptButton.setEnabled(scriptSelected);
284: refreshListButton.setEnabled(scriptSelected);
285:
286: if (logMessageSelected) {
287: ScriptLogger.LogEntry entry = (ScriptLogger.LogEntry) logList
288: .getModel().getValueAt(
289: logList.getSelectedRow(),
290: ScriptLogTableModel.MESSAGE_COLUMN);
291:
292: logDetailsButton
293: .setEnabled(entry.getDetails() != null
294: && entry.getDetails().length() > 0);
295: } else {
296: logDetailsButton.setEnabled(false);
297: }
298:
299: clearLogButton.setEnabled(hasLogMessages);
300:
301: }
302: });
303:
304: }
305:
306: private JPanel createDialogActionsPanel() {
307:
308: JButton closeButton = new ButtonWithMnemonic(RES_CLOSE_BUTTON);
309: JPanel actionsPanel = new JPanel(new FlowLayout(
310: FlowLayout.RIGHT));
311:
312: closeButton.setActionCommand(CLOSE_ACTION);
313: closeButton.addActionListener(this );
314: actionsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10,
315: 10, 10));
316: actionsPanel.add(closeButton);
317:
318: return actionsPanel;
319:
320: }
321:
322: public void actionPerformed(ActionEvent event) {
323: String command = event.getActionCommand();
324:
325: if (command.equals(CLOSE_ACTION)) {
326: close();
327: } else if (command.equals(REMOVE_SCRIPT_ACTION)) {
328:
329: if (JOptionPane
330: .showConfirmDialog(this , RES_REMOVE_MESSAGE,
331: RES_WARNING_DIALOG_TITLE,
332: JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
333: return;
334: }
335:
336: int[] selectedIndexes = scriptsList.getSelectedRows();
337: TableModel model = scriptsList.getModel();
338:
339: ColumbaScript[] scripts = new ColumbaScript[selectedIndexes.length];
340: for (int i = 0; i < selectedIndexes.length; i++) {
341: scripts[i] = (ColumbaScript) model.getValueAt(
342: selectedIndexes[i],
343: ScriptsTableModel.NAME_COLUMN);
344: }
345: document.removeScript(scripts);
346: } else if (command.equals(REFRESH_LIST_ACTION)) {
347: document.refreshScriptList();
348: } else if (command.equals(EDIT_SCRIPT_ACTION)) {
349: JOptionPane
350: .showMessageDialog(
351: this ,
352: "Ha ha, wouldn't it be really sweet if this were implemented?",
353: "TODO", JOptionPane.INFORMATION_MESSAGE);
354: } else if (command.equals(LOG_DETAILS_ACTION)) {
355: ScriptLogger.LogEntry entry = (ScriptLogger.LogEntry) logList
356: .getModel().getValueAt(logList.getSelectedRow(),
357: ScriptLogTableModel.MESSAGE_COLUMN);
358:
359: new MessageDetailsDialog(this , entry).setVisible(true);
360:
361: } else if (command.equals(CLEAR_LOG_ACTION)) {
362: ((ScriptLogTableModel) logList.getModel()).clearLog();
363: } else {
364: LOG.warning("Not handling: " + event.getActionCommand());
365: }
366:
367: setButtonStatus();
368: }
369:
370: private void close() {
371:
372: ((ScriptLogTableModel) logList.getModel()).dispose();
373:
374: setVisible(false);
375: dispose();
376: }
377:
378: }
|