|
1 /* Title: lib/jedit/plugin/isabelle_dock.scala |
|
2 ID: $Id$ |
|
3 Author: Makarius |
|
4 |
|
5 Dockable window for Isabelle process control. |
|
6 */ |
|
7 |
|
8 package isabelle.jedit |
|
9 |
|
10 import org.gjt.sp.jedit.View |
|
11 import org.gjt.sp.jedit.gui.DefaultFocusComponent |
|
12 import org.gjt.sp.jedit.gui.DockableWindowManager |
|
13 import org.gjt.sp.jedit.gui.RolloverButton |
|
14 import org.gjt.sp.jedit.gui.HistoryTextField |
|
15 import org.gjt.sp.jedit.GUIUtilities |
|
16 |
|
17 import java.awt.Color |
|
18 import java.awt.Insets |
|
19 import java.awt.BorderLayout |
|
20 import java.awt.Dimension |
|
21 import java.awt.event.ActionListener |
|
22 import java.awt.event.ActionEvent |
|
23 import javax.swing.BoxLayout |
|
24 import javax.swing.JPanel |
|
25 import javax.swing.JScrollPane |
|
26 import javax.swing.JTextPane |
|
27 import javax.swing.text.{StyledDocument, StyleConstants} |
|
28 import javax.swing.SwingUtilities |
|
29 import javax.swing.Icon |
|
30 import javax.swing.Box |
|
31 import javax.swing.JTextField |
|
32 import javax.swing.JComboBox |
|
33 import javax.swing.DefaultComboBoxModel |
|
34 |
|
35 |
|
36 class IsabelleDock(view: View, position: String) |
|
37 extends JPanel(new BorderLayout) with DefaultFocusComponent |
|
38 { |
|
39 private val text = new HistoryTextField("isabelle", false, true) |
|
40 private val logicCombo = new JComboBox |
|
41 |
|
42 { |
|
43 // output pane |
|
44 val pane = new JTextPane |
|
45 pane.setEditable(false) |
|
46 add(BorderLayout.CENTER, new JScrollPane(pane)) |
|
47 if (position == DockableWindowManager.FLOATING) |
|
48 setPreferredSize(new Dimension(1000, 500)) |
|
49 |
|
50 val doc = pane.getDocument.asInstanceOf[StyledDocument] |
|
51 |
|
52 def makeStyle(name: String, bg: Boolean, color: Color) = { |
|
53 val style = doc.addStyle(name, null) |
|
54 if (bg) StyleConstants.setBackground(style, color) |
|
55 else StyleConstants.setForeground(style, color) |
|
56 style |
|
57 } |
|
58 val rawStyle = makeStyle("raw", false, Color.GRAY) |
|
59 val infoStyle = makeStyle("info", true, new Color(160, 255, 160)) |
|
60 val warningStyle = makeStyle("warning", true, new Color(255, 255, 160)) |
|
61 val errorStyle = makeStyle("error", true, new Color(255, 160, 160)) |
|
62 |
|
63 IsabellePlugin.addPermanentConsumer (result => |
|
64 if (result != null && !result.is_system) { |
|
65 SwingUtilities.invokeLater(new Runnable { |
|
66 def run = { |
|
67 val logic = IsabellePlugin.isabelle.session |
|
68 logicCombo.setModel(new DefaultComboBoxModel(Array(logic).asInstanceOf[Array[AnyRef]])) |
|
69 logicCombo.setPrototypeDisplayValue("AAAA") // FIXME ?? |
|
70 |
|
71 val doc = pane.getDocument.asInstanceOf[StyledDocument] |
|
72 val style = result.kind match { |
|
73 case IsabelleProcess.Kind.WARNING => warningStyle |
|
74 case IsabelleProcess.Kind.ERROR => errorStyle |
|
75 case IsabelleProcess.Kind.TRACING => infoStyle |
|
76 case _ => if (result.is_raw) rawStyle else null |
|
77 } |
|
78 doc.insertString(doc.getLength, IsabellePlugin.result_content(result), style) |
|
79 if (!result.is_raw) doc.insertString(doc.getLength, "\n", style) |
|
80 pane.setCaretPosition(doc.getLength) |
|
81 } |
|
82 }) |
|
83 }) |
|
84 |
|
85 |
|
86 // control box |
|
87 val box = new Box(BoxLayout.X_AXIS) |
|
88 add(BorderLayout.SOUTH, box) |
|
89 |
|
90 |
|
91 // logic combo |
|
92 logicCombo.setToolTipText("Isabelle logics") |
|
93 logicCombo.setRequestFocusEnabled(false) |
|
94 logicCombo.setModel(new DefaultComboBoxModel(Array("default").asInstanceOf[Array[AnyRef]])) |
|
95 box.add(logicCombo) |
|
96 |
|
97 |
|
98 // mode combo |
|
99 val modeIsar = "Isar" |
|
100 val modeML = "ML" |
|
101 val modes = Array(modeIsar, modeML) |
|
102 var mode = modeIsar |
|
103 |
|
104 val modeCombo = new JComboBox |
|
105 modeCombo.setToolTipText("Toplevel mode") |
|
106 modeCombo.setRequestFocusEnabled(false) |
|
107 modeCombo.setModel(new DefaultComboBoxModel(modes.asInstanceOf[Array[AnyRef]])) |
|
108 modeCombo.setPrototypeDisplayValue("AAAA") |
|
109 modeCombo.addActionListener(new ActionListener { |
|
110 def actionPerformed(evt: ActionEvent): Unit = { |
|
111 mode = modeCombo.getSelectedItem.asInstanceOf[String] |
|
112 } |
|
113 }) |
|
114 box.add(modeCombo) |
|
115 |
|
116 |
|
117 // input field |
|
118 text.setToolTipText("Command line") |
|
119 text.addActionListener(new ActionListener { |
|
120 def actionPerformed(evt: ActionEvent): Unit = { |
|
121 val command = text.getText |
|
122 if (command.length > 0) { |
|
123 if (mode == modeIsar) |
|
124 IsabellePlugin.isabelle.command(command) |
|
125 else if (mode == modeML) |
|
126 IsabellePlugin.isabelle.ML(command) |
|
127 text.setText("") |
|
128 } |
|
129 } |
|
130 }) |
|
131 box.add(text) |
|
132 |
|
133 |
|
134 // buttons |
|
135 def iconButton(icon: String, tip: String, action: => Unit) = { |
|
136 val button = new RolloverButton(GUIUtilities.loadIcon(icon)) |
|
137 button.setToolTipText(tip) |
|
138 button.setMargin(new Insets(0,0,0,0)) |
|
139 button.setRequestFocusEnabled(false) |
|
140 button.addActionListener(new ActionListener { |
|
141 def actionPerformed(evt: ActionEvent): Unit = action |
|
142 }) |
|
143 box.add(button) |
|
144 } |
|
145 |
|
146 iconButton("Cancel.png", "Stop", IsabellePlugin.isabelle.interrupt) |
|
147 iconButton("Clear.png", "Clear", pane.setText("")) |
|
148 } |
|
149 |
|
150 def focusOnDefaultComponent: Unit = text.requestFocus |
|
151 } |
|
152 |