/[svn]/jsampler/trunk/src/org/jsampler/view/std/JSLSConsolePane.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/std/JSLSConsolePane.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1540 - (show annotations) (download)
Mon Dec 3 23:22:02 2007 UTC (16 years, 4 months ago) by iliev
File size: 29721 byte(s)
* Fantasia: by default the volume values are now shown in decibels
* Implemented support for retrieving instrument information
  from instrument files
* Some bugfixes and enhancements

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

  ViewVC Help
Powered by ViewVC