001: /*
002: * The contents of this file are subject to the Mozilla Public License
003: * Version 1.1 (the "License"); you may not use this file except in
004: * compliance with the License. You may obtain a copy of the License at
005: * http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
009: * License for the specific language governing rights and limitations
010: * under the License.
011: *
012: * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
013: *
014: * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
015: * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
016: *
017: * Contributor(s):
018: * Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
019: *
020: * If you didn't download this code from the following link, you should check
021: * if you aren't using an obsolete version: http://www.isqlviewer.com
022: */
023: package org.isqlviewer.ui;
024:
025: import java.awt.BorderLayout;
026: import java.awt.Color;
027: import java.awt.Component;
028: import java.awt.Dimension;
029: import java.awt.Font;
030: import java.awt.GridBagConstraints;
031: import java.awt.GridBagLayout;
032: import java.awt.Insets;
033: import java.awt.Window;
034: import java.awt.event.ActionEvent;
035: import java.awt.event.ActionListener;
036: import java.awt.event.WindowEvent;
037: import java.text.DateFormat;
038: import java.text.NumberFormat;
039: import java.util.Date;
040: import java.util.Enumeration;
041: import java.util.prefs.Preferences;
042:
043: import javax.swing.AbstractButton;
044: import javax.swing.Box;
045: import javax.swing.ButtonGroup;
046: import javax.swing.Icon;
047: import javax.swing.JButton;
048: import javax.swing.JComponent;
049: import javax.swing.JLabel;
050: import javax.swing.JMenuBar;
051: import javax.swing.JOptionPane;
052: import javax.swing.JPanel;
053: import javax.swing.JTabbedPane;
054: import javax.swing.JTextField;
055: import javax.swing.JToggleButton;
056: import javax.swing.RootPaneContainer;
057: import javax.swing.SwingConstants;
058: import javax.swing.UIManager;
059: import javax.swing.event.DocumentEvent;
060: import javax.swing.event.DocumentListener;
061: import javax.swing.event.UndoableEditEvent;
062: import javax.swing.event.UndoableEditListener;
063: import javax.swing.plaf.basic.BasicEditorPaneUI;
064: import javax.swing.plaf.basic.BasicTextAreaUI;
065: import javax.swing.plaf.basic.BasicTextFieldUI;
066: import javax.swing.plaf.basic.BasicTextUI;
067: import javax.swing.text.BadLocationException;
068: import javax.swing.text.Document;
069: import javax.swing.text.JTextComponent;
070: import javax.swing.undo.UndoManager;
071: import javax.swing.undo.UndoableEdit;
072:
073: import org.isqlviewer.bookmarks.Bookmark;
074: import org.isqlviewer.bookmarks.BookmarkFolder;
075: import org.isqlviewer.bookmarks.ColorLabel;
076: import org.isqlviewer.swing.SwingUtilities;
077: import org.isqlviewer.swing.WizardPanel;
078: import org.isqlviewer.swing.action.SwingEventManager;
079: import org.isqlviewer.ui.laf.ColorLedIcon;
080: import org.isqlviewer.util.LocalMessages;
081:
082: /**
083: * Editor UI for modifying and viewing bookmark information.
084: * <p>
085: *
086: * @author Markus A. Kobold <mkobold at sprintpcs dot com>
087: * @version 1.0
088: */
089: public class BookmarkEditor extends AbstractObjectEditor implements
090: DocumentListener, UndoableEditListener, ActionListener {
091:
092: private static final int ACTION_OK = 0;
093: private static final int ACTION_APPLY = 1;
094: private static final int ACTION_CANCEL = 2;
095:
096: private LocalMessages messages = new LocalMessages(
097: "org.isqlviewer.ui.ResourceBundle");
098:
099: private Bookmark bookmark = null;
100: private SqlCommandEditor sqlEditor = new SqlCommandEditor();
101: private Document nameDocument = null;
102: private Document createdDocument = null;
103: private Document locationDocument = null;
104: private Document lastUsedDocument = null;
105: private Document useCountDocument = null;
106: private UndoManager undoManager = new UndoManager();
107: private ButtonGroup colorLabelSelection = new ButtonGroup();
108:
109: private RootPaneContainer frameReference = null;
110: private OperationStatus status = OperationStatus.NOT_MODIFIED;
111:
112: public void undoableEditHappened(UndoableEditEvent e) {
113:
114: if (e == null || e.getEdit() == null) {
115: return;
116: }
117:
118: UndoableEdit edit = e.getEdit();
119: String name = edit.getPresentationName();
120: if (name != null && edit.canUndo()) {
121: if (name.indexOf("style") < 0) {
122: undoManager.addEdit(e.getEdit());
123: } else {
124: edit.die();
125: }
126: } else {
127: edit.die();
128: }
129: }
130:
131: public void actionPerformed(ActionEvent event) {
132:
133: int action = -1;
134: try {
135: action = Integer.parseInt(event.getActionCommand());
136: } catch (NumberFormatException ignored) {
137: // this will happen when the color label is changed since the action command is the color name and not a
138: // number //
139: }
140: Component component = (Component) event.getSource();
141: Window window = javax.swing.SwingUtilities
142: .getWindowAncestor(component);
143:
144: switch (action) {
145: case -1:
146: SwingUtilities.setFrameModified(frameReference, true);
147: break;
148: case ACTION_APPLY:
149: apply();
150: break;
151: case ACTION_OK:
152: if (SwingUtilities.isFrameModified(frameReference)
153: .booleanValue()) {
154: apply();
155: }
156: window.dispatchEvent(new WindowEvent(window,
157: WindowEvent.WINDOW_CLOSING));
158: break;
159: case ACTION_CANCEL:
160: int result = JOptionPane.NO_OPTION;
161: if (SwingUtilities.isFrameModified(frameReference)
162: .booleanValue()) {
163: String msg = messages
164: .getMessage("bookmarkeditor.cancel_warning");
165: result = JOptionPane.showConfirmDialog(window, msg, "",
166: JOptionPane.YES_NO_OPTION);
167: }
168: if (status == OperationStatus.NOT_MODIFIED
169: || result == JOptionPane.YES_OPTION) {
170: // if apply was called previously status will be MODIFIED //
171: if (status == OperationStatus.NOT_MODIFIED) {
172: status = OperationStatus.CANCELLED;
173: }
174: window.dispatchEvent(new WindowEvent(window,
175: WindowEvent.WINDOW_CLOSING));
176: }
177: break;
178: }
179: }
180:
181: public void changedUpdate(DocumentEvent e) {
182:
183: }
184:
185: public void insertUpdate(DocumentEvent e) {
186:
187: SwingUtilities.setFrameModified(frameReference, true);
188: if (e.getDocument() == nameDocument) {
189: precheckBookmarkName();
190: }
191: }
192:
193: public void removeUpdate(DocumentEvent e) {
194:
195: SwingUtilities.setFrameModified(frameReference, true);
196: if (e.getDocument() == nameDocument) {
197: precheckBookmarkName();
198: }
199: }
200:
201: @Override
202: public OperationStatus getStatus() {
203:
204: return status;
205: }
206:
207: @Override
208: public void initializeView(Object object) {
209:
210: if (object instanceof Bookmark) {
211: this .bookmark = (Bookmark) object;
212: }
213: initializeView();
214: }
215:
216: public void configureMenubar(JMenuBar menuBar) {
217:
218: sqlEditor.configureMenubar(menuBar);
219: }
220:
221: public void disposeView(Preferences preferences) {
222:
223: sqlEditor.disposeView(preferences);
224: }
225:
226: public void initializeView() {
227:
228: DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL,
229: DateFormat.FULL);
230: NumberFormat nf = NumberFormat.getIntegerInstance();
231:
232: sqlEditor.setText(bookmark.getCommandText());
233: SwingUtilities.replaceDocumentContent(nameDocument, bookmark
234: .getName());
235: Date date = bookmark.getCreationTime();
236: SwingUtilities.replaceDocumentContent(createdDocument, df
237: .format(date));
238: SwingUtilities.replaceDocumentContent(locationDocument,
239: bookmark.getPath());
240: date = bookmark.getLastAccess();
241: date = (date == null) ? new Date() : date;
242: SwingUtilities.replaceDocumentContent(lastUsedDocument, df
243: .format(date));
244: SwingUtilities.replaceDocumentContent(useCountDocument, nf
245: .format(bookmark.getUseCount()));
246:
247: nameDocument.addUndoableEditListener(this );
248: nameDocument.addDocumentListener(this );
249:
250: sqlEditor.addDocumentListener(this );
251: sqlEditor.initializeView();
252:
253: Enumeration<AbstractButton> buttons = colorLabelSelection
254: .getElements();
255: while (buttons.hasMoreElements()) {
256: AbstractButton colorButton = buttons.nextElement();
257: Object property = colorButton
258: .getClientProperty("COLOR_LABEL");
259: if (property instanceof ColorLabel) {
260: ColorLabel label = (ColorLabel) property;
261: if (label == bookmark.getColorLabel()) {
262: colorLabelSelection.setSelected(colorButton
263: .getModel(), true);
264: break;
265: }
266: } else if (bookmark.getColorLabel() == null) {
267: colorLabelSelection.setSelected(colorButton.getModel(),
268: true);
269: break;
270: }
271:
272: }
273: SwingUtilities.setFrameModified(frameReference, false);
274: }
275:
276: public void doLayout(JComponent parentComponent,
277: Preferences preferences, SwingEventManager eventManager) {
278:
279: frameReference = (RootPaneContainer) javax.swing.SwingUtilities
280: .getAncestorOfClass(RootPaneContainer.class,
281: parentComponent);
282: parentComponent.setLayout(new WizardPanel.Layout());
283: JComponent rootPanel = new JPanel(new BorderLayout());
284: JComponent commandPanel = new JPanel(new GridBagLayout());
285: JTabbedPane editorLayout = new JTabbedPane(SwingConstants.TOP);
286:
287: Object constraint = null;
288: JComponent component = null;
289: Icon icon = null;
290: String title = null;
291: String tip = null;
292:
293: component = new JPanel(new GridBagLayout());
294: layoutBasicEditor(preferences, eventManager, component);
295: title = messages.getMessage("bookmarkeditor.general_tab.title");
296: icon = SwingUtilities.loadIconResource("bookmark", 16);
297: tip = messages.getMessage("bookmarkeditor.general_tab.tip");
298: editorLayout.addTab(title, icon, component, tip);
299:
300: component = new JPanel(new GridBagLayout());
301: layoutInformationView(component);
302: title = messages.getMessage("bookmarkeditor.info_tab.title");
303: icon = SwingUtilities.loadIconResource("information", 16);
304: tip = messages.getMessage("bookmarkeditor.info_tab.tip");
305: editorLayout.addTab(title, icon, component, tip);
306:
307: JButton actionButton = null;
308: constraint = constrain(0, 0, 1, 1, 1.0, 0.0,
309: GridBagConstraints.CENTER,
310: GridBagConstraints.HORIZONTAL);
311: commandPanel.add(Box.createHorizontalGlue(), constraint);
312:
313: actionButton = new JButton(messages
314: .getMessage("bookmarkeditor.okbutton.title"));
315: actionButton.addActionListener(this );
316: actionButton.setActionCommand(Integer.toString(ACTION_OK));
317: actionButton.setToolTipText(messages
318: .getMessage("bookmarkeditor.okbutton.tip"));
319: constraint = constrain(1, 0, 1, 1, 0.0, 0.0,
320: GridBagConstraints.CENTER, GridBagConstraints.NONE);
321: commandPanel.add(actionButton, constraint);
322:
323: actionButton = new JButton(messages
324: .getMessage("bookmarkeditor.applybutton.title"));
325: actionButton.addActionListener(this );
326: actionButton.setActionCommand(Integer.toString(ACTION_APPLY));
327: actionButton.setToolTipText(messages
328: .getMessage("servicemanager.applybutton.tip"));
329: constraint = constrain(2, 0, 1, 1, 0.0, 0.0,
330: GridBagConstraints.CENTER, GridBagConstraints.NONE);
331: commandPanel.add(actionButton, constraint);
332:
333: actionButton = new JButton(messages
334: .getMessage("bookmarkeditor.cancelbutton.title"));
335: actionButton.addActionListener(this );
336: actionButton.setActionCommand(Integer.toString(ACTION_CANCEL));
337: actionButton.setToolTipText(messages
338: .getMessage("bookmarkeditor.cancelbutton.tip"));
339: constraint = constrain(3, 0, 1, 1, 0.0, 0.0,
340: GridBagConstraints.CENTER, GridBagConstraints.NONE);
341: commandPanel.add(actionButton, constraint);
342:
343: rootPanel.add(editorLayout, BorderLayout.CENTER);
344: rootPanel.add(commandPanel, BorderLayout.SOUTH);
345: parentComponent.add(rootPanel);
346:
347: rootPanel.setPreferredSize(new Dimension(512, 360));
348: }
349:
350: private void apply() {
351:
352: bookmark.setCommandText(sqlEditor.getText());
353: try {
354: bookmark.setName(nameDocument.getText(0, nameDocument
355: .getLength()));
356: } catch (BadLocationException e) {
357: e.printStackTrace();
358: }
359: String colorLabel = colorLabelSelection.getSelection()
360: .getActionCommand();
361: if (colorLabel == null) {
362: bookmark.setColorLabel(null);
363: } else {
364: bookmark.setColorLabel(ColorLabel.valueOf(colorLabel));
365: }
366:
367: SwingUtilities.setFrameModified(frameReference, false);
368: status = OperationStatus.MODIFIED;
369: }
370:
371: private void precheckBookmarkName() {
372:
373: try {
374: String text = nameDocument.getText(0, nameDocument
375: .getLength());
376: BookmarkFolder parentFolder = bookmark.getFolder();
377: JTextComponent textArea = (JTextComponent) nameDocument
378: .getProperty("JCOMPONENT");
379: if (parentFolder.containsBookmark(text)) {
380: textArea.setForeground(UIManager
381: .getColor("ToolTip.foreground"));
382: textArea.setBackground(UIManager
383: .getColor("ToolTip.background"));
384: } else {
385: String prefix = null;
386: BasicTextUI uiClass = (BasicTextUI) textArea.getUI();
387: // Why they didn't make the property prefix public in the UI is beyond me >.>
388: if (uiClass instanceof BasicTextAreaUI) {
389: prefix = "TextArea";
390: } else if (uiClass instanceof BasicTextFieldUI) {
391: prefix = "TextField";
392: } else if (uiClass instanceof BasicEditorPaneUI) {
393: prefix = "EditorPane";
394: }
395: if (prefix == null) {
396: textArea.setForeground(Color.BLACK);
397: textArea.setBackground(Color.WHITE);
398: } else {
399: textArea.setForeground(UIManager.getColor(prefix
400: + ".foreground"));
401: textArea.setBackground(UIManager.getColor(prefix
402: + ".background"));
403: }
404: }
405:
406: } catch (BadLocationException ignored) {
407: }
408: }
409:
410: private void layoutBasicEditor(Preferences preferences,
411: SwingEventManager eventManager, JComponent editorSheet) {
412:
413: Object constraint = null;
414: JComponent component = null;
415: JLabel label = null;
416: String title = null;
417: String tip = null;
418:
419: title = messages.format("bookmarkeditor.bookmark-name.title");
420: tip = messages.format("bookmarkeditor.bookmark-name.tip");
421: component = new JTextField();
422: nameDocument = ((JTextField) component).getDocument();
423: nameDocument.putProperty("JCOMPONENT", component);
424:
425: localizeTextComponent(((JTextField) component), undoManager);
426: component.setToolTipText(tip);
427: label = new JLabel(title);
428: label.setLabelFor(component);
429: constraint = constrain(0, 0, 1, 1, 0.0d, 0.0d,
430: GridBagConstraints.WEST, GridBagConstraints.NONE);
431: editorSheet.add(label, constraint);
432: constraint = constrain(0, 1, 1, 1, 1.0, 0.0,
433: GridBagConstraints.CENTER,
434: GridBagConstraints.HORIZONTAL);
435: editorSheet.add(component, constraint);
436:
437: title = messages.format("bookmarkeditor.bookmark-sql.title");
438: tip = messages.format("bookmarkeditor.bookmark-sql.tip");
439: label = new JLabel(title);
440: label.setLabelFor(component);
441: constraint = constrain(0, 2, 1, 1, 0.0d, 0.0d,
442: GridBagConstraints.WEST, GridBagConstraints.NONE);
443: editorSheet.add(label, constraint);
444: constraint = constrain(0, 3, 2, 1, 1.0d, 1.0d,
445: GridBagConstraints.WEST, GridBagConstraints.BOTH);
446: component = new JPanel();
447: editorSheet.add(component, constraint);
448:
449: sqlEditor.doLayout(component, preferences, eventManager);
450:
451: }
452:
453: private void layoutInformationView(JComponent editorSheet) {
454:
455: Object constraint = null;
456: JComponent component = null;
457: JLabel label = null;
458: String title = null;
459: String tip = null;
460: ColorLabel[] colorLabels = ColorLabel.values();
461: int labelCount = colorLabels.length + 2;
462:
463: title = messages.format("bookmarkeditor.path.title");
464: tip = messages.format("bookmarkeditor.path.tip");
465: component = new JTextField();
466: ((JTextField) component).setEditable(false);
467: localizeTextComponent(((JTextField) component), null);
468: locationDocument = ((JTextField) component).getDocument();
469: component.setFont(component.getFont().deriveFont(Font.BOLD));
470: component.setToolTipText(tip);
471: label = new JLabel(title);
472: label.setLabelFor(component);
473: constraint = constrain(0, 0, 1, 1, 0.0d, 0.0d,
474: GridBagConstraints.WEST, GridBagConstraints.NONE);
475: editorSheet.add(label, constraint);
476: constraint = constrain(1, 0, labelCount, 1, 1.0, 0.0,
477: GridBagConstraints.CENTER,
478: GridBagConstraints.HORIZONTAL);
479: editorSheet.add(component, constraint);
480:
481: title = messages.format("bookmarkeditor.created-date.title");
482: tip = messages.format("bookmarkeditor.created-date.tip");
483: component = new JTextField();
484: ((JTextField) component).setEditable(false);
485: localizeTextComponent(((JTextField) component), null);
486: createdDocument = ((JTextField) component).getDocument();
487: component.setFont(component.getFont().deriveFont(Font.BOLD));
488: component.setToolTipText(tip);
489: label = new JLabel(title);
490: label.setLabelFor(component);
491: constraint = constrain(0, 1, 1, 1, 0.0d, 0.0d,
492: GridBagConstraints.WEST, GridBagConstraints.NONE);
493: editorSheet.add(label, constraint);
494: constraint = constrain(1, 1, labelCount, 1, 1.0, 0.0,
495: GridBagConstraints.CENTER,
496: GridBagConstraints.HORIZONTAL);
497: editorSheet.add(component, constraint);
498:
499: title = messages.format("bookmarkeditor.lastused-date.title");
500: tip = messages.format("bookmarkeditor.lastused-date.tip");
501: component = new JTextField();
502: ((JTextField) component).setEditable(false);
503: localizeTextComponent(((JTextField) component), null);
504: lastUsedDocument = ((JTextField) component).getDocument();
505: component.setFont(component.getFont().deriveFont(Font.BOLD));
506: component.setToolTipText(tip);
507: label = new JLabel(title);
508: label.setLabelFor(component);
509: constraint = constrain(0, 2, 1, 1, 0.0d, 0.0d,
510: GridBagConstraints.WEST, GridBagConstraints.NONE);
511: editorSheet.add(label, constraint);
512: constraint = constrain(1, 2, labelCount, 1, 1.0, 0.0,
513: GridBagConstraints.CENTER,
514: GridBagConstraints.HORIZONTAL);
515: editorSheet.add(component, constraint);
516:
517: title = messages.format("bookmarkeditor.use-count.title");
518: tip = messages.format("bookmarkeditor.use-count.tip");
519: component = new JTextField();
520: ((JTextField) component).setEditable(false);
521: localizeTextComponent(((JTextField) component), null);
522: useCountDocument = ((JTextField) component).getDocument();
523: component.setFont(component.getFont().deriveFont(Font.BOLD));
524: component.setToolTipText(tip);
525: label = new JLabel(title);
526: label.setLabelFor(component);
527: constraint = constrain(0, 3, 1, 1, 0.0d, 0.0d,
528: GridBagConstraints.WEST, GridBagConstraints.NONE);
529: editorSheet.add(label, constraint);
530: constraint = constrain(1, 3, labelCount, 1, 1.0, 0.0,
531: GridBagConstraints.CENTER,
532: GridBagConstraints.HORIZONTAL);
533: editorSheet.add(component, constraint);
534:
535: constraint = constrain(0, 4, labelCount, 1, 0.0d, 0.0d,
536: GridBagConstraints.CENTER, GridBagConstraints.NONE);
537: editorSheet.add(Box.createVerticalStrut(12), constraint);
538:
539: title = messages.format("bookmarkeditor.color-label.title");
540: tip = messages.format("bookmarkeditor.color-label.tip");
541: label = new JLabel(title);
542: label.setToolTipText(tip);
543: constraint = constrain(0, 5, 1, 1, 0.0d, 0.0d,
544: GridBagConstraints.WEST, GridBagConstraints.NONE);
545: editorSheet.add(label, constraint);
546:
547: JToggleButton toggleButton = null;
548:
549: toggleButton = new JToggleButton();
550: toggleButton.setIcon(SwingUtilities.loadIconResource(
551: "close_view", 16));
552: toggleButton.addActionListener(this );
553: toggleButton.setFocusPainted(true);
554: toggleButton.setBorderPainted(false);
555: toggleButton.setSelected(false);
556: toggleButton.setMargin(new Insets(2, 2, 2, 2));
557: colorLabelSelection.add(toggleButton);
558: constraint = constrain(1, 5, 1, 1, 0.0, 0.0,
559: GridBagConstraints.WEST, GridBagConstraints.NONE);
560: editorSheet.add(toggleButton, constraint);
561:
562: for (int i = 0; i < colorLabels.length; i++) {
563: toggleButton = new JToggleButton();
564: toggleButton.setIcon(new ColorLedIcon(colorLabels[i]
565: .toColor(), 2, 2));
566: toggleButton.addActionListener(this );
567: toggleButton.setBorderPainted(false);
568: toggleButton.setFocusPainted(true);
569: toggleButton.setSelected(false);
570: toggleButton.setMargin(new Insets(2, 2, 2, 2));
571: toggleButton.putClientProperty("COLOR_LABEL",
572: colorLabels[i]);
573: toggleButton.setActionCommand(colorLabels[i].name());
574: colorLabelSelection.add(toggleButton);
575: constraint = constrain(2 + i, 5, 1, 1, 0.0, 0.0,
576: GridBagConstraints.WEST, GridBagConstraints.NONE);
577: editorSheet.add(toggleButton, constraint);
578: }
579:
580: constraint = constrain(0, 6, labelCount, 1, 0.0d, 1.0d,
581: GridBagConstraints.CENTER, GridBagConstraints.VERTICAL);
582: editorSheet.add(Box.createVerticalGlue(), constraint);
583: }
584: }
|