/[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 1883 - (show annotations) (download)
Sun Apr 5 09:15:35 2009 UTC (15 years ago) by iliev
File size: 29736 byte(s)
* fixed the channel order when exporting sampler configuration
* don't mute channels muted by solo channel when exporting
   sampler configuration
* don't ask whether to replace a file on Mac OS when using
  native file choosers

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

  ViewVC Help
Powered by ViewVC