52 private val buffer = text_area.getBuffer |
52 private val buffer = text_area.getBuffer |
53 private val prover = Isabelle.prover_setup(buffer).get.prover |
53 private val prover = Isabelle.prover_setup(buffer).get.prover |
54 |
54 |
55 |
55 |
56 private var col: Text.Change = null |
56 private var col: Text.Change = null |
|
57 private var doc_id: IsarDocument.Document_ID = prover.document(null).id |
|
58 def current_document() = prover.document(doc_id) |
57 |
59 |
58 private val col_timer = new Timer(300, new ActionListener() { |
60 private val col_timer = new Timer(300, new ActionListener() { |
59 override def actionPerformed(e: ActionEvent) = commit |
61 override def actionPerformed(e: ActionEvent) = commit |
60 }) |
62 }) |
61 |
63 |
68 |
70 |
69 /* activation */ |
71 /* activation */ |
70 |
72 |
71 private val selected_state_controller = new CaretListener { |
73 private val selected_state_controller = new CaretListener { |
72 override def caretUpdate(e: CaretEvent) = { |
74 override def caretUpdate(e: CaretEvent) = { |
73 val doc = prover.document |
75 val doc = current_document() |
74 val cmd = doc.find_command_at(e.getDot) |
76 val cmd = doc.find_command_at(e.getDot) |
75 if (cmd != null && doc.token_start(cmd.tokens.first) <= e.getDot && |
77 if (cmd != null && doc.token_start(cmd.tokens.first) <= e.getDot && |
76 Isabelle.prover_setup(buffer).get.selected_state != cmd) |
78 Isabelle.prover_setup(buffer).get.selected_state != cmd) |
77 Isabelle.prover_setup(buffer).get.selected_state = cmd |
79 Isabelle.prover_setup(buffer).get.selected_state = cmd |
78 } |
80 } |
83 text_area.addLeftOfScrollBar(phase_overview) |
85 text_area.addLeftOfScrollBar(phase_overview) |
84 text_area.getPainter.addExtension(TextAreaPainter.LINE_BACKGROUND_LAYER + 1, this) |
86 text_area.getPainter.addExtension(TextAreaPainter.LINE_BACKGROUND_LAYER + 1, this) |
85 buffer.setTokenMarker(new DynamicTokenMarker(buffer, prover)) |
87 buffer.setTokenMarker(new DynamicTokenMarker(buffer, prover)) |
86 buffer.addBufferListener(this) |
88 buffer.addBufferListener(this) |
87 |
89 |
88 val MAX = TheoryView.MAX_CHANGE_LENGTH |
90 col = Text.Change(doc_id, Isabelle.system.id(), 0, |
89 for (i <- 0 to buffer.getLength / MAX) { |
91 buffer.getText(0, buffer.getLength), "") |
90 prover ! new isabelle.proofdocument.Text.Change( |
92 commit |
91 Isabelle.system.id(), i * MAX, |
|
92 buffer.getText(i * MAX, MAX min buffer.getLength - i * MAX), "") |
|
93 } |
|
94 } |
93 } |
95 |
94 |
96 def deactivate() { |
95 def deactivate() { |
97 buffer.setTokenMarker(buffer.getMode.getTokenMarker) |
96 buffer.setTokenMarker(buffer.getMode.getTokenMarker) |
98 buffer.removeBufferListener(this) |
97 buffer.removeBufferListener(this) |
122 } |
121 } |
123 |
122 |
124 def _from_current(to_id: String, changes: List[Text.Change], pos: Int): Int = |
123 def _from_current(to_id: String, changes: List[Text.Change], pos: Int): Int = |
125 changes match { |
124 changes match { |
126 case Nil => pos |
125 case Nil => pos |
127 case Text.Change(id, start, added, removed) :: rest_changes => { |
126 case Text.Change(_, id, start, added, removed) :: rest_changes => { |
128 val shifted = |
127 val shifted = |
129 if (start <= pos) |
128 if (start <= pos) |
130 if (pos < start + added.length) start |
129 if (pos < start + added.length) start |
131 else pos - added.length + removed.length |
130 else pos - added.length + removed.length |
132 else pos |
131 else pos |
136 } |
135 } |
137 |
136 |
138 def _to_current(from_id: String, changes: List[Text.Change], pos: Int): Int = |
137 def _to_current(from_id: String, changes: List[Text.Change], pos: Int): Int = |
139 changes match { |
138 changes match { |
140 case Nil => pos |
139 case Nil => pos |
141 case Text.Change(id, start, added, removed) :: rest_changes => { |
140 case Text.Change(_, id, start, added, removed) :: rest_changes => { |
142 val shifted = _to_current(from_id, rest_changes, pos) |
141 val shifted = _to_current(from_id, rest_changes, pos) |
143 if (id == from_id) pos |
142 if (id == from_id) pos |
144 else if (start <= shifted) { |
143 else if (start <= shifted) { |
145 if (shifted < start + removed.length) start |
144 if (shifted < start + removed.length) start |
146 else shifted + added.length - removed.length |
145 else shifted + added.length - removed.length |
157 def from_current(document: isabelle.proofdocument.ProofDocument, pos: Int): Int = |
156 def from_current(document: isabelle.proofdocument.ProofDocument, pos: Int): Int = |
158 from_current(document.id, pos) |
157 from_current(document.id, pos) |
159 |
158 |
160 def repaint(cmd: Command) = |
159 def repaint(cmd: Command) = |
161 { |
160 { |
162 val document = prover.document |
161 val document = current_document() |
163 if (text_area != null) { |
162 if (text_area != null) { |
164 val start = text_area.getLineOfOffset(to_current(document.id, cmd.start(document))) |
163 val start = text_area.getLineOfOffset(to_current(document.id, cmd.start(document))) |
165 val stop = text_area.getLineOfOffset(to_current(document.id, cmd.stop(document)) - 1) |
164 val stop = text_area.getLineOfOffset(to_current(document.id, cmd.stop(document)) - 1) |
166 text_area.invalidateLineRange(start, stop) |
165 text_area.invalidateLineRange(start, stop) |
167 |
166 |
200 /* TextAreaExtension methods */ |
199 /* TextAreaExtension methods */ |
201 |
200 |
202 override def paintValidLine(gfx: Graphics2D, |
201 override def paintValidLine(gfx: Graphics2D, |
203 screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int) |
202 screen_line: Int, physical_line: Int, start: Int, end: Int, y: Int) |
204 { |
203 { |
205 val document = prover.document |
204 val document = current_document() |
206 def from_current(pos: Int) = this.from_current(document.id, pos) |
205 def from_current(pos: Int) = this.from_current(document.id, pos) |
207 def to_current(pos: Int) = this.to_current(document.id, pos) |
206 def to_current(pos: Int) = this.to_current(document.id, pos) |
208 val saved_color = gfx.getColor |
207 val saved_color = gfx.getColor |
209 |
208 |
210 val metrics = text_area.getPainter.getFontMetrics |
209 val metrics = text_area.getPainter.getFontMetrics |
220 |
219 |
221 gfx.setColor(saved_color) |
220 gfx.setColor(saved_color) |
222 } |
221 } |
223 |
222 |
224 override def getToolTipText(x: Int, y: Int) = { |
223 override def getToolTipText(x: Int, y: Int) = { |
225 val document = prover.document |
224 val document = current_document() |
226 val offset = from_current(document.id, text_area.xyToOffset(x, y)) |
225 val offset = from_current(document.id, text_area.xyToOffset(x, y)) |
227 val cmd = document.find_command_at(offset) |
226 val cmd = document.find_command_at(offset) |
228 if (cmd != null) { |
227 if (cmd != null) { |
229 document.token_start(cmd.tokens.first) |
228 document.token_start(cmd.tokens.first) |
230 cmd.type_at(offset - cmd.start(document)) |
229 cmd.type_at(offset - cmd.start(document)) |
238 private def commit: Unit = synchronized { |
237 private def commit: Unit = synchronized { |
239 if (col != null) { |
238 if (col != null) { |
240 def split_changes(c: Text.Change): List[Text.Change] = { |
239 def split_changes(c: Text.Change): List[Text.Change] = { |
241 val MAX = TheoryView.MAX_CHANGE_LENGTH |
240 val MAX = TheoryView.MAX_CHANGE_LENGTH |
242 if (c.added.length <= MAX) List(c) |
241 if (c.added.length <= MAX) List(c) |
243 else Text.Change(c.id, c.start, c.added.substring(0, MAX), c.removed) :: |
242 else Text.Change(c.base_id, c.id, c.start, c.added.substring(0, MAX), c.removed) :: |
244 split_changes(new Text.Change(id(), c.start + MAX, c.added.substring(MAX), c.removed)) |
243 split_changes(new Text.Change(c.id, id(), c.start + MAX, c.added.substring(MAX), "")) |
245 } |
244 } |
246 val new_changes = split_changes(col) |
245 val new_changes = split_changes(col) |
247 changes = new_changes.reverse ::: changes |
246 changes = new_changes.reverse ::: changes |
248 new_changes map (document_actor ! _) |
247 new_changes map (document_actor ! _) |
|
248 doc_id = new_changes.last.id |
249 } |
249 } |
250 col = null |
250 col = null |
251 if (col_timer.isRunning()) |
251 if (col_timer.isRunning()) |
252 col_timer.stop() |
252 col_timer.stop() |
253 } |
253 } |
269 override def preContentInserted(buffer: JEditBuffer, |
269 override def preContentInserted(buffer: JEditBuffer, |
270 start_line: Int, offset: Int, num_lines: Int, length: Int) |
270 start_line: Int, offset: Int, num_lines: Int, length: Int) |
271 { |
271 { |
272 val text = buffer.getText(offset, length) |
272 val text = buffer.getText(offset, length) |
273 if (col == null) |
273 if (col == null) |
274 col = new Text.Change(id(), offset, text, "") |
274 col = new Text.Change(doc_id, id(), offset, text, "") |
275 else if (col.start <= offset && offset <= col.start + col.added.length) |
275 else if (col.start <= offset && offset <= col.start + col.added.length) |
276 col = new Text.Change(col.id, col.start, col.added + text, col.removed) |
276 col = new Text.Change(doc_id, col.id, col.start, col.added + text, col.removed) |
277 else { |
277 else { |
278 commit |
278 commit |
279 col = new Text.Change(id(), offset, text, "") |
279 col = new Text.Change(doc_id, id(), offset, text, "") |
280 } |
280 } |
281 delay_commit |
281 delay_commit |
282 } |
282 } |
283 |
283 |
284 override def preContentRemoved(buffer: JEditBuffer, |
284 override def preContentRemoved(buffer: JEditBuffer, |
285 start_line: Int, start: Int, num_lines: Int, removed_length: Int) |
285 start_line: Int, start: Int, num_lines: Int, removed_length: Int) |
286 { |
286 { |
287 val removed = buffer.getText(start, removed_length) |
287 val removed = buffer.getText(start, removed_length) |
288 if (col == null) |
288 if (col == null) |
289 col = new Text.Change(id(), start, "", removed) |
289 col = new Text.Change(doc_id, id(), start, "", removed) |
290 else if (col.start > start + removed_length || start > col.start + col.added.length) { |
290 else if (col.start > start + removed_length || start > col.start + col.added.length) { |
291 commit |
291 commit |
292 col = new Text.Change(id(), start, "", removed) |
292 col = new Text.Change(doc_id, id(), start, "", removed) |
293 } |
293 } |
294 else { |
294 else { |
295 /* val offset = start - col.start |
295 /* val offset = start - col.start |
296 val diff = col.added.length - removed |
296 val diff = col.added.length - removed |
297 val (added, add_removed) = |
297 val (added, add_removed) = |
299 (offset max 0, diff - (offset max 0)) |
299 (offset max 0, diff - (offset max 0)) |
300 else |
300 else |
301 (diff - (offset min 0), offset min 0) |
301 (diff - (offset min 0), offset min 0) |
302 col = new Text.Changed(start min col.start, added, col.removed - add_removed)*/ |
302 col = new Text.Changed(start min col.start, added, col.removed - add_removed)*/ |
303 commit |
303 commit |
304 col = new Text.Change(id(), start, "", removed) |
304 col = new Text.Change(doc_id, id(), start, "", removed) |
305 } |
305 } |
306 delay_commit |
306 delay_commit |
307 } |
307 } |
308 |
308 |
309 override def bufferLoaded(buffer: JEditBuffer) { } |
309 override def bufferLoaded(buffer: JEditBuffer) { } |