001: package tide.editor;
002:
003: import tide.utils.SyntaxUtils;
004: import java.util.prefs.Preferences;
005: import snow.watchdog.WatchDog;
006: import java.io.File;
007: import tide.project.ProjectSettings;
008: import snow.files.FileChooserFilter;
009: import snow.sys.NetExplorer;
010: import snow.utils.gui.FileIcon;
011: import snow.screenshot.ScreenShot;
012: import java.io.BufferedReader;
013: import java.io.StringReader;
014: import snow.utils.gui.Icons;
015: import tide.sources.*;
016: import javax.swing.*;
017: import javax.swing.event.*;
018: import java.awt.event.*;
019: import java.util.*;
020: import snow.utils.*;
021: import snow.texteditor.*;
022: import snow.datatransfer.*;
023: import tide.editor.bookmarks.*;
024:
025: /** Some shared popups.
026: */
027: public final class SharedUtils {
028: private SharedUtils() {
029: }
030:
031: /** Used in the main frame, editor panel, sources tree, lib tree.
032: * Manage Bookmarks and bookmark list (jump) entry. No add function here.
033: * @param popup is either a menu or a popupmenu.
034: */
035: public static void addBookmarksPopup(JComponent popup,
036: final String filterForBookmarkManagement) {
037: JMenu bookmarksMenu = new JMenu("Bookmarks");
038: bookmarksMenu.setIcon(Icons.sharedRightArrow);
039: //popup.addSeparator();
040: popup.add(bookmarksMenu);
041:
042: JMenuItem manageBookmarks = new JMenuItem("Manage Bookmarks");
043: manageBookmarks.setAccelerator(KeyStroke.getKeyStroke(
044: KeyEvent.VK_B, KeyEvent.CTRL_MASK));
045: bookmarksMenu.add(manageBookmarks);
046: bookmarksMenu.addSeparator();
047: manageBookmarks.addActionListener(new ActionListener() {
048: public void actionPerformed(ActionEvent ae) {
049: // not modal
050: new BookmarksManagementDialog(
051: filterForBookmarkManagement);
052: }
053: });
054:
055: int n = 0;
056: List<SourceBookmark> bms = MainEditorFrame.instance
057: .getActualProject().getAllBookmarks_REF();
058: for (int i = bms.size() - 1; i >= 0; i--) // reverse => show first the new ones !
059: {
060: final SourceBookmark bm = bms.get(i);
061:
062: n++;
063: if (n > 30) {
064: JMenuItem more = new JMenuItem("...");
065: more.addActionListener(new ActionListener() {
066: public void actionPerformed(ActionEvent ae) {
067: new BookmarksManagementDialog("");
068: }
069: });
070: bookmarksMenu.add(more);
071: break;
072: }
073:
074: bookmarksMenu.add(createBookmarkMenuItem(bm));
075: }
076: }
077:
078: public static void addRecentBookmarks(JComponent popup, int max) {
079: for (SourceBookmark bmi : getRecentBookmarks(max)) {
080: popup.add(createBookmarkMenuItem(bmi));
081: }
082:
083: if (popup instanceof JPopupMenu) {
084: ((JPopupMenu) popup).addSeparator();
085: }
086: if (popup instanceof JMenu) {
087: ((JMenu) popup).addSeparator();
088: }
089:
090: JMenuItem more = new JMenuItem("Manage and edit...");
091: more.setAccelerator(Accelerators.manageBookmarks);
092: more.addActionListener(new ActionListener() {
093: public void actionPerformed(ActionEvent ae) {
094: new BookmarksManagementDialog("");
095: }
096: });
097: popup.add(more);
098: }
099:
100: private static JMenuItem createBookmarkMenuItem(
101: final SourceBookmark bm) {
102: final FileItem sff = MainEditorFrame.instance.getFileItem(bm
103: .getJavaName(), "");
104:
105: if (sff == null) {
106: return new JMenuItem("Cannot find type: "
107: + bm.getJavaName());
108: } else {
109: StringBuilder sb = new StringBuilder();
110: sb.append(SyntaxUtils.makeSingleJavaNameSimple(bm
111: .getJavaName())); // Simple name !
112: if (bm.getLinePosition() > 0
113: && bm.getRemark().length() == 0) // only show if remark is empty.
114: {
115: sb.append(": (Line " + bm.getLinePosition() + ")");
116: }
117: if (bm.getRemark().length() > 0) {
118: sb.append(": " + bm.getRemark());
119: }
120:
121: JMenuItem jumpI = new JMenuItem(sb.toString());
122: jumpI.addActionListener(new ActionListener() {
123: public void actionPerformed(ActionEvent ae) {
124: sff.setCaretPositionToRemember(
125: bm.getLinePosition(), bm
126: .getColumnPosition());
127: MainEditorFrame.instance
128: .setSourceOrItemToEditOrView(sff, true);
129: }
130: });
131:
132: return jumpI;
133: }
134: }
135:
136: public static Collection<SourceBookmark> getRecentBookmarks(int max) {
137: List<SourceBookmark> recent = new ArrayList<SourceBookmark>();
138: recent.addAll(MainEditorFrame.instance.getActualProject()
139: .getAllBookmarks_REF());
140: Collections.sort(recent, new Comparator<SourceBookmark>() // not necessary ! bookmarks are already sorted, first is the oldest.
141: {
142: public final boolean equals(final Object obj) {
143: throw new RuntimeException("stupid"); // return true;
144: }
145:
146: public final int compare(final SourceBookmark o1,
147: final SourceBookmark o2) {
148: return Long.valueOf(o2.getCreated()).compareTo(
149: o1.getCreated());
150: }
151: });
152:
153: return CollectionUtils.takeFirst(recent, max);
154: //return recent;
155: }
156:
157: /** null for separators */
158: public static List<JMenuItem> getUtilitiesMenuItems_(
159: final ProjectSettings actualProject) {
160: List<JMenuItem> ret = new ArrayList<JMenuItem>();
161:
162: JMenuItem uikeys = new JMenuItem("Swing UI Keys explorer");
163: uikeys.setAccelerator(Accelerators.uiKeysExplorer);
164: ret.add(uikeys);
165: uikeys.addActionListener(new ActionListener() {
166: public void actionPerformed(ActionEvent ae) {
167: new snow.sortabletable.UIKeysViewer(false);
168: }
169: });
170:
171: JMenuItem props = new JMenuItem("System properties explorer");
172: props.setAccelerator(Accelerators.systemPropsExplorer);
173: ret.add(props);
174: props.addActionListener(new ActionListener() {
175: public void actionPerformed(ActionEvent ae) {
176: new snow.sortabletable.SystemPropertiesViewer(
177: MainEditorFrame.instance);
178: }
179: });
180:
181: FileIcon dir3 = new FileIcon(true, 15);
182: dir3.setType(FileIcon.IconColor.RedGreen);
183: JMenuItem internalResourceExpl = new JMenuItem(
184: "Project resources explorer", dir3);
185: internalResourceExpl
186: .setAccelerator(Accelerators.internalResourcesExplorer);
187: //fsMenu.addSeparator();
188: ret.add(internalResourceExpl);
189: internalResourceExpl.addActionListener(new ActionListener() {
190: public void actionPerformed(ActionEvent ae) {
191: File home = MainEditorFrame.instance.getActualProject()
192: .getSources_Home();
193: FileItem viewed = MainEditorFrame.instance.editorPanel
194: .getActualDisplayedFile();
195: File editedSrc = (viewed instanceof SourceFile) ? ((SourceFile) viewed)
196: .getFileOrDirectory()
197: : null;
198: new ResourcesExplorer(home, home, editedSrc);
199: }
200: });
201:
202: JMenuItem unic = new JMenuItem("Unicode explorer",
203: new Icons.LetterIcon("\u03a9", false, 17, 17, true));
204: ret.add(null);
205: ret.add(unic);
206: unic.addActionListener(new ActionListener() {
207: public void actionPerformed(ActionEvent ae) {
208: new snow.sortabletable.UnicodeViewer(false);
209: }
210: });
211:
212: JMenuItem sshot = new JMenuItem("Screen shot and film utility",
213: new Icons.LetterIcon(" ", true, 17, 12, true));
214: ret.add(sshot);
215: sshot.addActionListener(new ActionListener() {
216: public void actionPerformed(ActionEvent ae) {
217: try {
218: new ScreenShot(false);
219: } catch (Exception e) {
220: e.printStackTrace();
221: }
222: }
223: });
224:
225: FileIcon dir = new FileIcon(true, 15);
226: dir.setType(FileIcon.IconColor.System);
227: JMenuItem jex = new JMenuItem("File explorer", dir);
228: ret.add(jex);
229: jex.addActionListener(new ActionListener() {
230: public void actionPerformed(ActionEvent ae) {
231: // just an utility...
232: File selDir = new File(actualProject.getProperty(
233: "FileExplorerPath", System
234: .getProperty("user.home")));
235: JFileChooser fs = new JFileChooser(selDir);
236: fs.setFileSelectionMode(fs.FILES_AND_DIRECTORIES);
237: fs.setSelectedFile(selDir);
238: FileChooserFilter fsf = new FileChooserFilter(fs);
239: fs.setAccessory(fsf);
240: if (fs.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
241: actualProject.setProperty("FileExplorerPath", ""
242: + fs.getSelectedFile());
243: }
244: }
245: });
246:
247: // A small utility
248:
249: JMenuItem miCountdown = new JMenuItem("Countdown",
250: Icons.sharedTimer);
251: ret.add(null);
252: ret.add(miCountdown);
253: miCountdown.addActionListener(new ActionListener() {
254: public void actionPerformed(ActionEvent ae) {
255: Countdown.getInstance().setVisible(true);
256: }
257: });
258:
259: JMenuItem miWD = new JMenuItem("tIDE's eye", Icons.sharedEye);
260: //ret.add(null);
261: ret.add(miWD);
262: miWD.addActionListener(new ActionListener() {
263: public void actionPerformed(ActionEvent ae) {
264: WatchDog.getInstance().setVisible(true);
265: }
266: });
267:
268: JMenuItem net = new JMenuItem("Network explorer");
269: ret.add(null);
270: ret.add(net);
271: net.addActionListener(new ActionListener() {
272: public void actionPerformed(ActionEvent ae) {
273: new NetExplorer(false);
274: }
275: });
276:
277: /*
278: if(MainEditorFrame.enableExperimental)
279: {
280: JMenuItem cli = new JMenuItem("Accept to be remote controlled", Icons.WizIcon.shared15);
281: ret.add(null);
282: ret.add(cli);
283: cli.addActionListener(new ActionListener()
284: {
285: public void actionPerformed(ActionEvent ae)
286: {
287: new remote.Client(false);
288: }
289: });
290:
291: JMenuItem srv = new JMenuItem("Start remote control", Icons.WizIcon.shared15);
292: ret.add(null);
293: ret.add(srv);
294: srv.addActionListener(new ActionListener()
295: {
296: public void actionPerformed(ActionEvent ae)
297: {
298: new remote.Remote(false);
299: }
300: });
301: }*/
302:
303: return ret;
304: }
305:
306: /** Copy, paste, paste-hist, delete, search, used for the output panels such as compiler and execution
307: * allow paste even for readonly documents, useful for stacktraces pasting !!
308: * Also adds the "paste" history from ClipboardUtils.j
309: *
310: * BE CAREFUL With shortcus, they are "fake" and focus is not really precise.
311: */
312: public static void addStandardPopupDocumentActions(
313: JPopupMenu popup, final SimpleDocument doc,
314: final SearchPanel searchPanel, final JTextPane pane,
315: final int clickedPos, boolean withCopyWithoutHead) {
316: final String sel = pane.getSelectedText();
317: if (sel != null) // nov 2007: only offer if available
318: {
319:
320: JMenuItem copy = new JMenuItem("Copy");
321: copy.setAccelerator(Accelerators.copy);
322: popup.add(copy);
323: copy.addActionListener(new ActionListener() {
324: public void actionPerformed(ActionEvent ae) {
325: if (sel != null) {
326: ClipboardUtils.copyToClipboard(sel);
327: }
328: }
329: });
330:
331: if (withCopyWithoutHead) {
332: JMenuItem copy2 = new JMenuItem(
333: "Copy without line headers");
334: popup.add(copy2);
335: copy2.addActionListener(new ActionListener() {
336: public void actionPerformed(ActionEvent ae) {
337: try {
338: String sel = pane.getSelectedText();
339: if (sel == null)
340: return;
341:
342: BufferedReader sr = new BufferedReader(
343: new StringReader(sel));
344: String line;
345: StringBuilder sb = new StringBuilder(sel
346: .length());
347: while ((line = sr.readLine()) != null) {
348: int pos = line.indexOf("> ");
349: if (pos < 0) {
350: sb.append(line + "\r\n");
351: } else {
352: sb.append(line.substring(pos + 2)
353: + "\r\n");
354: }
355: }
356:
357: if (sb.length() > 2) {
358: sb.setLength(sb.length() - 2); // remove last "\r\n"
359: ClipboardUtils.copyToClipboard(sb
360: .toString());
361: }
362: } catch (Exception e) {
363: e.printStackTrace();
364: }
365: }
366: });
367: }
368:
369: popup.addSeparator();
370: }
371:
372: // let discover during action if something exists to paste...
373:
374: JMenuItem paste = new JMenuItem("Paste");
375: paste.setAccelerator(Accelerators.paste);
376: popup.add(paste);
377: paste.addActionListener(new ActionListener() {
378: public void actionPerformed(ActionEvent ae) {
379: String txt = ClipboardUtils.getClipboardStringContent();
380: if (txt != null && txt.length() > 0) {
381: doc.insertString(txt, pane.getCaretPosition());
382: }
383: }
384: });
385:
386: if (ClipboardUtils.getInstance().getHistory().size() > 0) {
387: JMenu pasteHistory = new JMenu("Paste history ");
388: popup.add(pasteHistory);
389: for (final String p : ClipboardUtils.getInstance()
390: .getHistory()) {
391: JMenuItem pasteH = new JMenuItem(""
392: + StringUtils.shortFormForDisplay(p, 70));
393: pasteHistory.add(pasteH);
394: pasteH.addActionListener(new ActionListener() {
395: public void actionPerformed(ActionEvent ae) {
396: doc.insertString(p, pane.getCaretPosition());
397: }
398: });
399: }
400: }
401:
402: final int start = pane.getSelectionStart();
403: final int end = pane.getSelectionEnd();
404:
405: JMenuItem delete = new JMenuItem(
406: start >= end ? "Delete all text"
407: : "Delete selected text", Icons.sharedCross);
408: popup.addSeparator();
409: popup.add(delete);
410: delete.addActionListener(new ActionListener() {
411: public void actionPerformed(ActionEvent ae) {
412: if (start >= end) {
413: // delete all
414: doc.setText("");
415: } else {
416: // delete selected
417: try {
418: doc.remove(start, end - start);
419: } catch (Exception e) {
420: e.printStackTrace();
421: }
422: }
423:
424: }
425: });
426:
427: String selectedText = "";
428: if ((pane.getSelectionEnd() - pane.getSelectionStart()) > 0) {
429: selectedText = pane.getSelectedText();
430: } else {
431: // detect the word at the cursot
432: selectedText = DocumentUtils.getWordAt(doc, clickedPos);
433: }
434:
435: popup.addSeparator();
436: JMenuItem search = new JMenuItem("Search text",
437: Icons.sharedSearch);
438: search.setAccelerator(Accelerators.search);
439: popup.add(search);
440: search.addActionListener(new ActionListener() {
441: public void actionPerformed(ActionEvent ae) {
442: searchPanel.setVisible(true);
443: searchPanel.requestSearchFocus();
444: }
445: });
446:
447: if (selectedText != null && selectedText.length() > 0) {
448: final String ft = selectedText;
449: final String shortText = StringUtils.shortFormForDisplay(
450: selectedText, 70);
451: JMenuItem searchF = new JMenuItem("Search next \""
452: + shortText + "\"", Icons.sharedSearch);
453: popup.add(searchF);
454: searchF.addActionListener(new ActionListener() {
455: public void actionPerformed(ActionEvent ae) {
456: searchPanel.searchNext_calledFromPopup(ft,
457: clickedPos);
458:
459: }
460: });
461:
462: if (MainEditorFrame.instance != null) {
463:
464: popup.addSeparator();
465:
466: JMenuItem searchFE = new JMenuItem(
467: "Search in editor for first \"" + shortText
468: + "\"", Icons.sharedSearch);
469: popup.add(searchFE);
470:
471: searchFE.addActionListener(new ActionListener() {
472: public void actionPerformed(ActionEvent ae) {
473: //searchPanel.searchNext_calledFromPopup( ft, clickedPos);
474: MainEditorFrame.instance.editorPanel
475: .searchFirst(ft);
476: }
477: });
478:
479: JMenuItem searchG = new JMenuItem(
480: "Global search for \"" + shortText + "\"",
481: Icons.sharedSearch);
482: searchG.setAccelerator(Accelerators.globalSearch);
483: popup.add(searchG);
484:
485: searchG.addActionListener(new ActionListener() {
486: public void actionPerformed(ActionEvent ae) {
487: MainEditorFrame.instance.globalProperties
488: .setProperty("SearchTool_searchTF", ft);
489: MainEditorFrame.instance.globalProperties
490: .setBoolean("SearchTool_regex", false);
491:
492: new SearchTool(
493: MainEditorFrame.instance.sourcesTreePanel
494: .getTreeModel()
495: .getAllSourceFiles(false),
496: false, null);
497: }
498: });
499:
500: final FileItem actualDisplayedFile = MainEditorFrame.instance.editorPanel
501: .getActualDisplayedFile();
502: if (actualDisplayedFile != null) {
503: final String pn = actualDisplayedFile
504: .getPackageName();
505: JMenuItem searchInPackage = new JMenuItem(
506: "Search in package " + pn,
507: Icons.sharedSearch);
508: searchInPackage
509: .setAccelerator(Accelerators.searchInPackage);
510: popup.add(searchInPackage);
511: searchInPackage
512: .addActionListener(new ActionListener() {
513: public void actionPerformed(
514: ActionEvent ae) {
515: MainEditorFrame.instance.globalProperties
516: .setProperty(
517: "SearchTool_searchTF",
518: ft);
519: MainEditorFrame.instance.globalProperties
520: .setBoolean(
521: "SearchTool_regex",
522: false);
523:
524: if (actualDisplayedFile instanceof SourceFile) {
525: List<SourceFile> all = new ArrayList<SourceFile>();
526: MainEditorFrame.instance.sourcesTreePanel
527: .getTreeModel()
528: .getAllSourceFilesRecurse(
529: (SourceFile) actualDisplayedFile
530: .getParent(),
531: all, false,
532: false);
533: new SearchTool(all, false,
534: "Search in package "
535: + pn + " ("
536: + all.size()
537: + " sources)");
538: } else {
539: List<LibFileItem> all = new ArrayList<LibFileItem>();
540: MainEditorFrame.instance.librariesPanel
541: .getTreeModel()
542: .getAllFilesRecurse(
543: all,
544: (LibFileItem) actualDisplayedFile
545: .getParent(),
546: true);
547: new SearchTool(
548: all,
549: false,
550: "Search in package "
551: + pn
552: + " ("
553: + all.size()
554: + " lib classes)");
555: }
556: }
557: });
558: }
559: }
560: }
561:
562: }
563:
564: }
|