author | wenzelm |
Sat, 07 Sep 2013 00:02:19 +0200 | |
changeset 53449 | 913df2adc99c |
parent 52115 | 3660205b96fa |
child 53456 | d12be8f62285 |
permissions | -rw-r--r-- |
50686 | 1 |
/* Title: Pure/Tools/build_dialog.scala |
50365 | 2 |
Author: Makarius |
3 |
||
4 |
Dialog for session build process. |
|
5 |
*/ |
|
6 |
||
7 |
package isabelle |
|
8 |
||
9 |
||
50378 | 10 |
import java.awt.{GraphicsEnvironment, Point, Font} |
50379
a8b0d3729a69
added keyboard shortcut for button (canonical way to do that?);
wenzelm
parents:
50378
diff
changeset
|
11 |
|
50365 | 12 |
import scala.swing.{ScrollPane, Button, CheckBox, FlowPanel, |
51254
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
13 |
BorderPanel, MainFrame, TextArea, SwingApplication, Component, Label} |
50365 | 14 |
import scala.swing.event.ButtonClicked |
15 |
||
16 |
||
50404
898cac1dad5e
avoid startup within GUI thread -- it is only required later for dialog;
wenzelm
parents:
50403
diff
changeset
|
17 |
object Build_Dialog |
50365 | 18 |
{ |
53449 | 19 |
/* command line entry point */ |
20 |
||
50404
898cac1dad5e
avoid startup within GUI thread -- it is only required later for dialog;
wenzelm
parents:
50403
diff
changeset
|
21 |
def main(args: Array[String]) = |
50365 | 22 |
{ |
51617 | 23 |
GUI.init_laf() |
50365 | 24 |
try { |
25 |
args.toList match { |
|
50369 | 26 |
case |
50403
87868964733c
more uniform default logic, using settings, options, args etc.;
wenzelm
parents:
50381
diff
changeset
|
27 |
logic_option :: |
50546 | 28 |
logic :: |
50369 | 29 |
Properties.Value.Boolean(system_mode) :: |
50403
87868964733c
more uniform default logic, using settings, options, args etc.;
wenzelm
parents:
50381
diff
changeset
|
30 |
include_dirs => |
50404
898cac1dad5e
avoid startup within GUI thread -- it is only required later for dialog;
wenzelm
parents:
50403
diff
changeset
|
31 |
val options = Options.init() |
53449 | 32 |
val dirs = include_dirs.map(Path.explode(_)) |
50403
87868964733c
more uniform default logic, using settings, options, args etc.;
wenzelm
parents:
50381
diff
changeset
|
33 |
val session = |
50404
898cac1dad5e
avoid startup within GUI thread -- it is only required later for dialog;
wenzelm
parents:
50403
diff
changeset
|
34 |
Isabelle_System.default_logic(logic, |
898cac1dad5e
avoid startup within GUI thread -- it is only required later for dialog;
wenzelm
parents:
50403
diff
changeset
|
35 |
if (logic_option != "") options.string(logic_option) else "") |
50403
87868964733c
more uniform default logic, using settings, options, args etc.;
wenzelm
parents:
50381
diff
changeset
|
36 |
|
53449 | 37 |
if (!dialog(options, system_mode, dirs, session, (rc: Int) => sys.exit(rc))) |
38 |
sys.exit(0) |
|
50404
898cac1dad5e
avoid startup within GUI thread -- it is only required later for dialog;
wenzelm
parents:
50403
diff
changeset
|
39 |
|
50365 | 40 |
case _ => error("Bad arguments:\n" + cat_lines(args)) |
41 |
} |
|
42 |
} |
|
43 |
catch { |
|
44 |
case exn: Throwable => |
|
51616 | 45 |
GUI.error_dialog(null, "Isabelle build failure", GUI.scrollable_text(Exn.message(exn))) |
50365 | 46 |
sys.exit(2) |
47 |
} |
|
48 |
} |
|
49 |
||
50 |
||
53449 | 51 |
/* dialog */ |
52 |
||
53 |
def dialog(options: Options, system_mode: Boolean, dirs: List[Path], session: String, |
|
54 |
continue: Int => Unit): Boolean = |
|
55 |
{ |
|
56 |
val more_dirs = dirs.map((false, _)) |
|
57 |
||
58 |
if (Build.build(options = options, build_heap = true, no_build = true, |
|
59 |
more_dirs = more_dirs, sessions = List(session)) == 0) false |
|
60 |
else { |
|
61 |
Swing_Thread.later { |
|
62 |
val top = build_dialog(options, system_mode, more_dirs, session, continue) |
|
63 |
top.pack() |
|
64 |
||
65 |
val point = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint() |
|
66 |
top.location = |
|
67 |
new Point(point.x - top.size.width / 2, point.y - top.size.height / 2) |
|
68 |
||
69 |
top.visible = true |
|
70 |
} |
|
71 |
true |
|
72 |
} |
|
73 |
} |
|
74 |
||
50369 | 75 |
def build_dialog( |
50404
898cac1dad5e
avoid startup within GUI thread -- it is only required later for dialog;
wenzelm
parents:
50403
diff
changeset
|
76 |
options: Options, |
50369 | 77 |
system_mode: Boolean, |
50405
366c4a602500
clarified build_dialog: regular up-to-date check (extra cost of approx. 5s startup for HOL);
wenzelm
parents:
50404
diff
changeset
|
78 |
more_dirs: List[(Boolean, Path)], |
53449 | 79 |
session: String, |
80 |
continue: Int => Unit): MainFrame = new MainFrame |
|
50365 | 81 |
{ |
51615
072a7249e1ac
separate module "GUI", to keep this out of the way of generic Isabelle_System operations, notably for non-Isabelle/jEdit applications;
wenzelm
parents:
51254
diff
changeset
|
82 |
iconImage = GUI.isabelle_image() |
50854 | 83 |
|
84 |
||
50368 | 85 |
/* GUI state */ |
50365 | 86 |
|
51253 | 87 |
@volatile private var is_stopped = false |
50742 | 88 |
private var return_code = 2 |
50368 | 89 |
|
53449 | 90 |
def close(rc: Int) { visible = false; continue(rc) } |
91 |
override def closeOperation { close(return_code) } |
|
50740 | 92 |
|
50368 | 93 |
|
50365 | 94 |
/* text */ |
95 |
||
96 |
val text = new TextArea { |
|
51616 | 97 |
font = new Font("SansSerif", Font.PLAIN, GUI.resolution_scale(10) max 14) |
50365 | 98 |
editable = false |
50850
4cd2d090be8f
tuned font size, notably for current HD displays;
wenzelm
parents:
50848
diff
changeset
|
99 |
columns = 50 |
4cd2d090be8f
tuned font size, notably for current HD displays;
wenzelm
parents:
50848
diff
changeset
|
100 |
rows = 20 |
50365 | 101 |
} |
102 |
||
50852
a667ac8c7afe
forced scroll to bottom, for improved cross-platform appearance;
wenzelm
parents:
50850
diff
changeset
|
103 |
val scroll_text = new ScrollPane(text) |
a667ac8c7afe
forced scroll to bottom, for improved cross-platform appearance;
wenzelm
parents:
50850
diff
changeset
|
104 |
|
50368 | 105 |
val progress = new Build.Progress |
106 |
{ |
|
50846
529e652d389d
more uniform theory progress in build -v and build_dialog;
wenzelm
parents:
50845
diff
changeset
|
107 |
override def echo(msg: String): Unit = |
50852
a667ac8c7afe
forced scroll to bottom, for improved cross-platform appearance;
wenzelm
parents:
50850
diff
changeset
|
108 |
Swing_Thread.later { |
a667ac8c7afe
forced scroll to bottom, for improved cross-platform appearance;
wenzelm
parents:
50850
diff
changeset
|
109 |
text.append(msg + "\n") |
a667ac8c7afe
forced scroll to bottom, for improved cross-platform appearance;
wenzelm
parents:
50850
diff
changeset
|
110 |
val vertical = scroll_text.peer.getVerticalScrollBar |
a667ac8c7afe
forced scroll to bottom, for improved cross-platform appearance;
wenzelm
parents:
50850
diff
changeset
|
111 |
vertical.setValue(vertical.getMaximum) |
a667ac8c7afe
forced scroll to bottom, for improved cross-platform appearance;
wenzelm
parents:
50850
diff
changeset
|
112 |
} |
50846
529e652d389d
more uniform theory progress in build -v and build_dialog;
wenzelm
parents:
50845
diff
changeset
|
113 |
override def theory(session: String, theory: String): Unit = |
529e652d389d
more uniform theory progress in build -v and build_dialog;
wenzelm
parents:
50845
diff
changeset
|
114 |
echo(session + ": theory " + theory) |
51253 | 115 |
override def stopped: Boolean = is_stopped |
50368 | 116 |
} |
117 |
||
50365 | 118 |
|
51254
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
119 |
/* layout panel with dynamic actions */ |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
120 |
|
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
121 |
val action_panel = new FlowPanel(FlowPanel.Alignment.Center)() |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
122 |
val layout_panel = new BorderPanel |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
123 |
layout_panel.layout(scroll_text) = BorderPanel.Position.Center |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
124 |
layout_panel.layout(action_panel) = BorderPanel.Position.South |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
125 |
|
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
126 |
contents = layout_panel |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
127 |
|
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
128 |
def set_actions(cs: Component*) |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
129 |
{ |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
130 |
action_panel.contents.clear |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
131 |
action_panel.contents ++= cs |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
132 |
layout_panel.revalidate |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
133 |
layout_panel.repaint |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
134 |
} |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
135 |
|
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
136 |
|
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
137 |
/* actions */ |
50848
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
138 |
|
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
139 |
var do_auto_close = true |
53449 | 140 |
def check_auto_close(): Unit = |
141 |
if (do_auto_close && return_code == 0) close(return_code) |
|
50848
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
142 |
|
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
143 |
val auto_close = new CheckBox("Auto close") { |
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
144 |
reactions += { |
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
145 |
case ButtonClicked(_) => do_auto_close = this.selected |
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
146 |
check_auto_close() |
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
147 |
} |
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
148 |
} |
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
149 |
auto_close.selected = do_auto_close |
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
150 |
auto_close.tooltip = "Automatically close dialog when finished" |
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
151 |
|
50365 | 152 |
|
51254
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
153 |
val stop_button = new Button("Stop") { |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
154 |
reactions += { |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
155 |
case ButtonClicked(_) => |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
156 |
is_stopped = true |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
157 |
set_actions(new Label("Stopping ...")) |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
158 |
} |
50376 | 159 |
} |
50930
23601c59f347
delay to give users a chance to see what was happening, even with auto_close enabled;
wenzelm
parents:
50854
diff
changeset
|
160 |
|
51254
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
161 |
set_actions(stop_button, auto_close) |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
162 |
|
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
163 |
|
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
164 |
/* exit */ |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
165 |
|
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
166 |
val delay_exit = |
50930
23601c59f347
delay to give users a chance to see what was happening, even with auto_close enabled;
wenzelm
parents:
50854
diff
changeset
|
167 |
Swing_Thread.delay_first(Time.seconds(1.0)) |
23601c59f347
delay to give users a chance to see what was happening, even with auto_close enabled;
wenzelm
parents:
50854
diff
changeset
|
168 |
{ |
23601c59f347
delay to give users a chance to see what was happening, even with auto_close enabled;
wenzelm
parents:
50854
diff
changeset
|
169 |
check_auto_close() |
51254
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
170 |
val button = |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
171 |
new Button(if (return_code == 0) "OK" else "Exit") { |
53449 | 172 |
reactions += { case ButtonClicked(_) => close(return_code) } |
51254
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
173 |
} |
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
174 |
set_actions(button) |
50930
23601c59f347
delay to give users a chance to see what was happening, even with auto_close enabled;
wenzelm
parents:
50854
diff
changeset
|
175 |
button.peer.getRootPane.setDefaultButton(button.peer) |
23601c59f347
delay to give users a chance to see what was happening, even with auto_close enabled;
wenzelm
parents:
50854
diff
changeset
|
176 |
} |
50365 | 177 |
|
50848
4e123d57c9b4
tuned build_dialog: auto_close checkbox avoids user sitting and waiting;
wenzelm
parents:
50846
diff
changeset
|
178 |
|
50369 | 179 |
/* main build */ |
180 |
||
50374 | 181 |
title = "Isabelle build (" + Isabelle_System.getenv("ML_IDENTIFIER") + ")" |
50372 | 182 |
progress.echo("Build started for Isabelle/" + session + " ...") |
50369 | 183 |
|
184 |
default_thread_pool.submit(() => { |
|
185 |
val (out, rc) = |
|
186 |
try { |
|
187 |
("", |
|
52115 | 188 |
Build.build(options = options, progress = progress, |
189 |
build_heap = true, more_dirs = more_dirs, |
|
50370 | 190 |
system_mode = system_mode, sessions = List(session))) |
50369 | 191 |
} |
192 |
catch { case exn: Throwable => (Exn.message(exn) + "\n", 2) } |
|
50376 | 193 |
Swing_Thread.now { |
194 |
progress.echo(out + (if (rc == 0) "OK\n" else "Return code: " + rc + "\n")) |
|
50740 | 195 |
return_code = rc |
51254
5bae6fc0e125
more explicit GUI components for dynamic actions;
wenzelm
parents:
51253
diff
changeset
|
196 |
delay_exit.invoke() |
50371 | 197 |
} |
50369 | 198 |
}) |
50365 | 199 |
} |
200 |
} |
|
201 |