Mercurial > ~dholland > hg > ag > index.cgi
diff anagram/vaclgui/gtview.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/gtview.cpp Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,2176 @@ +/* + * AnaGram, A System for Syntax Directed Programming + * Copyright 1997-2002 Parsifal Software. All Rights Reserved. + * See the file COPYING for license and usage terms. + * + * gtview.cpp + */ + +//#include <commctrl.h> +//#include <imsgbox.hpp> +#include <windows.h> + +#include "agstring.h" +#include "arrays.h" +#include "ctrlpanel.hpp" +#include "data.h" +#include "dc.h" +#include "dspar.hpp" +#include "dvplug.hpp" +#include "gtview.hpp" +#include "helpview.hpp" +#include "minmax.h" +#include "myalloc.h" +#include "p.h" +#include "rule.h" +#include "tracedc.h" +#include "vaclgui-res.h" +#include "vaclgui.hpp" + +//#define INCLUDE_LOGGING +#include "log.h" + + +#define RESET "&Reset" +#define HELP "&Help" +#define PROCEED "&Proceed" +#define SINGLE_STEP "&Single step" + +//static char *buttonLabel[] = { +// RESET, HELP, PROCEED, SINGLE_STEP +//}; + +GTView::GTView(GTWindow *owner_, DcRef<FtParserDc> parserDc_) + : ICanvas(nextChildId(), owner_, owner_, IRectangle(), + ICanvas::classDefaultStyle | IWindow::clipChildren) + , parserDc(parserDc_) + , parser(parserDc->parser) + , stackViewData(new AgDataViewPlug(parserDc)) + , mainSplitter(nextChildId(), this, this, + IRectangle(), ISplitCanvas::horizontal | IWindow::visible) + , tracePanels(nextChildId(), &mainSplitter, &mainSplitter) + , leftPanel(nextChildId(), &tracePanels, &tracePanels) + , stackView(&leftPanel) + , stackTitle(nextChildId(), &leftPanel, &leftPanel) + , rightPanel(nextChildId(), &tracePanels, &tracePanels) + , tokenListView(&rightPanel) + , tokenListTitle(nextChildId(), &rightPanel, &rightPanel) + , bottomPanel(nextChildId(), &mainSplitter, &mainSplitter, + IRectangle(), ISplitCanvas::vertical | visible) + , reductionChoiceView(&bottomPanel) + , ruleView(&bottomPanel) + , focusControl(GTWindow::tokenTab) + , activePanel(GTWindow::tokenTab) + , frame(owner_) + , dataColorChange(this, onColorChange) + , fontChange(this, onFontChange) + , leftButtonState(buttonIdle) + , itemStack(parser.x1x_new()) +{ + LOGSECTION("GTView::GTView"); + LOGV(id()); + + LOGV((int) &stackView); + LOGV((int) &stackView.dataArea); + LOGV((int) &tokenListView); + LOGV((int) &tokenListView.dataArea); + + setFont(tokenListView.dataArea.font()); + + dataColorChange.attach(&ColorSpec::inactiveCursor); + dataColorChange.attach(&ColorSpec::activeCursor); + fontChange.attach(&FontSpec::columnHead); + + ruleView.setEnterAction(AgAction()); + stackView.helpTopic = "Token Stack"; + tokenListView.helpTopic = "Allowable Input"; + tokenListView.copyTitle = "Grammar Trace: Allowable Input"; + ruleView.copyTitle = "Grammar Trace: Rule Stack"; + reductionChoiceView.copyTitle = "Grammar Trace: Reduction Choices"; + stackView.copyTitle = "Grammar Trace: Parser Stack"; + + stackView.init(stackViewData); + parserDc->windowConnector = stackViewData; + + reductionMenu = new FtParserReductionDc(parser); + AgDataViewPlug *connector = new AgDataViewPlug(reductionMenu); + reductionMenu->windowConnector = connector; + reductionChoiceView.init(connector); + + bottomPanel.setSplitWindowPercentage(&reductionChoiceView, 0); + bottomPanel.setSplitWindowPercentage(&ruleView, 100); + + stackTitle + . setText("Parser Stack") + . setAlignment(IStaticText::centerCenter) + . setBackgroundColor(ColorSpec::inactiveTitle.bg()) + . setForegroundColor(ColorSpec::inactiveTitle.fg()) + ; + AgString tokenTitle = + AgString::format("Allowable input - State %d", parser.state.number); + tokenListTitle + . setText(tokenTitle.pointer()) + . setAlignment(IStaticText::centerCenter) + . setBackgroundColor(ColorSpec::inactiveTitle.bg()) + . setForegroundColor(ColorSpec::inactiveTitle.fg()) + ; + LOGS("titles set up"); + int width = stackTitle.minimumSize().width(); + int height = font().externalLeading() + font().maxSize().height(); + ISize minSize(width, 5*height); + + leftPanel + . addToCell(&stackView, 1,1) + . addToCell(&stackTitle, 1,2) + . setColumnWidth(1,width,true) + . setRowHeight(1,0,true) + . setMinimumSize(minSize) + ; + width = tokenListTitle.minimumSize().width(); + minSize= ISize(width, 5*height); + rightPanel + . addToCell(&tokenListView, 1,1) + . addToCell(&tokenListTitle,1,2) + . setColumnWidth(1,width,true) + . setRowHeight(1,0,true) + . setMinimumSize(minSize) + ; + + //dc_ref ruleWindow = parserDc->rule_stack(parser.stateStack.size()); + itemStack = parser.x1x_new(); + //dc_ref ruleWindow = new rule_stack_dc(itemStack, parser.stateStack.size(), + // parserDc->head_title); + ruleControl = new rule_stack_dc(itemStack,parser.stateStack.size(), + parserDc->head_title); + //parser.ruleControl = ruleWindow; + //ruleConnector = new AgDataViewPlug(ruleWindow); + ruleConnector = new AgDataViewPlug(ruleControl); + //ruleWindow->windowConnector = ruleConnector; + ruleControl->windowConnector = ruleConnector; + ruleView.init(ruleConnector); + + mainSplitter.setSplitWindowPercentage(&tracePanels, 55); + mainSplitter.setSplitWindowPercentage(&bottomPanel, 45); + tracePanels.setSplitWindowPercentage(&leftPanel, 25); + tracePanels.setSplitWindowPercentage(&rightPanel, 75); + + AgFocusHandler::handleEventsFor(&stackView.dataArea); + IMouseHandler::handleEventsFor(&stackTitle); + AgFocusHandler::handleEventsFor(&tokenListView.dataArea); + IMouseHandler::handleEventsFor(&tokenListTitle); + AgFocusHandler::handleEventsFor(&reductionChoiceView.dataArea); + AgFocusHandler::handleEventsFor(&ruleView.dataArea); + //AgFocusHandler::handleEventsFor(&frame->comboBox); + //AgFocusHandler::handleEventsFor(&frame->containerBar); + IFocusHandler::handleEventsFor(&frame->comboBox); + //IFocusHandler::handleEventsFor(&frame->containerBar); + IPaintHandler::handleEventsFor(this); + LOGS("all done"); +} + +GTView::~GTView() { + AgFocusHandler::stopHandlingEventsFor(&stackView.dataArea); + IMouseHandler::stopHandlingEventsFor(&stackTitle); + AgFocusHandler::stopHandlingEventsFor(&tokenListView.dataArea); + IMouseHandler::stopHandlingEventsFor(&tokenListTitle); + AgFocusHandler::stopHandlingEventsFor(&reductionChoiceView.dataArea); + AgFocusHandler::stopHandlingEventsFor(&ruleView.dataArea); + //AgFocusHandler::stopHandlingEventsFor(&frame->comboBox); + //AgFocusHandler::stopHandlingEventsFor(&frame->containerBar); + IFocusHandler::stopHandlingEventsFor(&frame->comboBox); + //IFocusHandler::stopHandlingEventsFor(&frame->containerBar); + IPaintHandler::stopHandlingEventsFor(this); +} + + +Boolean GTView::paintWindow(IPaintEvent &event) { + LOGSECTION("GTView::paintWindow"); + LOGV(event.rect().asString()); + event.clearBackground(IGUIColor::dialogBgnd); + return false; +} + +GTView >View::refreshRules(int rule) { + LOGSECTION("GTView::refreshRules"); + LOGV(rule); + 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(); + LOGV(itemStack->nt); + LOGV(parser.stateStack.size()); + //parser.ruleControl->des->d_size.y = k; + ruleControl->des->d_size.y = k; + //ruleWindow->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(); + frame->ruleViewLine = k; + return *this; +} + +Boolean GTView::mouseClicked(IMouseClickEvent &event) { + LOGSECTION("GTView::mouseClicked"); + if (event.mouseAction() != IMouseClickEvent::down) { + return false; + } + if (event.controlWindow() == &tokenListTitle) { + LOGS("tokenList should get focus"); + if (!tokenListView.dataArea.hasFocus()) { + tokenListView.dataArea.setFocus(); + } + return false; + } + else if (event.controlWindow() == &stackTitle) { + LOGS("stackView should get focus"); + if (!stackView.dataArea.hasFocus()) { + stackView.dataArea.setFocus(); + } + return false; + } + return false; +} + + +Boolean GTView::gotFocus(IControlEvent &event) { + LOGSECTION("GTView::gotFocus(c)"); + return gotFocus((IEvent &)event); +} + +Boolean GTView::gotFocus(IEvent &event) { + LOGSECTION("GTView::gotFocus"); + LOGV(ruleView.windowId); + if (event.controlWindow() == 0) { + return false; + } +#ifdef INCLUDE_LOGGING + IWindowHandle handle = (void *) event.parameter1(); + IWindow *lastWindow; + do { + lastWindow = IWindow::windowWithHandle(handle); + LOGV((int) lastWindow); + handle = GetParent(handle); + } while (lastWindow == 0 && handle != 0); + LOGV((int) event.controlWindow()) LCV((int)event.dispatchingWindow()); +#endif + if (event.controlWindow() == &stackView.dataArea) { + stackTitle.setBackgroundColor(ColorSpec::activeTitle.bg()); + stackTitle.setForegroundColor(ColorSpec::activeTitle.fg()); + stackTitle.refresh(); + focusControl = activePanel = GTWindow::stackTab; + } + else if (event.controlWindow() == &tokenListView.dataArea) { + tokenListTitle.setBackgroundColor(ColorSpec::activeTitle.bg()); + tokenListTitle.setForegroundColor(ColorSpec::activeTitle.fg()); + tokenListTitle.refresh(); + focusControl = GTWindow::tokenTab; + } + else if (event.controlWindow() == &reductionChoiceView.dataArea) { + focusControl = activePanel = GTWindow::choiceTab; + } + else if (event.controlWindow() == &ruleView.dataArea) { + focusControl = activePanel = GTWindow::ruleTab; + } + else if (event.controlWindow() == &frame->comboBox) { + focusControl = activePanel = GTWindow::comboTab; + } + else if (event.controlWindow() == &frame->containerBar) { + focusControl = activePanel = GTWindow::comboTab; + } + else if (event.dispatchingWindow() == &frame->comboBox) { + focusControl = activePanel = GTWindow::comboTab; + } + else if (event.dispatchingWindow() == &frame->containerBar) { + focusControl = activePanel = GTWindow::comboTab; + } + else { + return false; + } + + // Can't field mouse clicks reliably on combobox, so we show + // help using gotFocus(). + LOGV(leftButtonState); + if (focusControl == GTWindow::comboTab + && leftButtonState == buttonIdle + && ControlPanel::helpCursorSet) { + //ControlPanel::helpCursorSet = 0; + //AgHelpWindow::showHelp("Text Entry"); + //ControlPanel::resetCursor(); + followUpPending = 1; + defer(this, followUpFocusMsg); + return true; + } + + + frame->stepButton.disableDefault(); + frame->resetButton.disableDefault(); + frame->helpButton.disableDefault(); + frame->proceedButton.enableDefault(); + LOGV(ruleView.windowId); + LOGV(focusControl); + return false; +} + +void GTView::followUpFocusMsg() { + if (!followUpPending) { + return; + } + ControlPanel::helpCursorSet = 0; + AgHelpWindow::showHelp("Text Entry"); + ControlPanel::resetCursor(); + followUpPending = 0; +} + +Boolean GTView::lostFocus(IControlEvent &event) { + LOGSECTION("GTView::lostFocus(c)"); + return lostFocus((IEvent &) event); +} + +Boolean GTView::lostFocus(IEvent &event) { + LOGSECTION("GTView::lostFocus"); + LOGV(focusControl); +#ifdef INCLUDE_LOGGING + IWindowHandle handle = (void *) event.parameter1(); + IWindow *nextWindow; + do { + nextWindow = IWindow::windowWithHandle(handle); + LOGV((int) nextWindow); + handle = GetParent(handle); + } while (nextWindow == 0 && handle != 0); + + LOGV((int) nextWindow); + LOGV((int) event.controlWindow()) LCV((int)event.dispatchingWindow()); +#endif + if (event.controlWindow() == &stackView.dataArea) { + stackTitle.setBackgroundColor(ColorSpec::inactiveTitle.bg()); + stackTitle.setForegroundColor(ColorSpec::inactiveTitle.fg()); + stackTitle.refresh(); + } + if (event.controlWindow() == &tokenListView.dataArea) { + tokenListTitle.setBackgroundColor(ColorSpec::inactiveTitle.bg()); + tokenListTitle.setForegroundColor(ColorSpec::inactiveTitle.fg()); + tokenListTitle.refresh(); + } + LOGV(focusControl); + return false; +} + + +Boolean GTWindow::virtualKeyPress(IKeyboardEvent &event) { + LOGSECTION("GTWindow::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 >= proceedTab) { + tabControl[focusControl].action.performDeferred(); + IPushButton *button = (IPushButton *)tabControl[focusControl].window; + button->disableDefault(); + button->unhighlight(); + } + else { + activePanel = focusControl; + proceed(); + } + return true; + } + case IKeyboardEvent::right: + case IKeyboardEvent::down: + if (focusControl < proceedTab) { + return AgFrame::virtualKeyPress(event); + } + if (focusControl + 1 == nTabs) { + increment = proceedTab - focusControl; + } + else { + increment = 1; + } + break; + case IKeyboardEvent::tab: + increment = 1; + break; + case IKeyboardEvent::left: + case IKeyboardEvent::up: + if (focusControl < proceedTab) { + return AgFrame::virtualKeyPress(event); + } + if (focusControl == proceedTab) { + increment = nTabs - 1 - proceedTab; + } + 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 >= proceedTab) { + button = (IPushButton *) tabControl[focusControl].window; + button->unhighlight(); + button->disableDefault(); + } + do { + focusControl = (focusControl + increment) % nTabs; + } while (!tabControl[focusControl].enabled); + LOGV(focusControl) LCV(increment); + if (focusControl >= proceedTab) { + button = (IPushButton *) tabControl[focusControl].window; + } + else { + button = &proceedButton; + } + button->enableDefault(); + setFocus(); + return true; +} + +Boolean GTWindow::mouseClicked(IMouseClickEvent &event) { + LOGSECTION("GTWindow::mouseClicked"); + GTView::ButtonState &lbs = canvas.leftButtonState; + ok_ptr(this); + LOGV(event.mouseButton()) LCV(event.mouseAction()); + if (event.mouseButton() != 0) { + return false; + } + LOGV(lbs); + if (event.mouseAction() == IMouseClickEvent::down) { + lbs = GTView::buttonDown; + } + else if (event.mouseAction() == IMouseClickEvent::up) { + lbs = GTView::waitingForClick; + } + else if (event.mouseAction() == IMouseClickEvent::click) { + lbs = GTView::buttonIdle; + } + LOGV(lbs); + int &focusControl = canvas.focusControl; + int &activePanel = canvas.activePanel; + LOGV(focusControl) LCV(activePanel); + IWindow *controlWindow = event.controlWindow(); + LOGV((int)controlWindow) LCV((int)event.dispatchingWindow()); + if (event.controlWindow() == &statusField) { + 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; + } + + LOGV(ControlPanel::helpCursorSet); + if (ControlPanel::helpCursorSet) { + if (event.mouseAction() == IMouseClickEvent::up) { + ControlPanel::helpCursorSet = 0; + canvas.followUpPending = 0; + LOGV(tabControl[tab].helpTopic); + AgHelpWindow::showHelp(tabControl[tab].helpTopic); + ControlPanel::resetCursor(); + } + return true; + } + LOGV(focusControl) LCV(activePanel); + if (tab < proceedTab) { + return false; + } + if (focusControl >= proceedTab) { + IPushButton *button = (IPushButton *) tabControl[focusControl].window; + button->unhighlight(); + button->disableDefault(); + } + IPushButton *button = (IPushButton *) tabControl[tab].window; + if (event.mouseAction() == IMouseClickEvent::down) { + if (focusControl < proceedTab) 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 < proceedTab) { + button->disableDefault(); + proceedButton.enableDefault(); + focusControl = activePanel; + setFocus(); + } + else { + button->disableDefault(); + proceedButton.enableDefault(); + focusControl = proceedTab; + setFocus(); + } + } + return true; +} + +Boolean GTWindow::characterKeyPress(IKeyboardEvent &event) { + LOGSECTION("GTWindow::characterKeyPress"); + ok_ptr(this); + if (event.isCtrlDown()) { + return true; + } + if (canvas.focusControl < proceedTab) { + canvas.activePanel = canvas.focusControl; + } + char character = event.character(); + switch (character) { + case 'p': + case 'P': + proceed(); + return true; + case 's': + case 'S': + doStep(); + return true; + case 'r': + case 'R': + resetParser(); + return true; + case 'h': + case 'H': + AgHelpWindow::showHelp("Grammar Trace"); + helpButton.disableDefault(); + helpButton.unhighlight(); + stepButton.enableDefault(); + //canvas.focusControl = tokenTab; + if (comboBox.text().length()) { + canvas.focusControl = comboTab; + } + else { + canvas.focusControl = tokenTab; + } + return true; + } + return false; +} + +GTWindow >Window::setFocus() { + LOGSECTION("GTWindow::setFocus"); + //int protectHelp = ControlPanel::helpCursorSet; + //ControlPanel::helpCursorSet = 0; + ok_ptr(this); + int &focusControl = canvas.focusControl; + if (focusControl < proceedTab) { + canvas.activePanel = focusControl; + } + LOGV(focusControl); + LOGV(canvas.ruleView.windowId); + assert(focusControl >= 0 && focusControl < nTabs); + LOGV(canvas.ruleView.windowId); + tabControl[focusControl].window->setFocus(); + LOGV(canvas.ruleView.windowId); + IPushButton *button; + for (int i = proceedTab; i < nTabs; i++) { + button = (IPushButton *)tabControl[i].window; + LOGV((int) button); + button->disableDefault(); + button->unhighlight(); + } + LOGV(canvas.ruleView.windowId); + if (focusControl >= proceedTab) { + button = (IPushButton *)tabControl[focusControl].window; + } + else { + button = &proceedButton; + } + LOGV(canvas.ruleView.windowId); + LOGV((int) button); + button->enableDefault(); + LOGV(canvas.ruleView.windowId); + //ControlPanel::helpCursorSet = protectHelp; + LOGS("all done"); + return *this; +} + +void GTWindow::init() { + LOGSECTION("GTWindow::init"); + ok_ptr(this); + tabControl[stackTab] = TabControl(&canvas.stackView.dataArea, + "Parser Stack Pane"); + tabControl[tokenTab] = TabControl(&canvas.tokenListView.dataArea, + "Allowable Input Pane"); + tabControl[choiceTab] = TabControl(&canvas.reductionChoiceView.dataArea, + "Reduction Choices Pane"); + tabControl[choiceTab].enabled = 0; + tabControl[ruleTab] = TabControl(&canvas.ruleView.dataArea, + "Rule Stack Pane"); + tabControl[comboTab] + = TabControl(&comboBox, "Text Entry Field", + actionObject(this, comboBoxEnter)); + tabControl[proceedTab] + = TabControl(&proceedButton, "Proceed", actionObject(this, proceed)); + tabControl[stepTab] + = TabControl(&stepButton, "Single Step", actionObject(this, doStep)); + tabControl[resetTab] + = TabControl(&resetButton, "Reset", actionObject(this, resetParser)); + tabControl[helpTab] + = TabControl(&helpButton, "Grammar Trace", actionObject(this, showHelp)); +/* + LOGV((int) &comboBox) LCV((int) &containerBar); + new ControlHelpDemon(&containerBar, "Container Bar"); + new ControlHelpDemon(&toolBar, "Tool Bar"); +*/ + //parser.displayControl = parserDc; + setClient(&canvas); + addExtension(&toolBar, IFrameWindow::belowClient, IFrameWindow::thickLine); + + IFont buttonFont = stepButton.font(); + int buttonWidth = buttonFont.textWidth(" Synch Parse "); + LOGV(buttonWidth); + IColor buttonTextColor = resetButton.foregroundColor(); + + ISize minimum = stepButton.minimumSize(); + minimum.setWidth(buttonWidth); + stepButton.setMinimumSize(minimum); + statusField.setFont(buttonFont); + LOGV(statusField.font().name()); + int statusFieldWidth = buttonFont.textWidth("MSelect reduction tokenM"); + statusField.setMinimumSize(ISize(statusFieldWidth,minimum.height())); + LOGV(statusField.minimumSize().asString()); + statusField.setBackgroundColor(IGUIColor::dialogBgnd); + statusField.setForegroundColor(buttonTextColor); + + ISize margin = toolBar.margin(); + margin.setHeight(0); + toolBar.setMargin(margin); + containerBar.setMargin(ISize()); + margin = buttonGroup.margin(); + margin.setWidth(0); + margin.setHeight(margin.height()/2); + buttonGroup.setMargin(margin); + ISize pad = buttonGroup.pad(); + pad.setWidth(0); + buttonGroup.setPad(pad); + + proceedButton.enableDefault(); + + LOGV(proceedButton.minimumSize().asString()); + LOGV(stepButton.minimumSize().asString()); + LOGV(resetButton.minimumSize().asString()); + LOGV(helpButton.minimumSize().asString()); + + int minWidth = toolBar.minimumSize().width(); + LOGV(parser.stateStack.size()); + tokenList = parserDc->tokenMenu(parser.stateStack.size()); + LOGV((int) (dc *)tokenList); + tokenList->windowConnector = new AgDataViewPlug(tokenList); + LOGV((int)tokenList->windowConnector); + + canvas.tokenListView + . init(tokenList->windowConnector->windowData()) + . adjustMaxWidth("Token0\tAction\tToken Name") + . setColumnTitles("Token\tAction\tToken Name") + ; + canvas.stackView + . adjustMaxWidth(" 1\tState:\tToken0\tToken Name") + . setColumnTitles("\tState\tToken\tToken Name") + ; + int loopControl = 2; + ISize sizeLeft; + ISize sizeRight; + while (loopControl--) { + int desktopWidth = IWindow::desktopWindow()->size().width(); + sizeLeft = canvas.stackView.suggestSize(); + if (sizeLeft.width() > desktopWidth/6) { + sizeLeft.setWidth(desktopWidth/3); + } + sizeRight = canvas.tokenListView.suggestSize(); + if (sizeRight.width() > desktopWidth/2) { + sizeRight.setWidth(desktopWidth/2); + } + int thickness = + 2*canvas.tracePanels.splitBarThickness(ISplitCanvas::splitBarEdge); + LOGV(canvas.tracePanels.splitBarThickness(ISplitCanvas::splitBarEdge)); + LOGV(canvas.tracePanels.splitBarThickness(ISplitCanvas::splitBarMiddle)); + LOGV(borderWidth()); + thickness += + canvas.tracePanels.splitBarThickness(ISplitCanvas::splitBarMiddle); + thickness += 2*borderWidth(); + int width = sizeLeft.width() + sizeRight.width() + thickness; + int height = max(6*sizeLeft.height(), sizeRight.height()); + LOGV(height); + height = + min(height, + 3*AgDataView::defaultWindowHeight*canvas.stackView.lineHeight()/2); + height += 2*canvas.stackView.columnHeadTitle.size().height(); + height += canvas.stackTitle.minimumSize().height(); + LOGV(height); + if (width < minWidth) { + width = minWidth; + } + if (width > (2*desktopWidth)/3) { + width = (2*desktopWidth)/3; + } + int toolbarWidth = toolBar.minimumSize().width(); + if (width < toolbarWidth) { + width = toolbarWidth; + } + ISize clientSize(width, height); + LOGV(clientSize.asString()); + IRectangle frameRect(frameRectFor(clientSize)); + ISize frameSize = frameRect.size(); + LOGV(frameSize.asString()); + ISize resultant = clientRectFor(frameRect).size(); + LOGV(resultant.asString()); + sizeTo(frameRect.size()); + LOGV(sizeLeft.asString()); + LOGV(sizeRight.asString()); + setStatusField(); + } + + int left = canvas.stackView.tableWidth; + int right = canvas.tokenListView.tableWidth; + if (left > sizeLeft.width()) { + left = sizeLeft.width(); + } + if (right > sizeRight.width()) { + right = sizeRight.width(); + } + + LOGV(left); + LOGV(right); + + canvas.tracePanels.setSplitWindowPercentage(&canvas.leftPanel, left); + canvas.tracePanels.setSplitWindowPercentage(&canvas.rightPanel, right); + positionFrame(); + + stackViewLine = parser.stateStack.size(); + canvas.stackView + . setEnterAction(AgAction()) + . setSelectAction(actionObject(this, stackSelect)) + . setCursorLine(stackViewLine) + ; + canvas.ruleView + . setSelectAction(actionObject(this, ruleSelect)) + . setEnterAction(AgAction()) + ; + canvas.tokenListView + //. setEnterAction(AgAction()) + . setEnterAction(actionObject(this, tokenEnter)) + . setSelectAction(actionObject(this, tokenSelect)) + ; + canvas.reductionChoiceView + . setEnterAction(actionObject(this, reductionChoiceEnter)) + . setSelectAction(actionObject(this, reductionChoiceSelect)) + ; + + listViewLine = canvas.tokenListView.getCursorLine(); + + LOGV(listViewLine); + stackViewLine = parser.stateStack.size(); + ruleViewLine = canvas.ruleView.getCursorLine(); + LOGV(canvas.ruleView.windowId); + + syntaxDependent = 1; + LOGV(parser.stateStack.size()); + IShowListHandler::handleEventsFor(&comboBox); + listViewLine = + tokenList->positionCursor(parser.state.number,parser.state.token); + LOGV(canvas.ruleView.windowId); + canvas.tokenListView.setCursorLine(listViewLine); + LOGV(canvas.ruleView.windowId); + synchRules(parser.stateStack.size(), parser.state.token); + LOGV(canvas.ruleView.windowId); + frameHandler->setDeactivateAction(actionObject(this, onDeactivate)); + LOGV(canvas.ruleView.windowId); + AgFocusHandler::handleEventsFor(this); + for (int i = 0; i < nTabs; i++) { + IKeyboardHandler::handleEventsFor(tabControl[i].window); + if (i == comboTab) { + continue; + } + IMouseHandler::handleEventsFor(tabControl[i].window); + } + IMouseHandler::handleEventsFor(&statusField); + IKeyboardHandler::handleEventsFor(&containerBar); + LOGV(canvas.ruleView.windowId); + show(); + LOGV(canvas.ruleView.windowId); + //setFocus(); + //LOGS("Returned from setFocus"); + LOGV(canvas.ruleView.windowId); + canvas.ruleView.setCursorLine(canvas.itemStack->nt - 1); + refresh(); + LOGS("refresh call returned"); + canvas.ruleView.setCursorLine(ruleViewLine); + canvas.tokenListView.dataArea.setFocus(); + LOGS("all done"); +} + +GTWindow::GTWindow(trace_window_dc* gtControl) + : AgFrame( IFrameWindow::dialogBackground + | IFrameWindow::systemMenu + | IFrameWindow::maximizeButton + | IFrameWindow::sizingBorder) + , parser((gtControl == 0 ? 0 : gtControl->parser_stack)) + , parserDc(new FtParserDc(parser)) + , canvas(this, parserDc) + , toolBar(this, ISetCanvas::packTight | ISetCanvas::centerVerticalAlign) + , containerBar(&toolBar, ISetCanvas::packTight) + , statusField(nextChildId(), &containerBar, &containerBar, IRectangle(), + IStaticText::defaultStyle() + | IStaticText::center + | IStaticText::vertCenter + | IStaticText::border3D) + , statusFieldHelp(&statusField, "Parse Status") + , comboBox(&containerBar, "Now is the time for ") + //, comboBoxHelp(&comboBox, "Grammar Trace Text Entry") + , buttonGroup(&toolBar, ISetCanvas::packExpanded) + , proceedButton(IDTB_PROCEED, &buttonGroup, PROCEED) + , stepButton(IDTB_STEP, &buttonGroup, SINGLE_STEP) + , resetButton(IDTB_RESET, &buttonGroup, RESET) + , helpButton(IDTB_HELP, &buttonGroup, HELP) + , comboBoxActive(0) + , comboBoxListShowing(0) + , ruleSelectActive(0) + , selectedToken(0) +{ + LOGSECTION("GTWindow::GTWindow"); + ok_ptr(this); + AgString title; + if (gtControl == 0) { + title = "Grammar Trace"; + } + else { + if (gtControl->foot_title.exists()) { + title = AgString::format("%s (%s)", + gtControl->head_title.pointer(), + gtControl->foot_title.pointer()); + } + else { + title = gtControl->head_title; + } + } + LOGV(title.pointer()); + AgString objectName = AgString::format("AnaGram : %s", + simple_file_name.pointer()); + LOGV(objectName.pointer()); + windowTitle.setObjectText(objectName.pointer()); + windowTitle.setViewText(title.pointer()); + registerTitle(title.pointer()); + init(); +} + +GTWindow::GTWindow(tsd *initialStates, AgString headTitle, AgString footTitle) + : AgFrame( IFrameWindow::dialogBackground + | IFrameWindow::systemMenu + | IFrameWindow::maximizeButton + | IFrameWindow::sizingBorder) + , parser(initialStates) + , parserDc(new FtParserDc(parser)) + , canvas(this, parserDc) + , toolBar(this, ISetCanvas::packTight | ISetCanvas::centerVerticalAlign) + , containerBar(&toolBar, ISetCanvas::packTight) + , statusField(nextChildId(), &containerBar, &containerBar, IRectangle(), + IStaticText::defaultStyle() + | IStaticText::center + | IStaticText::vertCenter + | IStaticText::border3D) + , statusFieldHelp(&statusField, "Parse Status") + , comboBox(&containerBar, "Now is the time for ") + //, comboBoxHelp(&comboBox, "Grammar Trace Text Entry") + , buttonGroup(&toolBar, ISetCanvas::packExpanded) + , proceedButton(IDTB_PROCEED, &buttonGroup, PROCEED) + , stepButton(IDTB_STEP, &buttonGroup, SINGLE_STEP) + , resetButton(IDTB_RESET, &buttonGroup, RESET) + , helpButton(IDTB_HELP, &buttonGroup, HELP) + , comboBoxActive(0) + , comboBoxListShowing(0) + , ruleSelectActive(0) + , selectedToken(0) +{ + LOGSECTION("GTWindow::GTWindow"); + ok_ptr(this); + + AgString objectName = AgString::format("AnaGram : %s", + simple_file_name.pointer()); + LOGV(objectName.pointer()); + AgString title; + if (footTitle.exists()) { + title = AgString::format("%s (%s)", + headTitle.pointer(), + footTitle.pointer()); + } + else { + title = headTitle; + } + + windowTitle.setObjectText(objectName.pointer()); + windowTitle.setViewText(title.pointer()); + registerTitle(title.pointer()); + init(); + comboBox.setEnterAction(actionObject(this, comboBoxEnter)); +} + +void GTWindow::setRuleViewCursor() { + LOGSECTION("GTWindow::setRuleViewCursor"); + ok_ptr(this); + LOGV(canvas.ruleView.cursorLine); + canvas.ruleView.setCursorLine(canvas.itemStack->nt - 1); + LOGV(canvas.ruleView.cursorLine); + canvas.ruleView.setCursorLine(ruleViewLine); + LOGV(canvas.ruleView.cursorLine); +} + +void GTWindow::onDeactivate() { + LOGSECTION("GTWindow::onDeactivate"); + ok_ptr(this); + //if (comboBox.hasFocus()) canvas.focusControl = comboTab; +} + + +GTWindow::~GTWindow() { + IShowListHandler::stopHandlingEventsFor(&comboBox); + AgFocusHandler::stopHandlingEventsFor(this); + for (int i = 0; i < nTabs; i++) { + IKeyboardHandler::stopHandlingEventsFor(tabControl[i].window); + if (i == comboTab) { + continue; + } + IMouseHandler::stopHandlingEventsFor(tabControl[i].window); + } + IMouseHandler::stopHandlingEventsFor(&statusField); + IKeyboardHandler::stopHandlingEventsFor(&containerBar); +} + +AgString GTWindow::copyTitle() { + ok_ptr(this); + switch (canvas.focusControl) { + case stackTab: return canvas.stackView.copyTitle;; + case tokenTab: return canvas.tokenListView.copyTitle;; + case choiceTab: return canvas.reductionChoiceView.copyTitle;; + case ruleTab: return canvas.ruleView.copyTitle;; + } + return AgString(); +} + +GTWindow >Window::copyTo(IClipboard &c) { + ok_ptr(this); + switch (canvas.focusControl) { + case stackTab: canvas.stackView.copyTo(c); break; + case tokenTab: canvas.tokenListView.copyTo(c); break; + case choiceTab: canvas.reductionChoiceView.copyTo(c); break; + case ruleTab: canvas.ruleView.copyTo(c); break; + } + return *this; +} + +/* +GTView >View::completeReduction() { + LOGSECTION("GTView::completeReduction"); + reductionMenu->des->d_size.y = 0; + bottomPanel.setSplitWindowPercentage(&reductionChoiceView, 0); + bottomPanel.setSplitWindowPercentage(&ruleView, 100); + bottomPanel.refresh(); + tabControl[comboTab].enabled = 0; + frame->reductionChoiceLine = reductionChoiceView.getCursorLine(); + int token = ibnfs[ibnfb[parser.ruleToReduce]+frame->reductionChoiceLine]; + LOGV(token); + parser.completeReduction(token); + return *this; +} +*/ + +void GTWindow::reductionChoiceSelect() { + LOGSECTION("GTWindow::reductionChoiceSelect"); + ok_ptr(this); + int sn = parser.reductionState.number; + reductionChoiceLine = canvas.reductionChoiceView.getCursorLine(); + int tn = canvas.reductionMenu->token(reductionChoiceLine); + parser.reductionState.token= tn; + LOGV(sn) LCV(tn); + listViewLine = tokenList->positionCursor(sn,tn); + canvas.tokenListView.setCursorLine(listViewLine); + canvas.stackView.repaintLine(parser.stateStack.size()); +} + +void GTWindow::ruleSelect() { + LOGSECTION("GTWindow::ruleSelect"); + ok_ptr(this); + LOGV(listViewLine); + LOGV(stackViewLine); + LOGV(ruleViewLine); + int tn = 0; + int k = canvas.ruleView.getCursorLine(); + if (k == ruleViewLine) { + return; + } + ruleViewLine = k; + LOGV(k); + k = canvas.itemStack->nt - k - 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); + if (fx < length) { + //tn = lstptr(map_form_number[fn],tokens)[fx]; + tn = Rule(fn).token(fx); + } + 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); + if (n < 0) { + return; + } + canvas.reductionChoiceView.setCursorLine(n); + parser.reductionState.token = tn; + synchTokenList(sn, tn); + canvas.stackView.repaintLine(stackDepth); + return; + } + canvas.stackView.setCursorLine(stackLevel); + stackViewLine = stackLevel; + synchTokenList(sn, tn); +} + +void GTWindow::setLookaheadToken(unsigned token) { + LOGSECTION("GTWindow::setLookaheadToken"); + ok_ptr(this); + LOGV(parser.stateStack.size()); + LOGV(canvas.stackView.cursorLine); + parser.state.token = token; + LOGV(token); + int line = parser.stateStack.size(); + canvas.stackView.setCursorLine(line); +} + + +void GTWindow::synchRules(unsigned stackIndex, unsigned token) { + LOGSECTION("GTWindow::synchRules"); + ok_ptr(this); + LOGV(stackIndex) LCV(token); + unsigned stackLocation = canvas.itemStack->nt; + LOGV(stackLocation); + int snx, sn, sx; + 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; + } + } + assert(sx == stackIndex); + int k = stackLocation; + LOGV(sn); + LOGV(token); + if (stackIndex >= parser.stateStack.size()) { + 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 (sx == stackIndex && fx < length + // && token == lstptr(map_form_number[fn],tokens)[fx]) { + 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); + ruleViewLine = k; + return; + } + k--; + LOGV(k); + LOGV(sn) LCV(snx); + } while (k >= 0 && sx == stackIndex); +} + +void GTWindow::setUpViews() { + LOGSECTION("GTWindow::setUpViews"); + ok_ptr(this); + unsigned stackDepth = parser.stateStack.size(); + int stackCursor = stackDepth; + LOGV(tokenList->state_number); + canvas.activePanel = canvas.focusControl; + if (parser.processState == FtParser::selectionRequired) { + LOGV(statusField.font().name()); + showReductionSelection(); + LOGV(statusField.font().name()); + stackCursor = parser.reductionIndex; + 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(); + tabControl[choiceTab].enabled = 0; + } + LOGV(tokenList->state_number); + canvas.refreshRules(parser.ruleToReduce); + LOGV(tokenList->state_number); + IString text = comboBox.text(); + LOGV(parser.state.token); + int sn = parser.state.number; + int tn = 0; + if (parser.processState != FtParser::ready) { + tn = parser.state.token; + } + if (parser.processState == FtParser::selectionRequired) { + LOGS("selection required"); + sn = parser.reductionState.number; + tn = + canvas.reductionMenu->token(canvas.reductionChoiceView.getCursorLine()); + LOGV(sn) LCV(tn); + } + else if (parser.processState <= FtParser::running) { + tn = parser.state.token; + parser.processState = FtParser::ready; + } + else if (canvas.focusControl == comboTab) { + LOGS("Text in the combobox"); + LOGV(text); + if (text.length()) { + parser.prime((const char*) text); + tn = parser.state.token; + LOGV(tn); + state_number_map *sp = &map_state_number[sn]; + unsigned *tokenPointer = lstptr(*sp,t_actions); + int k; + for (k = 0; tokenPointer[k]; k++) { + if (tokenPointer[k] == tn) { + break; + } + } + LOGV(tn) LCV(k) LCV(tokenPointer[k]); + tn = tokenPointer[k]; + int snx; + k = canvas.ruleView.getCursorLine(); + LOGV(k) LCV(canvas.itemStack->nt); + k = canvas.itemStack->nt - k - 1; + LOGV(k) LCV(sn); + if (tn) { + do { + int sx, fn, fx; + xtxf(canvas.itemStack, k, &sx, &snx, &fn, &fx); + LOGV(k) LCV(sx) LCV(snx) LCV(fn) LCV(fx);; + int length = Rule(fn)->length(); + LOGV(length); + if (sn == snx && fx < length) { + if (tn == Rule(fn).token(fx)) { + break; + } + //if (tn == lstptr(map_form_number[fn],tokens)[fx]) break; + } + if (k == 0) { + break; + } + k--; + } while (sn == snx); + } + LOGV(sn) LCV(snx); + if (tn && sn == snx) { + k = canvas.itemStack->nt - k - 1; + canvas.ruleView.setCursorLine(k).synchCursor(k); + ruleViewLine = k; + } + else { + tn == 0; + } + } + } + LOGV(tokenList->state_number); + LOGV(parser.state.token); + if (parser.processState == FtParser::running) { + parser.processState = FtParser::ready; + } + LOGV(sn); + LOGV(tn); + + canvas.stackView + . reset() + . setLayoutDistorted(IWindow::layoutChanged | IWindow::immediateUpdate, 0) + . setCursorLine(stackCursor) + . refresh() + ; + LOGV(tokenList->state_number); + LOGV(parser.state.token); + stackViewLine = stackCursor; + LOGS("stackView set up"); + + LOGS("new token menu created"); + LOGV(parser.state.number); + tokenList->reset(parser.state.number); + + LOGV(parser.state.token); + LOGV(tokenList->state_number); + LOGS("new tokenList created"); + char buf[100]; + sprintf(buf, "Allowable input - State %d", parser.state.number); + //AgString tokenTitle = AgString::format("Allowable input - State %d", + // parser.state.number); + //LOGV(tokenTitle.pointer()); + canvas.tokenListTitle + //. setText(tokenTitle.pointer()) + . setText(buf) + . refresh() + ; + LOGS("tokenListTitle set up"); + LOGV(tokenList->state_number); + listViewLine = tokenList->positionCursor(sn, tn); + canvas.tokenListView + . reset() + . setCursorLine(listViewLine) + . setLayoutDistorted(IWindow::layoutChanged | IWindow::immediateUpdate, 0) + . refresh() + ; + LOGV(parser.state.token); + LOGS("tokenListView set up"); + LOGV(tokenList->state_number); + LOGV(listViewLine); + LOGV(stackViewLine); + LOGV(ruleViewLine); + LOGV(parser.location()); + setStatusField(); + LOGV(tokenList->state_number); + setFocus(); + LOGV(tokenList->state_number); +} + +void GTWindow::reductionChoiceEnter() { + LOGSECTION("GTWindow::reductionChoiceEnter"); + ok_ptr(this); + tabControl[choiceTab].enabled = 0; + reductionChoiceLine = canvas.reductionChoiceView.getCursorLine(); + int tn = canvas.reductionMenu->token(reductionChoiceLine); + parser.reductionState.token = tn; + unsigned sn = parser.reductionState.number; + LOGV(sn) LCV(tn); + listViewLine = tokenList->positionCursor(sn,tn); + canvas.tokenListView.setCursorLine(listViewLine); + if (comboBox.text().length()) canvas.focusControl = comboTab; + else canvas.focusControl = tokenTab; + acceptToken(); + setFocus(); +} + +Boolean GTWindow::windowResize(IResizeEvent &event){ + LOGSECTION("GTWindow::windowResize"); + ok_ptr(this); + if (event.controlWindow() != this) { + return false; + } + LOGV(id()); + canvas.mainSplitter.sizeTo( + clientRectFor(IRectangle(IPoint(), event.newSize())).size() + ); + return false; +} + +void GTWindow::synchTokenList(unsigned sn, unsigned tn) { + LOGSECTION("GTWindow::synchTokenList"); + ok_ptr(this); + AgString tokenTitle = AgString::format("Allowable input - State %d", sn); + canvas.tokenListTitle.setText(tokenTitle.pointer()); + + LOGV(sn); + + tokenList->reset(sn); + + listViewLine = tokenList->positionCursor(sn,tn); + canvas.tokenListView + . reset() + . setCursorLine(listViewLine) + . setLayoutDistorted(IWindow::layoutChanged | IWindow::immediateUpdate, 0) + . refresh() + ; +} + +void GTWindow::stackSelect() { + LOGSECTION("GTWindow::stackSelect"); + ok_ptr(this); + int ln = canvas.stackView.getCursorLine(); + LOGV(listViewLine); + LOGV(stackViewLine); + LOGV(ruleViewLine); + FtParser::State state = + (ln >= parser.stateStack.size()) ? parser.state : parser.stateStack[ln]; + int sn = state.number, tn = state.token; + synchTokenList(sn, tn); + synchRules(ln, tn); +} + +GTWindow >Window::showReductionSelection() { + LOGSECTION("GTWindow::showReductionSelection"); + ok_ptr(this); + + LOGV(statusField.font().name()); + + 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()); + + canvas.reductionChoiceView.setEnterAction(actionObject(this, + reductionChoiceEnter)); + + 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()); + reductionChoiceLine = parser.reductionSelection; + canvas.reductionChoiceView + . setCursorLine(reductionChoiceLine) + . synchCursor(reductionChoiceLine) + ; + canvas.focusControl = choiceTab; + setFocus(); + + int sn = parser.reductionState.number; + int tn = canvas.reductionMenu->token(0); + listViewLine = tokenList->positionCursor(sn, tn); + canvas.tokenListView.setCursorLine(listViewLine); + + return *this; +} + +void GTWindow::comboBoxSelect() { + LOGSECTION("GTWindow::comboBoxSelect"); + ok_ptr(this); + IString text = comboBox.itemText(comboBox.selection()); + LOGV((char *) text); + comboBox.setText(text); +} + +void GTWindow::comboBoxEnter() { + LOGSECTION("GTWindow::comboBoxEnter"); + ok_ptr(this); + canvas.focusControl = comboTab; + int selection = comboBox.selection(); + LOGV(selection); + LOGV(IComboBox::notFound); + LOGV(comboBox.isListShowing()); + LOGV(comboBox.hasChanged()); + if (comboBoxListShowing) { + comboBoxListShowing = 0; + LOGV(selection); + if (selection == IComboBox::notFound) { + return; + } + IString text = comboBox.itemText(selection); + LOGV((char *) text); + comboBox.setText(text); + LOGV(comboBox.selection()); + return; + } + comboBoxProceed(); + proceedButton.unhighlight(); +} + +Boolean GTWindow::listShown(IControlEvent &) { + LOGSECTION("GTWindow::listShown"); + ok_ptr(this); + comboBoxListShowing = 1; + return false; +} + +void GTWindow::ComboBox::saveText() { + LOGSECTION("GTWindow::comboBox::saveText()"); + IString contents = text(); + if (contents.length() == 0) { + return; + } + int n = count(); + while (n--) { + if (itemText(n) == contents) { + remove(n); + break; + } + } + addAsFirst(contents); + IEntryField::removeAll(); + n = count(); + LOGV(count()); + if (n < 8 && n > minimumRows()) { + setMinimumRows(8); + } + LOGV(minimumRows()); +} + +void GTWindow::proceed() { + LOGSECTION("GTWindow::proceed"); + ok_ptr(this); + IString text = comboBox.text(); + LOGV(text); + LOGV(canvas.focusControl); + //if (comboBox.hasFocus()) { + // canvas.focusControl = canvas.activePanel = comboTab; + //} + LOGV(canvas.focusControl) LCV(canvas.activePanel); + //switch(canvas.focusControl) { + switch(canvas.activePanel) { + case stackTab: + case ruleTab: { + messageBeep(); + setFocus(); + return; + } + case tokenTab: { + tokenProceed(); + break; + } + case choiceTab: { + reductionChoiceEnter(); + break; + } + case comboTab: { + comboBoxProceed(); + break; + } + case proceedTab: { // proceed button has focus + if (parser.processState == FtParser::selectionRequired) { + reductionChoiceEnter(); + } + else if (text.length() > 0) { + comboBoxProceed(); + } + else tokenProceed(); + break; + } + default: + assert(0); + } + + proceedButton.unhighlight(); + proceedButton.enableDefault(); + setFocus(); +} + +void GTWindow::doStep() { + LOGSECTION("GTWindow::doStep"); + ok_ptr(this); + IString text = comboBox.text(); + LOGV(text); + + LOGV(canvas.focusControl); + //if (comboBox.hasFocus()) { + // canvas.focusControl = canvas.activePanel = comboTab; + //} + LOGV(canvas.focusControl) LCV(canvas.activePanel); + //switch(canvas.focusControl) { + switch(canvas.activePanel) { + case stackTab: + case ruleTab: { + messageBeep(); + setFocus(); + return; + } + case tokenTab: { + canvas.focusControl = tokenTab; + acceptToken(); + break; + } + case choiceTab: { + reductionChoiceEnter(); + break; + } + case comboTab: { + comboBoxStep(); + break; + } + case stepTab: { // step button has focus + if (parser.processState == FtParser::selectionRequired) { + reductionChoiceEnter(); + } + else if (text.length() > 0) { + comboBoxStep(); + } + else { + canvas.focusControl = tokenTab; + acceptToken(); + } + break; + } + default: + assert(0); + } + + proceedButton.enableDefault(); + stepButton.unhighlight(); + stepButton.disableDefault(); + setFocus(); +} + + +void GTWindow::comboBoxProceed() { + LOGSECTION("GTWindow::comboBoxProceed"); + ok_ptr(this); + canvas.focusControl = comboTab; + if (parser.processState == FtParser::finished) { + messageBeep(); + setFocus(); + return; + } + LOGV(comboBox.selectedTextLength()); + LOGV(comboBox.hasSelectedText()); + IString text = comboBox.text(); + LOGV((char *) text); + if (text.length() == 0) { + messageBeep(); + setFocus(); + return; + } + + if (parser.processState == FtParser::selectionRequired) { + parser.ruleToReduce = 0; + canvas.reductionMenu->des->d_size.y = 0; + canvas.bottomPanel.setSplitWindowPercentage(&canvas.reductionChoiceView,0); + canvas.bottomPanel.setSplitWindowPercentage(&canvas.ruleView, 100); + tabControl[choiceTab].enabled = 0; + canvas.bottomPanel.refresh(); + parser.processState = FtParser::running; + } + + unsigned stackLevel = canvas.stackView.getCursorLine(); + unsigned stackDepth = parser.stateStack.size(); + if (stackLevel != stackDepth) { + LOGV(stackDepth); + while (stackDepth > stackLevel) { + parser.stateStack.pop(parser.state); + stackDepth--; + } + parserDc->des->d_size.y = stackLevel+1; + } + + parser.parse(text); + if (parser.processState > FtParser::running) { + messageBeep(); + } + LOGV(comboBox.selectedTextLength()); + LOGV(comboBox.hasSelectedText()); + + int k = (char *) text + strlen(text) - (char *) parser.state.pointer; + comboBox.saveText(); + comboBox.setText((char *) parser.state.pointer); + if (k > 0) { + comboBox.setText((char *) parser.state.pointer); + } + + if (parser.processState == FtParser::selectionRequired) { + int k = parser.stateStack.size() - parser.reductionIndex; + assert((unsigned) k <= (unsigned) parser.stateStack.size()); + LOGV(k); + parser.stateStack.discardData(k); + parser.state = parser.reductionState; + } + LOGV(parser.state.number); + LOGV(parser.state.token); + tokenList->reset(parser.state.number); + stackDepth = parser.stateStack.size(); + //parser.displayControl->des->d_size.y = stackDepth+1; + parserDc->des->d_size.y = stackDepth+1; + LOGV(stackDepth); + LOGV(parser.processState); + LOGV(tokenList->state_number); + + setUpViews(); +} + +void GTWindow::comboBoxStep() { + LOGSECTION("GTWindow::comboBoxStep"); + ok_ptr(this); + LOGV(comboBox.selectedTextLength()); + LOGV(comboBox.hasSelectedText()); + IString text = comboBox.text(); + LOGV((char *) text); + if (text.length() == 0 || parser.processState == FtParser::finished) { + messageBeep(); + return; + } + + if (parser.processState == FtParser::selectionRequired) { + parser.ruleToReduce = 0; + tabControl[choiceTab].enabled = 0; + canvas.reductionMenu->des->d_size.y = 0; + canvas.bottomPanel.setSplitWindowPercentage(&canvas.reductionChoiceView,0); + canvas.bottomPanel.setSplitWindowPercentage(&canvas.ruleView, 100); + canvas.bottomPanel.refresh(); + parser.processState = FtParser::running; + } + + canvas.focusControl = comboTab; + unsigned stackLevel = canvas.stackView.getCursorLine(); + unsigned stackDepth = parser.stateStack.size(); + if (stackLevel != stackDepth) { + LOGV(stackDepth); + while (stackDepth > stackLevel) { + parser.stateStack.pop(parser.state); + stackDepth--; + } + parserDc->des->d_size.y = stackLevel+1; + } + + LOGV((int)(char *) text); + LOGV(parser.state.pointer); + + parser.processState = FtParser::running; + parser.step(text); + if (parser.processState > FtParser::running) { + messageBeep(); + } + + LOGV(comboBox.selectedTextLength()); + LOGV(comboBox.hasSelectedText()); + int k = (char *) text + strlen(text) - (char *) parser.state.pointer; + LOGV(k); + comboBox.saveText(); + if (k > 0) { + comboBox.setText((char *) parser.state.pointer); + } + + if (parser.processState == FtParser::selectionRequired) { + int k = parser.stateStack.size() - parser.reductionIndex; + assert((unsigned) k <= (unsigned) parser.stateStack.size()); + LOGV(k); + parser.stateStack.discardData(k); + parser.state = parser.reductionState; + } + LOGV(parser.state.number); + LOGV(parser.state.token); + tokenList->reset(parser.state.number); + stackDepth = parser.stateStack.size(); + //parser.displayControl->des->d_size.y = stackDepth+1; + parserDc->des->d_size.y = stackDepth+1; + LOGV(stackDepth); + LOGV(parser.processState); + LOGV(tokenList->state_number); + + setUpViews(); +} + +void GTWindow::tokenSelect() { + LOGSECTION("GTWindow::tokenSelect"); + ok_ptr(this); + LOGV(canvas.tokenListView.getCursorLine()); + + int line = canvas.tokenListView.getCursorLine(); + LOGV(line); + LOGV(listViewLine); + LOGV(stackViewLine); + LOGV(ruleViewLine); + + int stackLine = canvas.stackView.getCursorLine(); + LOGV(stackLine); + if (stackLine == stackViewLine && line == listViewLine) { + return; + } + listViewLine = line; + int stackDepth = parser.stateStack.size(); + LOGV(stackDepth); + int sn; + if (stackLine >= stackDepth) { + sn = parser.state.number; + } + else { + sn = parser.stateStack[stackLine].number; + } + LOGV(sn); + state_number_map *sp = &map_state_number[sn]; + + unsigned token = lstptr(*sp,t_actions)[line]; + LOGV(token); + if (parser.processState == FtParser::selectionRequired) { + int n = ibnfn[parser.ruleToReduce]; + while (n--) { + if (token == ibnfs[ibnfb[parser.ruleToReduce]+n]) { + canvas.reductionChoiceView.setCursorLine(n); + reductionChoiceLine = n; + break; + } + } + } +} + +void GTWindow::acceptToken() { + LOGSECTION("GTWindow::acceptToken"); + ok_ptr(this); + LOGV(canvas.tokenListView.getCursorLine()); + LOGV(listViewLine); + LOGV(stackViewLine); + LOGV(ruleViewLine); + + canvas.focusControl = tokenTab; + if (parser.processState == FtParser::finished) { + messageBeep(); + setFocus(); + return; + } + int line = canvas.tokenListView.getCursorLine(); + LOGV(tokenList->state_number); + + + int stackLevel = canvas.stackView.getCursorLine(); + int stackDepth = parser.stateStack.size(); + if (stackLevel != stackDepth) { + LOGV(stackDepth); + while (stackDepth > stackLevel) { + parser.stateStack.pop(parser.state); + stackDepth--; + } + parserDc->des->d_size.y = stackLevel+1; + } + + LOGV(parser.state.token); + + if (parser.processState == FtParser::selectionRequired) { + parser.ruleToReduce = 0; + tabControl[choiceTab].enabled = 0; + canvas.reductionMenu->des->d_size.y = 0; + canvas.bottomPanel.setSplitWindowPercentage(&canvas.reductionChoiceView,0); + canvas.bottomPanel.setSplitWindowPercentage(&canvas.ruleView, 100); + canvas.bottomPanel.refresh(); + parser.processState = FtParser::running; + } + + state_number_map *sp = &map_state_number[parser.state.number]; + unsigned token = lstptr(*sp, t_actions)[line]; + + LOGV(canvas.tokenListView.cursorLine); + AgString lineText = canvas.tokenListView.windowData-> + getLine(canvas.tokenListView.cursorLine); + LOGV(lineText.pointer()); + if (lineText == "No Default") { + messageBeep(); + setFocus(); + return; + } + + LOGV(parser.state.token); + parser.stepToken(token); + + if (parser.processState > FtParser::running) { + messageBeep(); + } + + if (parser.processState == FtParser::selectionRequired) { + int k = parser.stateStack.size() - parser.reductionIndex; + assert((unsigned) k <= (unsigned) parser.stateStack.size()); + LOGV(k); + parser.stateStack.discardData(k); + parser.state = parser.reductionState; + unsigned stackDepth = parser.stateStack.size(); + //parser.displayControl->des->d_size.y = stackDepth+1; + parserDc->des->d_size.y = stackDepth+1; + } + LOGV(parser.state.number); + LOGV(parser.state.token); + tokenList->reset(parser.state.number); + stackDepth = parser.stateStack.size(); + //parser.displayControl->des->d_size.y = stackDepth+1; + parserDc->des->d_size.y = stackDepth+1; + + LOGV(stackDepth); + LOGV(parser.processState); + LOGV(tokenList->state_number); + setUpViews(); + LOGV(tokenList->state_number); + AgFrame::windowRegistry.refresh("Trace Coverage"); +} + +void GTWindow::tokenEnter() { + LOGSECTION("GTWindow::tokenEnter"); + ok_ptr(this); + //acceptToken(); + //comboBox.saveText(); + tokenProceed(); +} + + +void GTWindow::tokenProceed() { + LOGSECTION("GTWindow::tokenProceed"); + ok_ptr(this); + LOGV(canvas.tokenListView.getCursorLine()); + LOGV(listViewLine); + LOGV(stackViewLine); + LOGV(ruleViewLine); + canvas.focusControl = tokenTab; + if (parser.processState == FtParser::finished) { + messageBeep(); + setFocus(); + return; + } + int line = canvas.tokenListView.getCursorLine(); + LOGV(tokenList->state_number); + + + int stackLevel = canvas.stackView.getCursorLine(); + int stackDepth = parser.stateStack.size(); + if (stackLevel != stackDepth) { + LOGV(stackDepth); + while (stackDepth > stackLevel) { + parser.stateStack.pop(parser.state); + stackDepth--; + } + parserDc->des->d_size.y = stackLevel+1; + } + + LOGV(parser.state.token); + + if (parser.processState == FtParser::selectionRequired) { + parser.ruleToReduce = 0; + tabControl[choiceTab].enabled = 0; + canvas.reductionMenu->des->d_size.y = 0; + canvas.bottomPanel.setSplitWindowPercentage(&canvas.reductionChoiceView,0); + canvas.bottomPanel.setSplitWindowPercentage(&canvas.ruleView, 100); + canvas.bottomPanel.refresh(); + parser.processState = FtParser::running; + } + + state_number_map *sp = &map_state_number[parser.state.number]; + unsigned token = lstptr(*sp,t_actions)[line]; + + LOGV(canvas.tokenListView.cursorLine); + AgString lineText = canvas.tokenListView.windowData-> + getLine(canvas.tokenListView.cursorLine); + LOGV(lineText.pointer()); + if (lineText == "No Default") { + messageBeep(); + setFocus(); + return; + } + + LOGV(parser.state.token); + if (token) { + parser.parseToken(token); + } + else { + parser.stepToken(token); + } + + if (parser.processState > FtParser::running) { + messageBeep(); + } + + if (parser.processState == FtParser::selectionRequired) { + int k = parser.stateStack.size() - parser.reductionIndex; + assert((unsigned) k <= (unsigned) parser.stateStack.size()); + LOGV(k); + parser.stateStack.discardData(k); + parser.state = parser.reductionState; + unsigned stackDepth = parser.stateStack.size(); + //parser.displayControl->des->d_size.y = stackDepth+1; + parserDc->des->d_size.y = stackDepth+1; + } + LOGV(parser.state.number); + LOGV(parser.state.token); + tokenList->reset(parser.state.number); + stackDepth = parser.stateStack.size(); + //parser.displayControl->des->d_size.y = stackDepth+1; + parserDc->des->d_size.y = stackDepth+1; + + //comboBox.saveText(); + + LOGV(stackDepth); + LOGV(parser.processState); + LOGV(tokenList->state_number); + setUpViews(); + LOGV(tokenList->state_number); + AgFrame::windowRegistry.refresh("Trace Coverage"); +} + +Boolean GTWindow::findNext(AgString s) { + LOGSECTION("GTWindow::findNext"); + ok_ptr(this); + LOGV(canvas.focusControl); + int flag; + switch (canvas.focusControl) { + case stackTab: { + flag = canvas.stackView.findNext(s); + if (flag) { + stackSelect(); + } + return flag; + } + case tokenTab: { + flag = canvas.tokenListView.findNext(s); + if (flag) { + tokenSelect(); + } + return flag; + } + case choiceTab: { + flag = canvas.reductionChoiceView.findNext(s); + if (flag) { + reductionChoiceSelect(); + } + return flag; + } + case ruleTab: { + flag = canvas.ruleView.findNext(s); + if (flag) { + ruleSelect(); + } + return flag; + } + default: + messageBeep(); + return false; + } +} + +Boolean GTWindow::findPrev(AgString s) { + LOGSECTION("GTWindow::findPrev"); + ok_ptr(this); + LOGV(canvas.focusControl); + int flag; + switch (canvas.focusControl) { + case stackTab: { + flag = canvas.stackView.findPrev(s); + if (flag) { + stackSelect(); + } + return flag; + } + case tokenTab: { + flag = canvas.tokenListView.findPrev(s); + if (flag) { + tokenSelect(); + } + return flag; + } + case choiceTab: { + flag = canvas.reductionChoiceView.findPrev(s); + if (flag) { + reductionChoiceSelect(); + } + return flag; + } + case ruleTab: { + flag = canvas.ruleView.findPrev(s); + if (flag) { + ruleSelect(); + } + return flag; + } + default: + messageBeep(); + return false; + } +} + + +char *GTWindow::processStateText[] = { + "Ready", + "Running", //running, + "Parse Complete", //finished, + "Syntax Error", //syntaxError, + "Unexpected End of File", //unexpectedEndOfFile, + "Select Reduction Token", //selectionRequired + "Selection Error" +}; + +GTWindow >Window::setStatusField() { + ok_ptr(this); + char *msg = processStateText[parser.processState]; + statusField.setText(msg); + statusField.refresh(); + AgString tokenTitle = AgString::format("Allowable input - State %d", + parser.state.number); + canvas.tokenListTitle.setText(tokenTitle.pointer()); + return *this; +} + +void GTWindow::resetParser() { + LOGSECTION("GTWindow::resetParser"); + ok_ptr(this); + 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(); + } + tabControl[choiceTab].enabled = 0; + comboBox.saveText(); + parser.reset(); + LOGV(parser.state.token); + LOGV(parser.processState); + int stackDepth = parser.stateStack.size(); + parserDc->des->d_size.y = stackDepth + 1; + canvas.stackView.setCursorLine(stackDepth); + tokenList->reset(parser.state.number); + LOGV(parser.state.token); + canvas.tokenListView.reset(); + LOGV(parser.state.token); + LOGV(parser.state.token); + LOGV(parser.processState); + listViewLine + = tokenList->positionCursor(parser.state.number, parser.state.token); + canvas.tokenListView.setCursorLine(listViewLine); + LOGV(parser.state.token); + canvas.refreshRules(0); + synchRules(parser.stateStack.size(), parser.state.token); + LOGV(parser.processState); + +// if (comboBox.text().length()) canvas.focusControl = comboTab; +// else canvas.focusControl = tokenTab; + canvas.focusControl = tokenTab; + setFocus(); + canvas.stackView.refresh(); + canvas.tokenListView.refresh(); + LOGV(parser.processState); + setStatusField(); + resetButton.unhighlight(); + resetButton.disableDefault(); + proceedButton.enableDefault(); +} + +void GTWindow::showHelp() { + ok_ptr(this); + AgHelpWindow::showHelp("Grammar Trace"); + helpButton.unhighlight(); + helpButton.disableDefault(); + proceedButton.enableDefault(); + if (comboBox.text().length()) { + canvas.focusControl = comboTab; + } + else { + canvas.focusControl = tokenTab; + } +} +