src/Pure/Tools/build_dialog.scala
author wenzelm
Sat, 12 Jan 2013 20:13:34 +0100
changeset 51865 4cd2d090be8f
parent 51863 4e123d57c9b4
child 51867 a667ac8c7afe
permissions -rw-r--r--
tuned font size, notably for current HD displays;
wenzelm@51701
     1
/*  Title:      Pure/Tools/build_dialog.scala
wenzelm@51380
     2
    Author:     Makarius
wenzelm@51380
     3
wenzelm@51380
     4
Dialog for session build process.
wenzelm@51380
     5
*/
wenzelm@51380
     6
wenzelm@51380
     7
package isabelle
wenzelm@51380
     8
wenzelm@51380
     9
wenzelm@51393
    10
import java.awt.{GraphicsEnvironment, Point, Font}
wenzelm@51394
    11
wenzelm@51380
    12
import scala.swing.{ScrollPane, Button, CheckBox, FlowPanel,
wenzelm@51380
    13
  BorderPanel, MainFrame, TextArea, SwingApplication}
wenzelm@51380
    14
import scala.swing.event.ButtonClicked
wenzelm@51380
    15
wenzelm@51380
    16
wenzelm@51419
    17
object Build_Dialog
wenzelm@51380
    18
{
wenzelm@51419
    19
  def main(args: Array[String]) =
wenzelm@51380
    20
  {
wenzelm@51554
    21
    Platform.init_laf()
wenzelm@51380
    22
    try {
wenzelm@51380
    23
      args.toList match {
wenzelm@51384
    24
        case
wenzelm@51418
    25
          logic_option ::
wenzelm@51561
    26
          logic ::
wenzelm@51384
    27
          Properties.Value.Boolean(system_mode) ::
wenzelm@51418
    28
          include_dirs =>
wenzelm@51420
    29
            val more_dirs = include_dirs.map(s => ((false, Path.explode(s))))
wenzelm@51419
    30
wenzelm@51419
    31
            val options = Options.init()
wenzelm@51418
    32
            val session =
wenzelm@51419
    33
              Isabelle_System.default_logic(logic,
wenzelm@51419
    34
                if (logic_option != "") options.string(logic_option) else "")
wenzelm@51418
    35
wenzelm@51547
    36
            if (Build.build(Build.Ignore_Progress, options, build_heap = true, no_build = true,
wenzelm@51420
    37
                more_dirs = more_dirs, sessions = List(session)) == 0) sys.exit(0)
wenzelm@51419
    38
            else
wenzelm@51419
    39
              Swing_Thread.later {
wenzelm@51420
    40
                val top = build_dialog(options, system_mode, more_dirs, session)
wenzelm@51419
    41
                top.pack()
wenzelm@51419
    42
wenzelm@51419
    43
                val point = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint()
wenzelm@51547
    44
                top.location =
wenzelm@51547
    45
                  new Point(point.x - top.size.width / 2, point.y - top.size.height / 2)
wenzelm@51419
    46
wenzelm@51419
    47
                top.visible = true
wenzelm@51419
    48
              }
wenzelm@51380
    49
        case _ => error("Bad arguments:\n" + cat_lines(args))
wenzelm@51380
    50
      }
wenzelm@51380
    51
    }
wenzelm@51380
    52
    catch {
wenzelm@51380
    53
      case exn: Throwable =>
wenzelm@51380
    54
        Library.error_dialog(null, "Isabelle build failure",
wenzelm@51380
    55
          Library.scrollable_text(Exn.message(exn)))
wenzelm@51380
    56
        sys.exit(2)
wenzelm@51380
    57
    }
wenzelm@51380
    58
  }
wenzelm@51380
    59
wenzelm@51380
    60
wenzelm@51384
    61
  def build_dialog(
wenzelm@51419
    62
    options: Options,
wenzelm@51384
    63
    system_mode: Boolean,
wenzelm@51420
    64
    more_dirs: List[(Boolean, Path)],
wenzelm@51384
    65
    session: String): MainFrame = new MainFrame
wenzelm@51380
    66
  {
wenzelm@51383
    67
    /* GUI state */
wenzelm@51383
    68
wenzelm@51383
    69
    private var is_stopped = false
wenzelm@51757
    70
    private var return_code = 2
wenzelm@51383
    71
wenzelm@51755
    72
    override def closeOperation { sys.exit(return_code) }
wenzelm@51755
    73
wenzelm@51383
    74
wenzelm@51380
    75
    /* text */
wenzelm@51380
    76
wenzelm@51380
    77
    val text = new TextArea {
wenzelm@51865
    78
      font = new Font("SansSerif", Font.PLAIN, Library.resolution_scale(10))
wenzelm@51380
    79
      editable = false
wenzelm@51865
    80
      columns = 50
wenzelm@51865
    81
      rows = 20
wenzelm@51380
    82
    }
wenzelm@51380
    83
wenzelm@51383
    84
    val progress = new Build.Progress
wenzelm@51383
    85
    {
wenzelm@51861
    86
      override def echo(msg: String): Unit =
wenzelm@51861
    87
        Swing_Thread.later { text.append(msg + "\n") }
wenzelm@51861
    88
      override def theory(session: String, theory: String): Unit =
wenzelm@51861
    89
        echo(session + ": theory " + theory)
wenzelm@51383
    90
      override def stopped: Boolean =
wenzelm@51383
    91
        Swing_Thread.now { val b = is_stopped; is_stopped = false; b  }
wenzelm@51383
    92
    }
wenzelm@51383
    93
wenzelm@51380
    94
wenzelm@51863
    95
    /* action panel */
wenzelm@51863
    96
wenzelm@51863
    97
    var do_auto_close = true
wenzelm@51863
    98
    def check_auto_close(): Unit = if (do_auto_close && return_code == 0) sys.exit(return_code)
wenzelm@51863
    99
wenzelm@51863
   100
    val auto_close = new CheckBox("Auto close") {
wenzelm@51863
   101
      reactions += {
wenzelm@51863
   102
        case ButtonClicked(_) => do_auto_close = this.selected
wenzelm@51863
   103
        check_auto_close()
wenzelm@51863
   104
      }
wenzelm@51863
   105
    }
wenzelm@51863
   106
    auto_close.selected = do_auto_close
wenzelm@51863
   107
    auto_close.tooltip = "Automatically close dialog when finished"
wenzelm@51863
   108
wenzelm@51380
   109
wenzelm@51391
   110
    var button_action: () => Unit = (() => is_stopped = true)
wenzelm@51391
   111
    val button = new Button("Cancel") {
wenzelm@51391
   112
      reactions += { case ButtonClicked(_) => button_action() }
wenzelm@51391
   113
    }
wenzelm@51863
   114
    def button_exit()
wenzelm@51391
   115
    {
wenzelm@51863
   116
      check_auto_close()
wenzelm@51863
   117
      button.text = if (return_code == 0) "OK" else "Exit"
wenzelm@51863
   118
      button_action = (() => sys.exit(return_code))
wenzelm@51396
   119
      button.peer.getRootPane.setDefaultButton(button.peer)
wenzelm@51380
   120
    }
wenzelm@51380
   121
wenzelm@51863
   122
wenzelm@51863
   123
    val action_panel = new FlowPanel(FlowPanel.Alignment.Center)(button, auto_close)
wenzelm@51383
   124
wenzelm@51383
   125
wenzelm@51383
   126
    /* layout panel */
wenzelm@51383
   127
wenzelm@51383
   128
    val layout_panel = new BorderPanel
wenzelm@51383
   129
    layout_panel.layout(new ScrollPane(text)) = BorderPanel.Position.Center
wenzelm@51391
   130
    layout_panel.layout(action_panel) = BorderPanel.Position.South
wenzelm@51383
   131
wenzelm@51383
   132
    contents = layout_panel
wenzelm@51384
   133
wenzelm@51384
   134
wenzelm@51384
   135
    /* main build */
wenzelm@51384
   136
wenzelm@51389
   137
    title = "Isabelle build (" + Isabelle_System.getenv("ML_IDENTIFIER") + ")"
wenzelm@51387
   138
    progress.echo("Build started for Isabelle/" + session + " ...")
wenzelm@51384
   139
wenzelm@51384
   140
    default_thread_pool.submit(() => {
wenzelm@51384
   141
      val (out, rc) =
wenzelm@51384
   142
        try {
wenzelm@51384
   143
          ("",
wenzelm@51420
   144
            Build.build(progress, options, build_heap = true, more_dirs = more_dirs,
wenzelm@51385
   145
              system_mode = system_mode, sessions = List(session)))
wenzelm@51384
   146
        }
wenzelm@51384
   147
        catch { case exn: Throwable => (Exn.message(exn) + "\n", 2) }
wenzelm@51391
   148
      Swing_Thread.now {
wenzelm@51391
   149
        progress.echo(out + (if (rc == 0) "OK\n" else "Return code: " + rc + "\n"))
wenzelm@51755
   150
        return_code = rc
wenzelm@51863
   151
        button_exit()
wenzelm@51386
   152
      }
wenzelm@51384
   153
    })
wenzelm@51380
   154
  }
wenzelm@51380
   155
}
wenzelm@51380
   156