src/Tools/jEdit/src/pretty_text_area.scala
changeset 75393 87ebf5a50283
parent 73367 77ef8bef0593
child 75394 42267c650205
equal deleted inserted replaced
75388:b3ca4a6ed74b 75393:87ebf5a50283
    28 
    28 
    29 
    29 
    30 class Pretty_Text_Area(
    30 class Pretty_Text_Area(
    31   view: View,
    31   view: View,
    32   close_action: () => Unit = () => (),
    32   close_action: () => Unit = () => (),
    33   propagate_keys: Boolean = false) extends JEditEmbeddedTextArea
    33   propagate_keys: Boolean = false
    34 {
    34 ) extends JEditEmbeddedTextArea {
    35   text_area =>
    35   text_area =>
    36 
    36 
    37   GUI_Thread.require {}
    37   GUI_Thread.require {}
    38 
    38 
    39   private var current_font_info: Font_Info = Font_Info.main()
    39   private var current_font_info: Font_Info = Font_Info.main()
    51   private var current_search_pattern: Option[Regex] = None
    51   private var current_search_pattern: Option[Regex] = None
    52   def get_search_pattern(): Option[Regex] = GUI_Thread.require { current_search_pattern }
    52   def get_search_pattern(): Option[Regex] = GUI_Thread.require { current_search_pattern }
    53 
    53 
    54   def get_background(): Option[Color] = None
    54   def get_background(): Option[Color] = None
    55 
    55 
    56   def refresh(): Unit =
    56   def refresh(): Unit = {
    57   {
       
    58     GUI_Thread.require {}
    57     GUI_Thread.require {}
    59 
    58 
    60     val font = current_font_info.font
    59     val font = current_font_info.font
    61     getPainter.setFont(font)
    60     getPainter.setFont(font)
    62     getPainter.setAntiAlias(new AntiAlias(jEdit.getProperty("view.antiAlias")))
    61     getPainter.setAntiAlias(new AntiAlias(jEdit.getProperty("view.antiAlias")))
   114           }
   113           }
   115         })
   114         })
   116     }
   115     }
   117   }
   116   }
   118 
   117 
   119   def resize(font_info: Font_Info): Unit =
   118   def resize(font_info: Font_Info): Unit = {
   120   {
       
   121     GUI_Thread.require {}
   119     GUI_Thread.require {}
   122 
   120 
   123     current_font_info = font_info
   121     current_font_info = font_info
   124     refresh()
   122     refresh()
   125   }
   123   }
   126 
   124 
   127   def update(
   125   def update(
   128     base_snapshot: Document.Snapshot, base_results: Command.Results, body: XML.Body): Unit =
   126     base_snapshot: Document.Snapshot,
   129   {
   127     base_results: Command.Results,
       
   128     body: XML.Body
       
   129   ): Unit = {
   130     GUI_Thread.require {}
   130     GUI_Thread.require {}
   131     require(!base_snapshot.is_outdated, "document snapshot outdated")
   131     require(!base_snapshot.is_outdated, "document snapshot outdated")
   132 
   132 
   133     current_base_snapshot = base_snapshot
   133     current_base_snapshot = base_snapshot
   134     current_base_results = base_results
   134     current_base_results = base_results
   135     current_body = body
   135     current_body = body
   136     refresh()
   136     refresh()
   137   }
   137   }
   138 
   138 
   139   def detach: Unit =
   139   def detach: Unit = {
   140   {
       
   141     GUI_Thread.require {}
   140     GUI_Thread.require {}
   142     Info_Dockable(view, current_base_snapshot, current_base_results, current_body)
   141     Info_Dockable(view, current_base_snapshot, current_base_results, current_body)
   143   }
   142   }
   144 
   143 
   145   def detach_operation: Option[() => Unit] =
   144   def detach_operation: Option[() => Unit] =
   151   val search_label: Component = new Label("Search:") {
   150   val search_label: Component = new Label("Search:") {
   152     tooltip = "Search and highlight output via regular expression"
   151     tooltip = "Search and highlight output via regular expression"
   153   }
   152   }
   154 
   153 
   155   val search_field: Component =
   154   val search_field: Component =
   156     Component.wrap(new Completion_Popup.History_Text_Field("isabelle-search")
   155     Component.wrap(new Completion_Popup.History_Text_Field("isabelle-search") {
   157       {
   156       private val input_delay =
   158         private val input_delay =
   157         Delay.last(PIDE.options.seconds("editor_input_delay"), gui = true) {
   159           Delay.last(PIDE.options.seconds("editor_input_delay"), gui = true) {
   158           search_action(this)
   160             search_action(this)
   159         }
   161           }
   160       getDocument.addDocumentListener(new DocumentListener {
   162         getDocument.addDocumentListener(new DocumentListener {
   161         def changedUpdate(e: DocumentEvent): Unit = input_delay.invoke()
   163           def changedUpdate(e: DocumentEvent): Unit = input_delay.invoke()
   162         def insertUpdate(e: DocumentEvent): Unit = input_delay.invoke()
   164           def insertUpdate(e: DocumentEvent): Unit = input_delay.invoke()
   163         def removeUpdate(e: DocumentEvent): Unit = input_delay.invoke()
   165           def removeUpdate(e: DocumentEvent): Unit = input_delay.invoke()
       
   166         })
       
   167         setColumns(20)
       
   168         setToolTipText(search_label.tooltip)
       
   169         setFont(GUI.imitate_font(getFont, scale = 1.2))
       
   170       })
   164       })
       
   165       setColumns(20)
       
   166       setToolTipText(search_label.tooltip)
       
   167       setFont(GUI.imitate_font(getFont, scale = 1.2))
       
   168     })
   171 
   169 
   172   private val search_field_foreground = search_field.foreground
   170   private val search_field_foreground = search_field.foreground
   173 
   171 
   174   private def search_action(text_field: JTextField): Unit =
   172   private def search_action(text_field: JTextField): Unit = {
   175   {
       
   176     val (pattern, ok) =
   173     val (pattern, ok) =
   177       text_field.getText match {
   174       text_field.getText match {
   178         case null | "" => (None, true)
   175         case null | "" => (None, true)
   179         case s =>
   176         case s =>
   180           val re = Library.make_regex(s)
   177           val re = Library.make_regex(s)
   201       override def processKeyEvent(evt: KeyEvent, from: Int, global: Boolean): Unit = {}
   198       override def processKeyEvent(evt: KeyEvent, from: Int, global: Boolean): Unit = {}
   202       override def handleKey(key: KeyEventTranslator.Key, dry_run: Boolean): Boolean = false
   199       override def handleKey(key: KeyEventTranslator.Key, dry_run: Boolean): Boolean = false
   203     })
   200     })
   204 
   201 
   205   addKeyListener(JEdit_Lib.key_listener(
   202   addKeyListener(JEdit_Lib.key_listener(
   206     key_pressed = (evt: KeyEvent) =>
   203     key_pressed = (evt: KeyEvent) => {
   207       {
   204       val strict_control =
   208         val strict_control =
   205         JEdit_Lib.command_modifier(evt) && !JEdit_Lib.shift_modifier(evt)
   209           JEdit_Lib.command_modifier(evt) && !JEdit_Lib.shift_modifier(evt)
   206 
   210 
   207       evt.getKeyCode match {
   211         evt.getKeyCode match {
   208         case KeyEvent.VK_C | KeyEvent.VK_INSERT
   212           case KeyEvent.VK_C | KeyEvent.VK_INSERT
   209         if strict_control && text_area.getSelectionCount != 0 =>
   213           if strict_control && text_area.getSelectionCount != 0 =>
   210           Registers.copy(text_area, '$')
   214             Registers.copy(text_area, '$')
   211           evt.consume
   215             evt.consume
   212 
   216 
   213         case KeyEvent.VK_A
   217           case KeyEvent.VK_A
   214         if strict_control =>
   218           if strict_control =>
   215           text_area.selectAll
   219             text_area.selectAll
   216           evt.consume
   220             evt.consume
   217 
   221 
   218         case KeyEvent.VK_ESCAPE =>
   222           case KeyEvent.VK_ESCAPE =>
   219           if (Isabelle.dismissed_popups(view)) evt.consume
   223             if (Isabelle.dismissed_popups(view)) evt.consume
   220 
   224 
   221         case _ =>
   225           case _ =>
       
   226         }
       
   227         if (propagate_keys) JEdit_Lib.propagate_key(view, evt)
       
   228       },
       
   229     key_typed = (evt: KeyEvent) =>
       
   230       {
       
   231         if (propagate_keys) JEdit_Lib.propagate_key(view, evt)
       
   232       }
   222       }
   233     )
   223       if (propagate_keys) JEdit_Lib.propagate_key(view, evt)
       
   224     },
       
   225     key_typed = (evt: KeyEvent) => {
       
   226       if (propagate_keys) JEdit_Lib.propagate_key(view, evt)
       
   227     })
   234   )
   228   )
   235 
   229 
   236 
   230 
   237   /* init */
   231   /* init */
   238 
   232