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

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

  ViewVC Help
Powered by ViewVC