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.swing;
024:
025: import java.awt.Component;
026: import java.awt.Toolkit;
027: import java.awt.datatransfer.Clipboard;
028: import java.awt.datatransfer.StringSelection;
029: import java.awt.event.ActionEvent;
030: import java.awt.event.ActionListener;
031: import java.awt.event.KeyEvent;
032: import java.awt.event.MouseEvent;
033: import java.awt.event.MouseListener;
034: import java.text.DateFormat;
035: import java.util.Date;
036:
037: import javax.swing.JMenu;
038: import javax.swing.JMenuItem;
039: import javax.swing.JPopupMenu;
040: import javax.swing.text.BadLocationException;
041: import javax.swing.text.JTextComponent;
042:
043: import org.apache.log4j.Logger;
044: import org.isqlviewer.util.IsqlToolkit;
045: import org.isqlviewer.util.LocalMessages;
046: import org.isqlviewer.util.StringUtilities;
047:
048: /**
049: * @author Mark A. Kobold <mkobold at isqlviewer dot com>
050: * @version 1.0
051: */
052: public class JTextPopup extends JPopupMenu implements MouseListener,
053: ActionListener {
054:
055: private static final long serialVersionUID = -4349534125094508822L;
056: private static final String BUNDLE_IDENTIFIER = "org.isqlviewer.swing.ResourceBundle";
057:
058: private static final int ACTION_SELECT_ALL = 1;
059: private static final int ACTION_CLEAR = 2;
060: private static final int ACTION_PASTE = 3;
061: private static final int ACTION_COPY = 4;
062: private static final int ACTION_DELETE = 5;
063: private static final int ACTION_CUT = 6;
064: private static final int ACTION_LONG_TO_DATE = 7;
065: private static final int ACTION_B64_DECODE = 8;
066: private static final int ACTION_B64_ENCODE = 9;
067: private static final int ACTION_NATIVE_TO_ASCII = 10;
068: private static final int ACTION_ASCII_TO_NATIVE = 11;
069:
070: private LocalMessages messages = new LocalMessages(
071: BUNDLE_IDENTIFIER);
072: private JMenuItem cut = new JMenuItem(messages
073: .format("JTextPopup.cut.action"));
074: private JMenuItem delete = new JMenuItem(messages
075: .format("JTextPopup.delete.action"));
076: private JMenuItem copy = new JMenuItem(messages
077: .format("JTextPopup.copy.action"));
078: private JMenuItem paste = new JMenuItem(messages
079: .format("JTextPopup.paste.action"));
080: private JMenuItem clear = new JMenuItem(messages
081: .format("JTextPopup.clear_all.action"));
082: private JMenuItem selectAll = new JMenuItem(messages
083: .format("JTextPopup.select_all.action"));
084:
085: private JMenuItem asciiToNative = new JMenuItem(messages
086: .format("JTextPopup.unicode_decode.action"));
087: private JMenuItem nativeToAscii = new JMenuItem(messages
088: .format("JTextPopup.unicode_encode.action"));
089: private JMenuItem encodeBase64 = new JMenuItem(messages
090: .format("JTextPopup.base64_encode.action"));
091: private JMenuItem decodeBase64 = new JMenuItem(messages
092: .format("JTextPopup.base64_decode.action"));
093: private JMenuItem longToDate = new JMenuItem(messages
094: .format("JTextPopup.millisecond_date_decode.action"));
095:
096: private JTextComponent textComponent;
097: private DateFormat dateFormat = DateFormat.getDateTimeInstance(
098: DateFormat.FULL, DateFormat.FULL);
099: private Logger logger = IsqlToolkit.getApplicationLogger();
100:
101: public JTextPopup() {
102:
103: JMenu tools = new JMenu(messages
104: .format("JTextPopup.text_tools.title"));
105: tools.add(decodeBase64);
106: tools.add(encodeBase64);
107: tools.add(asciiToNative);
108: tools.add(nativeToAscii);
109: tools.addSeparator();
110: tools.add(longToDate);
111:
112: add(cut);
113: add(copy);
114: add(paste);
115: add(delete);
116: addSeparator();
117: add(tools);
118: add(clear);
119: add(selectAll);
120:
121: cut.setActionCommand(Integer.toString(ACTION_CUT));
122: delete.setActionCommand(Integer.toString(ACTION_DELETE));
123: copy.setActionCommand(Integer.toString(ACTION_COPY));
124: paste.setActionCommand(Integer.toString(ACTION_PASTE));
125: clear.setActionCommand(Integer.toString(ACTION_CLEAR));
126: selectAll.setActionCommand(Integer.toString(ACTION_SELECT_ALL));
127:
128: asciiToNative.setActionCommand(Integer
129: .toString(ACTION_ASCII_TO_NATIVE));
130: nativeToAscii.setActionCommand(Integer
131: .toString(ACTION_NATIVE_TO_ASCII));
132: encodeBase64.setActionCommand(Integer
133: .toString(ACTION_B64_ENCODE));
134: decodeBase64.setActionCommand(Integer
135: .toString(ACTION_B64_DECODE));
136: longToDate.setActionCommand(Integer
137: .toString(ACTION_LONG_TO_DATE));
138:
139: if (!SwingUtilities.isMacOS()) {
140: selectAll.setIcon(SwingUtilities.loadIconResource("spacer",
141: 16));
142: cut
143: .setIcon(SwingUtilities.loadIconResource(
144: "edit_cut", 16));
145: copy.setIcon(SwingUtilities.loadIconResource("edit_copy",
146: 16));
147: paste.setIcon(SwingUtilities.loadIconResource("edit_paste",
148: 16));
149: clear.setIcon(SwingUtilities.loadIconResource("edit_clear",
150: 16));
151: delete.setIcon(SwingUtilities.loadIconResource(
152: "edit_delete", 16));
153: tools
154: .setIcon(SwingUtilities.loadIconResource("spacer",
155: 16));
156: }
157:
158: paste.setAccelerator(SwingUtilities.createKeyStroke(
159: KeyEvent.VK_V, SwingUtilities.MENU_SHORTCUT_MASK));
160: copy.setAccelerator(SwingUtilities.createKeyStroke(
161: KeyEvent.VK_C, SwingUtilities.MENU_SHORTCUT_MASK));
162: selectAll.setAccelerator(SwingUtilities.createKeyStroke(
163: KeyEvent.VK_A, SwingUtilities.MENU_SHORTCUT_MASK));
164: cut.setAccelerator(SwingUtilities.createKeyStroke(
165: KeyEvent.VK_X, SwingUtilities.MENU_SHORTCUT_MASK));
166:
167: selectAll.addActionListener(this );
168: cut.addActionListener(this );
169: copy.addActionListener(this );
170: paste.addActionListener(this );
171: clear.addActionListener(this );
172: decodeBase64.addActionListener(this );
173: encodeBase64.addActionListener(this );
174: asciiToNative.addActionListener(this );
175: nativeToAscii.addActionListener(this );
176: longToDate.addActionListener(this );
177: }
178:
179: public final void removeJTextComponent(JTextComponent jtc) {
180:
181: jtc.removeMouseListener(this );
182: }
183:
184: public final void addJTextComponent(JTextComponent jtc) {
185:
186: jtc.addMouseListener(this );
187: }
188:
189: public void actionPerformed(ActionEvent actionEvent) {
190:
191: if (textComponent == null) {
192: return;
193: }
194: String actionCommand = actionEvent.getActionCommand();
195: int action = -1;
196: try {
197: action = Integer.parseInt(actionCommand);
198: } catch (Exception ignored) {
199: }
200:
201: String text = textComponent.getText();
202: String selectedText = textComponent.getSelectedText();
203: int offset = textComponent.getSelectionStart();
204: boolean selection = selectedText != null;
205:
206: switch (action) {
207: case ACTION_SELECT_ALL:
208: textComponent.selectAll();
209: break;
210: case ACTION_CLEAR:
211: if (textComponent.isEnabled()) {
212: textComponent.setText("");
213: textComponent.setCaretPosition(0);
214: }
215: break;
216: case ACTION_PASTE:
217: textComponent.paste();
218: break;
219: case ACTION_COPY:
220: textComponent.copy();
221: break;
222: case ACTION_DELETE:
223: if (selectedText != null && textComponent.isEditable()) {
224: try {
225: textComponent.getDocument().remove(offset,
226: selectedText.length());
227: } catch (BadLocationException ignored) {
228: logger.debug("textComponent.remove(int,int)",
229: ignored);
230: }
231: }
232: break;
233: case ACTION_CUT:
234: textComponent.copy();
235: if (textComponent.isEditable()) {
236: textComponent.cut();
237: }
238: break;
239: case ACTION_LONG_TO_DATE:
240: String dateString = null;
241: long milliseconds = -1;
242: try {
243: if (selection) {
244: Long.parseLong(selectedText);
245: } else {
246: Long.parseLong(text);
247: }
248: } catch (NumberFormatException ignored) {
249: SwingUtilities.beep();
250: return;
251: }
252:
253: Date date = new Date(milliseconds);
254: dateString = dateFormat.format(date);
255: if (textComponent.isEditable()) {
256: if (selection) {
257: textComponent.replaceSelection(dateString);
258: } else {
259: textComponent.setText(dateString);
260: }
261: } else {
262: Clipboard cb = Toolkit.getDefaultToolkit()
263: .getSystemClipboard();
264: StringSelection ss = new StringSelection(dateString);
265: cb.setContents(ss, ss);
266: logger
267: .info(messages
268: .format("JTextPopup.content_copied_to_clipboard"));
269: }
270: break;
271: case ACTION_B64_DECODE:
272: if (textComponent.isEditable()) {
273: if (selection) {
274: selectedText = StringUtilities
275: .decodeBase64(selectedText);
276: textComponent.replaceSelection(selectedText);
277: } else {
278: text = StringUtilities.decodeBase64(text);
279: textComponent.setText(text);
280: }
281: } else {
282: Clipboard cb = Toolkit.getDefaultToolkit()
283: .getSystemClipboard();
284: StringSelection ss = null;
285: if (selection) {
286: ss = new StringSelection(StringUtilities
287: .decodeBase64(selectedText));
288: } else {
289: ss = new StringSelection(StringUtilities
290: .decodeBase64(text));
291: }
292: cb.setContents(ss, ss);
293: logger
294: .info(messages
295: .format("JTextPopup.content_copied_to_clipboard"));
296: }
297: break;
298: case ACTION_B64_ENCODE:
299: if (textComponent.isEditable()) {
300: if (selection) {
301: selectedText = StringUtilities
302: .encodeBase64(selectedText);
303: textComponent.replaceSelection(selectedText);
304: } else {
305: text = StringUtilities.encodeBase64(text);
306: textComponent.setText(text);
307: }
308: } else {
309: Clipboard cb = Toolkit.getDefaultToolkit()
310: .getSystemClipboard();
311: StringSelection ss = null;
312: if (selection) {
313: ss = new StringSelection(StringUtilities
314: .encodeBase64(selectedText));
315: } else {
316: ss = new StringSelection(StringUtilities
317: .encodeBase64(text));
318: }
319: cb.setContents(ss, ss);
320: logger
321: .info(messages
322: .format("JTextPopup.content_copied_to_clipboard"));
323: }
324: break;
325: case ACTION_NATIVE_TO_ASCII:
326: if (textComponent.isEditable()) {
327: if (selection) {
328: selectedText = StringUtilities
329: .decodeASCII(selectedText);
330: textComponent.replaceSelection(selectedText);
331: } else {
332: text = StringUtilities.decodeASCII(text);
333: textComponent.setText(text);
334: }
335: } else {
336: Clipboard cb = Toolkit.getDefaultToolkit()
337: .getSystemClipboard();
338: StringSelection ss = null;
339: if (selection) {
340: ss = new StringSelection(StringUtilities
341: .decodeASCII(selectedText));
342: } else {
343: ss = new StringSelection(StringUtilities
344: .decodeASCII(text));
345: }
346: cb.setContents(ss, ss);
347: logger
348: .info(messages
349: .format("JTextPopup.content_copied_to_clipboard"));
350: }
351: break;
352: case ACTION_ASCII_TO_NATIVE:
353: if (textComponent.isEditable()) {
354: if (selection) {
355: selectedText = StringUtilities
356: .encodeASCII(selectedText);
357: textComponent.replaceSelection(selectedText);
358: } else {
359: text = StringUtilities.encodeASCII(text);
360: textComponent.setText(text);
361: }
362: } else {
363: Clipboard cb = Toolkit.getDefaultToolkit()
364: .getSystemClipboard();
365: StringSelection ss = null;
366: if (selection) {
367: ss = new StringSelection(StringUtilities
368: .encodeASCII(selectedText));
369: } else {
370: ss = new StringSelection(StringUtilities
371: .encodeASCII(text));
372: }
373: cb.setContents(ss, ss);
374: }
375: break;
376: default:
377: break;
378: }
379: }
380:
381: @Override
382: public void show(Component com, int x, int y) {
383:
384: Component deepest = javax.swing.SwingUtilities
385: .getDeepestComponentAt(com, x, y);
386: if (deepest instanceof JTextComponent && com.isEnabled()) {
387: textComponent = (JTextComponent) deepest;
388:
389: cut.setEnabled(textComponent.isEditable());
390: paste.setEnabled(textComponent.isEditable());
391: delete.setEnabled(textComponent.isEditable());
392: super .show(com, x, y);
393: }
394: }
395:
396: public void mouseReleased(MouseEvent e) {
397:
398: doPopup(e);
399: }
400:
401: public void mouseClicked(MouseEvent e) {
402:
403: doPopup(e);
404: }
405:
406: public void mousePressed(MouseEvent e) {
407:
408: doPopup(e);
409: }
410:
411: public void mouseEntered(MouseEvent e) {
412:
413: }
414:
415: public void mouseExited(MouseEvent e) {
416:
417: }
418:
419: private boolean doPopup(MouseEvent e) {
420:
421: if (e.isPopupTrigger()) {
422: show(e.getComponent(), e.getX(), e.getY());
423: e.consume();
424: return true;
425: }
426: return false;
427: }
428: }
|