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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 913 - (show 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 /*
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