/[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 1143 - (hide annotations) (download)
Mon Apr 2 21:18:31 2007 UTC (17 years ago) by iliev
File size: 32514 byte(s)
* upgrading to version 0.4a

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

  ViewVC Help
Powered by ViewVC