/[svn]/jsampler/trunk/src/org/jsampler/view/classic/LSConsolePane.java
ViewVC logotype

Annotation of /jsampler/trunk/src/org/jsampler/view/classic/LSConsolePane.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 913 - (hide annotations) (download)
Mon Aug 7 18:45:48 2006 UTC (17 years, 8 months ago) by iliev
File size: 31323 byte(s)
updating to JSampler 0.3a

1 iliev 913 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4     * Copyright (C) 2005, 2006 Grigor Kirilov Iliev
5     *
6     * This file is part of JSampler.
7     *
8     * JSampler is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License version 2
10     * as published by the Free Software Foundation.
11     *
12     * JSampler is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with JSampler; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20     * MA 02111-1307 USA
21     */
22    
23     package org.jsampler.view.classic;
24    
25     import java.awt.Color;
26     import java.awt.Dimension;
27     import java.awt.Point;
28     import java.awt.Window;
29    
30     import java.awt.event.ActionEvent;
31     import java.awt.event.ActionListener;
32     import java.awt.event.ComponentAdapter;
33     import java.awt.event.ComponentEvent;
34     import java.awt.event.InputEvent;
35     import java.awt.event.KeyEvent;
36     import java.awt.event.MouseAdapter;
37     import java.awt.event.MouseEvent;
38     import java.awt.event.WindowAdapter;
39     import java.awt.event.WindowEvent;
40    
41     import java.io.BufferedReader;
42     import java.io.StringReader;
43    
44     import java.util.logging.Level;
45    
46     import javax.swing.AbstractAction;
47     import javax.swing.Action;
48     import javax.swing.BorderFactory;
49     import javax.swing.Box;
50     import javax.swing.BoxLayout;
51     import javax.swing.JButton;
52     import javax.swing.JComponent;
53     import javax.swing.JLabel;
54     import javax.swing.JList;
55     import javax.swing.JMenu;
56     import javax.swing.JMenuItem;
57     import javax.swing.JPanel;
58     import javax.swing.JPopupMenu;
59     import javax.swing.JScrollPane;
60     import javax.swing.JTextField;
61     import javax.swing.JTextPane;
62     import javax.swing.JWindow;
63     import javax.swing.KeyStroke;
64     import javax.swing.ListSelectionModel;
65     import javax.swing.SwingUtilities;
66     import javax.swing.TransferHandler;
67    
68     import javax.swing.border.EtchedBorder;
69    
70     import javax.swing.event.DocumentEvent;
71     import javax.swing.event.DocumentListener;
72    
73     import javax.swing.text.Style;
74     import javax.swing.text.StyleConstants;
75     import javax.swing.text.StyleContext;
76     import javax.swing.text.StyledDocument;
77    
78     import org.jsampler.CC;
79     import org.jsampler.DefaultLSConsoleModel;
80     import org.jsampler.HF;
81     import org.jsampler.Instrument;
82     import org.jsampler.LSConsoleModel;
83     import org.jsampler.LscpUtils;
84    
85     import org.jsampler.event.LSConsoleEvent;
86     import org.jsampler.event.LSConsoleListener;
87    
88     import static javax.swing.KeyStroke.*;
89     import static org.jsampler.view.classic.ClassicI18n.i18n;
90    
91    
92     /**
93     *
94     * @author Grigor Iliev
95     */
96     public class LSConsolePane extends JPanel {
97     private enum AutocompleteMode { AUTOCOMPLETE, HISTORY_SEARCH, CMD_LIST_SEARCH }
98     private AutocompleteMode autocompleteMode = AutocompleteMode.AUTOCOMPLETE;
99    
100     private Window owner;
101    
102     private final JButton btnMenu = new ToolbarButton();
103     private JPopupMenu menu = new JPopupMenu();
104    
105     private final LSConsoleTextPane console = new LSConsoleTextPane();
106    
107     private final JPanel inputPane = new JPanel();
108     private final JLabel lInput = new JLabel();
109     private final JTextField tfSearch = new JTextField();
110     private final CmdLineTextField tfInput = new CmdLineTextField();
111    
112     private AutoCompleteWindow autoCompleteWindow;
113    
114     private final LSConsoleModel model = new DefaultLSConsoleModel();
115    
116     private final StringBuffer consoleText = new StringBuffer();
117    
118     private final LSConsoleViewMode lsConsoleViewMode;
119    
120     private boolean processingSearch = false;
121    
122    
123     /** Creates a new instance of <code>LSConsolePane</code>. */
124     public
125     LSConsolePane(Window owner) {
126     setOwner(owner);
127    
128     model.setCommandHistorySize(ClassicPrefs.getLSConsoleHistSize());
129     String s = ClassicPrefs.getLSConsoleHistory();
130    
131     BufferedReader br = new BufferedReader(new StringReader(s));
132    
133     try {
134     s = br.readLine();
135     while(s != null) {
136     model.addToCommandHistory(s);
137     s = br.readLine();
138     }
139     } catch(Exception x) {
140     CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
141     }
142    
143     lsConsoleViewMode = new LSConsoleViewMode();
144    
145     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
146     setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
147    
148     JPanel p = new JPanel();
149     p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
150     p.add(Box.createGlue());
151    
152     btnMenu.setIcon(Res.iconDown16);
153     btnMenu.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
154     btnMenu.setFocusPainted(false);
155     p.add(btnMenu);
156     p.setMaximumSize(new Dimension(Short.MAX_VALUE, p.getPreferredSize().height));
157    
158     add(p);
159    
160     setBackgroundColor(ClassicPrefs.getLSConsoleBackgroundColor());
161    
162     setTextColor(ClassicPrefs.getLSConsoleTextColor());
163    
164     add(new JScrollPane(console));
165    
166     inputPane.setLayout(new BoxLayout(inputPane, BoxLayout.X_AXIS));
167     inputPane.setBorder(tfInput.getBorder());
168     tfInput.setBorder(BorderFactory.createEmptyBorder());
169     tfSearch.setBorder(BorderFactory.createEmptyBorder());
170    
171     lInput.setOpaque(false);
172     lInput.setVisible(false);
173     inputPane.add(lInput);
174    
175     Dimension d = new Dimension(Short.MAX_VALUE, tfSearch.getPreferredSize().height);
176     tfSearch.setMaximumSize(d);
177    
178     tfSearch.setVisible(false);
179     tfSearch.setFocusTraversalKeysEnabled(false);
180     inputPane.add(tfSearch);
181    
182     d = new Dimension(Short.MAX_VALUE, tfInput.getPreferredSize().height);
183     tfInput.setMaximumSize(d);
184    
185     tfInput.setFocusTraversalKeysEnabled(false);
186     inputPane.add(tfInput);
187    
188     add(inputPane);
189    
190     tfInput.addActionListener(getHandler());
191     tfInput.getDocument().addDocumentListener(getHandler());
192     getModel().addLSConsoleListener(getHandler());
193    
194     tfSearch.addActionListener(new Actions(Actions.APPLY_SEARCH));
195    
196     installKeyboardListeners();
197     initMenu(owner);
198     }
199    
200     private void
201     installKeyboardListeners() {
202     KeyStroke k = getKeyStroke(KeyEvent.VK_TAB, 0);
203     tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.AUTOCOMPLETE);
204     tfInput.getActionMap().put(Actions.AUTOCOMPLETE, new Actions(Actions.AUTOCOMPLETE));
205    
206     k = getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK);
207     tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.HISTORY_SEARCH);
208     tfInput.getActionMap().put (
209     Actions.HISTORY_SEARCH, new Actions(Actions.HISTORY_SEARCH)
210     );
211    
212     k = getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK);
213     tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.CMD_LIST_SEARCH);
214     tfInput.getActionMap().put (
215     Actions.CMD_LIST_SEARCH, new Actions(Actions.CMD_LIST_SEARCH)
216     );
217    
218     k = getKeyStroke(KeyEvent.VK_UP, 0);
219     tfInput.getInputMap(JComponent.WHEN_FOCUSED).put(k, Actions.MOVE_UP);
220     tfInput.getActionMap().put(Actions.MOVE_UP, new Actions(Actions.MOVE_UP));
221    
222     k = getKeyStroke(KeyEvent.VK_DOWN, 0);
223     tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_DOWN);
224     tfInput.getActionMap().put(Actions.MOVE_DOWN, new Actions(Actions.MOVE_DOWN));
225    
226     k = getKeyStroke(KeyEvent.VK_HOME, 0);
227     tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_HOME);
228     tfInput.getActionMap().put(Actions.MOVE_HOME, new Actions(Actions.MOVE_HOME));
229    
230     k = getKeyStroke(KeyEvent.VK_END, 0);
231     tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_END);
232     tfInput.getActionMap().put(Actions.MOVE_END, new Actions(Actions.MOVE_END));
233    
234     k = getKeyStroke(KeyEvent.VK_L, InputEvent.CTRL_MASK);
235     tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.CLEAR_CONSOLE);
236     tfInput.getActionMap().put (
237     Actions.CLEAR_CONSOLE, new Actions(Actions.CLEAR_CONSOLE)
238     );
239    
240     k = getKeyStroke(KeyEvent.VK_ESCAPE, 0);
241     tfInput.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
242     k, Actions.CANCEL_SELECTION
243     );
244     tfInput.getActionMap().put (
245     Actions.CANCEL_SELECTION, new Actions(Actions.CANCEL_SELECTION)
246     );
247    
248     k = getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_MASK);
249     tfInput.getInputMap(WHEN_FOCUSED).put(k, Actions.QUIT_SESSION);
250     tfInput.getActionMap().put(Actions.QUIT_SESSION, new Actions(Actions.QUIT_SESSION));
251    
252    
253     k = getKeyStroke(KeyEvent.VK_UP, 0);
254     tfSearch.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_UP);
255     tfSearch.getActionMap().put(Actions.MOVE_UP, new Actions(Actions.MOVE_UP));
256    
257     k = getKeyStroke(KeyEvent.VK_DOWN, 0);
258     tfSearch.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_DOWN);
259     tfSearch.getActionMap().put(Actions.MOVE_DOWN, new Actions(Actions.MOVE_DOWN));
260    
261     k = getKeyStroke(KeyEvent.VK_HOME, 0);
262     tfSearch.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_HOME);
263     tfSearch.getActionMap().put(Actions.MOVE_HOME, new Actions(Actions.MOVE_HOME));
264    
265     k = getKeyStroke(KeyEvent.VK_END, 0);
266     tfSearch.getInputMap(WHEN_FOCUSED).put(k, Actions.MOVE_END);
267     tfSearch.getActionMap().put(Actions.MOVE_END, new Actions(Actions.MOVE_END));
268    
269     k = getKeyStroke(KeyEvent.VK_ESCAPE, 0);
270     tfSearch.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
271     k, Actions.CANCEL_SEARCH
272     );
273     tfSearch.getActionMap().put (
274     Actions.CANCEL_SEARCH, new Actions(Actions.CANCEL_SEARCH)
275     );
276     }
277    
278     private void
279     initMenu(Window owner) {
280     JMenuItem mi = new JMenuItem(lsConsoleViewMode);
281     menu.add(mi);
282    
283     menu.addSeparator();
284    
285     JMenu clearMenu = new JMenu(i18n.getMenuLabel("LSConsolePane.clear"));
286    
287     mi = new JMenuItem(i18n.getMenuLabel("LSConsolePane.clearConsole"));
288     clearMenu.add(mi);
289     mi.addActionListener(new Actions(Actions.CLEAR_CONSOLE));
290    
291     mi = new JMenuItem(i18n.getMenuLabel("LSConsolePane.clearSessionHistory"));
292     clearMenu.add(mi);
293     mi.addActionListener(new Actions(Actions.CLEAR_SESSION_HISTORY));
294    
295     menu.add(clearMenu);
296    
297     JMenu exportMenu = new JMenu(i18n.getMenuLabel("LSConsolePane.export"));
298    
299     mi = new JMenuItem(i18n.getMenuLabel("LSConsolePane.exportSession"));
300     exportMenu.add(mi);
301     mi.addActionListener(new ActionListener() {
302     public void
303     actionPerformed(ActionEvent e) {
304     LscpScriptDlg dlg = new LscpScriptDlg();
305     dlg.setCommands(getModel().getSessionHistory());
306     dlg.setVisible(true);
307     }
308     });
309    
310     mi = new JMenuItem(i18n.getMenuLabel("LSConsolePane.exportCommandHistory"));
311     exportMenu.add(mi);
312     mi.addActionListener(new ActionListener() {
313     public void
314     actionPerformed(ActionEvent e) {
315     LscpScriptDlg dlg = new LscpScriptDlg();
316     dlg.setCommands(getModel().getCommandHistory());
317     dlg.setVisible(true);
318     }
319     });
320    
321     menu.add(exportMenu);
322    
323     mi = new JMenuItem(i18n.getMenuLabel("LSConsolePane.runScript"));
324     menu.add(mi);
325     mi.addActionListener(new ActionListener() {
326     public void
327     actionPerformed(ActionEvent e) {
328     ((MainFrame)CC.getMainFrame()).runScript();
329     }
330     });
331    
332     btnMenu.addActionListener(new ActionListener() {
333     public void
334     actionPerformed(ActionEvent e) {
335     int x = (int)btnMenu.getMinimumSize().getWidth();
336     x -= (int)menu.getPreferredSize().getWidth();
337     int y = (int)btnMenu.getMinimumSize().getHeight() + 1;
338     menu.show(btnMenu, x, y);
339     }
340     });
341     }
342    
343     /**
344     * Gets the LS Console data model.
345     * @return The LS Console data model.
346     */
347     public LSConsoleModel
348     getModel() { return model; }
349    
350     /**
351     * Sets the text color of the LS Console.
352     * @param c The text color of the LS Console.
353     */
354     public void
355     setTextColor(Color c) {
356     console.setTextColor(c);
357    
358     lInput.setForeground(c);
359     tfInput.setForeground(c);
360     tfSearch.setForeground(c);
361    
362     autoCompleteWindow.setTextColor(c);
363     }
364    
365     /**
366     * Gets the text color of the LS Console.
367     * @return The text color of the LS Console.
368     */
369     public Color
370     getTextColor() { return console.getTextColor(); }
371    
372     /**
373     * Sets the background color of the LS Console.
374     * @param c The background color of the LS Console.
375     */
376     public void
377     setBackgroundColor(Color c) {
378     console.setBackground(c);
379    
380     lInput.setBackground(c);
381     inputPane.setBackground(c);
382     tfInput.setBackground(c);
383     tfSearch.setBackground(c);
384    
385     autoCompleteWindow.setBackgroundColor(c);
386     }
387    
388     /**
389     * Gets the background color of the LS Console.
390     * @return The background color of the LS Console.
391     */
392     public Color
393     getBackgroundColor() { return console.getBackground(); }
394    
395     /**
396     * Sets the notification messages' color.
397     * @param c The notification messages' color.
398     */
399     public void
400     setNotifyColor(Color c) { console.setNotifyColor(c); }
401    
402     /**
403     * Sets the warning messages' color.
404     * @param c The warning messages' color.
405     */
406     public void
407     setWarningColor(Color c) { console.setWarningColor(c); }
408    
409     /**
410     * Sets the error messages' color.
411     * @param c The error messages' color.
412     */
413     public void
414     setErrorColor(Color c) { console.setErrorColor(c); }
415    
416     public class CmdLineTextField extends JTextField {
417     CmdLineTextField() {
418     setTransferHandler(new TransferHandler("instrumentLoad"));
419     }
420    
421     public String
422     getInstrumentLoad() { return getSelectedText(); }
423    
424     public void setInstrumentLoad(String instr) {
425     if(instr == null) return;
426    
427     if(!Instrument.isDnDString(instr)) {
428     replaceSelection(instr);
429     return;
430     }
431    
432     String[] args = instr.split("\n");
433     if(args.length < 6) return;
434    
435     String s = "LOAD INSTRUMENT NON_MODAL '" + args[4] + "' " + args[5] + " ";
436     getModel().setCommandLineText(s);
437     requestFocus();
438     }
439     }
440    
441     private class LSConsoleViewMode extends AbstractAction {
442     LSConsoleViewMode() { }
443    
444     public void
445     actionPerformed(ActionEvent e) {
446     MainFrame mainFrame = (MainFrame)CC.getMainFrame();
447     mainFrame.setLSConsolePopOut(!mainFrame.isLSConsolePopOut());
448    
449     setName(mainFrame.isLSConsolePopOut());
450     }
451    
452     private void
453     setName(boolean b) {
454     if(b) {
455     putValue(Action.NAME, i18n.getMenuLabel("LSConsolePane.popin"));
456     } else {
457     putValue(Action.NAME, i18n.getMenuLabel("LSConsolePane.popout"));
458     }
459     }
460     }
461    
462     /**
463     * Updates the text of the menu item responsible for changing the pop-out/pop-in mode.
464     */
465     public void
466     updateLSConsoleViewMode() {
467     if(getOwner() instanceof LSConsoleDlg) lsConsoleViewMode.setName(true);
468     else if(getOwner() instanceof MainFrame) {
469     lsConsoleViewMode.setName(((MainFrame)getOwner()).isLSConsolePopOut());
470     }
471     }
472    
473     public void
474     setOwner(Window owner) {
475     if(autoCompleteWindow != null && autoCompleteWindow.isVisible())
476     autoCompleteWindow.setVisible(false);
477    
478     autoCompleteWindow = new AutoCompleteWindow(owner);
479    
480     if(getOwner() != null) getOwner().removeWindowListener(getHandler());
481     owner.addWindowListener(getHandler());
482    
483     this.owner = owner;
484     }
485    
486     public Window
487     getOwner() { return owner; }
488    
489     /** Hides the autocomplete window. */
490     public void
491     hideAutoCompleteWindow() { autoCompleteWindow.setVisible(false); }
492    
493    
494     private final SearchHandler searchHandler = new SearchHandler();
495    
496     private SearchHandler
497     getSearchHandler() { return searchHandler; }
498    
499     private class SearchHandler implements DocumentListener {
500     // DocumentListener
501     public void
502     insertUpdate(DocumentEvent e) { processSearch(); }
503    
504     public void
505     removeUpdate(DocumentEvent e) { processSearch(); }
506    
507     public void
508     changedUpdate(DocumentEvent e) { processSearch(); }
509     }
510    
511    
512     private final Handler eventHandler = new Handler();
513    
514     private Handler
515     getHandler() { return eventHandler; }
516    
517     private class Handler extends WindowAdapter
518     implements ActionListener, DocumentListener, LSConsoleListener {
519    
520     // ActionListener
521     public void
522     actionPerformed(ActionEvent e) {
523     if(autoCompleteWindow.isVisible()) autoCompleteWindow.applySelection();
524     else getModel().execCommand();
525     }
526    
527     // DocumentListener
528     public void
529     insertUpdate(DocumentEvent e) { getModel().setCommandLineText(tfInput.getText()); }
530    
531     public void
532     removeUpdate(DocumentEvent e) { getModel().setCommandLineText(tfInput.getText()); }
533    
534     public void
535     changedUpdate(DocumentEvent e) { getModel().setCommandLineText(tfInput.getText()); }
536    
537     // WindowListener
538     public void
539     windowActivated(WindowEvent e) {
540     if(autocompleteMode == AutocompleteMode.AUTOCOMPLETE) {
541     tfInput.requestFocusInWindow();
542     } else tfSearch.requestFocusInWindow();
543     }
544    
545     public void
546     windowDeactivated(WindowEvent e) { autoCompleteWindow.setVisible(false); }
547    
548     public void
549     windowIconified(WindowEvent e) { autoCompleteWindow.setVisible(false); }
550    
551     // LSConsoleListener
552    
553     /** Invoked when the text in the command line is changed. */
554     public void
555     commandLineTextChanged(LSConsoleEvent e) {
556     commandChanged(e.getPreviousCommandLineText());
557     }
558    
559     /** Invoked when the command in the command line has been executed. */
560     public void
561     commandExecuted(LSConsoleEvent e) {
562     console.addCommand(getModel().getLastExecutedCommand());
563     }
564    
565     /** Invoked when response is received from LinuxSampler. */
566     public void
567     responseReceived(LSConsoleEvent e) {
568     console.addCommandResponse(e.getResponse());
569     }
570     }
571    
572     private void
573     commandChanged(String oldCmdLine) {
574     if(!tfInput.getText().equals(getModel().getCommandLineText()))
575     tfInput.setText(getModel().getCommandLineText());
576    
577     if(LscpUtils.spellCheck(tfInput.getText())) {
578     tfInput.setForeground(console.getTextColor());
579     } else {
580     tfInput.setForeground(console.getErrorColor());
581     if(autoCompleteWindow.isVisible()) autoCompleteWindow.setVisible(false);
582     }
583    
584     if(autoCompleteWindow.isVisible()) processAutoComplete(oldCmdLine);
585     }
586    
587     private boolean
588     isProcessingSearch() { return processingSearch; }
589    
590     private void
591     setProcessingSearch(boolean b) { processingSearch = b; }
592    
593     /** Invoked when the tab key is pressed. */
594     private void
595     processAutoComplete() {
596     processAutoComplete(null);
597     }
598    
599     private void
600     processAutoComplete(String oldCmdLine) {
601     String cmdLine = getModel().getCommandLineText();
602     switch(autocompleteMode) {
603     case AUTOCOMPLETE:
604    
605     break;
606     case HISTORY_SEARCH:
607     case CMD_LIST_SEARCH:
608     if(autoCompleteWindow.isVisible()) return;
609     }
610    
611     autocompleteMode = AutocompleteMode.AUTOCOMPLETE;
612    
613     final String[] cmdS;
614    
615     try {
616     cmdS = LscpUtils.getCompletionPossibilities(cmdLine);
617     } catch(IllegalStateException e) {
618     autoCompleteWindow.setVisible(false);
619     java.awt.Toolkit.getDefaultToolkit().beep();
620     return;
621     }
622    
623     if(cmdS.length == 0) {
624     autoCompleteWindow.setVisible(false);
625     return;
626     }
627     if(cmdS.length == 1) {
628     if(oldCmdLine != null && oldCmdLine.startsWith(cmdLine)) return;
629    
630     // To prevent IllegalStateException exception.
631     SwingUtilities.invokeLater(new Runnable() {
632     public void
633     run() { tfInput.setText(cmdS[0]); }
634     });
635    
636     return;
637     }
638    
639     autoCompleteWindow.setCommandList(cmdS);
640     autoCompleteWindow.setVisible(true);
641     }
642    
643     private void
644     startHistorySearch() {
645     autocompleteMode = AutocompleteMode.HISTORY_SEARCH;
646     lInput.setText("History Search: ");
647    
648     startSearch();
649     }
650    
651     private void
652     startCmdListSearch() {
653     autocompleteMode = AutocompleteMode.CMD_LIST_SEARCH;
654     lInput.setText("Command List Search: ");
655    
656     startSearch();
657     }
658    
659     private void
660     startSearch() {
661     if(!isProcessingSearch())
662     tfSearch.getDocument().addDocumentListener(getSearchHandler());
663    
664     setProcessingSearch(true);
665    
666     lInput.setVisible(true);
667     tfInput.setVisible(false);
668     tfSearch.setText(getModel().getCommandLineText());
669     tfSearch.setVisible(true);
670     tfSearch.requestFocusInWindow();
671    
672     revalidate();
673     repaint();
674    
675     processSearch();
676     }
677    
678     private void
679     processSearch() {
680     String[] cmdS = null;
681    
682     switch(autocompleteMode) {
683     case HISTORY_SEARCH:
684     cmdS = getModel().searchCommandHistory(tfSearch.getText());
685     break;
686     case CMD_LIST_SEARCH:
687     cmdS = getModel().searchCommandList(tfSearch.getText());
688     break;
689     }
690    
691     autoCompleteWindow.setCommandList(cmdS);
692     autoCompleteWindow.setVisible(cmdS.length > 0);
693     }
694    
695     private void
696     stopSearch(boolean cancelSearch) {
697     setProcessingSearch(false);
698    
699     tfSearch.getDocument().removeDocumentListener(getSearchHandler());
700    
701     lInput.setVisible(false);
702     lInput.setText("");
703     tfSearch.setVisible(false);
704     tfInput.setVisible(true);
705     tfInput.requestFocusInWindow();
706    
707     revalidate();
708     repaint();
709    
710     if(cancelSearch) {
711     autoCompleteWindow.setVisible(false);
712     return;
713     }
714    
715     if(autoCompleteWindow.isVisible()) autoCompleteWindow.applySelection();
716     else getModel().setCommandLineText(tfSearch.getText());
717     }
718    
719    
720     private class Actions extends AbstractAction {
721     private static final String AUTOCOMPLETE = "autocomplete";
722     private static final String HISTORY_SEARCH = "historySearch";
723     private static final String CMD_LIST_SEARCH = "cmdListSearch";
724     private static final String CANCEL_SEARCH = "cancelSearch";
725     private static final String APPLY_SEARCH = "applySearch";
726     private static final String MOVE_UP = "moveUp";
727     private static final String MOVE_DOWN = "moveDown";
728     private static final String MOVE_HOME = "moveHome";
729     private static final String MOVE_END = "moveEnd";
730     private static final String CANCEL_SELECTION = "cancelSelection";
731     private static final String CLEAR_CONSOLE = "clearConsole";
732     private static final String CLEAR_SESSION_HISTORY = "clearSessionHistory";
733     private static final String CLEAR_COMMAND_HISTORY = "clearCommandHistory";
734     private static final String QUIT_SESSION = "quitSession";
735    
736     Actions(String name) { super(name); }
737    
738     public void
739     actionPerformed(ActionEvent e) {
740     String key = getValue(Action.NAME).toString();
741    
742     if(key == AUTOCOMPLETE) {
743     processAutoComplete();
744     } else if(key == HISTORY_SEARCH) {
745     startHistorySearch();
746     } else if(key == CMD_LIST_SEARCH) {
747     startCmdListSearch();
748     } else if(key == CANCEL_SEARCH) {
749     stopSearch(true);
750     } else if(key == APPLY_SEARCH) {
751     stopSearch(false);
752     } else if(key == MOVE_UP) {
753     if(autoCompleteWindow.isVisible()) {
754     autoCompleteWindow.selectPreviousItem();
755     return;
756     }
757    
758     getModel().browseCommandHistoryUp();
759     } else if(key == MOVE_DOWN) {
760     if(autoCompleteWindow.isVisible()) {
761     autoCompleteWindow.selectNextItem();
762     return;
763     }
764    
765     getModel().browseCommandHistoryDown();
766     } else if(key == MOVE_HOME) {
767     if(autoCompleteWindow.isVisible()) {
768     autoCompleteWindow.selectFirstItem();
769     return;
770     }
771    
772     JTextField tf = tfInput.isVisible() ? tfInput : tfSearch;
773     tf.setCaretPosition(0);
774     } else if(key == MOVE_END) {
775     if(autoCompleteWindow.isVisible()) {
776     autoCompleteWindow.selectLastItem();
777     return;
778     }
779    
780     JTextField tf = tfInput.isVisible() ? tfInput : tfSearch;
781     tf.setCaretPosition(tf.getText().length());
782     } else if(key == CANCEL_SELECTION) {
783     autoCompleteWindow.setVisible(false);
784     } else if(key == CLEAR_CONSOLE) {
785     console.setText("");
786     } else if(key == CLEAR_SESSION_HISTORY) {
787     getModel().clearSessionHistory();
788     } else if(key == CLEAR_COMMAND_HISTORY) {
789     getModel().clearCommandHistory();
790     } else if(key == QUIT_SESSION) {
791     getModel().clearSessionHistory();
792     console.setText("");
793     ((MainFrame)CC.getMainFrame()).setLSConsoleVisible(false);
794     }
795     }
796     }
797    
798     private class AutoCompleteWindow extends JWindow {
799     private int MAX_HEIGHT = 140;
800    
801     private JList list = new JList();
802     private JScrollPane scrollPane;
803    
804     AutoCompleteWindow(Window owner) {
805     super(owner);
806    
807     owner.addComponentListener(getHandler());
808    
809     list.addMouseListener(new MouseAdapter() {
810     public void
811     mouseClicked(MouseEvent e) {
812     if(list.getSelectedIndex() != -1) applySelection();
813     }
814     });
815    
816     list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
817    
818     scrollPane = new JScrollPane(list);
819     //sp.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
820     scrollPane.setPreferredSize (
821     new Dimension(scrollPane.getPreferredSize().width, MAX_HEIGHT)
822     );
823     add(scrollPane);
824    
825     int i = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
826     getRootPane().getInputMap(i).put (
827     KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
828     "applySelection"
829     );
830    
831     getRootPane().getActionMap().put ("applySelection", new AbstractAction() {
832     public void
833     actionPerformed(ActionEvent e) { applySelection(); }
834     });
835    
836     }
837    
838     public void
839     setCommandList(String[] cmdS) {
840     list.setListData(cmdS);
841     if(cmdS.length > 0) list.setSelectedIndex(0);
842    
843     int h = list.getPreferredSize().height + 6;
844     if(h > MAX_HEIGHT) h = MAX_HEIGHT;
845     if(h == scrollPane.getSize().height) return;
846    
847     scrollPane.setPreferredSize (
848     new Dimension(scrollPane.getPreferredSize().width, h)
849     );
850    
851     scrollPane.setMaximumSize (
852     new Dimension(scrollPane.getPreferredSize().width, h)
853     );
854    
855     setVisible(false);
856     setSize(getSize().width, h);
857     setVisible(true);
858     }
859    
860     public void
861     setVisible(boolean b) {
862     if(b) updateLocation0();
863     super.setVisible(b);
864     }
865    
866     public void
867     selectNextItem() {
868     int size = list.getModel().getSize();
869     if(size == 0) return;
870    
871     int i = list.getSelectedIndex();
872     if(i == -1 || i == size - 1) list.setSelectedIndex(0);
873     else list.setSelectedIndex(i + 1);
874    
875     list.ensureIndexIsVisible(list.getSelectedIndex());
876     }
877    
878     public void
879     selectPreviousItem() {
880     int size = list.getModel().getSize();
881     if(size == 0) return;
882    
883     int i = list.getSelectedIndex();
884     if(i == -1 || i == 0) list.setSelectedIndex(size - 1);
885     else list.setSelectedIndex(i - 1);
886    
887     list.ensureIndexIsVisible(list.getSelectedIndex());
888     }
889    
890     public void
891     selectFirstItem() {
892     int size = list.getModel().getSize();
893     if(size == 0) return;
894    
895     list.setSelectedIndex(0);
896    
897     list.ensureIndexIsVisible(list.getSelectedIndex());
898     }
899    
900     public void
901     selectLastItem() {
902     int size = list.getModel().getSize();
903     if(size == 0) return;
904    
905     list.setSelectedIndex(size - 1);
906    
907     list.ensureIndexIsVisible(list.getSelectedIndex());
908     }
909    
910     /**
911     * Sets the text color of the autocompletion list.
912     * @param c The text color of autocompletion list.
913     */
914     public void
915     setTextColor(Color c) {
916     //Object o = list.getCellRenderer();
917     //if(o instanceof JComponent) ((JComponent)o).setForeground(c);
918     list.setForeground(c);
919     }
920    
921     /**
922     * Sets the background color of the autocompletion list.
923     * @param c The background color of the autocompletion list.
924     */
925     public void
926     setBackgroundColor(Color c) { list.setBackground(c); }
927    
928     private void
929     updateLocation() {
930     if(!isVisible()) return;
931     updateLocation0();
932     }
933    
934     private void
935     updateLocation0() {
936     Dimension d;
937     d = new Dimension(inputPane.getSize().width - 6, getSize().height);
938     setPreferredSize(d);
939    
940     Point p = inputPane.getLocationOnScreen();
941     pack();
942     setLocation(p.x + 3, p.y - getSize().height);
943     }
944    
945     private void
946     applySelection() {
947     Object o = list.getSelectedValue();
948     if(o != null) tfInput.setText(o.toString());
949     setVisible(false);
950     }
951    
952     private final Handler eventHandler = new Handler();
953    
954     private Handler
955     getHandler() { return eventHandler; }
956    
957     private class Handler extends ComponentAdapter {
958    
959     // ComponentListener
960     public void
961     componentMoved(ComponentEvent e) { updateLocation(); }
962    
963     public void
964     componentResized(ComponentEvent e) { updateLocation(); }
965     }
966     }
967     }
968    
969     class LSConsoleTextPane extends JTextPane {
970     private final String STYLE_ROOT = "root";
971     private final String STYLE_REGULAR = "regular";
972     private final String STYLE_BOLD = "bold";
973     private final String STYLE_NOTIFY_0 = "notificationMessage0";
974     private final String STYLE_NOTIFY = "notificationMessage";
975     private final String STYLE_WARN_0 = "warningMessage0";
976     private final String STYLE_WARN = "warningMessage";
977     private final String STYLE_ERROR_0 = "errorMessage0";
978     private final String STYLE_ERROR = "errorMessage";
979    
980     private Color cmdColor;
981     private Color notifyColor;
982     private Color warnColor;
983     private Color errorColor;
984    
985     LSConsoleTextPane() {
986     cmdColor = ClassicPrefs.getLSConsoleTextColor();
987     notifyColor = ClassicPrefs.getLSConsoleNotifyColor();
988     errorColor = ClassicPrefs.getLSConsoleErrorColor();
989     warnColor = ClassicPrefs.getLSConsoleWarningColor();
990    
991     Style def;
992     def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
993     StyledDocument doc = getStyledDocument();
994     Style root = doc.addStyle(STYLE_ROOT, def);
995     Style regular = doc.addStyle(STYLE_REGULAR, root);
996    
997     Style style = doc.addStyle(STYLE_BOLD, regular);
998     StyleConstants.setBold(style, true);
999    
1000     style = doc.addStyle(STYLE_NOTIFY_0, regular);
1001     StyleConstants.setForeground(style, notifyColor);
1002     doc.addStyle(STYLE_NOTIFY, style);
1003    
1004     style = doc.addStyle(STYLE_WARN_0, regular);
1005     StyleConstants.setForeground(style, warnColor);
1006     doc.addStyle(STYLE_WARN, style);
1007    
1008     style = doc.addStyle(STYLE_ERROR_0, regular);
1009     StyleConstants.setForeground(style, errorColor);
1010     doc.addStyle(STYLE_ERROR, style);
1011    
1012     setEditable(false);
1013    
1014     }
1015    
1016     /**
1017     * Sets the text color.
1018     * @param c The text color.
1019     */
1020     public void
1021     setTextColor(Color c) {
1022     cmdColor = c;
1023    
1024     StyledDocument doc = getStyledDocument();
1025     Style root = doc.getStyle(STYLE_ROOT);
1026     StyleConstants.setForeground(root, cmdColor);
1027     }
1028    
1029     /**
1030     * Gets the text color of the LS Console.
1031     * @return The text color of the LS Console.
1032     */
1033     public Color
1034     getTextColor() { return cmdColor; }
1035    
1036     /**
1037     * Sets the notification messages' color.
1038     * @param c The notification messages' color.
1039     */
1040     public void
1041     setNotifyColor(Color c) {
1042     notifyColor = c;
1043    
1044     Style notify = getStyledDocument().getStyle(STYLE_NOTIFY_0);
1045     StyleConstants.setForeground(notify, notifyColor);
1046     }
1047    
1048     /**
1049     * Gets the notification messages' color.
1050     * @return The notification messages' color.
1051     */
1052     public Color
1053     getNotifyColor() { return notifyColor; }
1054    
1055     /**
1056     * Gets the warning messages' color.
1057     * @return The warning messages' color.
1058     */
1059     public Color
1060     getWarningColor() { return warnColor; }
1061    
1062     /**
1063     * Sets the warning messages' color.
1064     * @param c The warning messages' color.
1065     */
1066     public void
1067     setWarningColor(Color c) {
1068     warnColor = c;
1069    
1070     Style warn = getStyledDocument().getStyle(STYLE_WARN_0);
1071     StyleConstants.setForeground(warn, warnColor);
1072     }
1073    
1074     /**
1075     * Gets the error messages' color.
1076     * @return The error messages' color.
1077     */
1078     public Color
1079     getErrorColor() { return errorColor; }
1080    
1081     /**
1082     * Sets the error messages' color.
1083     * @param c The error messages' color.
1084     */
1085     public void
1086     setErrorColor(Color c) {
1087     errorColor = c;
1088    
1089     Style error = getStyledDocument().getStyle(STYLE_ERROR_0);
1090     StyleConstants.setForeground(error, errorColor);
1091     }
1092    
1093     /**
1094     * Adds the specified command to this text pane.
1095     * @param cmd The command to be added.
1096     */
1097     public void
1098     addCommand(String cmd) {
1099     StyledDocument doc = getStyledDocument();
1100     try {
1101     String s = "lscp> ";
1102     doc.insertString(doc.getLength(), s, doc.getStyle(STYLE_BOLD));
1103     s = cmd + "\n";
1104     doc.insertString(doc.getLength(), s, doc.getStyle(STYLE_REGULAR));
1105     } catch(Exception x) {
1106     CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
1107     }
1108     }
1109    
1110     /**
1111     * Adds the specified command response to this text pane.
1112     * @param cmd The command response to be added.
1113     */
1114     public void
1115     addCommandResponse(String cmdResponse) {
1116     StyledDocument doc = getStyledDocument();
1117     try {
1118     String s = cmdResponse + "\n";
1119     Style style = doc.getStyle(STYLE_REGULAR);
1120     if(s.startsWith("ERR:")) style = doc.getStyle(STYLE_ERROR);
1121     else if(s.startsWith("WRN:")) style = doc.getStyle(STYLE_WARN);
1122     else if(s.startsWith("NOTIFY:")) style = doc.getStyle(STYLE_NOTIFY);
1123     doc.insertString(doc.getLength(), s, style);
1124     } catch(Exception x) {
1125     CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
1126     }
1127     }
1128     }

  ViewVC Help
Powered by ViewVC