# HG changeset patch # User wenzelm # Date 1347819388 -7200 # Node ID 0fa4389c04f9e45133e95bc88a0d0d548807dbb9 # Parent 4f9585401f1a7a043b157b53d386512f632cebc6 alternative output panel, based on Pretty_Text_Area, based on JEditEmbeddedTextArea; diff -r 4f9585401f1a -r 0fa4389c04f9 src/Tools/jEdit/lib/Tools/jedit --- a/src/Tools/jEdit/lib/Tools/jedit Sun Sep 16 13:12:55 2012 +0200 +++ b/src/Tools/jEdit/lib/Tools/jedit Sun Sep 16 20:16:28 2012 +0200 @@ -21,7 +21,9 @@ "src/jedit_thy_load.scala" "src/jedit_options.scala" "src/output_dockable.scala" + "src/output2_dockable.scala" "src/plugin.scala" + "src/pretty_text_area.scala" "src/protocol_dockable.scala" "src/raw_output_dockable.scala" "src/readme_dockable.scala" diff -r 4f9585401f1a -r 0fa4389c04f9 src/Tools/jEdit/src/Isabelle.props --- a/src/Tools/jEdit/src/Isabelle.props Sun Sep 16 13:12:55 2012 +0200 +++ b/src/Tools/jEdit/src/Isabelle.props Sun Sep 16 20:16:28 2012 +0200 @@ -40,9 +40,10 @@ #menu actions plugin.isabelle.jedit.Plugin.menu.label=Isabelle -plugin.isabelle.jedit.Plugin.menu=isabelle.session-panel isabelle.output-panel isabelle.raw-output-panel isabelle.protocol-panel isabelle.readme-panel isabelle.syslog-panel +plugin.isabelle.jedit.Plugin.menu=isabelle.session-panel isabelle.output-panel isabelle.output2-panel isabelle.raw-output-panel isabelle.protocol-panel isabelle.readme-panel isabelle.syslog-panel isabelle.session-panel.label=Prover Session panel isabelle.output-panel.label=Output panel +isabelle.output2-panel.label=Output2 panel isabelle.raw-output-panel.label=Raw Output panel isabelle.protocol-panel.label=Protocol panel isabelle.readme-panel.label=README panel @@ -51,6 +52,7 @@ #dockables isabelle-session.title=Prover Session isabelle-output.title=Output +isabelle-output2.title=Output2 isabelle-raw-output.title=Raw Output isabelle-protocol.title=Protocol isabelle-readme.title=README diff -r 4f9585401f1a -r 0fa4389c04f9 src/Tools/jEdit/src/actions.xml --- a/src/Tools/jEdit/src/actions.xml Sun Sep 16 13:12:55 2012 +0200 +++ b/src/Tools/jEdit/src/actions.xml Sun Sep 16 20:16:28 2012 +0200 @@ -22,6 +22,11 @@ wm.addDockableWindow("isabelle-output"); + + + wm.addDockableWindow("isabelle-output2"); + + wm.addDockableWindow("isabelle-raw-output"); diff -r 4f9585401f1a -r 0fa4389c04f9 src/Tools/jEdit/src/dockables.xml --- a/src/Tools/jEdit/src/dockables.xml Sun Sep 16 13:12:55 2012 +0200 +++ b/src/Tools/jEdit/src/dockables.xml Sun Sep 16 20:16:28 2012 +0200 @@ -14,6 +14,9 @@ new isabelle.jedit.Output_Dockable(view, position); + + new isabelle.jedit.Output2_Dockable(view, position); + new isabelle.jedit.Raw_Output_Dockable(view, position); diff -r 4f9585401f1a -r 0fa4389c04f9 src/Tools/jEdit/src/output2_dockable.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Tools/jEdit/src/output2_dockable.scala Sun Sep 16 20:16:28 2012 +0200 @@ -0,0 +1,160 @@ +/* Title: Tools/jEdit/src/output2_dockable.scala + Author: Makarius + +Dockable window with result message output. +*/ + +package isabelle.jedit + + +import isabelle._ + +import scala.actors.Actor._ + +import scala.swing.{FlowPanel, Button, CheckBox} +import scala.swing.event.ButtonClicked + +import java.lang.System +import java.awt.BorderLayout +import java.awt.event.{ComponentEvent, ComponentAdapter} + +import org.gjt.sp.jedit.View + + +class Output2_Dockable(view: View, position: String) extends Dockable(view, position) +{ + Swing_Thread.require() + + + /* component state -- owned by Swing thread */ + + private var zoom_factor = 100 + private var show_tracing = false + private var do_update = true + private var current_state = Command.empty.empty_state + private var current_body: XML.Body = Nil + + + /* pretty text panel */ + + private val pretty_text_area = new Pretty_Text_Area + set_content(pretty_text_area) + + + private def handle_resize() + { + Swing_Thread.require() + + pretty_text_area.resize(Isabelle.font_family(), + scala.math.round(Isabelle.font_size() * zoom_factor / 100)) + } + + private def handle_update(follow: Boolean, restriction: Option[Set[Command]]) + { + Swing_Thread.require() + + val new_state = + if (follow) { + Document_View(view.getTextArea) match { + case Some(doc_view) => + val snapshot = doc_view.model.snapshot() + snapshot.node.command_at(doc_view.text_area.getCaretPosition).map(_._1) match { + case Some(cmd) => snapshot.state.command_state(snapshot.version, cmd) + case None => Command.empty.empty_state + } + case None => Command.empty.empty_state + } + } + else current_state + + val new_body = + if (!restriction.isDefined || restriction.get.contains(new_state.command)) + new_state.results.iterator.map(_._2).filter( + { // FIXME not scalable + case XML.Elem(Markup(Isabelle_Markup.TRACING, _), _) => show_tracing + case _ => true + }).toList + else current_body + + if (new_body != current_body) pretty_text_area.update(new_body) + + current_state = new_state + current_body = new_body + } + + + /* main actor */ + + private val main_actor = actor { + loop { + react { + case Session.Global_Settings => + Swing_Thread.later { handle_resize() } + case changed: Session.Commands_Changed => + Swing_Thread.later { handle_update(do_update, Some(changed.commands)) } + case Session.Caret_Focus => + Swing_Thread.later { handle_update(do_update, None) } + case bad => System.err.println("Output_Dockable: ignoring bad message " + bad) + } + } + } + + override def init() + { + Swing_Thread.require() + + Isabelle.session.global_settings += main_actor + Isabelle.session.commands_changed += main_actor + Isabelle.session.caret_focus += main_actor + handle_update(true, None) + } + + override def exit() + { + Swing_Thread.require() + + Isabelle.session.global_settings -= main_actor + Isabelle.session.commands_changed -= main_actor + Isabelle.session.caret_focus -= main_actor + delay_resize.revoke() + } + + + /* resize */ + + private val delay_resize = + Swing_Thread.delay_first( + Time.seconds(Isabelle.options.real("editor_update_delay"))) { handle_resize() } + + addComponentListener(new ComponentAdapter { + override def componentResized(e: ComponentEvent) { delay_resize.invoke() } + }) + + + /* controls */ + + private val zoom = new Library.Zoom_Box(factor => { zoom_factor = factor; handle_resize() }) + zoom.tooltip = "Zoom factor for basic font size" + + private val tracing = new CheckBox("Tracing") { + reactions += { + case ButtonClicked(_) => show_tracing = this.selected; handle_update(do_update, None) } + } + tracing.selected = show_tracing + tracing.tooltip = "Indicate output of tracing messages" + + private val auto_update = new CheckBox("Auto update") { + reactions += { + case ButtonClicked(_) => do_update = this.selected; handle_update(do_update, None) } + } + auto_update.selected = do_update + auto_update.tooltip = "Indicate automatic update following cursor movement" + + private val update = new Button("Update") { + reactions += { case ButtonClicked(_) => handle_update(true, None) } + } + update.tooltip = "Update display according to the command at cursor position" + + private val controls = new FlowPanel(FlowPanel.Alignment.Right)(zoom, tracing, auto_update, update) + add(controls.peer, BorderLayout.NORTH) +} diff -r 4f9585401f1a -r 0fa4389c04f9 src/Tools/jEdit/src/pretty_text_area.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Tools/jEdit/src/pretty_text_area.scala Sun Sep 16 20:16:28 2012 +0200 @@ -0,0 +1,78 @@ +/* Title: Tools/jEdit/src/pretty_text_area.scala + Author: Makarius + +GUI component for pretty-printed with markup, rendered like jEdit text area. +*/ + +package isabelle.jedit + + +import isabelle._ + +import java.awt.{Font, FontMetrics} +import org.gjt.sp.jedit.textarea.{AntiAlias, JEditEmbeddedTextArea} +import org.gjt.sp.jedit.jEdit +import org.gjt.sp.util.SyntaxUtilities +import scala.swing.{BorderPanel, Component} + + +class Pretty_Text_Area extends BorderPanel +{ + Swing_Thread.require() + + val text_area = new JEditEmbeddedTextArea + + private var current_font_metrics: FontMetrics = null + private var current_font_family = "Dialog" + private var current_font_size: Int = 12 + private var current_margin: Int = 0 + private var current_body: XML.Body = Nil + + def refresh() + { + Swing_Thread.require() + + val font = new Font(current_font_family, Font.PLAIN, current_font_size) + + val painter = text_area.getPainter + painter.setFont(font) + painter.setAntiAlias(new AntiAlias(jEdit.getProperty("view.antiAlias"))) + painter.setStyles(SyntaxUtilities.loadStyles(current_font_family, current_font_size)) + + current_font_metrics = painter.getFontMetrics(font) + current_margin = (size.width / (current_font_metrics.charWidth(Pretty.spc) max 1) - 4) max 20 + + val text = + Pretty.string_of(current_body, current_margin, Pretty.font_metric(current_font_metrics)) + + val buffer = text_area.getBuffer + try { + buffer.beginCompoundEdit + text_area.setText(text) + text_area.setCaretPosition(0) + } + finally { + buffer.endCompoundEdit + } + } + + def resize(font_family: String, font_size: Int) + { + Swing_Thread.require() + + current_font_family = font_family + current_font_size = font_size + refresh() + } + + def update(body: XML.Body) + { + Swing_Thread.require() + + current_body = body + refresh() + } + + layout(Component.wrap(text_area)) = BorderPanel.Position.Center +} +