Mercurial > ~dholland > hg > ag > index.cgi
diff anagram/vaclgui/ftview.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/anagram/vaclgui/ftview.cpp Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,1355 @@ +/* + * AnaGram, A System for Syntax Directed Programming + * Copyright 1997-2002 Parsifal Software. All Rights Reserved. + * See the file COPYING for license and usage terms. + * + * ftview.cpp + */ + +//#include <imsgbox.hpp> +//#include <itbarcnr.hpp> + +#include "agstring.h" +#include "agview.hpp" +#include "arrays.h" +#include "ctrlpanel.hpp" +#include "data.h" +#include "dc.h" +#include "dvplug.hpp" +#include "ftpar.h" +#include "ftview.hpp" +#include "helpview.hpp" +#include "myalloc.h" +#include "p.h" +#include "rule.h" +#include "vaclgui.hpp" + +//#define INCLUDE_LOGGING +#include "log.h" + + +#define PARSE_FILE "&Parse File" +#define SINGLE_STEP "&Single step" +#define RELOAD "Re&load" +#define RESET "&Reset" +#define HELP "&Help" +#define SYNCH_PARSE "&Synch Parse" + +//void logChildren(IWindow *window) { +// LOGSECTION("logChildren"); +// LOGV(window->id()); +// IWindow::ChildCursor cursor(*window); +// for (cursor.setToFirst(); cursor.isValid(); cursor.setToNext()) { +// IWindow child(window->childAt(cursor)); +// LOGS(" ") LV(child.id()); +// } +//} + +FileTraceView::FileTraceView(FileTraceWindow *frame_, + text_file text_, + AgString fileName_) + : ICanvas(nextChildId(), frame_, frame_, IRectangle(), + ICanvas::classDefaultStyle + | IWindow::clipChildren) + , mainSplitter(nextChildId(), this, this, IRectangle(), + ISplitCanvas::horizontal + | IWindow::visible) + , tracePanels(nextChildId(), &mainSplitter, &mainSplitter, IRectangle(), + ISplitCanvas::classDefaultStyle) + , leftPanel(nextChildId(), &tracePanels, &tracePanels, IRectangle(), + visible) + , rightPanel(nextChildId(), &tracePanels, &tracePanels, IRectangle(), + visible) + , stackView(&leftPanel) + , fileView(&rightPanel, text_, fileName_) + , fileTitle(nextChildId(), &rightPanel, &rightPanel) + , fileName(fileName_) + , textFile(text_) + , bottomPanel(nextChildId(), &mainSplitter, &mainSplitter, IRectangle(), + ISplitCanvas::vertical + | visible) + , reductionChoiceView(&bottomPanel) + , ruleView(&bottomPanel) + , frame(frame_) + , dataColorChange(this, onColorChange) + , fontChange(this, onFontChange) + , focusControl(FileTraceWindow::fileTab) + , activePanel(FileTraceWindow::fileTab) + , fileViewHelp(&rightPanel, "Test File") +{ + LOGSECTION("FileTraceView::FileTraceView"); + + LOGV((int) &mainSplitter); + LOGV((int) &tracePanels); + LOGV((int) &leftPanel); + LOGV((int) &rightPanel); + LOGV((int) &bottomPanel); + LOGV((int) &stackView); + LOGV((int) &fileView); + LOGV((int) &reductionChoiceView); + LOGV((int) &ruleView); + LOGV((int) &this); + + LOGV(id()) LCV(handle().asDebugInfo()); + LOGV(leftPanel.id()) LCV((int) &leftPanel) + LCV(leftPanel.handle().asDebugInfo()); + LOGV(rightPanel.id()) LCV((int) &rightPanel) + LCV(rightPanel.handle().asDebugInfo()); + LOGV(stackView.id()) LCV((int) &stackView) + LCV(stackView.handle().asDebugInfo()); + LOGV(fileView.id()) LCV((int) &fileView) + LCV(fileView.handle().asDebugInfo()); + LOGV(fileTitle.id()) LCV((int) &fileTitle) + LCV(fileTitle.handle().asDebugInfo()); + + setFont(stackView.dataArea.font()); + + ruleView.setEnterAction(AgAction()); + ruleView.copyTitle = "File Trace: Rule Stack"; + reductionChoiceView.copyTitle = "File Trace: Reduction Choices"; + stackView.copyTitle = "File Trace: Parser Stack"; + + dataColorChange.attach(&ColorSpec::inactiveTitle); + dataColorChange.attach(&ColorSpec::activeTitle); + fontChange.attach(&FontSpec::columnHead); + + reductionMenu = new FtParserReductionDc(fileView.parser); + AgDataViewPlug *connector = new AgDataViewPlug(reductionMenu); + reductionMenu->windowConnector = connector; + reductionChoiceView.init(connector); + + bottomPanel.setSplitWindowPercentage(&reductionChoiceView, 0); + bottomPanel.setSplitWindowPercentage(&ruleView, 100); + + fileTitle + . setText(fileName.pointer()) + . setAlignment(IStaticText::centerCenter) + . setBackgroundColor(ColorSpec::inactiveTitle.bg()) + . setForegroundColor(ColorSpec::inactiveTitle.fg()) + ; + LOGS("titles set up"); + //dc_ref stackWindow = new FtParserDc(fileView.parser); + parserDc = new FtParserDc(fileView.parser); + + //fileView.parser.displayControl = stackWindow; + //stackConnector = new AgDataViewPlug(stackWindow); + stackConnector = new AgDataViewPlug(parserDc); + //stackWindow->windowConnector = stackConnector; + parserDc->windowConnector = stackConnector; + stackView.init(stackConnector); + + itemStack = fileView.parser.x1x_new(); + //dc_ref ruleWindow = new rule_stack_dc(itemStack,0,stackWindow->head_title); + //ruleControl = new rule_stack_dc(itemStack,0, stackWindow->head_title); + ruleControl = new rule_stack_dc(itemStack, 0, parserDc->head_title); + //fileView.parser.ruleControl = ruleWindow; + //ruleConnector = new AgDataViewPlug(ruleWindow); + ruleConnector = new AgDataViewPlug(ruleControl); + //ruleWindow->windowConnector = ruleConnector; + ruleControl->windowConnector = ruleConnector; + ruleView.init(ruleConnector); + + int width = stackView.tableWidth; + int height = font().externalLeading() + font().maxSize().height(); + ISize minSize(width, 5*height); + + LOGV(minSize.asString()); + leftPanel + . addToCell(&stackView, 1,1) + . setColumnWidth(1,width,true) + . setRowHeight(1,0,true) + . setMinimumSize(minSize) + ; + width = fileTitle.minimumSize().width(); + int maxWidth = IWindow::desktopWindow()->size().width()/3; + IFont titleFont = fileTitle.font(); + int lineHeight = titleFont.maxCharHeight() + titleFont.externalLeading() + + titleFont.maxDescender(); + if (width > maxWidth) { + width = maxWidth; + } + minSize.setWidth(maxWidth); + minSize.setHeight(lineHeight); + fileTitle.setMinimumSize(minSize); + minSize = ISize(width, 5*height); + LOGV(minSize.asString()); + rightPanel + . addToCell(&fileTitle, 1, 1) + . addToCell(&fileView, 1, 2) + . setColumnWidth(1, width, true) + . setRowHeight(2, 0, true) + . setMinimumSize(minSize) + ; + mainSplitter.setSplitWindowPercentage(&tracePanels, 60); + mainSplitter.setSplitWindowPercentage(&bottomPanel, 40); + tracePanels.setSplitWindowPercentage(&leftPanel, 25); + tracePanels.setSplitWindowPercentage(&rightPanel, 75); + LOGS("splitters set"); + AgFocusHandler::handleEventsFor(&stackView.dataArea); + AgFocusHandler::handleEventsFor(&fileTitle); + AgFocusHandler::handleEventsFor(&fileView.dataArea); + AgFocusHandler::handleEventsFor(&reductionChoiceView.dataArea); + AgFocusHandler::handleEventsFor(&ruleView.dataArea); + LOGS("Focus handler set"); + IMouseHandler::handleEventsFor(&fileTitle); + IPaintHandler::handleEventsFor(this); + LOGS("Mouse handler set"); + focusControl = FileTraceWindow::fileTab; + LOGS("all done"); +} + +FileTraceView::~FileTraceView() { + AgFocusHandler::stopHandlingEventsFor(&stackView.dataArea); + AgFocusHandler::stopHandlingEventsFor(&fileTitle); + AgFocusHandler::stopHandlingEventsFor(&fileView.dataArea); + AgFocusHandler::stopHandlingEventsFor(&reductionChoiceView.dataArea); + AgFocusHandler::stopHandlingEventsFor(&ruleView.dataArea); + IMouseHandler::stopHandlingEventsFor(&fileTitle); + IPaintHandler::stopHandlingEventsFor(this); +} + +Boolean FileTraceView::paintWindow(IPaintEvent &event) { + LOGSECTION("FileTraceView::paintWindow"); + LOGV(event.rect().asString()); + event.clearBackground(IGUIColor::dialogBgnd); + return false; +} + +FileTraceView &FileTraceView::refreshRules(int rule) { + LOGSECTION("FileTraceView::refreshRules"); + LOGV(rule); + FtParser &parser = fileView.parser; + delete_tsd(itemStack); + itemStack = parser.x1x_new(); + //parser.ruleControl->parser_stack = parser.itemStack; + ruleControl->parser_stack = itemStack; + int k = itemStack->nt; + int ln = parser.stateStack.size(); + //parser.ruleControl->des->d_size.y = k; + ruleControl->des->d_size.y = k; + //LOGV(k); + while (k--) { + int sx, sn, fn, fx; + xtxf(itemStack, k, &sx, &sn, &fn, &fx); + int length = Rule(fn)->length(); + //LOGV(length); + if (sx == ln && rule == 0) { + break; + } + if (rule && fn == rule && fx == 0 && sx+length >= ln) { + break; + } + } + k = itemStack->nt - 1 - k; + //LOGV(k); + + ruleView + . reset() + . setCursorLine(itemStack->nt-1) + . setCursorLine(k) + . synchCursor(k); + //. refresh(); + return *this; +} + +Boolean FileTraceView::mouseClicked(IMouseClickEvent &event) { + LOGSECTION("FileTraceView::mouseClicked"); + LOGV(event.mouseButton()) LCV(event.mouseAction()); + if (event.mouseAction() != IMouseClickEvent::down) { + return false; + } + IWindow *controlWindow = event.controlWindow(); + if (controlWindow == &fileTitle) { + fileView.dataArea.setFocus(); + focusControl = FileTraceWindow::fileTab; + return false; + } + return false; +} + +Boolean FileTraceView::gotFocus(IEvent &event) { + LOGSECTION("FileTraceView::gotFocus"); + LOGV(focusControl); + IWindowHandle handle = (void *) event.parameter1(); + //IWindow *lastWindow = IWindow::windowWithHandle(handle); + //LOGV(handle.asUnsigned()) LCV((int) lastWindow); + LOGV((int) event.controlWindow()) LCV((int) event.dispatchingWindow()); + if (event.controlWindow() == &fileView.dataArea) { + ColorSpec *color = &ColorSpec::activeTitle; + fileTitle.setBackgroundColor(color->bg()); + fileTitle.setForegroundColor(color->fg()); + focusControl = activePanel = FileTraceWindow::fileTab; + + fileTitle.refresh(); + } + else if (event.controlWindow() == &stackView.dataArea) { + focusControl = activePanel = FileTraceWindow::stackTab; + } + else if (event.controlWindow() == &reductionChoiceView.dataArea) { + focusControl = activePanel = FileTraceWindow::choiceTab; + } + else if (event.controlWindow() == &ruleView.dataArea) { + focusControl = activePanel = FileTraceWindow::ruleTab; + } + frame->parseButton.disableDefault(); + frame->resetButton.disableDefault(); + frame->reloadButton.disableDefault(); + frame->helpButton.disableDefault(); + frame->stepButton.enableDefault(); + + LOGV(focusControl); + return false; +} + +Boolean FileTraceView::lostFocus(IEvent &event) { + LOGSECTION("FileTraceView::lostFocus"); + LOGV(focusControl); + IWindowHandle handle = (void *) event.parameter1(); + //IWindow *nextWindow = IWindow::windowWithHandle(handle); + //LOGV(handle.asUnsigned()) LCV((int) nextWindow); + if (event.controlWindow() == &fileView.dataArea) { + ColorSpec *color = &ColorSpec::inactiveTitle; + fileTitle.setBackgroundColor(color->bg()); + fileTitle.setForegroundColor(color->fg()); + fileTitle.refresh(); + } + return false; +} + +Boolean FileTraceWindow::characterKeyPress(IKeyboardEvent &event) { + LOGSECTION("FileTraceWindow::characterKeyPress"); + ok_ptr(this); + char character = event.character(); + LOGV(character) LCV(event.isCtrlDown()); + if (event.isCtrlDown()) { + return true; + } + if (canvas.focusControl < stepTab) { + canvas.activePanel = canvas.focusControl; + } + switch (character) { + case 'p': + case 'P': + parseFile(); + return true; + case 's': + case 'S': + doStep(); + return true; + case 'r': + case 'R': + resetParser(); + return true; + case 'l': + case 'L': + reload(); + return true; + case 'h': + case 'H': + AgHelpWindow::showHelp("File Trace"); + helpButton.disableDefault(); + helpButton.unhighlight(); + stepButton.enableDefault(); + canvas.focusControl = fileTab; + return true; + } + return false; +} + +Boolean FileTraceWindow::virtualKeyPress(IKeyboardEvent &event) { + LOGSECTION("FileTraceWindow::virtualKeyPress"); + ok_ptr(this); + int increment = 0; + int &focusControl = canvas.focusControl; + int &activePanel = canvas.activePanel; + LOGV(focusControl); + LOGV((int) event.controlWindow()) LCV((int) event.dispatchingWindow()); + LOGV(event.virtualKey()); + switch (event.virtualKey()) { + case IKeyboardEvent::enter: + case IKeyboardEvent::newLine: { + //activePanel = focusControl; + if (focusControl >= stepTab) { + tabControl[focusControl].action.performDeferred(); + IPushButton *button = (IPushButton *)tabControl[focusControl].window; + button->disableDefault(); + button->unhighlight(); + } + else { + activePanel = focusControl; + doStep(); + } + return true; + } + case IKeyboardEvent::right: + case IKeyboardEvent::down: + if (focusControl < stepTab) { + return AgFrame::virtualKeyPress(event); + } + if (focusControl + 1 == nTabs) { + increment = stepTab - focusControl; + } + else { + increment = 1; + } + break; + case IKeyboardEvent::tab: + increment = 1; + break; + case IKeyboardEvent::left: + case IKeyboardEvent::up: + if (focusControl < stepTab) { + return AgFrame::virtualKeyPress(event); + } + if (focusControl == stepTab) { + increment = nTabs - 1 - stepTab; + } + else { + increment = nTabs - 1; + } + break; + case IKeyboardEvent::backTab: + increment = nTabs - 1; + break; + default: + return AgFrame::virtualKeyPress(event); + } + if (event.controlWindow() != event.dispatchingWindow()) { + return true; + } + IPushButton *button; + if (focusControl >= stepTab) { + button = (IPushButton *) tabControl[focusControl].window; + button->unhighlight(); + button->disableDefault(); + } + do { + focusControl = (focusControl + increment) % nTabs; + } while (!tabControl[focusControl].enabled); + LOGV(focusControl) LCV(increment); + if (focusControl >= stepTab) { + button = (IPushButton *) tabControl[focusControl].window; + } + else { + button = &stepButton; + } + button->enableDefault(); + setFocus(); + return true; +} + +Boolean FileTraceWindow::mouseClicked(IMouseClickEvent &event) { + LOGSECTION("FileTraceWindow::mouseClicked"); + ok_ptr(this); + LOGV(event.mouseButton()) LCV(event.mouseAction()); + if (event.mouseButton() != 0) { + return false; + } + int &focusControl = canvas.focusControl; + int &activePanel = canvas.activePanel; + IWindow *controlWindow = event.controlWindow(); + LOGV((int)controlWindow) LCV((int)event.dispatchingWindow()); + + if (event.mouseAction() == IMouseClickEvent::click) { + return false; + } + if (event.mouseAction() == IMouseClickEvent::doubleClick) { + return false; + } + + int tab; + for (tab = 0; tab < nTabs; tab++) { + LOGV(tab) LCV((int) tabControl[tab].window); + if (controlWindow == tabControl[tab].window) { + break; + } + } + if (tab == nTabs) { + return False; + } + + if (ControlPanel::helpCursorSet) { + if (event.mouseAction() == IMouseClickEvent::up) { + ControlPanel::helpCursorSet = 0; + LOGV(tabControl[tab].helpTopic); + AgHelpWindow::showHelp(tabControl[tab].helpTopic); + ControlPanel::resetCursor(); + } + return true; + } + LOGV(focusControl) LCV(activePanel); + if (tab < stepTab) { + return false; + } + if (focusControl >= stepTab) { + IPushButton *button = (IPushButton *) tabControl[focusControl].window; + button->unhighlight(); + button->disableDefault(); + } + IPushButton *button = (IPushButton *) tabControl[tab].window; + if (event.mouseAction() == IMouseClickEvent::down) { + if (focusControl < stepTab) { + activePanel = focusControl; + } + button->highlight(); + button->setFocus(); + focusControl = tab; + button->capturePointer(); + return true; + } + if (event.mouseAction() == IMouseClickEvent::up) { + button->unhighlight(); + button->releasePointer(); + AgAction &action = tabControl[tab].action; + IWindowHandle h = tabControl[tab].window->handle(); + if (h == event.windowUnderPointer()) { + action.performDeferred(); + } + else if (activePanel < stepTab) { + button->disableDefault(); + parseButton.enableDefault(); + focusControl = activePanel; + setFocus(); + } + else { + button->disableDefault(); + stepButton.enableDefault(); + focusControl = stepTab; + setFocus(); + } + return true; + } + return false; +} + + +FileTraceWindow &FileTraceWindow::setFocus() { + LOGSECTION("FileTraceWindow::setFocus"); + ok_ptr(this); + int &focusControl = canvas.focusControl; + if (focusControl < stepTab) { + canvas.activePanel = focusControl; + } + LOGV(focusControl) LCV((int) tabControl[focusControl].window); + tabControl[focusControl].window->setFocus(); + IPushButton *button; + for (int i = stepTab; i < nTabs; i++) { + button = (IPushButton *)tabControl[i].window; + button->disableDefault(); + button->unhighlight(); + } + button = &stepButton; + if (focusControl > stepTab) { + button = (IPushButton *)tabControl[focusControl].window; + } + button->enableDefault(); + return *this; +} + + +FileTraceWindow::FileTraceWindow(AgString fileName_, + int flags) + : AgFrame( IFrameWindow::dialogBackground + | IFrameWindow::systemMenu + | IFrameWindow::maximizeButton + | IFrameWindow::sizingBorder) + , canvas(this, text_file(fileName_, flags), fileName_) + , fileName(fileName_) + , toolBar(this, ISetCanvas::packTight | ISetCanvas::centerVerticalAlign) + , locationField(nextChildId(), &toolBar, &toolBar, IRectangle(), + IStaticText::defaultStyle() + | IStaticText::center + | IStaticText::vertCenter + | IStaticText::border3D) + , locationFieldHelp(&locationField, "Parse Location") + , statusField(nextChildId(), &toolBar, &toolBar, IRectangle(), + IStaticText::defaultStyle() + | IStaticText::center + | IStaticText::vertCenter + | IStaticText::border3D) + , statusFieldHelp(&statusField, "Parse Status") + , buttonGroup(&toolBar, ISetCanvas::packExpanded) + , stepButton(IDTB_STEP, &buttonGroup, SINGLE_STEP) + , parseButton(IDTB_PARSE_FILE, &buttonGroup, PARSE_FILE) + , resetButton(IDTB_RESET, &buttonGroup, RESET) + , reloadButton(IDTB_RELOAD, &buttonGroup, RELOAD) + , helpButton(IDTB_HELP, &buttonGroup, HELP) +{ + LOGSECTION("FileTraceWindow::FileTraceWindow"); + ok_ptr(this); + + tabControl[stackTab] = TabControl(&canvas.stackView.dataArea, + "Parser Stack Pane"); + tabControl[fileTab] = TabControl(&canvas.fileView.dataArea, + "Test File Pane"); + tabControl[choiceTab] = TabControl(&canvas.reductionChoiceView.dataArea, + "Reduction Choices Pane"); + tabControl[choiceTab].enabled = 0; + tabControl[ruleTab] = TabControl(&canvas.ruleView.dataArea, + "Rule Stack Pane"); + tabControl[stepTab] + = TabControl(&stepButton, "Single Step", actionObject(this, doStep)); + tabControl[parseTab] + = TabControl(&parseButton, "Parse File", actionObject(this, parseFile)); + tabControl[resetTab] + = TabControl(&resetButton, "Reset", actionObject(this, resetParser)); + tabControl[reloadTab] + = TabControl(&reloadButton, "Reload", actionObject(this, reload)); + tabControl[helpTab] + = TabControl(&helpButton, "File Trace", actionObject(this, showHelp)); + +#ifdef INCLUDE_LOGGING + { + for (int tab = 0; tab < nTabs; tab++) { + LOGV(tab) LCV((int) tabControl[tab].window); + } + } +#endif + setFont(canvas.stackView.dataArea.font()); + + ISize buttonSize= stepButton.minimumSize(); + IFont buttonFont = stepButton.font(); + int buttonWidth = buttonFont.textWidth(" Synch Parse "); + LOGV(buttonWidth); + buttonSize.setWidth(buttonWidth); + stepButton.setMinimumSize(buttonSize); + parseButton.setMinimumSize(buttonSize); + int buttonHeight = buttonSize.height(); + + syntaxDependent = 1; + IColor buttonTextColor = stepButton.foregroundColor(); + + ISize minimum(buttonWidth, buttonHeight); + LOGV(minimum.asString()); + + locationField.setFont(buttonFont); + + locationField.setMinimumSize( + ISize(locationField.font().textWidth("9999:999"), + minimum.height()) + ); + locationField.setBackgroundColor(IGUIColor::dialogBgnd); + locationField.setForegroundColor(buttonTextColor); + LOGV(locationField.minimumSize().asString()); + + statusField.setFont(buttonFont); + LOGV(statusField.minimumSize().asString()); + statusField.setMinimumSize( + ISize(statusField.font().textWidth("MSelect reduction tokenM"), + minimum.height()) + ); + LOGV(statusField.minimumSize().asString()); + statusField.setBackgroundColor(IGUIColor::dialogBgnd); + statusField.setForegroundColor(buttonTextColor); + + ISize margin = toolBar.margin(); + margin.setHeight(0); + toolBar.setMargin(margin); + margin = buttonGroup.margin(); + margin.setWidth(0); + margin.setHeight(margin.height()/2); + buttonGroup.setMargin(margin); + ISize pad = buttonGroup.pad(); + pad.setWidth(0); + buttonGroup.setPad(pad); + + stepButton.enableDefault(); + + LOGV(stepButton.minimumSize().asString()); + LOGV(parseButton.minimumSize().asString()); + LOGV(resetButton.minimumSize().asString()); + LOGV(reloadButton.minimumSize().asString()); + LOGV(helpButton.minimumSize().asString()); + + LOGV((int) this); + setClient(&canvas); + AgString objectTitle = AgString::format("AnaGram : %s", + simple_file_name.pointer()); + windowTitle.setObjectText(objectTitle.pointer()); + + addExtension(&toolBar, IFrameWindow::belowClient, IFrameWindow::thickLine); + canvas.fileView.desynchAction = actionObject(this, onDesynch); + canvas.fileView.resynchAction = actionObject(this, onResynch); + + windowTitle.setViewText("File Trace"); + registerTitle("File Trace"); + + canvas.stackView.setColumnTitles("\tState\tToken\tToken Name"); + ISize sizeLeft = canvas.stackView.suggestSize(); + ISize sizeRight = canvas.fileView.suggestSize(); + LOGV(sizeLeft.asString()); + LOGV(sizeRight.asString()); + int thickness = + 2*canvas.tracePanels.splitBarThickness(ISplitCanvas::splitBarEdge); + thickness += + canvas.tracePanels.splitBarThickness(ISplitCanvas::splitBarMiddle); + int width = sizeLeft.width() + sizeRight.width() + thickness; + int height = max(2*sizeLeft.height(), sizeRight.height()); + height += height/2; + + LOGV(width) LCV(height); + int maxWidth = 2*IWindow::desktopWindow()->size().width()/3; + LOGV(maxWidth); + int toolWidth = toolBar.minimumSize().width(); + if (maxWidth < toolWidth) { + maxWidth = toolWidth; + } + if (width > maxWidth) { + width = maxWidth; + } + if (width < toolWidth) { + width = toolWidth; + } + + int left = canvas.stackView.columnHeadWidth; + left += 2*font().avgCharWidth(); + int maxRight = maxWidth - left; + int right = sizeRight.width(); + LOGV(right); + LOGV(maxRight); + if (right > maxRight) right = maxRight; + int sum = left+right; + LOGV(left) LCV(right) LCV(sum); + canvas.tracePanels.setSplitWindowPercentage( + &canvas.leftPanel, (100*left)/sum); + canvas.tracePanels.setSplitWindowPercentage( + &canvas.rightPanel, (100*right)/sum); + LOGS("percentages set") LCV((100*left)/sum) LCV((100*right)/sum); + ISize clientSize(width, height); + LOGV(clientSize.asString()); + IRectangle frameRect(frameRectFor(clientSize)); + LOGV(frameRect.asString()); + sizeTo(frameRect.size()); + LOGV(frameRect.size().asString()); + + positionFrame(); + canvas.stackView + . setFrame(this) + . setEnterAction(AgAction()) + . setSelectAction(actionObject(this, stackSelect)) + ; + + canvas.fileView + . setFrame(this) + . setEnterAction(actionObject(this, fileEnter)) + ; + + canvas.ruleView + . setEnterAction(AgAction()) + . setSelectAction(actionObject(this, ruleSelect)) + . setFrame(this) + ; + + canvas.reductionChoiceView + . setEnterAction(actionObject(this, reductionChoiceEnter)) + . setSelectAction(actionObject(this, tokenSelect)) + ; + + FtParser &parser = canvas.fileView.parser; + setLocationField(canvas.fileView.parser.displayLocation()); + statusField.setText(FtParser::processStateText[parser.processState]); + + for (int i = 0; i < nTabs; i++) { + IKeyboardHandler::handleEventsFor(tabControl[i].window); + IMouseHandler::handleEventsFor(tabControl[i].window); + } + frameHandler->setActivateAction(actionObject(this, onActivate)); + AgFocusHandler::handleEventsFor(this); + LOGS("Handlers set"); + canvas.focusControl = canvas.activePanel = fileTab; + canvas.fileView.dataArea.setFocus(); + //setFocus(); + show(); + LOGS("all done"); +} + +void FileTraceWindow::onDesynch() { + LOGSECTION("FileTrace"); + ok_ptr(this); + stepButton.setText(SYNCH_PARSE); +} + +void FileTraceWindow::onResynch() { + LOGSECTION("FileTrace"); + ok_ptr(this); + stepButton.setText(SINGLE_STEP); +} + +void FileTraceWindow::onActivate() { + LOGSECTION("FileTraceWindow::onActivate"); + ok_ptr(this); + //canvas.setFocus(); +} + +FileTraceWindow::~FileTraceWindow() { + AgFocusHandler::stopHandlingEventsFor(this); + for (int i = 0; i < nTabs; i++) { + IKeyboardHandler::stopHandlingEventsFor(tabControl[i].window); + IMouseHandler::stopHandlingEventsFor(tabControl[i].window); + } +} + +Boolean FileTraceWindow::gotFocus(IEvent &event) { + LOGSECTION("FileTraceWindow::gotFocus"); + ok_ptr(this); + //int &focusControl = canvas.focusControl; + //LOGV(focusControl); + IWindowHandle handle = (void *) event.parameter1(); + //IWindow *lastWindow = IWindow::windowWithHandle(handle); + //LOGV((int) lastWindow); + LOGV((int) &canvas.stackView.dataArea); + LOGV((int) &canvas.ruleView.dataArea); + return false; +} + +AgString FileTraceWindow::copyTitle() { + ok_ptr(this); + + switch (canvas.focusControl) { + case 0: return canvas.stackView.copyTitle;; + case 2: return canvas.reductionChoiceView.copyTitle;; + case 3: return canvas.ruleView.copyTitle;; + } + return AgString(); +} + +FileTraceWindow &FileTraceWindow::copyTo(IClipboard &c) { + ok_ptr(this); + + switch (canvas.focusControl) { + case 0: canvas.stackView.copyTo(c); break; + case 2: canvas.reductionChoiceView.copyTo(c); break; + case 3: canvas.ruleView.copyTo(c); break; + } + return *this; +} + + +Boolean FileTraceWindow::windowResize(IResizeEvent &event){ + LOGSECTION("FileTraceWindow::windowResize"); + ok_ptr(this); + + if (event.controlWindow() != this) { + return false; + } + canvas.mainSplitter.sizeTo( + clientRectFor(IRectangle(IPoint(), event.newSize())).size() + ); + LOGV(id()); + return false; +} + +FileTraceWindow &FileTraceWindow::setLocationField(cint loc) { + ok_ptr(this); + char buffer[100]; + sprintf(buffer, "%d:%d", loc.y+1, loc.x+1); + locationField.setText(buffer); + return *this; +} + +FileTraceWindow &FileTraceWindow::setStatusField(const char *msg) { + ok_ptr(this); + statusField.setText(msg); + statusField.refresh(IWindow::immediate); + return *this; +} + +FileTraceWindow &FileTraceWindow::showReductionSelection() { + LOGSECTION("FileTraceWindow::showReductionSelection"); + ok_ptr(this); + FtParser &parser = canvas.fileView.parser; + canvas.reductionMenu = new FtParserReductionDc(parser); + AgDataViewPlug *connector = new AgDataViewPlug(canvas.reductionMenu); + canvas.reductionMenu->windowConnector = connector; + + canvas.reductionChoiceView.init(connector); + + LOGV(canvas.reductionMenu->columnHeadTitle.pointer()); + LOGV(connector->columnHeadTitle().pointer()); + + ISize tableSize = canvas.reductionChoiceView.suggestSize(); + + int width = 40*font().avgCharWidth(); + int testWidth = tableSize.width(); + if (testWidth < width/2) { + width = width/2; + } + else if (testWidth > 2*width) { + width = 2*width; + } + else { + width = testWidth; + } + + int rightWidth = canvas.bottomPanel.size().width(); + + int thickness = + 2*canvas.tracePanels.splitBarThickness(ISplitCanvas::splitBarEdge); + thickness += + canvas.tracePanels.splitBarThickness(ISplitCanvas::splitBarMiddle); + canvas.bottomPanel.setSplitWindowPercentage(&canvas.reductionChoiceView, + width); + canvas.bottomPanel.setSplitWindowPercentage(&canvas.ruleView, + rightWidth - width - thickness); + + canvas.bottomPanel.refresh(); + LOGV(canvas.size().asString()); + int ln = parser.reductionSelection; + canvas.reductionChoiceView + . setCursorLine(ln) + . show() + ; + parser.reductionState.token = ibnfs[ibnfb[parser.ruleToReduce]+ln]; + canvas.stackView.repaintLine(parser.stateStack.size()); + canvas.reductionChoiceView.dataArea.setFocus(); + return *this; +} + +FileTraceView &FileTraceView::completeReduction() { + LOGSECTION("FileTraceView::completeReduction"); + reductionMenu->des->d_size.y = 0; + bottomPanel.setSplitWindowPercentage(&reductionChoiceView, 0); + bottomPanel.setSplitWindowPercentage(&ruleView, 100); + bottomPanel.refresh(); + FtParser &parser = fileView.parser; + int lineNumber = reductionChoiceView.getCursorLine(); + LOGV(lineNumber); + int token = ibnfs[ibnfb[parser.ruleToReduce]+lineNumber]; + LOGV(token); + parser.completeReduction(token); + int fileIndex = (char *) parser.state.pointer - parser.text.pointer(); + fileView.reductionTable[fileIndex] = token; + LOGV(fileIndex) LCV(token) LCV(fileView.reductionTable[fileIndex]); + return *this; +} + +void FileTraceWindow::reductionChoiceEnter() { + LOGSECTION("FileTraceWindow::reductionChoiceEnter"); + ok_ptr(this); + canvas.completeReduction(); + fileEnter(); +} + +void FileTraceWindow::synchRules(unsigned stackIndex, unsigned token) { + LOGSECTION("FileTraceWindow::synchRules"); + ok_ptr(this); + FtParser &parser = canvas.fileView.parser; + unsigned stackLocation = canvas.itemStack->nt; + int sx, sn, snx; + if (stackIndex >= parser.stateStack.size()) { + sn = parser.state.number; + } + else { + sn = parser.stateStack[stackIndex].number; + } + state_number_map *sp = &map_state_number[sn]; + LOGV(stackLocation); + while (stackLocation--) { + int fn, fx; + xtxf(canvas.itemStack,stackLocation, &sx, &snx, &fn, &fx); + if (sx == stackIndex) { + break; + } + } + int k = stackLocation; + LOGV(sn); + LOGV(token); + if (stackIndex >= parser.stateStack.size()) { + int ruleViewLine = canvas.itemStack->nt - stackLocation - 1; + do { + int fn, fx; + xtxf(canvas.itemStack, k, &sx, &snx, &fn, &fx); + if (fx < Rule(fn)->length() + && token == Rule(fn).token(fx)) + //&& token == lstptr(map_form_number[fn],tokens)[fx]) + { + k = canvas.itemStack->nt - k - 1; + canvas.ruleView.setCursorLine(k).synchCursor(k); + ruleViewLine = k; + return; + } + unsigned *p = lstptr(*sp,reductions); + unsigned n = sp->n_reductions; + while (n--) { + unsigned tn = *p++; + unsigned rule = *p++; + if (rule == fn && tn == token) { + k = canvas.itemStack->nt - k - 1; + canvas.ruleView.setCursorLine(k).synchCursor(k); + ruleViewLine = k; + return; + } + } + k--; + } while (k >= 0 && sx == stackIndex); + canvas.ruleView.setCursorLine(ruleViewLine).synchCursor(ruleViewLine); + return; + } + int nextState; + if (stackIndex + 1 >= parser.stateStack.size()) { + nextState = parser.state.number; + } + else { + nextState = parser.stateStack[stackIndex+1].number; + } + int charToken = map_state_number[nextState].char_token; + LOGV(nextState) LCV(charToken); + do { + int fn,fx; + xtxf(canvas.itemStack, k, &sx, &snx, &fn, &fx); + int length = Rule(fn)->length(); + LOGV(k) LCV(snx); + LOGV(fn) LCV(fx) LCV(length); + if (fx < length + && charToken == Rule(fn).token(fx)) { + //&& charToken == lstptr(map_form_number[fn],tokens)[fx]) { + k = canvas.itemStack->nt - k - 1; + canvas.ruleView.setCursorLine(k).synchCursor(k); + return; + } + k--; + LOGV(k); + LOGV(sn) LCV(snx); + } while (k >= 0 && sx == stackIndex); +} + +void FileTraceWindow::ruleSelect() { + LOGSECTION("FileTraceWindow::ruleSelect"); + ok_ptr(this); + FtParser &parser = canvas.fileView.parser; + int ruleLine = canvas.ruleView.getCursorLine(); + + int k = canvas.itemStack->nt - ruleLine - 1; + LOGV(k); + int sx, sn, fn, fx; + xtxf(canvas.itemStack, k, &sx, &sn, &fn, &fx); + int length = Rule(fn)->length(); + LOGV(fn); + LOGV(fx); + LOGV(length); + int stackDepth = parser.stateStack.size(); + int stackLevel = sx; + LOGV(stackLevel) LCV(stackDepth); + if (stackLevel == stackDepth && + parser.processState == FtParser::selectionRequired) { + if (fx >= length) { + return; + } + //int tn = lstptr(map_form_number[fn],tokens)[fx]; + int tn = Rule(fn).token(fx); + LOGV(tn); + int n = ibnfn[parser.ruleToReduce]; + while (n--) { + LOGV(n); + LOGV(ibnfs[ibnfb[parser.ruleToReduce]+n]); + if (ibnfs[ibnfb[parser.ruleToReduce]+n] == tn) { + break; + } + } + LOGV(fn) LCV(n) LCV(tn); + canvas.reductionChoiceView.setCursorLine(n); + parser.reductionState.token = tn; + canvas.stackView.repaintLine(stackDepth); + return; + } + canvas.stackView.setCursorLine(stackLevel); + //canvas.fileView.turnHighlightOn(stackLevel); + if (parser.processState != FtParser::finished) { + canvas.fileView.turnHighlightOn(stackLevel); + } +} + +void FileTraceWindow::stackSelect() { + LOGSECTION("FileTraceWindow::stackSelect"); + ok_ptr(this); + int ln = canvas.stackView.getCursorLine(); + LOGV(ln); + FtParser &parser = canvas.fileView.parser; + if (parser.processState != FtParser::finished) { + canvas.fileView.turnHighlightOn(ln); + } + //int sn = parser.state.number; + int tn = parser.state.token; + if (ln < parser.stateStack.size()) { + tn = parser.stateStack[ln].token; + } + synchRules(ln, tn); +} + +void FileTraceWindow::tokenSelect() { + LOGSECTION("FileTraceWindow::tokenSelect"); + ok_ptr(this); + int ln = canvas.reductionChoiceView.getCursorLine(); + LOGV(ln); + FtParser &parser = canvas.fileView.parser; + parser.reductionSelection = ln; + int flag = parser.validSelection(ln, parser.reductionState.number); + parser.processState = + flag ? FtParser::selectionRequired : FtParser::selectionError; + statusField.setText(FtParser::processStateText[parser.processState]); + parser.reductionState.token = ibnfs[ibnfb[parser.ruleToReduce]+ln]; + canvas.stackView.repaintLine(parser.stateStack.size()); +} + +void FileTraceWindow::fileEnter() { + LOGSECTION("FileTraceWindow::fileEnter"); + ok_ptr(this); + LOGV(canvas.focusControl) LCV(canvas.fileView.dataArea.hasFocus()); + LOGV(canvas.fileView.cursorHideCount); + if (stepButton.text() != SINGLE_STEP) { + stepButton.setText(SINGLE_STEP); + } + FtParser &parser = canvas.fileView.parser; + LOGV(parser.location()); + unsigned stackDepth = parser.stateStack.size(); + //parser.displayControl->des->d_size.y = stackDepth+1; + canvas.parserDc->des->d_size.y = stackDepth+1; + LOGV(stackDepth); + LOGV(parser.processState); + + if (parser.processState > FtParser::running) { + messageBeep(); + } + + int stackCursor = stackDepth; + canvas.focusControl = canvas.activePanel = fileTab; + if (parser.processState == FtParser::selectionRequired) { + canvas.fileView.turnHighlightOn(stackCursor); + + int k = parser.stateStack.size() - parser.reductionIndex; + LOGV(k); + assert((unsigned) k <= (unsigned) parser.stateStack.size()); + parser.stateStack.discardData(k); + unsigned stackDepth = parser.stateStack.size(); + //parser.displayControl->des->d_size.y = stackDepth+1; + canvas.parserDc->des->d_size.y = stackDepth+1; + + showReductionSelection(); + stackCursor = parser.reductionIndex; + canvas.reductionChoiceView.dataArea.setFocus(); + canvas.focusControl = canvas.activePanel = choiceTab; + tabControl[choiceTab].enabled = 1; + } + else if (parser.ruleToReduce) { + parser.ruleToReduce = 0; + canvas.reductionMenu->des->d_size.y = 0; + canvas.bottomPanel.setSplitWindowPercentage(&canvas.reductionChoiceView,0); + canvas.bottomPanel.setSplitWindowPercentage(&canvas.ruleView, 100); + canvas.bottomPanel.refresh(); + statusField.setText(FtParser::processStateText[parser.processState]); + canvas.fileView.turnHighlightOff(); + canvas.fileView.dataArea.setFocus(); + tabControl[choiceTab].enabled = 0; + } + + LOGV(canvas.focusControl) LCV(canvas.fileView.dataArea.hasFocus()); + canvas.stackView.reset(); + LOGV(canvas.focusControl) LCV(canvas.fileView.dataArea.hasFocus()); + LOGV(canvas.fileView.cursorHideCount); + canvas.stackView.setCursorLine(stackCursor); + LOGV(canvas.focusControl) LCV(canvas.fileView.dataArea.hasFocus()); + LOGV(canvas.fileView.cursorHideCount); + canvas.stackView. refresh(); + LOGV(canvas.focusControl) LCV(canvas.fileView.dataArea.hasFocus()); + LOGV(canvas.fileView.cursorHideCount); + + LOGV(parser.location()); + canvas.refreshRules(parser.ruleToReduce); + LOGV(canvas.focusControl) LCV(canvas.fileView.dataArea.hasFocus()); + LOGV(canvas.fileView.cursorHideCount); + LOGV(parser.location()); + + setLocationField(canvas.fileView.parser.displayLocation()); + LOGV(canvas.focusControl) LCV(canvas.fileView.dataArea.hasFocus()); + LOGV(canvas.fileView.cursorHideCount); + setStatusField(FtParser::processStateText[parser.processState]); + LOGV(canvas.focusControl) LCV(canvas.fileView.dataArea.hasFocus()); + LOGV(canvas.fileView.cursorHideCount); + //canvas.fileView.dataArea.setFocus(); + //canvas.focusControl = 1; + setFocus(); + LOGV(canvas.focusControl) LCV(canvas.fileView.dataArea.hasFocus()); + LOGV(canvas.fileView.cursorHideCount); + + AgFrame::windowRegistry.refresh("Trace Coverage"); + stepButton.enableDefault(); + setMousePointer(IPointerHandle()); +} + +void FileTraceWindow::reload() { + ok_ptr(this); + canvas.fileView.reductionTable.reset(); + canvas.fileView.reload(); + canvas.fileView.refresh(); + resetParser(); +} + +void FileTraceWindow::showHelp() { + ok_ptr(this); + AgHelpWindow::showHelp("File Trace"); + helpButton.disableDefault(); + helpButton.unhighlight(); + stepButton.enableDefault(); + canvas.focusControl = FileTraceWindow::fileTab; +} + + + +void FileTraceWindow::resetParser() { + ok_ptr(this); + FtParser &parser = canvas.fileView.parser; + if (parser.ruleToReduce) { + parser.ruleToReduce = 0; + canvas.reductionMenu->des->d_size.y = 0; + canvas.bottomPanel.setSplitWindowPercentage(&canvas.reductionChoiceView,0); + canvas.bottomPanel.setSplitWindowPercentage(&canvas.ruleView, 100); + canvas.bottomPanel.refresh(); + } + parser.reset(); + onResynch(); + setLocationField(canvas.fileView.parser.displayLocation()); + LOGV(parser.state.number) LCV(parser.state.token); + //parser.displayControl->des->d_size.y = parser.stateStack.size() + 1; + canvas.parserDc->des->d_size.y = parser.stateStack.size() + 1; + canvas.refreshRules(0); + synchRules(parser.stateStack.size(), parser.state.token); + statusField.setText(FtParser::processStateText[parser.processState]); + canvas.stackView.reset().setCursorLine(0).refresh(); + canvas.fileView.turnHighlightOff(); + canvas.fileView.setCursorLocation(cint(0,0)); + canvas.fileView.refresh(); + canvas.fileView.dataArea.setFocus(); + canvas.focusControl = canvas.activePanel = fileTab; + tabControl[choiceTab].enabled = 0; + stepButton.unhighlight(); + stepButton.enableDefault(); +} + +Boolean FileTraceWindow::findNext(AgString s) { + LOGSECTION("FileTraceWindow::findNext"); + ok_ptr(this); + LOGV(canvas.focusControl); + int flag = 0; + + switch (canvas.focusControl) { + case 0: { + flag = canvas.stackView.findNext(s); + if (flag) { + stackSelect(); + } + return flag; + } + case 1: { + flag = canvas.fileView.findNext(s); + return flag; + } + case 2: { + flag = canvas.reductionChoiceView.findNext(s); + if (flag) { + tokenSelect(); + } + return flag; + } + case 3: { + flag = canvas.ruleView.findNext(s); + if (flag) { + ruleSelect(); + } + return flag; + } + } + + return flag; +} + +Boolean FileTraceWindow::findPrev(AgString s) { + LOGSECTION("FileTraceWindow::findPrev"); + ok_ptr(this); + LOGV(canvas.focusControl); + int flag = 0; + + switch (canvas.focusControl) { + case 0: { + flag = canvas.stackView.findPrev(s); + if (flag) { + stackSelect(); + } + return flag; + } + case 1: + return canvas.fileView.findPrev(s); + case 2: { + flag = canvas.reductionChoiceView.findPrev(s); + if (flag) { + tokenSelect(); + } + return flag; + } + case 3: { + flag = canvas.ruleView.findPrev(s); + if (flag) { + ruleSelect(); + } + return flag; + } + } + return flag; +} + + +void FileTraceWindow::doStep() { + LOGSECTION("FileTraceWindow::doStep"); + ok_ptr(this); + FtParser &parser = canvas.fileView.parser; + LOGV(parser.processState); + canvas.focusControl = canvas.activePanel = fileTab; + if (parser.processState == FtParser::selectionRequired && + parser.location() == canvas.fileView.cursorLocation) { + reductionChoiceEnter(); + } + else { + canvas.fileView.step(); + } + setLocationField(parser.displayLocation()); + statusField.setText(FtParser::processStateText[parser.processState]); + stepButton.unhighlight(); + stepButton.enableDefault(); + setFocus(); + LOGV(parser.processState); +} + +void FileTraceWindow::parseFile() { + LOGSECTION("FileTraceWindow::parseFile"); + ok_ptr(this); + FtParser &parser = canvas.fileView.parser; + LOGV(parser.processState); + if (parser.processState == FtParser::selectionRequired) { + reductionChoiceEnter(); + } + if (parser.processState > FtParser::running) { + messageBeep(); + canvas.focusControl = canvas.activePanel = fileTab; + parseButton.disableDefault(); + parseButton.unhighlight(); + setFocus(); + return; + } + while (parser.processState <= FtParser::running) { + canvas.fileView.parse(); + if (parser.processState != FtParser::selectionRequired) { + continue; + } + int fileIndex = (char *) parser.state.pointer - parser.text.pointer(); + int tn = canvas.fileView.reductionTable[fileIndex]; + LOGV(fileIndex) LCV(tn); + if (tn == 0) { + continue; + } + parser.completeReduction(tn); + } + setLocationField(parser.displayLocation()); + statusField.setText(FtParser::processStateText[parser.processState]); + LOGV(parser.processState); + parseButton.unhighlight(); + parseButton.disableDefault(); +}