001: /*
002: * MacroManagerGui.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.macros;
013:
014: import java.awt.BorderLayout;
015: import java.awt.EventQueue;
016: import java.beans.PropertyChangeListener;
017: import java.util.ArrayList;
018: import java.util.Collections;
019: import java.util.List;
020:
021: import javax.swing.AbstractListModel;
022: import javax.swing.JLabel;
023: import javax.swing.JList;
024: import javax.swing.JPanel;
025: import javax.swing.JScrollPane;
026: import javax.swing.JSplitPane;
027: import javax.swing.JToolBar;
028: import javax.swing.border.CompoundBorder;
029: import javax.swing.border.EmptyBorder;
030: import javax.swing.event.ListSelectionEvent;
031: import javax.swing.event.ListSelectionListener;
032:
033: import workbench.gui.WbSwingUtilities;
034: import workbench.gui.actions.DeleteListEntryAction;
035: import workbench.gui.actions.NewListEntryAction;
036: import workbench.gui.actions.SaveListFileAction;
037: import workbench.gui.components.StringPropertyEditor;
038: import workbench.gui.components.WbSplitPane;
039: import workbench.gui.components.WbToolbar;
040: import workbench.gui.components.WbTraversalPolicy;
041: import workbench.gui.sql.EditorPanel;
042: import workbench.interfaces.FileActions;
043: import workbench.resource.ResourceMgr;
044: import workbench.resource.Settings;
045: import workbench.sql.MacroManager;
046:
047: /**
048: * Displays all stored macros and lets the user add, edit and delete macros.
049: * It uses {@link workbench.sql.MacroManager} to retrieve and store
050: * the macros.
051: */
052: public class MacroManagerGui extends JPanel implements FileActions,
053: ListSelectionListener, PropertyChangeListener {
054: private JToolBar toolbar;
055: private int lastIndex = -1;
056: private MacroEntry currentEntry;
057: private JSplitPane jSplitPane1;
058: protected JList macroList;
059: private EditorPanel macroEditor;
060: private StringPropertyEditor macroNameField;
061: private MacroListModel model;
062:
063: public MacroManagerGui() {
064: this .toolbar = new WbToolbar();
065: this .toolbar.add(new NewListEntryAction(this ));
066: this .toolbar.add(new SaveListFileAction(this ));
067: this .toolbar.addSeparator();
068: this .toolbar.add(new DeleteListEntryAction(this ));
069:
070: JPanel listPanel = new JPanel();
071: listPanel.setLayout(new BorderLayout());
072: listPanel.add(this .toolbar, BorderLayout.NORTH);
073:
074: this .jSplitPane1 = new WbSplitPane();
075:
076: this .model = new MacroListModel();
077: this .macroList = new JList(this .model);
078:
079: this .setLayout(new BorderLayout());
080:
081: jSplitPane1.setDividerLocation(100);
082:
083: JScrollPane scroll = new JScrollPane(this .macroList);
084: scroll.setBorder(WbSwingUtilities.EMPTY_BORDER);
085: listPanel.add(scroll, java.awt.BorderLayout.CENTER);
086:
087: this .macroEditor = EditorPanel.createSqlEditor();
088: this .macroEditor.showFindOnPopupMenu();
089: this .macroEditor.showFormatSql();
090:
091: jSplitPane1.setLeftComponent(listPanel);
092:
093: JPanel namePanel = new JPanel();
094: namePanel.setLayout(new BorderLayout());
095: JLabel l = new JLabel(ResourceMgr.getString("LblMacroName"));
096: l.setBorder(new CompoundBorder(new EmptyBorder(0, 5, 0, 5), l
097: .getBorder()));
098: this .macroNameField = new StringPropertyEditor(); //new JTextField(40);
099: this .macroNameField.setColumns(40);
100: this .macroNameField.setImmediateUpdate(true);
101: this .macroNameField.addPropertyChangeListener(this );
102: //this.macroNameField.setBorder(new CompoundBorder(new EmptyBorder(0,0,0,5), this.macroNameField.getBorder()));
103:
104: namePanel.add(l, BorderLayout.WEST);
105: namePanel.add(this .macroNameField, BorderLayout.CENTER);
106:
107: // Create some visiual space above and below the entry field
108: JPanel p = new JPanel();
109: namePanel.add(p, BorderLayout.SOUTH);
110: p = new JPanel();
111: namePanel.add(p, BorderLayout.NORTH);
112:
113: JPanel editor = new JPanel();
114: editor.setLayout(new BorderLayout());
115: editor.add(namePanel, BorderLayout.NORTH);
116: editor.add(macroEditor, BorderLayout.CENTER);
117: jSplitPane1.setRightComponent(editor);
118:
119: add(jSplitPane1, BorderLayout.CENTER);
120: macroList.addListSelectionListener(this );
121:
122: WbTraversalPolicy policy = new WbTraversalPolicy();
123: policy.addComponent(macroList);
124: policy.addComponent(macroNameField);
125: policy.addComponent(macroEditor);
126: policy.setDefaultComponent(macroList);
127: this .setFocusTraversalPolicy(policy);
128: }
129:
130: public JList getMacroList() {
131: return this .macroList;
132: }
133:
134: public String getSelectedMacroName() {
135: int index = this .macroList.getSelectedIndex();
136: if (index < 0)
137: return null;
138: String name = this .model.getKeyAt(index);
139: return name;
140: }
141:
142: public void deleteItem() throws Exception {
143: int index = this .macroList.getSelectedIndex();
144: if (index < 0)
145: return;
146: this .macroList.clearSelection();
147: //this.macroList.setValueIsAdjusting(true);
148: this .macroEditor.setText("");
149: this .macroNameField.setText("");
150: this .model.removeElementAt(index);
151:
152: // check if the last driver was deleted
153: if (index > this .model.getSize() - 1)
154: index--;
155: //this.macroList.setValueIsAdjusting(false);
156:
157: if (index >= 0) {
158: this .macroList.setSelectedIndex(index);
159: this .macroList.repaint();
160: }
161: }
162:
163: /**
164: * Create a new profile. This will only be
165: * created in the ListModel.
166: */
167: public void newItem(boolean copyCurrent) throws Exception {
168: String key;
169: String text;
170: if (copyCurrent) {
171: int index = this .macroList.getSelectedIndex();
172: key = this .model.getKeyAt(index);
173: if (key == null) {
174: key = ResourceMgr.getString("TxtEmptyMacroName");
175: text = "";
176: } else {
177: text = MacroManager.getInstance().getMacroText(key);
178: }
179: } else {
180: key = ResourceMgr.getString("TxtEmptyMacroName");
181: text = "";
182: }
183: MacroEntry entry = this .model.addMacro(key, text);
184: this .macroList.setSelectedIndex(this .model.getSize() - 1);
185: this .macroList.updateUI();
186: this .showMacro(entry);
187: }
188:
189: private void selectListLater() {
190: EventQueue.invokeLater(new Runnable() {
191: public void run() {
192: macroList.requestFocusInWindow();
193: }
194: });
195: }
196:
197: public void saveItem() throws Exception {
198: int index = this .macroList.getSelectedIndex();
199: if (index >= 0) {
200: this .model.setMacroAt(index, this .macroNameField.getText(),
201: this .macroEditor.getText());
202: }
203: this .model.saveMacros();
204: }
205:
206: public void saveSettings() {
207: int location = this .jSplitPane1.getDividerLocation();
208: Settings.getInstance().setProperty(
209: this .getClass().getName() + ".divider", location);
210: String macro = this .getSelectedMacroName();
211: if (macro != null) {
212: Settings.getInstance().setProperty(
213: this .getClass().getName() + ".lastmacro", macro);
214: }
215: }
216:
217: public void restoreSettings() {
218: int location = Settings.getInstance().getIntProperty(
219: this .getClass().getName() + ".divider", 140);
220: this .jSplitPane1.setDividerLocation(location);
221: String macro = Settings.getInstance().getProperty(
222: this .getClass().getName() + ".lastmacro", null);
223: this .selectMacro(macro);
224: this .selectListLater();
225: }
226:
227: private void selectMacro(String macro) {
228: if (this .model == null || this .macroList == null)
229: return;
230: int count = this .model.getSize();
231: if (macro == null) {
232: this .macroList.setSelectedIndex(0);
233: return;
234: }
235:
236: for (int i = 0; i < count; i++) {
237: MacroEntry entry = (MacroEntry) this .model.getElementAt(i);
238: if (macro.equalsIgnoreCase(entry.getName())) {
239: macroList.setSelectedIndex(i);
240: return;
241: }
242: }
243: // if we get here, the macro was not found
244: this .macroList.setSelectedIndex(0);
245: }
246:
247: public void addSelectionListener(ListSelectionListener aListener) {
248: this .macroList.addListSelectionListener(aListener);
249: }
250:
251: public void valueChanged(ListSelectionEvent evt) {
252: if (this .macroList.getValueIsAdjusting())
253: return;
254: if (this .lastIndex >= 0) {
255: this .model.setMacroAt(this .lastIndex, this .macroNameField
256: .getText(), this .macroEditor.getText());
257: }
258: this .lastIndex = this .macroList.getSelectedIndex();
259: if (this .lastIndex < 0)
260: return;
261: if (this .lastIndex > this .model.getSize() - 1)
262: return;
263:
264: MacroEntry entry = (MacroEntry) this .model
265: .getElementAt(this .lastIndex);
266: this .showMacro(entry);
267: }
268:
269: private void showMacro(final MacroEntry entry) {
270: this .currentEntry = entry;
271: this .macroNameField.setSourceObject(this .currentEntry, "name",
272: entry.getName());
273: this .macroNameField.setImmediateUpdate(true);
274: this .macroEditor.setText(entry.getText());
275: this .macroEditor.setCaretPosition(0);
276: }
277:
278: public void propertyChange(java.beans.PropertyChangeEvent evt) {
279: this .macroList.repaint();
280: }
281:
282: }
283:
284: class MacroListModel extends AbstractListModel {
285: ArrayList macros;
286:
287: public MacroListModel() {
288: List keys = MacroManager.getInstance().getMacroList();
289: Collections.sort(keys);
290: int size = keys.size();
291: if (size == 0) {
292: macros = new ArrayList(10);
293: return;
294: }
295: macros = new ArrayList(size);
296:
297: for (int i = 0; i < size; i++) {
298: String key = (String) keys.get(i);
299: String text = MacroManager.getInstance().getMacroText(key);
300: macros.add(new MacroEntry(key, text));
301: }
302: }
303:
304: /*
305: public void addListDataListener(javax.swing.event.ListDataListener l)
306: {
307: }
308: */
309: public Object getElementAt(int index) {
310: return this .macros.get(index);
311: }
312:
313: public int getSize() {
314: return this .macros.size();
315: }
316:
317: /*
318: public void removeListDataListener(javax.swing.event.ListDataListener l)
319: {
320: }
321: */
322:
323: public void setMacroAt(int index, String aName, String aText) {
324: if (index < 0 || index >= this .macros.size())
325: return;
326: MacroEntry entry = (MacroEntry) this .macros.get(index);
327: entry.setName(aName);
328: entry.setText(aText);
329: this .fireContentsChanged(this , index, index);
330: }
331:
332: public MacroEntry addMacro(String aKey, String aText) {
333: MacroEntry entry = new MacroEntry(aKey, aText);
334: this .macros.add(entry);
335: int size = this .macros.size();
336: this .fireContentsChanged(this , size, size);
337: return entry;
338: }
339:
340: public void removeElementAt(int index) {
341: this .macros.remove(index);
342: this .fireContentsChanged(this , index, index);
343: }
344:
345: public String getKeyAt(int index) {
346: String name = null;
347: if (index > -1 && index < this .macros.size()) {
348: MacroEntry entry = (MacroEntry) this .macros.get(index);
349: name = entry.getName();
350: }
351: return name;
352: }
353:
354: public void saveMacros() {
355: MacroManager mgr = MacroManager.getInstance();
356: mgr.setMacros(macros);
357: mgr.saveMacros();
358: }
359: }
|