001: package tide.editor;
002:
003: import java.awt.Component;
004: import javax.swing.border.CompoundBorder;
005: import javax.swing.border.Border;
006: import snow.utils.gui.CustomEtchedBorder;
007: import javax.swing.border.EmptyBorder;
008: import snow.utils.DateUtils;
009: import tide.execute.ExecuteActions;
010: import snow.utils.gui.Icons;
011: import java.awt.Color;
012: import java.awt.Dimension;
013: import java.util.*;
014: import java.awt.Insets;
015: import tide.sources.*;
016: import javax.swing.*;
017: import javax.swing.event.*;
018: import java.awt.event.*;
019:
020: /** Contains
021: * + the last opened files, as quick access buttons
022: * + the line number button (and its popup)
023: * + the history of positions (with jump to dependencies, recent edited, ...)
024: * + the execution button and its popup.
025: * The number of buttons is limited by the screen width..
026: */
027: public final class SourcesNavigationBar extends JPanel {
028: final EditorPanel editor;
029:
030: private final JButton lineLabel = new JButton("Line 0");
031: private final JButton previousJump = new JButton(
032: Icons.sharedLeftArrow);
033: private final JButton nextJump = new JButton(Icons.sharedRightArrow);
034: private final JButton runBT = new JButton(Icons.sharedStart);
035: private final JButton depsBT = new JButton(new Icons.HArrow(14, 14,
036: true, true, false));
037: private final JButton filesHistBT = new JButton(
038: new Icons.LetterIcon("R", false, 14, 14, true));
039: private final JButton utilitiesBT = new JButton(
040: new Icons.LetterIcon("U", false, 14, 14, true));
041:
042: // sync with the displayedHistoryTabs
043: private final JPanel tabsPanel = new JPanel();
044:
045: // just the viewed tabs, limited by the screen size !
046: final private List<TabButton> displayedHistoryTabs = new ArrayList<TabButton>();
047:
048: TabButton selected = null;
049:
050: final ActionListener jumpAction;
051:
052: SourcesNavigationBar(final EditorPanel editor) {
053: super ();
054: setBorder(null);
055: setLayout(new BoxLayout(this , BoxLayout.X_AXIS));
056: this .editor = editor;
057:
058: // fix elements
059: runBT.setMargin(new Insets(0, 0, 0, 0));
060: previousJump.setMargin(new Insets(0, 2, 0, 2));
061: nextJump.setMargin(new Insets(0, 2, 0, 2));
062: depsBT.setMargin(new Insets(0, 2, 0, 2));
063: filesHistBT.setMargin(new Insets(0, 2, 0, 2));
064: utilitiesBT.setMargin(new Insets(0, 2, 0, 2));
065:
066: runBT.setFocusPainted(false);
067: previousJump.setFocusPainted(false);
068: nextJump.setFocusPainted(false);
069: depsBT.setFocusPainted(false);
070: filesHistBT.setFocusPainted(false);
071: utilitiesBT.setFocusPainted(false);
072:
073: runBT.setToolTipText("Run");
074: previousJump
075: .setToolTipText("<html><body><b>Undo jump</b> (right-click to see history) <small>Ctrl+Alt+Left</small>");
076: nextJump
077: .setToolTipText("<html><body>Redo jump <small>Ctrl+Alt+Right</small>");
078: filesHistBT.setToolTipText("Access to recent files");
079: utilitiesBT.setToolTipText("Some utilities");
080: depsBT.setToolTipText("Dependencies of the actual source");
081:
082: JPanel cp = MainEditorFrame.instance.editorControlPanel; //new JPanel();
083: cp.setBorder(new EmptyBorder(1, 1, 1, 1));
084:
085: cp.add(runBT);
086: cp.add(Box.createHorizontalStrut(10));
087:
088: cp.add(previousJump);
089: cp.add(nextJump);
090:
091: cp.add(Box.createHorizontalStrut(5));
092: cp.add(lineLabel);
093: cp.add(Box.createHorizontalStrut(5));
094:
095: cp.add(depsBT);
096:
097: cp.add(Box.createHorizontalStrut(5));
098:
099: cp.add(filesHistBT);
100:
101: cp.add(Box.createHorizontalStrut(5));
102: cp.add(utilitiesBT);
103:
104: // tricky
105: lineLabel.setText(" Line 0000 ");
106: lineLabel.setMargin(new Insets(0, 1, 0, 1));
107: lineLabel.setFont(UIManager.getFont("smallFont"));
108: lineLabel.setPreferredSize(new Dimension((int) lineLabel
109: .getPreferredSize().getWidth(), (int) runBT
110: .getPreferredSize().getHeight()));
111: lineLabel.setMinimumSize(lineLabel.getPreferredSize());
112: lineLabel.setText("Line 1 ");
113:
114: add(tabsPanel);
115: tabsPanel.setLayout(new BoxLayout(tabsPanel, BoxLayout.X_AXIS));
116:
117: setMinimumSize(new Dimension(50, 10)); // if not set, takes too much and the main editor split is no more resizable !!
118:
119: jumpAction = new ActionListener() {
120: public void actionPerformed(ActionEvent ae) {
121: String def = MainEditorFrame.instance.globalProperties
122: .getProperty("CustomJumpToLine", "1");
123: String rep = JOptionPane.showInputDialog(lineLabel,
124: "Jump to line: ", def);
125: if (rep != null) {
126: try {
127: int line = Integer.parseInt(rep.trim());
128: editor.selectLine(line - 1);
129: MainEditorFrame.instance.globalProperties
130: .setProperty("CustomJumpToLine", ""
131: + line);
132: } catch (NumberFormatException nfe) {
133: nfe.printStackTrace();
134: }
135: }
136: }
137: };
138:
139: lineLabel.setFocusPainted(false);
140: lineLabel.setMargin(new Insets(0, 2, 0, 2));
141: lineLabel.addActionListener(new ActionListener() {
142: public void actionPerformed(ActionEvent ae) {
143: JPopupMenu pop = new JPopupMenu("Line popup");
144: JMenuItem jump = new JMenuItem("Jump to line...",
145: Icons.sharedRightArrow);
146: jump.setAccelerator(Accelerators.jumpToLineNumber);
147: pop.add(jump);
148: jump.addActionListener(jumpAction);
149:
150: JMenuItem hideViewLines = new JMenuItem(editor
151: .getLinePanel().isVisible() ? "Hide line panel"
152: : "Show line panel");
153: if (editor.getLinePanel().isVisible()) {
154: hideViewLines.setIcon(Icons.sharedCross);
155: }
156: pop.addSeparator();
157: pop.add(hideViewLines);
158: hideViewLines.addActionListener(new ActionListener() {
159: public void actionPerformed(ActionEvent ae) {
160: editor.getLinePanel().setVisible(
161: !editor.getLinePanel().isVisible());
162: }
163: });
164:
165: pop.show(lineLabel, 0, 15);
166: }
167: });
168:
169: this .previousJump.addActionListener(new ActionListener() {
170: public void actionPerformed(ActionEvent ae) {
171: JumpManager jm = editor.jumpManager;
172: jm.jumpToPrevious();
173: }
174: });
175: this .nextJump.addActionListener(new ActionListener() {
176: public void actionPerformed(ActionEvent ae) {
177: editor.jumpManager.redoUndoedJump();
178: }
179: });
180:
181: this .previousJump.addMouseListener(new MouseAdapter() {
182: @Override
183: public void mousePressed(MouseEvent me) {
184: if (me.isPopupTrigger())
185: showPopup(me);
186: }
187:
188: @Override
189: public void mouseReleased(MouseEvent me) {
190: if (me.isPopupTrigger())
191: showPopup(me);
192: }
193:
194: void showPopup(MouseEvent me) {
195: if (editor.jumpManager.getPositionsUndoHistory_REF()
196: .size() > 0) {
197: JPopupMenu pop = editor.jumpManager
198: .getUndoPopup(editor.jumpManager
199: .getPositionsUndoHistory_REF());
200: pop.show(previousJump, 0, 18);
201: }
202: }
203: });
204: this .nextJump.addMouseListener(new MouseAdapter() {
205: @Override
206: public void mousePressed(MouseEvent me) {
207: if (me.isPopupTrigger())
208: showPopup(me);
209: }
210:
211: @Override
212: public void mouseReleased(MouseEvent me) {
213: if (me.isPopupTrigger())
214: showPopup(me);
215: }
216:
217: void showPopup(MouseEvent me) {
218: if (editor.jumpManager.getPositionsRedoHistory_REF()
219: .size() > 0) {
220: JPopupMenu pop = editor.jumpManager
221: .getUndoPopup(editor.jumpManager
222: .getPositionsRedoHistory_REF());
223: pop.show(nextJump, 0, 18);
224: }
225: }
226: });
227:
228: this .filesHistBT.addMouseListener(new MouseAdapter() {
229:
230: @Override
231: public void mousePressed(MouseEvent me) {
232: showPopup(me);
233: }
234:
235: void showPopup(MouseEvent me) {
236: if (editor.jumpManager.getPositionsUndoHistory_REF()
237: .size() > 0) {
238: JPopupMenu pop = editor.jumpManager
239: .getRecentViewsPopup(editor.jumpManager
240: .getPositionsUndoHistory_REF());
241: JMenu tabsM = new JMenu("opened tabs");
242: pop.add(tabsM);
243: for (String jni : getTabsJavaNames()) {
244: JMenuItem mi = new JMenuItem(jni);
245: mi.addActionListener(editor.jumpManager
246: .createJumpAction(jni));
247: tabsM.add(mi);
248: }
249:
250: pop.show(filesHistBT, 0, 18);
251: }
252: }
253: });
254:
255: utilitiesBT.addMouseListener(new MouseAdapter() {
256:
257: @Override
258: public void mousePressed(MouseEvent me) {
259: showPopup(me);
260: }
261:
262: void showPopup(MouseEvent me) {
263: JPopupMenu pop = new JPopupMenu();
264: for (Component ci : SharedUtils
265: .getUtilitiesMenuItems_(MainEditorFrame.instance
266: .getActualProject())) {
267: if (ci == null)
268: pop.addSeparator();
269: else
270: pop.add(ci);
271: }
272:
273: pop.show(utilitiesBT, 0, 18);
274: }
275: });
276:
277: this .depsBT.addMouseListener(new MouseAdapter() {
278:
279: @Override
280: public void mousePressed(MouseEvent me) {
281: showPopup(me);
282: }
283:
284: void showPopup(MouseEvent me) {
285: JPopupMenu pop = editor.jumpManager
286: .getDependenciesPopup();
287: pop.show(depsBT, 0, 18);
288: }
289: });
290:
291: runBT.addActionListener(new ActionListener() {
292: public void actionPerformed(ActionEvent ae) {
293: JPopupMenu pop = new JPopupMenu();
294:
295: FileItem fi = MainEditorFrame.instance.editorPanel
296: .getActualDisplayedFile();
297: if (fi != null && ExecuteActions.isExecutable(fi)) {
298: for (JMenuItem it : ExecuteActions
299: .createNormalRunActions(fi)) {
300: if (it == null) {
301: pop.addSeparator();
302: } else {
303: pop.add(it);
304: }
305: }
306: pop.addSeparator();
307:
308: JMenu dm = new JMenu("Profile & Debug");
309: dm.setIcon(Icons.sharedDebugStart);
310: pop.add(dm);
311:
312: for (JMenuItem it : ExecuteActions
313: .createDebugRunActions(fi)) {
314: if (it == null) {
315: dm.addSeparator();
316: } else {
317: dm.add(it);
318: }
319: }
320:
321: pop.addSeparator();
322: }
323:
324: pop.add(ExecuteActions.createProjectRunAction());
325:
326: List<JMenuItem> acts = ExecuteActions
327: .createRunActionsForAlreadyRan();
328: if (acts.size() > 0) {
329: JMenu arm = new JMenu("Run already ran...");
330: pop.addSeparator();
331: pop.add(arm);
332: int n = 0;
333: for (JMenuItem mi : acts) {
334: arm.add(mi);
335: n++;
336: if (n > 30) {
337: arm.add("" + (acts.size() - 30)
338: + " more items...");
339: break;
340: }
341: }
342:
343: if (acts.size() > 5) {
344: List<JMenuItem> mrl = ExecuteActions
345: .createRunActionsForMostRan();
346: if (mrl.size() > 0) {
347: JMenu arm2 = new JMenu("Run most ran...");
348: //pop.addSeparator();
349: pop.add(arm2);
350: for (JMenuItem mi : mrl) {
351: arm2.add(mi);
352: }
353: }
354: }
355: }
356:
357: if (fi != null && fi instanceof SourceFile) {
358: JMenuItem compileChanged = new JMenuItem(
359: "Compile changed files",
360: new Icons.LetterIcon("C", true, 16, 16,
361: true));
362: compileChanged
363: .setAccelerator(Accelerators.compileChangedFiles);
364: compileChanged
365: .addActionListener(new ActionListener() {
366: public void actionPerformed(
367: ActionEvent ae) {
368: editor.saveChangedFiles();
369: MainEditorFrame.instance
370: .compileOnlyChangedFiles();
371: }
372: });
373: pop.addSeparator();
374: pop.add(compileChanged);
375: }
376:
377: pop.show(runBT, 0, runBT.getHeight() - 2);
378: }
379: });
380:
381: editor.jumpManager.addChangeListener(new ChangeListener() {
382: public void stateChanged(ChangeEvent ce) {
383: previousJump.setEnabled(editor.jumpManager.hasUndo());
384: nextJump.setEnabled(editor.jumpManager.hasRedo());
385: }
386: });
387:
388: this .previousJump.setEnabled(false);
389: this .nextJump.setEnabled(false);
390: this .lineLabel.setEnabled(false);
391: }
392:
393: void setLine(int line) {
394: lineLabel.setText("Line " + (line + 1));
395: }
396:
397: /** Called when a source file has been deleted in the tree.
398: */
399: void removeTab(final FileItem sf) {
400: //System.out.println("Remove tab "+sf);
401: final TabButton tb = getTab(sf);
402: if (tb != null) {
403: int pos = displayedHistoryTabs.indexOf(tb);
404: displayedHistoryTabs.remove(tb);
405: if (editor.getActualDisplayedFile() == sf) {
406: editor.setSourceFileToEdit(null);
407: }
408: tabsPanel.remove(tb);
409: tabsPanel.updateUI();
410: tabsPanel.repaint();
411:
412: if (pos == displayedHistoryTabs.size())
413: pos--;
414: if (pos >= 0) {
415: FileItem nit = displayedHistoryTabs.get(pos).sf;
416: //System.out.println("Set file to edit "+nit.getJavaName());
417: MainEditorFrame.instance.setSourceOrItemToEditOrView(
418: nit, true);
419: }
420:
421: refreshTabs();
422: }
423:
424: }
425:
426: void setAsFirstTab(final FileItem sf) {
427: final TabButton tb = getTab(sf);
428: int pos = displayedHistoryTabs.indexOf(tb);
429: moveTab(sf, -pos);
430: }
431:
432: void moveTab(final FileItem sf, final int n) {
433: final TabButton tb = getTab(sf);
434: if (tb == null)
435: return;
436: int pos = displayedHistoryTabs.indexOf(tb);
437: System.out.println("Moving tab " + sf.getJavaName()
438: + " at pos " + pos + " n=" + n);
439:
440: if (n > 0 && pos + n < displayedHistoryTabs.size()) {
441: // move right
442: displayedHistoryTabs.remove(tb);
443: displayedHistoryTabs.add(pos + n, tb);
444:
445: // be careful, view must be removed first to avoid existing twice, what is forbidden
446: tabsPanel.remove(tb);
447: tabsPanel.add(tb, pos + n);
448: tabsPanel.updateUI();
449: tabsPanel.repaint();
450: } else if (n < 0 && pos + n >= 0) {
451: // move left
452: displayedHistoryTabs.remove(tb);
453: displayedHistoryTabs.add(pos + n, tb);
454:
455: tabsPanel.remove(tb);
456: tabsPanel.add(tb, pos + n);
457: tabsPanel.updateUI();
458: tabsPanel.repaint();
459: } else {
460: System.out.println("cannot move, pos+n=" + (pos + n));
461: }
462:
463: setSelectedTab(sf, false);
464:
465: }
466:
467: void refreshTabs() {
468: for (TabButton tab : displayedHistoryTabs) {
469: tab.refreshIcon();
470: }
471: enableIfTabsPresent();
472: }
473:
474: private TabButton getTab(final FileItem sf) {
475: for (TabButton tab : displayedHistoryTabs) {
476: if (tab.sf == sf) {
477: return tab;
478: }
479: }
480: return null;
481: }
482:
483: void updateHistoryIcons() {
484: for (TabButton tb : displayedHistoryTabs) {
485: tb.refreshIcon();
486: }
487: }
488:
489: /** Selects the corresponding tab, create one if necessary, and limit the
490: number of tabs according to the history bar width.
491: */
492: void setSelectedTab(final FileItem sf, boolean limitToVisibleWidth) {
493: boolean found = false;
494:
495: // reset colors and set selected color if found
496: for (TabButton tab : displayedHistoryTabs) {
497: if (tab.sf == sf) {
498: // select it
499: tab.setAsActiveTab(true);
500: found = true;
501: selected = tab;
502: } else {
503: tab.setAsActiveTab(false);
504: }
505: }
506:
507: if (sf == null) {
508: refreshTabs();
509: selected = null;
510: return;
511: }
512:
513: if (found) {
514: // look if visible !
515: //System.out.println("TPW="+ tabsPanel.getWidth()+", tx="+selected.getX());
516: if (editor.getWidth() > 0
517: && selected.getX() > editor.getWidth()
518: - selected.getWidth()) {
519: //System.out.println("REMOVE found TAB !");
520: tabsPanel.remove(selected);
521: displayedHistoryTabs.remove(selected);
522: found = false;
523: }
524: }
525:
526: if (!found) {
527: // create one
528: TabButton tb = new TabButton(sf);
529: tb.setAsActiveTab(true);
530: displayedHistoryTabs.add(0, tb);
531: tabsPanel.add(tb, 0); // only add place for new tabs
532: selected = tb;
533:
534: //System.out.println("tabs w="+tabsPanel.getPreferredSize().getWidth()+", ed w="+editor.getSize().getWidth()+", limit="+limitToVisibleWidth);
535: // limit to visible components
536: if (limitToVisibleWidth
537: && tabsPanel.getPreferredSize().getWidth() > editor
538: .getWidth() && tabsPanel.getWidth() > 0) {
539: //System.out.println("Remove the last tab because NOT visible.");
540: // remove the last
541: tabsPanel.remove(displayedHistoryTabs
542: .get(displayedHistoryTabs.size() - 1));
543: displayedHistoryTabs
544: .remove(displayedHistoryTabs.size() - 1);
545: }
546:
547: tabsPanel.updateUI();
548: tabsPanel.repaint();
549: }
550:
551: refreshTabs();
552: }
553:
554: void selectNextTab() {
555: if (selected == null)
556: return;
557: //not necessary... editor.saveChangedFiles();
558: int pos = displayedHistoryTabs.indexOf(selected);
559: if (pos + 1 >= displayedHistoryTabs.size())
560: return;
561:
562: displayedHistoryTabs.get(pos + 1).selectTab();
563: }
564:
565: void selectPreviousTab() {
566: if (selected == null)
567: return;
568: //not necessary... editor.saveChangedFiles();
569: int pos = displayedHistoryTabs.indexOf(selected);
570: if (pos - 1 < 0)
571: return;
572:
573: displayedHistoryTabs.get(pos - 1).selectTab();
574: }
575:
576: /** Is used to store the IDE state.
577: */
578: List<String> getTabsJavaNames() {
579: List<String> its = new ArrayList<String>();
580: for (TabButton tab : displayedHistoryTabs) {
581: its.add(tab.sf.getJavaName());
582: }
583:
584: return its;
585: }
586:
587: /** Called when reloading the project.
588: Just recreates the tabs, no selection is made.
589: */
590: void recreateTabsFromNames(java.util.List<String> javaNames) {
591: removeAllTabs();
592: for (int i = javaNames.size() - 1; i >= 0; i--) // reverse order to reconstruct as initially stored
593: {
594: FileItem fi = MainEditorFrame.instance.getFileItem(
595: javaNames.get(i), "");
596: setSelectedTab(fi, true);
597: }
598: enableIfTabsPresent();
599: }
600:
601: /** Also called on project change.
602: */
603: void removeAllTabs() {
604: //System.out.println("Remove all tabs "+displayedHistoryTabs.size()+" "+tabsPanel.getComponentCount());
605: editor.completionManager.closeOpenedDialogs();
606: if (displayedHistoryTabs.size() > 0) {
607: for (TabButton tab : displayedHistoryTabs) {
608: tabsPanel.remove(tab);
609: }
610: displayedHistoryTabs.clear();
611: tabsPanel.updateUI();
612: tabsPanel.repaint();
613:
614: editor.setSourceFileToEdit(null);
615: enableIfTabsPresent();
616: }
617: }
618:
619: private void enableIfTabsPresent() {
620: boolean is = tabsPanel.getComponentCount() > 0
621: || displayedHistoryTabs.size() > 0; // security?
622:
623: this .lineLabel.setEnabled(is);
624: this .previousJump.setEnabled(is);
625: this .nextJump.setEnabled(is);
626: }
627:
628: /** Represents a currently edited fileitem.
629: */
630: private class TabButton extends JButton {
631: final FileItem sf;
632: private final SourcesTreeIcon icon = new SourcesTreeIcon(false,
633: UIManager.getFont("Tree.font").getSize() + 2);
634:
635: public void setAsActiveTab(boolean isSelected) {
636: if (isSelected) {
637: Color selCol = createPureColor(UIManager
638: .getColor("Tree.selectionBackground"));
639: setBackground(selCol);
640: setBorder(selectedBorder);
641: } else {
642: setBackground(createPureColor(tabsPanel.getBackground()));
643: setBorder(origBorder);
644: }
645: }
646:
647: Border origBorder;
648: Border selectedBorder;
649:
650: TabButton(final FileItem sf) {
651: super (""); //
652:
653: origBorder = getBorder();
654: selectedBorder = new CompoundBorder(new CustomEtchedBorder(
655: true, true, false, true, Color.darkGray,
656: Color.darkGray), new EmptyBorder(2, 5, 2, 5));
657:
658: String name = sf.getName();
659: if (name.toLowerCase().endsWith(".java")) {
660: this .setText(name.substring(0, name.length() - 5)); // UUUh : this calls repaint below !!!
661: } else {
662: this .setText(name);
663: }
664:
665: StringBuilder tt = new StringBuilder("<html><body><b>"
666: + sf.getJavaName() + "</b>");
667:
668: if (sf instanceof LibFileItem) {
669: LibFileItem li = (LibFileItem) sf;
670: tt.append("<br>in " + li.getRootArchiveName());
671: tt.append("<br>Last modif: "
672: + DateUtils.formatDateAndTimeHuman(sf
673: .getLastModified()));
674:
675: if (li.decompiledContentOrSource != null)
676: tt.append("<br>Associated source or decompiled");
677: } else {
678: tt.append("<br>Last modif");
679: tt.append(" (at start): "
680: + DateUtils.formatDateAndTimeHuman(sf
681: .getLastModified()));
682:
683: long d = System.currentTimeMillis()
684: - sf.getLastModified();
685: if (d > DateUtils.oneDayMs) {
686: tt.append(" (" + DateUtils.formatTimeDifference(d)
687: + " ago)");
688: }
689: }
690:
691: tt.append("</body></html>");
692: this .setToolTipText(tt.toString());
693:
694: this .sf = sf;
695:
696: this .setFocusPainted(false);
697: this .setMargin(new Insets(0, 5, 0, 5));
698:
699: this .addMouseListener(new MouseAdapter() {
700: @Override
701: public void mousePressed(MouseEvent me) {
702: if (me.isPopupTrigger()) {
703: displayPopup(me);
704: } else {
705: selectTab();
706: }
707: }
708:
709: @Override
710: public void mouseReleased(MouseEvent me) {
711: if (me.isPopupTrigger()) {
712: displayPopup(me);
713: } else {
714: selectTab();
715: }
716: }
717: });
718:
719: // initial
720: refreshIcon();
721: }
722:
723: public void displayPopup(final MouseEvent me) {
724: JPopupMenu popup = new JPopupMenu();
725:
726: JMenuItem left = new JMenuItem("Move tab left");
727: left.setAccelerator(Accelerators.moveTabLeft);
728: popup.add(left);
729: left.addActionListener(new ActionListener() {
730: public void actionPerformed(ActionEvent ae) {
731: editor.saveChangedFiles();
732: moveTab(sf, -1);
733: }
734: });
735:
736: JMenuItem ri = new JMenuItem("Move tab right");
737: ri.setAccelerator(Accelerators.moveTabRight);
738: popup.add(ri);
739: ri.addActionListener(new ActionListener() {
740: public void actionPerformed(ActionEvent ae) {
741: editor.saveChangedFiles();
742: moveTab(sf, 1);
743: }
744: });
745:
746: if (displayedHistoryTabs.size() > 1
747: && displayedHistoryTabs.indexOf(this ) > 0) {
748: JMenuItem fi = new JMenuItem("Set as first tab"); // Todo: ALT+shift+1
749: fi.setAccelerator(Accelerators.moveTabPos1);
750: popup.add(fi);
751: fi.addActionListener(new ActionListener() {
752: public void actionPerformed(ActionEvent ae) {
753: editor.saveChangedFiles();
754: setAsFirstTab(sf);
755: }
756: });
757: }
758:
759: if (displayedHistoryTabs.size() > 1) {
760: popup.addSeparator();
761:
762: if (displayedHistoryTabs.indexOf(this ) > 0) {
763: JMenuItem gn = new JMenuItem("Go to previous tab",
764: Icons.sharedLeftArrow);
765: gn.setAccelerator(Accelerators.selectPreviousTab);
766: popup.add(gn);
767: gn.addActionListener(new ActionListener() {
768: public void actionPerformed(ActionEvent ae) {
769: selectPreviousTab();
770: }
771: });
772: }
773:
774: if (displayedHistoryTabs.indexOf(this ) < displayedHistoryTabs
775: .size() - 1) {
776: JMenuItem gn = new JMenuItem("Go to next tab",
777: Icons.sharedRightArrow);
778: gn.setAccelerator(Accelerators.selectNextTab);
779: popup.add(gn);
780: gn.addActionListener(new ActionListener() {
781: public void actionPerformed(ActionEvent ae) {
782: selectNextTab();
783: }
784: });
785: }
786: }
787:
788: JMenuItem ref = new JMenuItem("Refresh tabs");
789: if (MainEditorFrame.debug) {
790: popup.addSeparator(); //should be automatic...
791: popup.add(ref);
792: }
793: ref.addActionListener(new ActionListener() {
794: public void actionPerformed(ActionEvent ae) {
795: refreshIcon();
796: }
797: });
798:
799: JMenuItem remove = new JMenuItem("Remove tab",
800: Icons.sharedCross);
801: remove.setAccelerator(Accelerators.closeCurrentTab);// fake.
802: popup.addSeparator();
803: popup.add(remove);
804: remove.addActionListener(new ActionListener() {
805: public void actionPerformed(ActionEvent ae) {
806: editor.saveChangedFiles();
807: removeTab(sf);
808: }
809: });
810:
811: if (displayedHistoryTabs.size() > 1) {
812: JMenuItem removeA = new JMenuItem("Remove all "
813: + displayedHistoryTabs.size() + " tabs",
814: Icons.sharedCross);
815: popup.addSeparator();
816: popup.add(removeA);
817: removeA.addActionListener(new ActionListener() {
818: public void actionPerformed(ActionEvent ae) {
819: editor.saveChangedFiles();
820: removeAllTabs();
821: }
822: });
823:
824: JMenuItem removeA2 = new JMenuItem(
825: "Keep only actual tab", Icons.sharedCross);
826: //popup.addSeparator();
827: popup.add(removeA2);
828: removeA2.addActionListener(new ActionListener() {
829: public void actionPerformed(ActionEvent ae) {
830: FileItem fi = editor.getActualDisplayedFile();
831: editor.saveChangedFiles();
832: removeAllTabs();
833: MainEditorFrame.instance
834: .setSourceOrItemToEditOrView(fi, false); //already ?
835: }
836: });
837: }
838:
839: popup.show(this , me.getX(), me.getY());
840: }
841:
842: /** Call this when clicked to select the tab.
843: */
844: public void selectTab() {
845: if (sf instanceof SourceFile) {
846: SourceFile sff = (SourceFile) sf;
847: MainEditorFrame.instance.sourcesAndLibsPanel
848: .setSelectedIndex(0);
849: MainEditorFrame.instance.sourcesTreePanel
850: .setSelectedSource(sff, true);
851: } else if (sf instanceof LibFileItem) {
852: LibFileItem lit = (LibFileItem) sf;
853: MainEditorFrame.instance.sourcesAndLibsPanel
854: .setSelectedIndex(1);
855: MainEditorFrame.instance.librariesPanel
856: .setSelectedItem(lit, true);
857: }
858: }
859:
860: public void refreshIcon() {
861: if (MainEditorFrame.compactUI)
862: return;
863:
864: if (sf instanceof SourceFile) {
865: SourceFile sff = (SourceFile) sf;
866: SourcesTreeRenderer.setupIconFor(icon, sff);
867: this .setIcon(icon);
868: repaint();
869: } else if (sf instanceof LibFileItem) {
870: LibFileItem lf = (LibFileItem) sf;
871: LibTreeRenderer.setupIconFor(icon, lf);
872: this .setIcon(icon);
873: repaint();
874: } else {
875: // ??
876: }
877: }
878: }
879:
880: /** The UI manager and components gives UIColor, this create a pure Color object.
881: */
882: private static Color createPureColor(Color c) {
883: return new Color(c.getRed(), c.getGreen(), c.getBlue());
884: }
885:
886: }
|