| author | wenzelm | 
| Tue, 24 Jun 2025 21:05:48 +0200 | |
| changeset 82747 | 00828818a607 | 
| parent 82142 | 508a673c87ac | 
| child 82748 | 0ffcfc137624 | 
| permissions | -rw-r--r-- | 
| 75816 | 1 | /* Title: Tools/jEdit/src/document_dockable.scala | 
| 2 | Author: Makarius | |
| 3 | ||
| 4 | Dockable window for document build support. | |
| 5 | */ | |
| 6 | ||
| 7 | package isabelle.jedit | |
| 8 | ||
| 9 | ||
| 10 | import isabelle._ | |
| 11 | ||
| 12 | import java.awt.BorderLayout | |
| 13 | ||
| 82142 | 14 | import scala.swing.{ScrollPane, TabbedPane, BorderPanel, Component}
 | 
| 76602 | 15 | import scala.swing.event.SelectionChanged | 
| 76023 | 16 | |
| 82142 | 17 | import org.gjt.sp.jedit.View | 
| 75816 | 18 | |
| 19 | ||
| 76023 | 20 | object Document_Dockable {
 | 
| 76491 | 21 | /* state */ | 
| 22 | ||
| 76023 | 23 |   object State {
 | 
| 76681 | 24 | def init(): State = State() | 
| 76023 | 25 | } | 
| 26 | ||
| 27 | sealed case class State( | |
| 77146 | 28 | pending: Boolean = false, | 
| 76023 | 29 | process: Future[Unit] = Future.value(()), | 
| 77146 | 30 | progress: Progress = new Progress, | 
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 31 | output_results: Command.Results = Command.Results.empty, | 
| 81392 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 32 | output_main: List[XML.Elem] = Nil, | 
| 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 33 | output_more: List[XML.Elem] = Nil | 
| 76681 | 34 |   ) {
 | 
| 77146 | 35 | def running: Boolean = !process.is_finished | 
| 76681 | 36 | |
| 77147 | 37 | def run(process: Future[Unit], progress: Progress, reset_pending: Boolean): State = | 
| 38 | copy(process = process, progress = progress, pending = if (reset_pending) false else pending) | |
| 77146 | 39 | |
| 81392 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 40 | def output(results: Command.Results, main: List[XML.Elem]): State = | 
| 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 41 | copy(output_results = results, output_main = main, output_more = Nil) | 
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 42 | |
| 81392 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 43 | def finish(more: List[XML.Elem]): State = | 
| 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 44 | copy(process = Future.value(()), output_more = more) | 
| 76718 | 45 | |
| 81392 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 46 | def output_all: List[XML.Elem] = output_main ::: output_more | 
| 77157 
c0633a0da53e
clarified GUI events: reset everything on session context switch;
 wenzelm parents: 
77156diff
changeset | 47 | |
| 
c0633a0da53e
clarified GUI events: reset everything on session context switch;
 wenzelm parents: 
77156diff
changeset | 48 |     def reset(): State = {
 | 
| 
c0633a0da53e
clarified GUI events: reset everything on session context switch;
 wenzelm parents: 
77156diff
changeset | 49 | process.cancel() | 
| 
c0633a0da53e
clarified GUI events: reset everything on session context switch;
 wenzelm parents: 
77156diff
changeset | 50 | progress.stop() | 
| 
c0633a0da53e
clarified GUI events: reset everything on session context switch;
 wenzelm parents: 
77156diff
changeset | 51 | State.init() | 
| 
c0633a0da53e
clarified GUI events: reset everything on session context switch;
 wenzelm parents: 
77156diff
changeset | 52 | } | 
| 76681 | 53 | } | 
| 76023 | 54 | } | 
| 55 | ||
| 75816 | 56 | class Document_Dockable(view: View, position: String) extends Dockable(view, position) {
 | 
| 76609 
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
 wenzelm parents: 
76606diff
changeset | 57 | dockable => | 
| 
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
 wenzelm parents: 
76606diff
changeset | 58 | |
| 75816 | 59 |   GUI_Thread.require {}
 | 
| 60 | ||
| 61 | ||
| 76023 | 62 | /* component state -- owned by GUI thread */ | 
| 63 | ||
| 76681 | 64 | private val current_state = Synchronized(Document_Dockable.State.init()) | 
| 76023 | 65 | |
| 66 | private val process_indicator = new Process_Indicator | |
| 81490 | 67 | private val output: Output_Area = new Output_Area(view) | 
| 76023 | 68 | private val message_pane = new TabbedPane | 
| 69 | ||
| 81490 | 70 | override def detach_operation: Option[() => Unit] = output.pretty_text_area.detach_operation | 
| 71 | ||
| 72 | ||
| 76034 | 73 |   private def show_state(): Unit = GUI_Thread.later {
 | 
| 76023 | 74 | val st = current_state.value | 
| 75 | ||
| 81490 | 76 | output.pretty_text_area.update(Document.Snapshot.init, st.output_results, st.output_all) | 
| 75816 | 77 | |
| 77146 | 78 |     if (st.running) process_indicator.update("Running document build process ...", 15)
 | 
| 79 |     else if (st.pending) process_indicator.update("Waiting for pending document content ...", 5)
 | |
| 80 | else process_indicator.update(null, 0) | |
| 76034 | 81 | } | 
| 76023 | 82 | |
| 76034 | 83 |   private def show_page(page: TabbedPane.Page): Unit = GUI_Thread.later {
 | 
| 77156 
e3a7d3668629
clarified GUI events: ensure fresh output when switching pages;
 wenzelm parents: 
77155diff
changeset | 84 | show_state() | 
| 76034 | 85 | message_pane.selection.page = page | 
| 76023 | 86 | } | 
| 87 | ||
| 88 | ||
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 89 | /* progress */ | 
| 76023 | 90 | |
| 77174 | 91 |   class Log_Progress extends Program_Progress(default_title = "build") {
 | 
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 92 | progress => | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 93 | |
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 94 | override def detect_program(s: String): Option[String] = | 
| 77173 
f1063cdb0093
clarified terminology of inlined "PROGRAM START" messages;
 wenzelm parents: 
77170diff
changeset | 95 | Document_Build.detect_program_start(s) | 
| 76023 | 96 | |
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 97 | private val delay: Delay = | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 98 |       Delay.first(PIDE.session.output_delay) {
 | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 99 |         if (!stopped) {
 | 
| 77146 | 100 | output_process(progress) | 
| 77156 
e3a7d3668629
clarified GUI events: ensure fresh output when switching pages;
 wenzelm parents: 
77155diff
changeset | 101 | show_state() | 
| 76491 | 102 | } | 
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 103 | } | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 104 | |
| 77509 
3bc49507bae5
clarified treatment of "verbose" messages, e.g. Progress.theory();
 wenzelm parents: 
77502diff
changeset | 105 |     override def output(message: Progress.Message): Unit = { super.output(message); delay.invoke() }
 | 
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 106 |     override def stop_program(): Unit = { super.stop_program(); delay.invoke() }
 | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 107 | } | 
| 76021 
752425c69577
clarified component structure, concerning initialization order;
 wenzelm parents: 
75853diff
changeset | 108 | |
| 75816 | 109 | |
| 110 | /* document build process */ | |
| 111 | ||
| 76491 | 112 | private def init_state(): Unit = | 
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 113 |     current_state.change { st =>
 | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 114 | st.progress.stop() | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 115 | Document_Dockable.State(progress = new Log_Progress) | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 116 | } | 
| 76491 | 117 | |
| 76718 | 118 | private def cancel_process(): Unit = | 
| 119 |     current_state.change { st => st.process.cancel(); st }
 | |
| 120 | ||
| 121 | private def await_process(): Unit = | |
| 122 | current_state.guarded_access(st => if (st.process.is_finished) None else Some((), st)) | |
| 123 | ||
| 77146 | 124 |   private def output_process(progress: Log_Progress): Unit = {
 | 
| 81392 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 125 | val (results, main) = progress.output() | 
| 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 126 | current_state.change(_.output(results, main)) | 
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 127 | } | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 128 | |
| 77147 | 129 | private def pending_process(): Unit = | 
| 130 |     current_state.change { st =>
 | |
| 131 | if (st.pending) st | |
| 77149 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 132 |       else {
 | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 133 | delay_auto_build.revoke() | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 134 | delay_build.invoke() | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 135 | st.copy(pending = true) | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 136 | } | 
| 77147 | 137 | } | 
| 138 | ||
| 81392 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 139 | private def finish_process(output: List[XML.Elem]): Unit = | 
| 77147 | 140 |     current_state.change { st =>
 | 
| 77149 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 141 |       if (st.pending) {
 | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 142 | delay_auto_build.revoke() | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 143 | delay_build.invoke() | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 144 | } | 
| 77147 | 145 | st.finish(output) | 
| 146 | } | |
| 76718 | 147 | |
| 77147 | 148 |   private def run_process(reset_pending: Boolean = false)(body: Log_Progress => Unit): Boolean = {
 | 
| 76718 | 149 | val started = | 
| 150 |       current_state.change_result { st =>
 | |
| 151 |         if (st.process.is_finished) {
 | |
| 76994 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 152 | st.progress.stop() | 
| 
7c23db6b857b
more detailed Program_Progress / Log_Progress: each program gets its own log output, which is attached to the document via markup;
 wenzelm parents: 
76769diff
changeset | 153 | val progress = new Log_Progress | 
| 76718 | 154 | val process = | 
| 155 |             Future.thread[Unit](name = "Document_Dockable.process") {
 | |
| 156 | await_process() | |
| 157 | body(progress) | |
| 158 | } | |
| 77147 | 159 | (true, st.run(process, progress, reset_pending)) | 
| 76718 | 160 | } | 
| 161 | else (false, st) | |
| 162 | } | |
| 163 | show_state() | |
| 164 | started | |
| 165 | } | |
| 76716 
a7602257a825
clarified state document nodes for Theories_Status / Document_Dockable;
 wenzelm parents: 
76711diff
changeset | 166 | |
| 76681 | 167 |   private def load_document(session: String): Boolean = {
 | 
| 76718 | 168 | val options = PIDE.options.value | 
| 77147 | 169 |     run_process() { _ =>
 | 
| 76718 | 170 |       try {
 | 
| 171 | val session_background = | |
| 172 | Document_Build.session_background( | |
| 173 | options, session, dirs = JEdit_Sessions.session_dirs) | |
| 174 | PIDE.editor.document_setup(Some(session_background)) | |
| 76716 
a7602257a825
clarified state document nodes for Theories_Status / Document_Dockable;
 wenzelm parents: 
76711diff
changeset | 175 | |
| 76718 | 176 | finish_process(Nil) | 
| 177 |         GUI_Thread.later {
 | |
| 76725 
c8d5cc19270a
more thorough GUI updates, notably for multiple Document dockables;
 wenzelm parents: 
76720diff
changeset | 178 | refresh_theories() | 
| 76996 | 179 | show_page(input_page) | 
| 76718 | 180 | } | 
| 181 | } | |
| 182 |       catch {
 | |
| 183 | case exn: Throwable if !Exn.is_interrupt(exn) => | |
| 184 | finish_process(List(Protocol.error_message(Exn.print(exn)))) | |
| 77156 
e3a7d3668629
clarified GUI events: ensure fresh output when switching pages;
 wenzelm parents: 
77155diff
changeset | 185 | show_page(output_page) | 
| 76681 | 186 | } | 
| 187 | } | |
| 188 | } | |
| 189 | ||
| 77144 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 190 |   private def document_build_attempt(): Boolean = {
 | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 191 | val document_session = PIDE.editor.document_session() | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 192 | if (document_session.is_vacuous) true | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 193 | else if (document_session.is_pending) false | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 194 |     else {
 | 
| 77147 | 195 |       run_process(reset_pending = true) { progress =>
 | 
| 77153 
0bb95bcf804e
more accurate output: avoid output_body from last run;
 wenzelm parents: 
77152diff
changeset | 196 | output_process(progress) | 
| 77144 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 197 | show_page(output_page) | 
| 77153 
0bb95bcf804e
more accurate output: avoid output_body from last run;
 wenzelm parents: 
77152diff
changeset | 198 | |
| 77194 | 199 |         val result = Exn.capture {
 | 
| 200 | val snapshot = document_session.get_snapshot | |
| 77196 | 201 | using(JEdit_Sessions.open_session_context(document_snapshot = Some(snapshot)))( | 
| 202 | Document_Editor.build(_, document_session, progress)) | |
| 77194 | 203 | } | 
| 77144 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 204 | val msgs = | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 205 |           result match {
 | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 206 | case Exn.Res(_) => | 
| 77188 | 207 |               List(Protocol.writeln_message("DONE"))
 | 
| 77144 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 208 | case Exn.Exn(exn: Document_Build.Build_Error) => | 
| 80480 
972f7a4cdc0e
clarified YXML.Source: more direct support for String and Bytes, instead of CharSequence;
 wenzelm parents: 
78614diff
changeset | 209 | exn.log_errors.map(s => Protocol.error_message(YXML.parse_body(YXML.Source(s)))) | 
| 77144 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 210 | case Exn.Exn(exn) => | 
| 80480 
972f7a4cdc0e
clarified YXML.Source: more direct support for String and Bytes, instead of CharSequence;
 wenzelm parents: 
78614diff
changeset | 211 | List(Protocol.error_message(YXML.parse_body(YXML.Source(Exn.print(exn))))) | 
| 77144 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 212 | } | 
| 76732 | 213 | |
| 77144 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 214 | progress.stop_program() | 
| 77146 | 215 | output_process(progress) | 
| 77152 
4c9296390f20
more accurate output: avoid output_main from last run;
 wenzelm parents: 
77151diff
changeset | 216 | progress.stop() | 
| 81392 
92aa6f7b470c
clarified output representation: postpone Pretty.separate;
 wenzelm parents: 
81387diff
changeset | 217 | finish_process(msgs) | 
| 76732 | 218 | |
| 77155 
6840013a791a
clarified GUI: avoid odd jumping pages on "Cancel";
 wenzelm parents: 
77154diff
changeset | 219 | show_page(output_page) | 
| 77144 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 220 | } | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 221 | true | 
| 76023 | 222 | } | 
| 223 | } | |
| 224 | ||
| 77144 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 225 | private lazy val delay_build: Delay = | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 226 |     Delay.first(PIDE.session.output_delay, gui = true) {
 | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 227 | if (!document_build_attempt()) delay_build.invoke() | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 228 | } | 
| 
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
 wenzelm parents: 
77142diff
changeset | 229 | |
| 77149 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 230 | private lazy val delay_auto_build: Delay = | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 231 |     Delay.last(PIDE.session.document_delay, gui = true) {
 | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 232 | pending_process() | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 233 | } | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 234 | |
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 235 | private def document_pending() = current_state.value.pending | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 236 | |
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 237 |   private val document_auto = new JEdit_Options.Bool_Access("editor_document_auto")
 | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 238 | |
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 239 | |
| 75816 | 240 | |
| 241 | /* controls */ | |
| 242 | ||
| 76681 | 243 | private val document_session = | 
| 244 | JEdit_Sessions.document_selector(PIDE.options, standalone = true) | |
| 245 | ||
| 76602 | 246 | private lazy val delay_load: Delay = | 
| 76610 | 247 |     Delay.last(PIDE.session.load_delay, gui = true) {
 | 
| 76681 | 248 |       for (session <- document_session.selection_value) {
 | 
| 77157 
c0633a0da53e
clarified GUI events: reset everything on session context switch;
 wenzelm parents: 
77156diff
changeset | 249 | current_state.change(_.reset()) | 
| 76681 | 250 | if (!load_document(session)) delay_load.invoke() | 
| 77154 | 251 | else if (document_auto()) delay_auto_build.invoke() | 
| 76681 | 252 | } | 
| 76602 | 253 | } | 
| 254 | ||
| 77154 | 255 |   document_session.reactions += {
 | 
| 256 | case SelectionChanged(_) => | |
| 257 | delay_load.invoke() | |
| 258 | delay_build.revoke() | |
| 77157 
c0633a0da53e
clarified GUI events: reset everything on session context switch;
 wenzelm parents: 
77156diff
changeset | 259 | delay_auto_build.revoke() | 
| 77154 | 260 | } | 
| 76602 | 261 | |
| 77149 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 262 | private val auto_build_button = | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 263 |     new JEdit_Options.Bool_GUI(document_auto, "Auto") {
 | 
| 78614 | 264 | tooltip = Word.capitalized(document_auto.description) | 
| 77149 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 265 |       override def clicked(state: Boolean): Unit = {
 | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 266 | super.clicked(state) | 
| 77160 | 267 | |
| 77149 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 268 | if (state) delay_auto_build.invoke() | 
| 77160 | 269 | else delay_auto_build.revoke() | 
| 77149 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 270 | } | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 271 | } | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 272 | |
| 75853 | 273 | private val build_button = | 
| 81657 | 274 |     new GUI.Button(GUI.Style_HTML.enclose_bold("Build")) {
 | 
| 75816 | 275 | tooltip = "Build document" | 
| 77147 | 276 | override def clicked(): Unit = pending_process() | 
| 76023 | 277 | } | 
| 278 | ||
| 279 | private val view_button = | |
| 280 |     new GUI.Button("View") {
 | |
| 281 | tooltip = "View document" | |
| 76606 | 282 | override def clicked(): Unit = Document_Editor.view_document() | 
| 75816 | 283 | } | 
| 284 | ||
| 285 | private val controls = | |
| 77159 | 286 | Wrap_Panel(List(document_session, process_indicator.component, | 
| 77170 | 287 | auto_build_button, build_button, view_button)) | 
| 75816 | 288 | |
| 289 | add(controls.peer, BorderLayout.NORTH) | |
| 290 | ||
| 291 | override def focusOnDefaultComponent(): Unit = build_button.requestFocus() | |
| 292 | ||
| 293 | ||
| 76023 | 294 | /* message pane with pages */ | 
| 295 | ||
| 77159 | 296 | private val all_button = | 
| 297 |     new GUI.Button("All") {
 | |
| 298 | tooltip = "Select all document theories" | |
| 299 | override def clicked(): Unit = PIDE.editor.document_select_all(set = true) | |
| 300 | } | |
| 301 | ||
| 302 | private val none_button = | |
| 303 |     new GUI.Button("None") {
 | |
| 304 | tooltip = "Deselect all document theories" | |
| 76720 | 305 | override def clicked(): Unit = PIDE.editor.document_select_all(set = false) | 
| 306 | } | |
| 307 | ||
| 76726 | 308 |   private val purge_button = new GUI.Button("Purge") {
 | 
| 309 | tooltip = "Remove theories that are no longer required" | |
| 310 | override def clicked(): Unit = PIDE.editor.purge() | |
| 311 | } | |
| 312 | ||
| 77159 | 313 | private val input_controls = | 
| 314 | Wrap_Panel(List(all_button, none_button, purge_button)) | |
| 76720 | 315 | |
| 76602 | 316 | private val theories = new Theories_Status(view, document = true) | 
| 77008 | 317 | private val theories_pane = new ScrollPane(theories.gui) | 
| 76567 | 318 | |
| 76725 
c8d5cc19270a
more thorough GUI updates, notably for multiple Document dockables;
 wenzelm parents: 
76720diff
changeset | 319 |   private def refresh_theories(): Unit = {
 | 
| 
c8d5cc19270a
more thorough GUI updates, notably for multiple Document dockables;
 wenzelm parents: 
76720diff
changeset | 320 | val domain = PIDE.editor.document_theories().toSet | 
| 
c8d5cc19270a
more thorough GUI updates, notably for multiple Document dockables;
 wenzelm parents: 
76720diff
changeset | 321 | theories.update(domain = Some(domain), trim = true, force = true) | 
| 
c8d5cc19270a
more thorough GUI updates, notably for multiple Document dockables;
 wenzelm parents: 
76720diff
changeset | 322 | theories.refresh() | 
| 
c8d5cc19270a
more thorough GUI updates, notably for multiple Document dockables;
 wenzelm parents: 
76720diff
changeset | 323 | } | 
| 
c8d5cc19270a
more thorough GUI updates, notably for multiple Document dockables;
 wenzelm parents: 
76720diff
changeset | 324 | |
| 76996 | 325 | private val input_page = | 
| 326 |     new TabbedPane.Page("Input", new BorderPanel {
 | |
| 77159 | 327 | layout(input_controls) = BorderPanel.Position.North | 
| 77008 | 328 | layout(theories_pane) = BorderPanel.Position.Center | 
| 76567 | 329 | }, "Selection and status of document theories") | 
| 330 | ||
| 77170 | 331 | |
| 332 | private val cancel_button = | |
| 333 |     new GUI.Button("Cancel") {
 | |
| 334 | tooltip = "Cancel build process" | |
| 335 | override def clicked(): Unit = cancel_process() | |
| 336 | } | |
| 337 | ||
| 81490 | 338 | private val output_controls = | 
| 339 | Wrap_Panel(List(cancel_button, output.pretty_text_area.zoom_component)) | |
| 76023 | 340 | |
| 341 | private val output_page = | |
| 342 |     new TabbedPane.Page("Output", new BorderPanel {
 | |
| 343 | layout(output_controls) = BorderPanel.Position.North | |
| 81490 | 344 | layout(output.text_pane) = BorderPanel.Position.Center | 
| 76996 | 345 | }, "Results from document build process") | 
| 76023 | 346 | |
| 76996 | 347 | message_pane.pages ++= List(input_page, output_page) | 
| 76023 | 348 | |
| 81493 
07e79b80e96d
clarified signature: avoid implicit functionality;
 wenzelm parents: 
81490diff
changeset | 349 | output.setup(dockable) | 
| 76023 | 350 | set_content(message_pane) | 
| 351 | ||
| 352 | ||
| 75816 | 353 | /* main */ | 
| 354 | ||
| 355 | private val main = | |
| 76567 | 356 |     Session.Consumer[Any](getClass.getName) {
 | 
| 75816 | 357 | case _: Session.Global_Options => | 
| 76567 | 358 |         GUI_Thread.later {
 | 
| 76578 
06b001094ddb
more uniform session selectors, with persistent options;
 wenzelm parents: 
76577diff
changeset | 359 | document_session.load() | 
| 81490 | 360 | output.handle_resize() | 
| 76725 
c8d5cc19270a
more thorough GUI updates, notably for multiple Document dockables;
 wenzelm parents: 
76720diff
changeset | 361 | refresh_theories() | 
| 76567 | 362 | } | 
| 363 | case changed: Session.Commands_Changed => | |
| 364 |         GUI_Thread.later {
 | |
| 76719 | 365 | val domain = PIDE.editor.document_theories().filter(changed.nodes).toSet | 
| 77150 | 366 |           if (domain.nonEmpty) {
 | 
| 367 | theories.update(domain = Some(domain)) | |
| 77149 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 368 | |
| 77150 | 369 | val pending = document_pending() | 
| 370 | val auto = document_auto() | |
| 371 |             if ((pending || auto) && PIDE.editor.document_session().is_ready) {
 | |
| 77149 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 372 |               if (pending) {
 | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 373 | delay_auto_build.revoke() | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 374 | delay_build.invoke() | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 375 | } | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 376 |               else if (auto) {
 | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 377 | delay_auto_build.invoke() | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 378 | } | 
| 
3991a35cd740
automatically build document when selected theories are finished;
 wenzelm parents: 
77147diff
changeset | 379 | } | 
| 77147 | 380 | } | 
| 76567 | 381 | } | 
| 75816 | 382 | } | 
| 383 | ||
| 384 |   override def init(): Unit = {
 | |
| 76701 | 385 | PIDE.editor.document_init(dockable) | 
| 76491 | 386 | init_state() | 
| 75816 | 387 | PIDE.session.global_options += main | 
| 76567 | 388 | PIDE.session.commands_changed += main | 
| 81490 | 389 | output.init() | 
| 76602 | 390 | delay_load.invoke() | 
| 75816 | 391 | } | 
| 392 | ||
| 393 |   override def exit(): Unit = {
 | |
| 394 | PIDE.session.global_options -= main | |
| 76567 | 395 | PIDE.session.commands_changed -= main | 
| 81490 | 396 | output.exit() | 
| 76701 | 397 | PIDE.editor.document_exit(dockable) | 
| 75816 | 398 | } | 
| 399 | } |