comparison anagram/vaclgui/trfview.cpp @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 /*
2 * AnaGram, A System for Syntax Directed Programming
3 * Copyright 1997-2002 Parsifal Software. All Rights Reserved.
4 * See the file COPYING for license and usage terms.
5 *
6 * trfview.cpp
7 */
8
9 #include <icoordsy.hpp>
10 #include <windows.h>
11
12 #include "agstring.h"
13 #include "cint.h"
14 #include "config.h"
15 #include "ctrlpanel.hpp"
16 #include "ftpar.h" // for precedes()
17 #include "ftview.hpp"
18 #include "minmax.h"
19 #include "trfview.hpp"
20 #include "vaclgui.hpp"
21
22 //#define INCLUDE_LOGGING
23 #include "log.h"
24
25
26 #define PARSE_LOCATION (parser.location())
27
28 DigSetter::Style TraceFileView::displayStyle[4] = {
29 DigSetter::Style(FontSpec::traceFile, ColorSpec::traceFileScanned),
30 DigSetter::Style(FontSpec::traceFile, ColorSpec::traceFileUnscanned),
31 DigSetter::Style(FontSpec::traceFile, ColorSpec::traceFileHilite),
32 DigSetter::Style(FontSpec::traceFile, ColorSpec::dialogBackground)
33 };
34
35 TraceFileView::TraceFileView(IWindow *owner, text_file &file_,
36 AgString fileName)
37 : FileView(owner, file_)
38 , windowFont(FontSpec::traceFile)
39 , margin(windowFont.avgCharWidth())
40 , painting(0)
41 , enWidth(windowFont.avgCharWidth())
42 , setter(&dataArea, displayStyle)
43 , beginHighlight(0,0)
44 , endHighlight(0,0)
45 , activeHighlight(0)
46 , parseAction(actionObject(this, parseToCursor))
47 , parser(file_.text)
48 , dataColorChange(this, onColorChange)
49 , fontChange(this, onFontChange)
50 , clickEnabled(0)
51 , doubleClickEnabled(0)
52 {
53 LOGSECTION("TraceFileView::TraceFileView");
54 LOGV((int) this);
55
56 dataColorChange.attach(&ColorSpec::traceFileScanned);
57 dataColorChange.attach(&ColorSpec::traceFileUnscanned);
58 dataColorChange.attach(&ColorSpec::traceFileHilite);
59
60 fontChange.attach(&FontSpec::traceFile);
61
62 for (int i = 0; i < 256; i++) {
63 charWidth[i] = windowFont.charWidth(i);
64 }
65 tableWidth = findMaxWidth();
66 dataHole.setBackgroundColor(ColorSpec::traceFileUnscanned.bg());
67 pixelCursor.x = margin;
68 enableCursor();
69
70 IMousePointerHandler::handleEventsFor(&verticalScrollBar);
71 IMousePointerHandler::handleEventsFor(&horizontalScrollBar);
72 IMousePointerHandler::handleEventsFor(&dataHole);
73 }
74
75
76 TraceFileView::~TraceFileView() {
77 LOGSECTION("TraceFileView::~TraceFileView");
78 IMousePointerHandler::stopHandlingEventsFor(&verticalScrollBar);
79 IMousePointerHandler::stopHandlingEventsFor(&horizontalScrollBar);
80 IMousePointerHandler::stopHandlingEventsFor(&dataHole);
81 }
82
83 void TraceFileView::onFontChange() {
84 LOGSECTION("TraceFileView::onFontChange");
85 setFont(FontSpec::syntaxFile);
86 dataHole.setFont(FontSpec::dataTable);
87 windowFont = FontSpec::traceFile;
88 //for (int i = 0; i < 256; i++) {
89 // charWidth[i] = windowFont.charWidth(i);
90 //}
91 doLayout();
92 refresh();
93 }
94
95 void TraceFileView::reload() {
96 LOGSECTION("TraceFileView::reload");
97 LOGV((int) file.text.pointer());
98 file.read_file();
99 parser.text = file.text;
100 LOGV((int) file.text.pointer());
101 doLayout();
102 }
103
104 TraceFileView &TraceFileView::doLayout() {
105 setFont(windowFont);
106 for (int i = 0; i < 256; i++) {
107 charWidth[i] = windowFont.charWidth(i);
108 }
109 enWidth = windowFont.avgCharWidth();
110 margin = enWidth;
111 lineHeight = windowFont.maxSize().height() + windowFont.externalLeading();
112 FileView::doLayout();
113 return *this;
114 }
115
116 cint TraceFileView::getCursorLocation() {
117 return cursorLocation;
118 }
119
120 int TraceFileView::findMaxWidth() {
121 LOGSECTION("TraceFileView::findMaxWidth");
122 int maxWidth = 0;
123 int nl = nLines();
124 LOGV(nl);
125
126 while (nl--) {
127 AgString line = getLine(nl);
128 if (!line.exists()) {
129 continue;
130 }
131 LOGV(line.pointer());
132 int width = measureWidth(line.pointer());
133 if (width > maxWidth) {
134 LOGV(nl) LCV(width);
135 maxWidth = width;
136 }
137 }
138 maxWidth += 2*margin;
139 LOGV(maxWidth);
140 return maxWidth;
141 }
142
143 ISize TraceFileView::suggestSize() {
144 LOGSECTION("TraceFileView::suggestSize");
145 int n = nLines();
146 if (n < 5) {
147 n = 5;
148 }
149 if (n > defaultWindowHeight) {
150 n = defaultWindowHeight;
151 }
152 int height = n*(windowFont.maxSize().height() +
153 windowFont.externalLeading());
154 int width = 60*windowFont.avgCharWidth() + 2 * margin;
155 int minWidth = 40*windowFont.avgCharWidth() + 2 * margin;
156 LOGV(width) LCV(minWidth);
157 LOGV(tableWidth);
158 if (width > tableWidth) {
159 width = tableWidth;
160 }
161 if (width < minWidth) {
162 width = minWidth;
163 }
164 return ISize(width, height);
165 }
166
167 TraceFileView &TraceFileView::parseLine(int ln, AgString line,
168 int begin, int end) {
169 LOGSECTION("TraceFileView::parseLine");
170 char *p = line.pointer();
171 if (p == 0) {
172 p = "";
173 }
174 assert(p != 0);
175 nDigs = 0;
176 nHoles = 0;
177 int ncw = 0;
178
179 int holeX = 0;
180 int x = margin;
181
182 int columnWidth = enWidth*tab_spacing;
183
184 int wordWidth = 0;
185
186 cint parseLoc = PARSE_LOCATION;
187 if (activeHighlight && precedes(parseLoc, endHighlight)) {
188 parseLoc = endHighlight;
189 }
190 int topToBaseline = windowFont.maxAscender();
191 cint where(0, topToBaseline + ln*lineHeight);
192 int hPos = horizontalScrollBar.scrollBoxPosition();
193 cint size(0, lineHeight);
194 cint loc(-1, ln+verticalScrollBar.scrollBoxPosition());
195 int styleIndex = !precedes(loc, parseLoc);
196 LOGV(loc);
197 LOGV(cursorLocation);
198 LOGV(styleIndex);
199 LOGV(measure);
200 LOGV(tableWidth);
201 LOGV((char *) dataArea.size().asString());
202 if (activeHighlight && styleIndex == 0) {
203 styleIndex = 2*(!precedes(loc, beginHighlight) &&
204 precedes(loc, endHighlight));
205 }
206
207 loc.x = 0;
208 for (; *p && x <= end; p++, loc.x++) {
209 int newStyleIndex = !precedes(loc, parseLoc);
210 LOGV(loc);
211 LOGV(cursorLocation);
212 LOGV(parseLoc);
213 LOGV(newStyleIndex);
214
215 if (activeHighlight && newStyleIndex == 0) {
216 newStyleIndex = 2*(!precedes(loc, beginHighlight) &&
217 precedes(loc, endHighlight));
218 }
219 if (newStyleIndex != styleIndex) {
220 cint holeLocation(holeX - hPos, where.y - topToBaseline);
221 LOGV(where.y) LCV(topToBaseline) LCV(holeLocation.y);
222 size.x = x - holeX;
223 if (x >= begin) {
224 hole.push(DigSetter::Hole(holeLocation, size, styleIndex));
225 LOGV(holeLocation);
226 LOGV(size);
227 LOGV(styleIndex);
228 nHoles++;
229 }
230 if (ncw) {
231 where.x = x-wordWidth - hPos;
232 if (x >= begin) {
233 dig.push(DigSetter::Dig(p-ncw, ncw,where, styleIndex));
234 nDigs++;
235 }
236 LOGV(ncw) LCV(p-ncw) LCV(x) LCV(wordWidth);
237 wordWidth = ncw = 0;
238 }
239 styleIndex = newStyleIndex;
240 holeX = x;
241 }
242 if (*p == '\t') {
243 LOGSECTION("TraceFileView::parseLine::tab");
244 if (ncw) {
245 where.x = x-wordWidth - hPos;
246 if (x >= begin) {
247 dig.push(DigSetter::Dig(p-ncw, ncw,where, styleIndex));
248 nDigs++;
249 }
250 LOGV(ncw) LCV(p-ncw) LCV(x) LCV(wordWidth);
251 wordWidth = ncw = 0;
252 }
253 LOGV(x) LCV(columnWidth);
254 x = ((x - margin + columnWidth)/columnWidth) * columnWidth + margin;
255 LOGV(x);
256 continue;
257 }
258 if (*p == ' ') {
259 if (ncw) {
260 where.x = x-wordWidth - hPos;
261 if (x >= begin) {
262 dig.push(DigSetter::Dig(p-ncw, ncw,where, styleIndex));
263 nDigs++;
264 }
265 LOGV(ncw) LCV(p-ncw) LCV(x) LCV(wordWidth);
266 wordWidth = ncw = 0;
267 }
268 x += enWidth;
269 continue;
270 }
271 int w = charWidth[*(unsigned char *) p];
272 x += w;
273 wordWidth += w;
274 ncw++;
275 }
276 if (ncw) {
277 where.x = x-wordWidth - hPos;
278 dig.push(DigSetter::Dig(p-ncw, ncw,where, styleIndex));
279 nDigs++;
280 LOGV(ncw) LCV(p-ncw) LCV(x) LCV(wordWidth);
281 wordWidth = ncw = 0;
282 }
283 int newStyleIndex = !precedes(loc, parseLoc);
284 if (activeHighlight && newStyleIndex == 0) {
285 newStyleIndex = 2*(!precedes(loc, beginHighlight) &&
286 precedes(loc, endHighlight));
287 }
288 if (newStyleIndex != styleIndex) {
289 LOGV(newStyleIndex);
290 LOGV(styleIndex);
291 cint holeLocation(holeX - hPos, where.y - topToBaseline);
292 LOGV(holeX);
293 LOGV(hPos);
294 size.x = x - holeX;
295 if (x >= begin) {
296 hole.push(DigSetter::Hole(holeLocation, size, styleIndex));
297 LOGV(holeLocation);
298 LOGV(size);
299 LOGV(styleIndex);
300 nHoles++;
301 }
302 styleIndex = newStyleIndex;
303 holeX = x;
304 }
305 where.x = holeX;
306 if (*p == 0) {
307 x = measure;
308 }
309 size.x = x - holeX;
310 size.x = measure - holeX;
311 cint holeLocation(holeX - hPos, where.y - topToBaseline);
312 hole.push(DigSetter::Hole(holeLocation, size, styleIndex));
313 LOGV(holeLocation);
314 LOGV(size);
315 LOGV(styleIndex);
316 nHoles++;
317 LOGV(nHoles) LCV(nDigs);
318 return *this;
319 }
320
321 int TraceFileView::measureWidth(const char *line) {
322 LOGSECTION("TraceFileView::measureWidth");
323 const char *p = line;
324 assert(p != 0);
325 int x = 0;
326
327 int columnWidth = enWidth*tab_spacing;
328
329 for (; *p; p++) {
330 if (*p == '\t') {
331 x = ((x + columnWidth)/columnWidth) * columnWidth + enWidth;
332 continue;
333 }
334 if (*p == ' ') {
335 x += enWidth;
336 continue;
337 }
338 int width = charWidth[*(unsigned char *) p];
339 x += width;
340 if (x > 1000) {
341 LOGV((unsigned)*p);
342 LOGV(charWidth[*(unsigned char *) p]);
343 LOGV(charWidth[*p]);
344 LOGV(width) LCV(p);
345 }
346 }
347 return x;
348 }
349
350
351 int TraceFileView::charPosition(int xPos, AgString line) {
352 int i = 0;
353 int x = margin;
354 int columnWidth = enWidth*tab_spacing;
355 unsigned char *p = (unsigned char *)line.pointer();
356
357 //LOGSECTION("TraceFileView::charPosition", Log::off);
358 LOGSECTION_OFF("TraceFileView::charPosition");
359
360 if (p) for (i = 0; p[i]; i++) {
361 int newX = x + charWidth[p[i]];
362 if (p[i] == '\t') {
363 LOGV(x);
364 newX = margin + ((x-margin + columnWidth)/columnWidth) * columnWidth;
365 LOGV(x);
366 }
367 if (p[i] == ' ') {
368 LOGV(x);
369 newX = x + enWidth;
370 }
371 //if (newX > xPos) {
372 if (xPos <= (x+newX)/2) {
373 LOGV(i);
374 LOGV(newX);
375 return i;
376 }
377 x = newX;
378 LOGV(i);
379 LOGV(x);
380 }
381 return i;
382 }
383
384 int TraceFileView::xPosition(int charPos, AgString line) {
385 int i;
386 int x = margin;
387 int columnWidth = enWidth*tab_spacing;
388 unsigned char *p = (unsigned char *) line.pointer();
389
390 //LOGSECTION("TraceFileView::xPosition", Log::off);
391 LOGSECTION_OFF("TraceFileView::xPosition");
392 LOGV(p);
393 LOGV(tab_spacing) LCV(enWidth) LCV(columnWidth);
394 LOGV(font().charWidth(' '));
395
396 if (p) for (i = 0; p[i] && i < charPos; i++) {
397 if (p[i] == '\t') {
398 LOGS("tab") LCV(x);
399 x = margin + ((x-margin + columnWidth)/columnWidth) * columnWidth;
400 LOGV(x);
401 continue;
402 }
403 if (p[i] == ' ') {
404 LOGV(x);
405 x += enWidth;
406 continue;
407 }
408 x += charWidth[p[i]];
409 LOGV(i);
410 LOGV(x);
411 }
412 return x;
413 }
414
415
416 Boolean TraceFileView::paintWindow(IPaintEvent &event) {
417 if (event.controlWindow() != &dataArea) {
418 return false;
419 }
420 if (painting) {
421 return true;
422 }
423 hideCursor();
424 painting++;
425 LOGSECTION("TraceFileView::paintWindow");
426
427 LOGV(windowFont.name());
428 setter.setEvent(event);
429
430 IRectangle invalidRect(
431 ICoordinateSystem::isConversionNeeded()
432 ? ICoordinateSystem::convertToApplication(event.rect(),dataArea.size())
433 : event.rect()
434 );
435 LOGV((char*) invalidRect.asString());
436 LOGV(dataArea.size().asString());
437
438 LOGV(rect().asString());
439 LOGV(verticalScrollBar.rect().asString());
440
441 topLine = verticalScrollBar.scrollBoxPosition();
442 int hPos = horizontalScrollBar.scrollBoxPosition();
443
444 int minX = invalidRect.minX() + hPos;
445 int maxX = invalidRect.maxX() + hPos;
446
447 int baseLine = verticalScrollBar.scrollBoxPosition();
448 int topY = baseLine*lineHeight;
449 int minY = invalidRect.minY();
450 int maxY = invalidRect.maxY();
451 //int bottomY = dataHole.size().height();
452
453 invalidRect = IRectangle(IPoint(minX,minY),
454 (IPoint(maxX, maxY)));
455
456 LOGV(invalidRect.asString());
457 LOGV(lineHeight);
458
459 int firstLine = baseLine + invalidRect.minY()/lineHeight;
460 int lastLine = baseLine + (invalidRect.maxY()+lineHeight - 1)/lineHeight - 1;
461
462 int windowWidth = dataArea.size().width();
463 measure = windowWidth > tableWidth ? windowWidth : tableWidth;
464 measure += 2*margin;
465
466 LOGV(windowWidth);
467 LOGV(tableWidth);
468 LOGV(measure);
469 //int topToBaseline = font.maxAscender();
470
471 //int whereX = 0;
472 int whereY = firstLine*lineHeight - topY; //topline location
473
474 LOGV(topLine);
475 LOGV(firstLine);
476 LOGV(lastLine);
477 LOGV(horizontalScrollBar.scrollBoxPosition());
478
479 //int lastInvalidLine = lastLine;
480 if (lastLine >= nLines()) {
481 lastLine = nLines() - 1;
482 }
483 //int windowHeight = dataArea.size().height();
484 int dataAreaWidth = windowWidth;
485 ISize lineSize(dataAreaWidth, lineHeight);
486 int k;
487
488 LOGV(beginHighlight);
489 LOGV(endHighlight);
490
491 LOGV(minX) LCV(maxX);
492
493 for (k = firstLine; k <= lastLine; k++, whereY += lineHeight) {
494 int i;
495 LOGV(k) LCV(whereY);
496 AgString line = getLine(k);
497 LOGV(line.pointer());
498 parseLine(k - baseLine, line, minX, maxX);
499 LOGV(hole[0].where.y);
500 LOGV(k);
501 for (i = 0; i < nHoles; i++) {
502 if (pixelCursor.x > hole[nHoles-1].where.x) {
503 LOGV(i);
504 LOGV(hole[i].where);
505 LOGV(hole[i].size);
506 }
507 setter.clear(hole[i]);
508 }
509 LOGV(nHoles) LCS("holes cleared");
510 for (i = 0; i < nDigs; i++) {
511 if (pixelCursor.x > hole[nHoles-1].where.x) {
512 LOGV(i);
513 LOGV(dig[i].where);
514 }
515 setter.setDig(dig[i]);
516 }
517 dig.discardData();
518 hole.discardData();
519 LOGV(nDigs);
520 LOGV(line.pointer());
521 }
522 invalidRect = IRectangle(IPoint(minX - hPos,whereY),
523 (IPoint(maxX - hPos, maxY)));
524 if (invalidRect.height() > 0) {
525 setter.clear(DigSetter::Hole(invalidRect, 3));
526 }
527 setter.closeEvent();
528 showCursor();
529 painting = false;
530 return true;
531 }
532
533 TraceFileView &TraceFileView::refreshLines(int first, int last) {
534 LOGSECTION("refreshLines");
535 int baseLine = verticalScrollBar.scrollBoxPosition();
536 first -= baseLine;
537 last -= baseLine;
538 first = first * lineHeight;
539 last = (last+1) * lineHeight;
540 IRectangle r(IPoint(0,first),IPoint(measure, last));
541 LOGV(r.asString());
542 //hideCursor();
543 dataArea.refresh(r,true);
544 //showCursor();
545 return *this;
546 }
547
548 TraceFileView &TraceFileView::turnHighlightOff() {
549 LOGSECTION("turnHighlightOff");
550 int flag = activeHighlight;
551 activeHighlight = 0;
552 if (flag) {
553 LOGV(beginHighlight);
554 refreshLines(beginHighlight.y, endHighlight.y);
555 //setCursorLocation(parser.state.position());
556 }
557 return *this;
558 }
559
560 TraceFileView &TraceFileView::turnHighlightOn(unsigned ln) {
561 LOGSECTION("turnHighlightOn");
562 if (activeHighlight) {
563 activeHighlight = 0;
564 refreshLines(beginHighlight.y, endHighlight.y);
565 }
566 unsigned stackDepth = parser.stateStack.size();
567 LOGV(parser.state.position());
568 LOGV(parser.reductionState.position());
569 LOGV(parser.processState);
570 LOGV(ln);
571 LOGV(parser.reductionIndex);
572
573 if (parser.processState == FtParser::selectionRequired &&
574 ln >= parser.reductionIndex) {
575 beginHighlight = parser.reductionState.position();
576 endHighlight = parser.state.position();
577 }
578 else if (ln >= stackDepth) {
579 //setCursorLocation(parser.state.position());
580 scrollTo(parser.state.position());
581 return *this;
582 }
583 else {
584 beginHighlight = parser.stateStack[ln++].position();
585 if (ln < stackDepth) {
586 endHighlight = parser.stateStack[ln].position();
587 }
588 else if (parser.processState == FtParser::selectionRequired
589 && parser.reductionIndex >= parser.stateStack.size()) {
590 endHighlight = parser.reductionState.position();
591 }
592 else {
593 endHighlight = parser.state.position();
594 }
595 }
596 activeHighlight = 1;
597 LOGV(beginHighlight);
598 LOGV(endHighlight);
599 //setCursorLocation(beginHighlight);
600 scrollTo(beginHighlight);
601 refreshLines(beginHighlight.y, endHighlight.y);
602 return *this;
603 }
604
605 TraceFileView &TraceFileView::step() {
606 LOGSECTION("TraceFileView::step");
607 cint oldLoc = PARSE_LOCATION;
608 LOGV(oldLoc);
609 switch (parser.processState) {
610 case FtParser::selectionError:
611 parser.processState = FtParser::selectionRequired;
612 /* FALLTHROUGH */ /* ? - I think so */
613 case FtParser::selectionRequired:
614 parser.completeReduction();
615 }
616 if (parser.processState > FtParser::running) {
617 if (precedes(cursorLocation, PARSE_LOCATION)) {
618 if (parser.processState == FtParser::finished) {
619 parser.reset();
620 }
621 parser.processState = FtParser::running;
622 refreshHighlight(oldLoc);
623 }
624 else {
625 messageBeep();
626 return *this;
627 }
628 }
629 FileTraceWindow *x = (FileTraceWindow *) frameWindow;
630 ISystemPointerHandle newHandle(ISystemPointerHandle::wait);
631 x->setMousePointer(newHandle);
632 x->setStatusField("Running");
633
634 turnHighlightOff();
635 if (oldLoc != cursorLocation) {
636 parseToCursor();
637 return *this;
638 }
639 parser.step();
640 setCursorLocation(PARSE_LOCATION);
641 refreshHighlight(oldLoc);
642 onEnter();
643 return *this;
644 }
645
646
647 TraceFileView &TraceFileView::parse() {
648 LOGSECTION("TraceFileView::parse");
649 switch (parser.processState) {
650 case FtParser::finished:
651 messageBeep();
652 return *this;
653 case FtParser::selectionError:
654 parser.processState = FtParser::selectionRequired;
655 /* FALLTHROUGH */ /* ? - I think so */
656 case FtParser::selectionRequired:
657 parser.completeReduction();
658 }
659 if (parser.processState > FtParser::running) {
660 return *this;
661 }
662
663 FileTraceWindow *x = (FileTraceWindow *) frameWindow;
664 ISystemPointerHandle newHandle(ISystemPointerHandle::wait);
665 x->setMousePointer(newHandle);
666 x->setStatusField("Running");
667
668 turnHighlightOff();
669 cint oldLoc = PARSE_LOCATION;
670 LOGV(oldLoc);
671 parser.parse();
672 setCursorLocation(PARSE_LOCATION);
673 refreshHighlight(oldLoc);
674 onEnter();
675 return *this;
676 }
677
678 Boolean TraceFileView::virtualKeyPress(IKeyboardEvent &event) {
679 LOGSECTION("TraceFileView::virtualKeyPress");
680 LOGV(event.virtualKey());
681 switch (event.virtualKey()) {
682 case IKeyboardEvent::left:
683 case IKeyboardEvent::up:
684 case IKeyboardEvent::pageUp:
685 case IKeyboardEvent::right:
686 case IKeyboardEvent::down:
687 case IKeyboardEvent::pageDown:
688 case IKeyboardEvent::home:
689 case IKeyboardEvent::end:
690 {
691 int flag = PARSE_LOCATION == cursorLocation;
692 AgView::virtualKeyPress(event);
693 AgString line = getLine(cursorLocation.y);
694 pixelCursor.x = xPosition(cursorLocation.x, line);
695 cursorLocation.x = charPosition(pixelCursor.x, line);
696 if (flag) {
697 parseAction();
698 }
699 else if (PARSE_LOCATION == cursorLocation) {
700 resynchAction();
701 }
702 if (PARSE_LOCATION != cursorLocation) {
703 desynchAction();
704 }
705 return true;
706 }
707 case IKeyboardEvent::newLine:
708 case IKeyboardEvent::enter:
709 {
710 LOGSECTION("TraceFileView::enter");
711 cint oldLoc = PARSE_LOCATION;
712
713 LOGV(oldLoc);
714 LOGV(cursorLocation);
715 if (cursorLocation != oldLoc) {
716 parseAction();
717 return true;
718 }
719 parser.step();
720 cursorLocation = PARSE_LOCATION;
721 LOGV(cursorLocation);
722 cursorLine = cursorLocation.y;
723 pixelCursor.x = xPosition(cursorLocation.x,getLine(cursorLine));
724 pixelCursor.y = cursorLine*lineHeight;
725 setCursorPos(pixelCursor);
726 refreshHighlight(oldLoc);
727 onEnter();
728 return true;
729 }
730 }
731 return false;
732 };
733
734 Boolean TraceFileView::mousePointerChange(IMousePointerEvent &event) {
735 LOGSECTION("TraceFileView::mousePointerChange");
736 if (event.controlWindow() != &dataHole) {
737 return false;
738 }
739 if (ControlPanel::helpCursorSet) {
740 event.setMousePointer(ControlPanel::helpCursor);
741 }
742 else {
743 event.setMousePointer(ISystemPointerHandle(ISystemPointerHandle::text));
744 }
745 LOGS("Pointer changed");
746 return true;
747 }
748
749 Boolean TraceFileView::mouseClicked(IMouseClickEvent &event) {
750 LOGSECTION("TraceFileView::mouseClickEvent");
751 LOGV(event.mouseButton());
752 LOGV(event.mouseAction());
753 if (event.mouseAction() == IMouseClickEvent::down) {
754 dataArea.setFocus();
755 }
756 if (event.controlWindow() == &verticalScrollBar ||
757 event.controlWindow() == &horizontalScrollBar) {
758 //if (event.mouseAction() == IMouseClickEvent::down) {
759 // dataArea.setFocus();
760 //}
761 return false;
762 }
763 if (event.windowUnderPointer() != dataArea.handle()) {
764 return false;
765 }
766 if (event.controlWindow() != event.dispatchingWindow()) {
767 return false;
768 }
769
770 clickEnabled |= event.mouseAction() == IMouseClickEvent::down;
771 clickEnabled &= !ControlPanel::helpCursorSet;
772 int line = event.mousePosition().y()/lineHeight;
773 line += verticalScrollBar.scrollBoxPosition();
774 if (line >= nLines()) {
775 return false;
776 }
777
778 LOGV((int) event.controlWindow()) LCV((int) event.dispatchingWindow());
779
780 if (event.mouseButton() != IMouseClickEvent::button1) {
781 return false;
782 }
783 switch (event.mouseAction()) {
784 case IMouseClickEvent::down:
785 case IMouseClickEvent::up:
786 return false;
787 case IMouseClickEvent::click: {
788 if (!clickEnabled) {
789 return false;
790 }
791 clickEnabled = 0;
792 doubleClickEnabled = 1;
793 LOGSECTION("TraceFileView::click");
794 //setFocus();
795 cursorLine = line;
796 int offset = horizontalScrollBar.scrollBoxPosition();
797 int whereX = event.mousePosition().x() + offset;
798 LOGV(cursorLine) LCV(offset) LCV(whereX);
799 AgString text = getLine(line);
800 cint loc(charPosition(whereX, text), line);
801 LOGV(loc);
802
803 LOGV(cursorLocation) LCV(PARSE_LOCATION);
804 int synchFlag = cursorLocation == PARSE_LOCATION;
805 cursorLocation = loc;
806 cursorLine = cursorLocation.y;
807 pixelCursor.x = xPosition(loc.x, text);
808 pixelCursor.y = loc.y*lineHeight;
809 LOGV(pixelCursor);
810 setCursorPos(pixelCursor);
811 LOGV(cursorLocation) LCV(PARSE_LOCATION);
812 if (!synchFlag && PARSE_LOCATION == cursorLocation) {
813 resynchAction();
814 }
815 if (synchFlag && cursorLocation != PARSE_LOCATION) {
816 desynchAction();
817 }
818 return false;
819 }
820 case IMouseClickEvent::doubleClick: {
821 if (!doubleClickEnabled) {
822 return false;
823 }
824 doubleClickEnabled = 0;
825 LOGSECTION("TraceFileView::doubleClick");
826 //setFocus();
827 cursorLine = line;
828 int offset = horizontalScrollBar.scrollBoxPosition();
829 int whereX = event.mousePosition().x() + offset;
830 LOGV(cursorLine) LCV(offset) LCV(whereX);
831 AgString text = getLine(line);
832 cint loc(charPosition(whereX, text), line);
833 LOGV(loc);
834
835 cursorLocation = loc;
836 cursorLine = cursorLocation.y;
837 pixelCursor.x = xPosition(loc.x, text);
838 pixelCursor.y = loc.y*lineHeight;
839 LOGV(pixelCursor);
840 setCursorPos(pixelCursor);
841 parseAction();
842 return false;
843 }
844 }
845 //return TraceFileView::mouseClicked(event);
846 return false;
847 }
848
849 Boolean TraceFileView::findNext(AgString s) {
850 int synchFlag = cursorLocation == PARSE_LOCATION;
851 int flag = FileView::findNext(s);
852 if (!synchFlag && PARSE_LOCATION == cursorLocation) {
853 resynchAction();
854 }
855 if (synchFlag && cursorLocation != PARSE_LOCATION) {
856 desynchAction();
857 }
858 return flag;
859 }
860
861 Boolean TraceFileView::findPrev(AgString s) {
862 int synchFlag = cursorLocation == PARSE_LOCATION;
863 int flag = FileView::findPrev(s);
864 if (!synchFlag && PARSE_LOCATION == cursorLocation) {
865 resynchAction();
866 }
867 if (synchFlag && cursorLocation != PARSE_LOCATION) {
868 desynchAction();
869 }
870 return flag;
871 }
872
873 TraceFileView &TraceFileView::refreshHighlight(cint oldLoc) {
874 LOGSECTION("TraceFileView::refreshHighlight");
875 int newLine = cursorLocation.y;
876 int hPos = horizontalScrollBar.scrollBoxPosition();
877 LOGV(hPos);
878 if (cursorLocation != oldLoc) {
879 LOGV(oldLoc);
880 LOGV(cursorLocation);
881 int top = min(oldLoc.y, newLine);
882 top -= verticalScrollBar.scrollBoxPosition();
883 int bottom = max(oldLoc.y, newLine);
884 bottom -= verticalScrollBar.scrollBoxPosition();
885 bottom++;
886 //hideCursor();
887 LOGV(top);
888 LOGV(bottom);
889 updateCursor();
890 if (newLine == oldLoc.y) {
891 //int whereY = top*lineHeight;
892 AgString line = getLine(newLine);
893 int oldX = xPosition(oldLoc.x, line);
894 if (oldLoc.x == 0) {
895 oldX = 0;
896 }
897 IPoint oldPoint(oldX-hPos, lineHeight*top);
898 int newX = xPosition(cursorLocation.x, line);
899 if (cursorLocation.x == 0) {
900 newX = 0;
901 }
902 IPoint newPoint(newX - hPos, lineHeight*bottom);
903 LOGV(oldPoint.asString());
904 LOGV(newPoint.asString());
905 IRectangle rectangle(oldPoint, newPoint);
906 dataArea.refresh(rectangle, true);
907 LOGV(rectangle.asString());
908 }
909 else {
910 int width = dataArea.size().width();
911 IRectangle rectangle(0, lineHeight*top, width, lineHeight*bottom);
912 dataArea.refresh(rectangle, true);
913 LOGV(rectangle.asString());
914 }
915 //showCursor();
916 }
917 return *this;
918 }
919
920
921 void TraceFileView::parseToCursor() {
922 LOGSECTION("TraceFileView::parseToCursor");
923 cint oldLoc = PARSE_LOCATION;
924 LOGV(oldLoc);
925 LOGV(cursorLocation);
926 switch (parser.processState) {
927 case FtParser::finished: {
928 if (precedes(cursorLocation, PARSE_LOCATION)) {
929 parser.reset();
930 refreshHighlight(oldLoc);
931 oldLoc = PARSE_LOCATION;
932 break;
933 }
934 messageBeep();
935 return;
936 }
937 case FtParser::selectionError:
938 parser.processState = FtParser::selectionRequired;
939 /* FALLTHROUGH */ /* ? - I think so */
940 case FtParser::selectionRequired:
941 parser.completeReduction();
942 break;
943 case FtParser::syntaxError:
944 if (!precedes(cursorLocation, PARSE_LOCATION)) {
945 messageBeep();
946 return;
947 }
948 default:
949 parser.processState = FtParser::running;
950 refreshHighlight(oldLoc);
951 break;
952 }
953 LOGV(cursorLocation) LCV(PARSE_LOCATION);
954 turnHighlightOff();
955 LOGV(cursorLocation) LCV(PARSE_LOCATION);
956
957 //if (PARSE_LOCATION == cursorLocation) return;
958 if (PARSE_LOCATION != cursorLocation) {
959 FileTraceWindow *x = (FileTraceWindow *) frameWindow;
960 ISystemPointerHandle newHandle(ISystemPointerHandle::wait);
961 x->setMousePointer(newHandle);
962 x->setStatusField("Running");
963
964 //parser.parseTo(&cursorLocation);
965 do {
966 parser.parseTo(&cursorLocation);
967 if (parser.processState != FtParser::selectionRequired) {
968 continue;
969 }
970 int fileIndex = (char *) parser.state.pointer - parser.text.pointer();
971 int tn = reductionTable[fileIndex];
972 LOGV(fileIndex) LCV(tn);
973 if (tn == 0) {
974 continue;
975 }
976 parser.completeReduction(tn);
977 } while (parser.processState <= FtParser::running &&
978 precedes(PARSE_LOCATION, cursorLocation));
979 setCursorLocation(PARSE_LOCATION);
980 LOGV(oldLoc);
981 LOGV(cursorLocation);
982 refreshHighlight(oldLoc);
983 }
984 onEnter();
985 }
986