Mercurial > ~dholland > hg > ag > index.cgi
view anagram/vaclgui/dview.cpp @ 14:a02e9434072e
Fix friend declaration for gcc10.
XXX: did not check it against the IBM compiler, might end up needing
XXX: to be conditional.
author | David A. Holland |
---|---|
date | Tue, 31 May 2022 00:59:42 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/* * AnaGram, A System for Syntax Directed Programming * Copyright 1997-2002 Parsifal Software. All Rights Reserved. * See the file COPYING for license and usage terms. * * dview.cpp */ #include <icoordsy.hpp> #include <windows.h> #include "port.h" #include "agcstack.h" #include "arrays.h" #include "ctrlpanel.hpp" #include "dview.hpp" #include "dvplug.hpp" #include "helpview.hpp" #include "minmax.h" #include "myalloc.h" #include "vaclgui.hpp" //#define INCLUDE_LOGGING #include "log.h" const int AgDataView::defaultWindowHeight = 12; void logFont(IFont activeFont, char *p) { LOGV(activeFont.name()) LV(activeFont.pointSize()); LOGV(activeFont.isBold()) LCV(activeFont.isItalic()); LOGV(activeFont.textWidth(p)) LCV(p); } void logFont(IFont activeFont) { LOGV(activeFont.name()) LV(activeFont.pointSize()); LOGV(activeFont.isBold()) LCV(activeFont.isItalic()); } AgDataView::AgDataView(IWindow *ownerWindow_, WindowData *windowData_) : ICanvas(nextChildId(), ownerWindow_, ownerWindow_) , ownerWindow(ownerWindow_) , windowData(windowData_) , horizontalScrollBar(nextChildId(), this, this, IRectangle(), IScrollBar::horizontal | IWindow::visible) , verticalScrollBar(nextChildId(), this, this, IRectangle(), IScrollBar::vertical | IWindow::visible) , dataArea(this) , vsbShowing(false) , hsbShowing(false) , columnHeadTitle(nextChildId(), this) , columnHeadsPresent(0) , cursorLine(0) , mouseDown(0) , tabArray(0) , popUpMenu(this, nextChildId()) , popUpInitialized(0) , tableWidth(0) , color(&ColorSpec::data) , cursorColor(&ColorSpec::inactiveCursor) , prevHorizontal(0) , prevVertical(0) //, rightButtonDown(0) , rightButtonState(buttonIdle) , layoutActive(0) , dataColorChange(this, onColorChange) , fontChange(this, onFontChange) , enterAction(actionObject(messageBeep)) , verticalLineCount(0) , layoutComplete(0) , helpTopic(0) { windowId = id(); LOGSECTION("AgDataView::AgDataView"); LOGV(windowId); LOGV((int) this); setFont(FontSpec::dataTable); dataArea.setFont(FontSpec::dataTable); LOGV(dataArea.font().name()); columnHeadTitle.setFont(FontSpec::columnHead); dataColorChange.attach(&ColorSpec::data); dataColorChange.attach(&ColorSpec::inactiveCursor); dataColorChange.attach(&ColorSpec::activeCursor); fontChange.attach(&FontSpec::dataTable); fontChange.attach(&FontSpec::columnHead); fontChange.attach(&FontSpec::markedToken); horizontalScrollBar.setScrollableRange(IRange(0,100)); horizontalScrollBar.moveScrollBoxTo(0); verticalScrollBar.setScrollableRange(IRange(0,100)); verticalScrollBar.moveScrollBoxTo(0); cursorLine = 0; IWindow *f; for (f = ownerWindow; !f->isFrameWindow(); f=f->parent()); frameWindow = (AgFrame *) f; frameWindow->helpCursorSupported = 1; LOGV(frameWindow->windowTitle.text()); ok_ptr(windowData); AgString title = windowData->columnHeadTitle(); LOGV(title.pointer()); if (title.exists()) { columnHeadTitle.setTitles(windowData->nColumns(), title); columnHeadTitle.setMargin(avgCharWidth()); columnHeadTitle.enableFillBackground(); columnHeadTitle.show(); columnHeadsPresent = 1; } int nCols = windowData->nColumns(); tabArray = new int[nCols + 1]; memset(tabArray, 0, (nCols+1)*sizeof(int)); columnHeadTitle.setTabs(tabArray); LOGV(tabArray[0]); tableHeight = lineHeight()*windowData->nLines(); LOGV(windowData->nLines()); LOGV(tableHeight); LOGV(auxMenu.exists()); ICommandHandler ::handleEventsFor(this); IKeyboardHandler::handleEventsFor(this); IMouseHandler ::handleEventsFor(&dataArea); IMouseHandler ::handleEventsFor(&columnHeadTitle); IMouseHandler ::handleEventsFor(&verticalScrollBar); IMouseHandler ::handleEventsFor(&horizontalScrollBar); IPaintHandler ::handleEventsFor(&dataArea); IResizeHandler ::handleEventsFor(this); IScrollHandler ::handleEventsFor(this); AgHelpHandler ::handleEventsFor(frameWindow); AgFocusHandler ::handleEventsFor(&dataArea); ((AgDataViewPlug *)windowData)->connect(this); auxMenu = windowData->auxMenu(); if (auxMenu.exists()) { IMenuHandler::handleEventsFor(&dataArea); } LOGV(auxMenu.exists()); LOGS("menu handler attached"); initPopUp(); show(); windowData->synchCursor(cursorLine); } void AgDataView::disconnect() { LOGSECTION("AgDataView::disconnect"); LOGV((int) frameWindow); } AgDataView &AgDataView::setColumnTitles(AgString title) { LOGSECTION("AgDataView::setColumnTitles"); LOGV((int) frameWindow); if (title.exists()) { LOGV(title.pointer()); columnHeadTitle.setTitles(windowData->nColumns(), title); columnHeadTitle.setMargin(avgCharWidth()); columnHeadTitle.enableFillBackground(); columnHeadsPresent = 1; } return *this; } Boolean AgDataView::gotFocus(IEvent &) { LOGSECTION("AgDataView::gotFocus"); LOGV(windowId); LOGV((int) this); focusWindowId = windowId; columnHeadTitle.color = &ColorSpec::activeTitle; columnHeadTitle.refresh(); cursorColor = &ColorSpec::activeCursor; if (windowData == 0) { return true; } repaintLine(cursorLine); windowData->synchCursor(cursorLine); return false; } Boolean AgDataView::lostFocus(IEvent &) { LOGSECTION("AgDataView::lostFocus"); LOGV(windowId); LOGV((int) this) LCV((int) windowData); columnHeadTitle.color = &ColorSpec::inactiveTitle; columnHeadTitle.refresh(); cursorColor = &ColorSpec::inactiveCursor; if (windowData == 0) { return true; } ok_ptr(windowData); repaintLine(cursorLine); return false; } AgDataView &AgDataView::init(WindowData *windowData_) { LOGSECTION("AgDataView::init"); LOGV(windowId); LOGV((int) this); horizontalScrollBar.setScrollableRange(IRange(0,100)); horizontalScrollBar.moveScrollBoxTo(0); verticalScrollBar.setScrollableRange(IRange(0,100)); verticalScrollBar.moveScrollBoxTo(0); cursorLine = 0; ok_ptr(windowData_); windowData = windowData_; LOGV((int) frameWindow); LOGV((int) windowData); LOGV(windowId); AgString title = windowData->columnHeadTitle(); if (title.exists()) { LOGV(title.pointer()); columnHeadTitle.setTitles(windowData->nColumns(), title); columnHeadTitle.setMargin(avgCharWidth()); columnHeadTitle.enableFillBackground(); columnHeadTitle.show(); columnHeadsPresent = 1; } if (tabArray == NULL) { int nCols = windowData->nColumns(); tabArray = new int[nCols + 1]; memset(tabArray, 0, (nCols+1)*sizeof(int)); } columnHeadTitle.setTabs(tabArray); LOGV(tabArray[0]); tableHeight = lineHeight()*windowData->nLines(); LOGV(windowData->nLines()); LOGV(tableHeight); setLayoutDistorted(IWindow::layoutChanged,0); ((AgDataViewPlug *)windowData)->connect(this); auxMenu = windowData->auxMenu(); if (auxMenu.exists()) { IMenuHandler::handleEventsFor(&dataArea); LOGS("menu handler attached"); initPopUp(); } windowData->synchCursor(cursorLine); return *this; } AgDataView &AgDataView::reset() { LOGSECTION("AgDataView::reset"); LOGV(windowId); LOGV((int) this); ok_ptr(windowData); int nLines = windowData->nLines(); LOGV(nLines); int newTableHeight = lineHeight()*nLines; LOGV(windowData->nLines()); LOGV(tableHeight); if (cursorLine >= nLines) { cursorLine = nLines-1; } windowData->synchCursor(cursorLine); //if (tableHeight != newTableHeight) { tableHeight = newTableHeight; doLayout(); refresh(); //} LOGV(horizontalScrollBar.scrollBoxPosition()); LOGV(verticalScrollBar.scrollBoxPosition()); return *this; } AgDataView::AgDataView(IWindow *ownerWindow_) : ICanvas(nextChildId(), ownerWindow_, ownerWindow_) , ownerWindow(ownerWindow_) , windowData(NULL) , horizontalScrollBar(nextChildId(), this, this, IRectangle(), IScrollBar::horizontal | IWindow::visible) , verticalScrollBar(nextChildId(), this, this, IRectangle(), IScrollBar::vertical | IWindow::visible) , dataArea(this) , vsbShowing(false) , hsbShowing(false) , columnHeadTitle(nextChildId(), this) , columnHeadsPresent(0) , cursorLine(0) , mouseDown(0) , tabArray(0) , popUpMenu(this, nextChildId()) , popUpInitialized(0) , tableWidth(0) , color(&ColorSpec::data) , cursorColor(&ColorSpec::inactiveCursor) , prevHorizontal(0) , prevVertical(0) //, rightButtonDown(0) , rightButtonState(buttonIdle) , layoutActive(0) , dataColorChange(this, onColorChange) , fontChange(this, onFontChange) , enterAction(actionObject(messageBeep)) , verticalLineCount(0) , layoutComplete(0) , helpTopic(0) { windowId = id(); LOGSECTION("AgDataView::AgDataView"); LOGV(windowId); LOGV((int) this); setFont(FontSpec::dataTable); dataArea.setFont(FontSpec::dataTable); LOGV(dataArea.font().name()); columnHeadTitle.setFont(FontSpec::columnHead); dataColorChange.attach(&ColorSpec::data); dataColorChange.attach(&ColorSpec::inactiveCursor); dataColorChange.attach(&ColorSpec::activeCursor); fontChange.attach(&FontSpec::dataTable); fontChange.attach(&FontSpec::columnHead); fontChange.attach(&FontSpec::markedToken); IWindow *f; for (f = ownerWindow; !f->isFrameWindow(); f=f->parent()); frameWindow = (AgFrame *) f; frameWindow->helpCursorSupported = 1; LOGV(frameWindow->windowTitle.text()); LOGV((int) frameWindow); LOGV((int) this); LOGV(id()); ICommandHandler ::handleEventsFor(this); IKeyboardHandler::handleEventsFor(this); if (auxMenu.exists()) { IMenuHandler::handleEventsFor(&dataArea); } LOGV(auxMenu.exists()); LOGS("menu handler attached"); IMouseHandler ::handleEventsFor(&dataArea); IMouseHandler ::handleEventsFor(&columnHeadTitle); IMouseHandler ::handleEventsFor(&verticalScrollBar); IMouseHandler ::handleEventsFor(&horizontalScrollBar); IPaintHandler ::handleEventsFor(&dataArea); IResizeHandler ::handleEventsFor(this); IScrollHandler ::handleEventsFor(this); AgHelpHandler ::handleEventsFor(frameWindow); AgFocusHandler ::handleEventsFor(&dataArea); show(); } AgDataView::~AgDataView() { LOGSECTION("AgDataView::~AgDataView"); LOGV(windowId) LCV((int) this) LCV((int) windowData); ok_ptr(windowData); delete [] tabArray; //if (windowData == 0) return; ICommandHandler ::stopHandlingEventsFor(this); IKeyboardHandler::stopHandlingEventsFor(this); if (auxMenu.exists()) { IMenuHandler::stopHandlingEventsFor(&dataArea); } IMouseHandler ::stopHandlingEventsFor(&dataArea); IMouseHandler ::stopHandlingEventsFor(&columnHeadTitle); IMouseHandler ::stopHandlingEventsFor(&verticalScrollBar); IMouseHandler ::stopHandlingEventsFor(&horizontalScrollBar); IPaintHandler ::stopHandlingEventsFor(&dataArea); IResizeHandler ::stopHandlingEventsFor(this); IScrollHandler ::stopHandlingEventsFor(this); AgHelpHandler ::stopHandlingEventsFor(frameWindow); AgFocusHandler ::stopHandlingEventsFor(&dataArea); ok_ptr(windowData); delete windowData; } void AgDataView::onFontChange() { LOGSECTION("AgDataView::onFontChange"); disableUpdate(); LOGS("dataTableFont"); logFont(FontSpec::dataTable); setFont(FontSpec::dataTable); dataArea.setFont(FontSpec::dataTable); columnHeadTitle.setFont(FontSpec::columnHead); LOGS("font()"); logFont(font()); logFont(dataArea.font()); tableWidth = 0; doLayout(); enableUpdate(); show(); } int AgDataView::findMaxWidth() { LOGSECTION("AgDataView::findMaxWidth"); LOGV(windowId); LOGV((int) this); LOGV((int) frameWindow); int maxWidth = 0; ok_ptr(windowData); int nLines = windowData->nLines(); int nCols = windowData->nColumns(); char *columnTitles = columnHeadTitle.title.pointer(); int i; LOGV(nLines) LCV(nCols); if (tabArray == NULL) { tabArray = new int[nCols + 1]; } memset(tabArray, 0, (nCols+1)*sizeof(int)); IFont windowFont = font(); LOGV(windowFont.name()); LOGV(windowFont.pointSize()); int lastColumnTitleWidth = 0; //int *columnWidth = new int[nCols]; //int *columnWidth = local_array(nCols, int); LocalArray<int> columnWidth(nCols); memset(columnWidth, 0, nCols*sizeof(int)); LOGV(columnTitles); if (columnTitles) { //char *titles = new char[1+strlen(columnTitles)]; //char *titles = local_array(1+strlen(columnTitles), char); LocalArray<char> titles(1+strlen(columnTitles)); strcpy(titles, columnTitles); FindTabs tabs(titles); char *p = tabs.getField(); i = 0; while(i < nCols && p) { int width = columnHeadTitle.font().textWidth(p); columnWidth[i] = width; LOGV(width) LCV(p); lastColumnTitleWidth = width; if (++i >= nCols) { break; } p = tabs.getField(); } while (i < nCols) { tabArray[i++] = 0; } //delete [] titles; } else { for (i = 0; i < nCols; i++) { tabArray[i] = 0; } } LOGV(tabArray[0]); LOGV(columnWidth[0]); //int *width = new int[nCols]; //int *width = local_array(nCols, int); LocalArray<int> width(nCols); int partialWidth = 0; while (nLines--) { //LOGSECTION("AgDataView::findMaxWidth line detail", Log::off); LOGSECTION_OFF("AgDataView::findMaxWidth line detail"); AgString line = windowData->getLine(nLines); LOGV(line.pointer()); FindTabs tabs(line.pointer()); char *p = tabs.getField(); LOGV(nLines); LOGV(p); i = 0; while(i < nCols && p) { width[i] = windowFont.textWidth(p); LOGV(i) LCV(width[i]) LCV(p); if (width[i] > columnWidth[i]) { columnWidth[i] = width[i]; } if (++i >= nCols) { break; } p = tabs.getField(); } LOGV(width[0]) LCV(line.pointer()); if (i < nCols) { int w = 0; while (i--) { w += width[i]; } if (w > partialWidth) { partialWidth = w; } //continue; } } //delete [] width; for (i = 0; i < nCols; i++) { columnWidth[i] += 2*avgCharWidth(); if (columnWidth[i] > tabArray[i]) { tabArray[i] = columnWidth[i]; } maxWidth += tabArray[i]; LOGV(tabArray[i]) LCV(maxWidth); } LOGV(tabArray[0]); maxWidth += 2*avgCharWidth(); if (maxWidth < partialWidth) { maxWidth = partialWidth; } //delete [] columnWidth; columnHeadWidth = maxWidth - tabArray[nCols-1] + lastColumnTitleWidth+2*avgCharWidth(); LOGV(columnHeadWidth); return maxWidth; } AgDataView &AgDataView::adjustMaxWidth(AgString text) { int nCols = windowData->nColumns(); int maxWidth = 0; int margin = 2*avgCharWidth(); char *line = text.pointer(); LOGSECTION("AgDataView::adjustMaxWidth"); LOGV((int) frameWindow); LOGV(line); if (tableWidth == 0) { tableWidth = findMaxWidth(); } FindTabs tabs(line); char *p = tabs.getField(); LOGV(p); if (tabArray == NULL) { tabArray = new int[nCols + 1]; memset(tabArray, 0, (nCols+1)*sizeof(int)); } int i = 0; while(i < nCols && p) { int width = font().textWidth(p) + margin; if (width > tabArray[i]) { tabArray[i] = width; } LOGV(p) LCV(width); if (++i >= nCols) { break; } p = tabs.getField(); } for (i = 0; i < nCols; i++) { maxWidth += tabArray[i]; LOGV(tabArray[i]) LCV(maxWidth); } if (tableWidth < maxWidth) { tableWidth = maxWidth; } LOGV(maxWidth); LOGV(tabArray[0]); return *this; } AgDataView &AgDataView::layout() { LOGSECTION("AgDataView::layout"); LOGV(windowId); LOGV((int) this); LOGV((int) frameWindow); if (layoutActive) { return *this; } layoutActive++; doLayout(); ICanvas::setLayoutDistorted(0, IWindow::layoutChanged); ICanvas::layout(); layoutActive--; return *this; } AgDataView &AgDataView::setLayoutDistorted(unsigned long i, unsigned long j) { LOGSECTION("AgDataView::setLayoutDistorted"); LOGV((int) frameWindow); LOGV(windowId); LOGV((int) this); LOGV(i) LCV(j); LOGSTACK; ICanvas::setLayoutDistorted(i, j); return *this; } Boolean AgDataView::windowResize(IResizeEvent &event){ LOGSECTION("AgDataView::windowResize"); LOGV(windowId); LOGV((int) this); LOGV((int) frameWindow); //if (event.controlWindow() != this) { // return false; //} LOGV(id()); //setLayoutDistorted(IWindow::layoutChanged,0); doLayout(); return false; } ISize AgDataView::calcMinimumSize() const { int minWidth = 10*font().avgCharWidth(); int minHeight = 3*lineHeight(); if (columnHeadsPresent) { minHeight += 2 + columnHeadTitle.minimumSize().height(); } return ISize(minWidth, minHeight); } ISize AgDataView::suggestSize() { LOGSECTION("AgDataView::suggestSize"); LOGV(windowId); LOGV((int) this); LOGV((int) frameWindow); if (tableWidth == 0) { tableWidth = findMaxWidth(); /* int minWidth = 20*font().avgCharWidth(); int minHeight = 5*lineHeight(); if (columnHeadsPresent) { minHeight += 2 + columnHeadTitle.minimumSize().height(); } setMinimumSize(ISize(minWidth, minHeight)); */ } int width = tableWidth; int height = tableHeight; ok_ptr(windowData); LOGV(windowData->nLines()); LOGV(tableHeight); LOGV(columnHeadsPresent); LOGV(columnHeadTitle.minimumSize().height()); if (windowData->nLines() > defaultWindowHeight) { width += verticalScrollBar.minimumSize().width() + 1; height = lineHeight() * defaultWindowHeight; } else if (windowData->nLines() < 5) { height = lineHeight() * 5; } if (columnHeadsPresent) { height += 2 + columnHeadTitle.minimumSize().height(); } LOGV(height); LOGV(width) LCV(height); return ISize(width, height); } ColorSpec *AgDataView::getLineColor(int k) { if (k == cursorLine) { return cursorColor; } return color; } char *findDelimiter(char *p, char c) { // XXX: are we guaranteed that '\\' never occurs immediately before // the end of a string, or do we just zoom off into the beyond when // that happens? while (*p && *p != c) { if (*p == '\'') { p++; while (*p != '\'') { if (*p++ == '\\') { p++; } } } else if (*p == '"') { p++; while (*p != '"') { if (*p++ == '\\') { p++; } } } p++; } return p; } Boolean AgDataView::paintWindow(IPaintEvent &event) { if (event.controlWindow() != &dataArea) { return false; } if (windowData == 0) { return false; } int nLines = windowData->nLines() - 1; int height = lineHeight(); int leadingBias = 0; IFont markFont(FontSpec::markedToken); LOGSECTION("AgDataView::paintWindow"); LOGV(tabArray[0]); LOGV(windowId); LOGV((int) this); IPresSpaceHandle presSpaceHandle = event.presSpaceHandle(); font().beginUsingFont(presSpaceHandle); LOGV(font().name()) LCV(font().pointSize()); leadingBias = font().maxAscender() - markFont.maxAscender(); SetBkMode(presSpaceHandle, TRANSPARENT); LOGV((int) frameWindow); LOGV(nLines); IRectangle invalidRect( ICoordinateSystem::isConversionNeeded() ? ICoordinateSystem::convertToApplication(event.rect(),dataArea.size()) : event.rect() ); LOGV(invalidRect.asString()); LOGV(dataArea.size().asString()); int baseLine = verticalScrollBar.scrollBoxPosition(); int firstLine = baseLine + invalidRect.minY()/height; int lastLine = baseLine + (invalidRect.maxY()+height - 1)/height - 1; LOGV(horizontalScrollBar.scrollBoxPosition()); LOGV(verticalScrollBar.scrollBoxPosition()); LOGV(baseLine); LOGV(firstLine); LOGV(lastLine); int yBias = ICoordinateSystem::isConversionNeeded() ? height - maxDescender() : 0; int xMargin = avgCharWidth(); LOGV(yBias); int whereX = -horizontalScrollBar.scrollBoxPosition(); int whereY = (firstLine - baseLine)*height; //baseline location LOGV(baseLine); LOGV(firstLine); LOGV(lastLine); LOGV(horizontalScrollBar.scrollBoxPosition()); int lastInvalidLine = lastLine; if (lastLine > nLines) { lastLine = nLines; } int windowHeight = dataArea.rect().size().height(); int dataAreaWidth = dataArea.rect().size().width() - whereX; ISize lineSize(dataAreaWidth, height); IPoint offset(xMargin, 0); int k; LOGV(firstLine); LOGV(lastLine); for (k = firstLine; k >= 0 && k <= lastLine; k++, whereY += height) { LOGSECTION("AgDataView::paintWindow line loop"); IPoint trueWhere(whereX, whereY + yBias); IPoint where = ICoordinateSystem::isConversionNeeded() ? ICoordinateSystem::convertToNative(trueWhere, dataArea.size()) : trueWhere; IRectangle trueLineRect(0, whereY, dataAreaWidth, whereY+height); IRectangle lineRect = ICoordinateSystem::isConversionNeeded() ? ICoordinateSystem::convertToNative(trueLineRect, dataArea.size()) : trueLineRect; ColorSpec *lineColor = getLineColor(k); IColor bgndColor = lineColor->bg(); IColor fgndColor = lineColor->fg(); LOGV(lineRect.asString()); LOGV(where.asString()); event.clearBackground(lineRect,bgndColor); AgString line = windowData->getLine(k); char *p = line.pointer(); LOGV((int)p); LOGV(p); while (*p && *p != '<') { p++; } if (*p == '<') { while (*p && *p != '>') { p++; } } int bracketFlag = *p == '>'; LOGV(line.pointer()); FindTabs tabs(line.pointer()); p = tabs.getField(); int nCols = windowData->nColumns(); where += offset; int i = 0; char *star = 0; IPoint starWhere = where; if (*p == '*') { *p = ' '; star = p; } while (i < nCols && p) { LOGV(p - line.pointer()); LOGV(p); IPoint drawPoint(where); int j = 0; while (p[j] && p[j] == ' ') { j++; } int flag = bracketFlag && p[j] == 'R' && p[j+7] == '<' && p[j+8] != '<'; if (!flag) { char *q = p; while (*q && strncmp(q, ", <", 3) != 0) { q++; } //LOGV(q); if (*q == ',') { q += 2; *q = 0; logFont(font(), p); //LOGV(drawPoint.asString()); event.drawText(p, drawPoint, fgndColor); drawPoint += IPair(font().textWidth(p), 0); //drawPoint += IPair(gcFont.textWidth(p), 0); //LOGV(font().textWidth(p)) LCV(p); //LOGV(drawPoint.asString()); p = q; *p = '<'; } } else { p[j+7] = 0; logFont(font(), p); //LOGV(drawPoint.asString()); event.drawText(p, drawPoint, fgndColor); drawPoint += IPair(font().textWidth(p), 0); //LOGV(font().textWidth(p)) LCV(p); //LOGV(drawPoint.asString()); p += j+7; *p = '<'; } //LOGV(flag); //LOGV(p); if (bracketFlag && *p == '<' && p[1] != '<') { p += 2; IFont markFont(FontSpec::markedToken); char *q = p; q = findDelimiter(q, '>'); if (q) { *q = 0; } //LOGV(p); //LOGV(font().textWidth(p)); //LOGV(markFont.name()) LCV(markFont.pointSize()); //LOGV(markFont.textWidth(p)); logFont(font(), p); //LOGV(drawPoint.asString()); int saveY = drawPoint.y(); drawPoint.setY(saveY +leadingBias); //LOGV(drawPoint.asString()); markFont.beginUsingFont(presSpaceHandle); logFont(font(), p); event.drawText(p, drawPoint, fgndColor); drawPoint.setY(saveY); drawPoint += IPair(markFont.textWidth(p), 0); //LOGV(font().textWidth(p)) LCV(p); //LOGV(drawPoint.asString()); markFont.endUsingFont(presSpaceHandle); p = q+1; //LOGS("emphasis complete"); } logFont(font(), p); LOGV(drawPoint.asString()); event.drawText(p,drawPoint, fgndColor); where += IPoint(tabArray[i], 0); LOGV(font().textWidth(p)) LCV(p); LOGV(tabArray[i]); LOGV(where); if (++i >= nCols) { break; } p = tabs.getField(); } if (star) { event.drawText("*", starWhere, fgndColor); } } if (k <= lastInvalidLine) { IRectangle trueRemainder(0,whereY,dataAreaWidth, windowHeight); IRectangle remainder = ICoordinateSystem::isConversionNeeded() ? ICoordinateSystem::convertToNative(trueRemainder, dataArea.size()) : trueRemainder; //LOGV(remainder.asString()); event.clearBackground(remainder,color->bg()); } font().endUsingFont(presSpaceHandle); return true; } AgDataView &AgDataView::repaintLine(int line) { if (windowData == 0) { return *this; } if (line < 0 || line >= windowData->nLines()) { return *this; } int topLine = verticalScrollBar.scrollBoxPosition(); int y = (line - topLine)*lineHeight(); LOGSECTION("AgDataView::repaintLine"); LOGV(windowId); LOGV((int) this); LOGV((int) frameWindow); LOGV(horizontalScrollBar.scrollBoxPosition()); LOGV(verticalScrollBar.scrollBoxPosition()); LOGV(line); LOGV(cursorLine); IRectangle rect(0,y,dataArea.rect().size().width(), y + lineHeight()); LOGV(rect.asString()); //dataArea.refresh(rect, true); dataArea.refresh(rect); return *this; } AgDataView &AgDataView::copyTo(IClipboard &clipboard) { int i; int nLines = windowData->nLines(); AgCharStack charStack; if (copyTitle.exists()) { //charStack.push(copyTitle).push("\r\n\r\n"); charStack << copyTitle << "\r\n\r\n"; } //charStack.push(windowData->columnHeadTitle()); charStack << windowData->columnHeadTitle(); charStack.push("\r\n"); for (i = 0; i < nLines; i++) { //charStack.push(windowData->getLine(i)); charStack << windowData->getLine(i); charStack.push("\r\n"); } clipboard.setText(charStack.popString().pointer()); return *this; } AgDataView &AgDataView::repositionWindow() { LOGSECTION("AgDataView::repositionWindow"); LOGV(windowId); LOGV((int) this); int horizontalOffset = horizontalScrollBar.scrollBoxPosition() - prevHorizontal; int verticalOffset = verticalScrollBar.scrollBoxPosition() - prevVertical; IPoint displacement(-horizontalOffset, -lineHeight()*verticalOffset); LOGV(displacement.asString()); int oldCursor = cursorLine; int line = verticalScrollBar.scrollBoxPosition(); if (cursorLine < line) { cursorLine = line; } else { LOGV(windowData->nLines()); LOGV(verticalScrollBar.scrollableRange().asString()); LOGV(verticalScrollBar.visibleCount()); //line += verticalScrollBar.visibleCount() - 1; line += verticalLineCount - 1; if (line < 0) { line = 0; } if (cursorLine > line) { cursorLine = line; } } if (columnHeadsPresent) { int pos = horizontalScrollBar.scrollBoxPosition(); if (pos != columnHeadTitle.xPos) { columnHeadTitle.xPos = pos; columnHeadTitle.refresh(); } } LOGV(cursorLine); dataArea.scrollWindow(displacement); dataArea.refresh(); prevHorizontal = horizontalScrollBar.scrollBoxPosition(); prevVertical = verticalScrollBar.scrollBoxPosition(); if (cursorLine != oldCursor) { repaintLine(oldCursor); repaintLine(cursorLine); windowData->synchCursor(cursorLine); selectAction.performDeferred(); } return *this; } Boolean AgDataView::findNext(AgString s) { LOGSECTION("AgDataView::findNext"); LOGV(s); searchProcess.setKey(s); int ln = cursorLine + 1; while (ln < windowData->nLines()) { AgString line = windowData->getLine(ln); LOGV(line); char *p = searchProcess.scanForward(line.pointer(), line.size()); if (p) { LOGV(ln) LCV(line); setCursorLine(ln).synchCursor(ln); return true; } ln++; } return false; } Boolean AgDataView::findPrev(AgString s) { searchProcess.setKey(s); int ln = cursorLine - 1; while (ln >= 0) { AgString line = windowData->getLine(ln); char *p = searchProcess.scanReverse(line.pointer(), line.size()); if (p) { setCursorLine(ln).synchCursor(ln); return true; } ln--; } return false; } AgDataView &AgDataView::setCursorLine(int ln) { LOGSECTION("AgDataView::setCursorLine"); LOGV(ln); LOGV(windowId); LOGV(frameWindow->windowTitle.text()); LOGV((int) this); LOGV((int) frameWindow); LOGV(layoutComplete); int lastLine = windowData->nLines() - 1; if (ln > lastLine) { ln = lastLine; } if (ln < 0) { ln = 0; } int oldLine = cursorLine; LOGV(windowData->nLines()); LOGV(verticalScrollBar.scrollableRange().asString()); LOGV(verticalScrollBar.visibleCount()); //int count = verticalScrollBar.visibleCount(); int count = verticalLineCount; cursorLine = ln; if (!layoutComplete) { return *this; } LOGV(oldLine); LOGV(cursorLine); LOGV(count); int firstLine = verticalScrollBar.scrollBoxPosition(); lastLine = firstLine + count - 1; LOGV(firstLine); LOGV(lastLine); int repositionFlag = 0; if (cursorLine < firstLine) { firstLine = cursorLine; verticalScrollBar.moveScrollBoxTo(firstLine); repositionFlag = 1; } if (cursorLine > lastLine) { firstLine = cursorLine - (count - 1); if (firstLine < 0) { firstLine = 0; } verticalScrollBar.moveScrollBoxTo(firstLine); repositionFlag = 1; } if (repositionFlag) { repositionWindow(); } if (cursorLine == oldLine) { return *this; } //windowData->synchCursor(cursorLine); repaintLine(oldLine); repaintLine(cursorLine); LOGV(firstLine); return *this; } AgDataView &AgDataView::synchCursor(int ln) { windowData->synchCursor(ln); return *this; } /* * * Layout considerations: * * The data view consists of up to four parts: two scroll bars, a heading * and a data area. * * The presence or absence of the scroll bars depends on the relative size * of the data area and the size of the table to be displayed. */ AgDataView &AgDataView::doLayout() { LOGSECTION("AgDataView::doLayout"); LOGV((int) frameWindow); LOGV(id()); LOGV(windowId); LOGV((int) this); LOGV(font().name()); LOGV(font().pointSize()); ISize canvasSize = size(); int canvasWidth = canvasSize.width(); int canvasHeight = canvasSize.height(); if (canvasHeight == 0) { return *this; } //if (tableWidth == 0) tableWidth = findMaxWidth(); tableWidth = findMaxWidth(); tableHeight = lineHeight()*windowData->nLines(); LOGV(canvasWidth); LOGV(canvasHeight); int dataWidth = canvasWidth; int dataHeight = canvasHeight; int dataY = 0; ISize columnHeadSize = columnHeadTitle.minimumSize(); if (columnHeadsPresent) { dataY = columnHeadSize.height() + 2; columnHeadSize.setHeight(dataY); dataHeight -= dataY; columnHeadTitle.moveTo(IPoint(0, 0)); } LOGV(dataWidth); LOGV(dataHeight); int vsbWidth = verticalScrollBar.minimumSize().width(); int hsbHeight = horizontalScrollBar.minimumSize().height(); int horizontalPosition = horizontalScrollBar.scrollBoxPosition(); int verticalPosition = verticalScrollBar.scrollBoxPosition(); Boolean vsb = true; Boolean hsb = true; if (tableHeight > dataHeight && tableWidth <= canvasWidth - vsbWidth - 1) { // vertical scroll bar only vsb = true; hsb = false; } else if (tableWidth > canvasWidth && tableHeight <= dataHeight - hsbHeight - 1) { // horizontal scroll bar only vsb = false; hsb = true; } else if (tableWidth <= canvasWidth && tableHeight <= dataHeight) { // no scroll bars vsb = hsb = false; } if (vsb && !vsbShowing) { verticalScrollBar.moveScrollBoxTo(0); prevVertical = 0; verticalScrollBar.show(); vsbShowing = true; } if (!vsb && vsbShowing) { verticalScrollBar.hide(); vsbShowing = false; verticalScrollBar.moveScrollBoxTo(0); prevVertical = 0; } if (hsb && !hsbShowing) { horizontalScrollBar.show(); hsbShowing = true; horizontalScrollBar.moveScrollBoxTo(0); prevHorizontal = 0; } if (!hsb && hsbShowing) { horizontalScrollBar.hide(); hsbShowing = false; horizontalScrollBar.moveScrollBoxTo(0); prevHorizontal = 0; } if (vsbShowing) { dataWidth -= vsbWidth + 1; verticalScrollBar.moveTo(IPoint(dataWidth+1, 0)); verticalScrollBar.sizeTo(ISize(vsbWidth, canvasHeight)); } if (hsbShowing) { dataHeight -= hsbHeight + 1; horizontalScrollBar.moveTo(IPoint(0, canvasHeight - hsbHeight)); horizontalScrollBar.sizeTo(ISize(dataWidth, hsbHeight)); } dataArea.sizeTo(ISize(dataWidth, dataHeight)); dataArea.moveTo(IPoint(0, dataY)); LOGV(dataArea.size().asString()); LOGV(dataArea.parentSize().asString()); LOGV(rect().asString()); LOGV(dataArea.rect().asString()); LOGV(horizontalScrollBar.rect().asString()); LOGV(verticalScrollBar.rect().asString()); //int widthUnit = charWidth(); horizontalScrollBar.setScrollableRange(IRange(0,tableWidth-1)); horizontalScrollBar.setVisibleCount(dataWidth); LOGV(horizontalScrollBar.scrollableRange().asString()) LCV(tableWidth); LOGV(horizontalScrollBar.visibleCount()) LCV(dataWidth); verticalScrollBar.setScrollableRange(IRange(0, windowData->nLines() - 1)); verticalLineCount = dataHeight/lineHeight(); //verticalScrollBar.setVisibleCount(dataHeight/lineHeight()); verticalScrollBar.setVisibleCount(verticalLineCount); LOGV(dataHeight/lineHeight()); LOGV(windowData->nLines()); LOGV(verticalScrollBar.scrollableRange().asString()); LOGV(verticalScrollBar.visibleCount()); LOGV(verticalLineCount); horizontalPosition = min( (int) horizontalScrollBar.scrollBoxRange().upperBound(), horizontalPosition ); verticalPosition = min( (int) verticalScrollBar.scrollBoxRange().upperBound(), verticalPosition ); horizontalScrollBar.setMinScrollIncrement(charWidth()); verticalScrollBar.setMinScrollIncrement(1); prevHorizontal = horizontalScrollBar.scrollBoxPosition(); horizontalScrollBar.moveScrollBoxTo(horizontalPosition); prevVertical = verticalScrollBar.scrollBoxPosition(); verticalScrollBar.moveScrollBoxTo(verticalPosition); LOGV(prevHorizontal); LOGV(prevVertical); LOGV(horizontalPosition); LOGV(verticalPosition); LOGV(horizontalScrollBar.scrollBoxPosition()); LOGV(verticalScrollBar.scrollBoxPosition()); LOGV(verticalPosition); if (columnHeadsPresent) { columnHeadSize.setWidth(dataWidth); columnHeadTitle.sizeTo(columnHeadSize); columnHeadTitle.xPos = horizontalPosition; columnHeadTitle.refresh(); } layoutComplete = 1; setCursorLine(cursorLine).synchCursor(cursorLine); return *this; } Boolean AgDataView::lineDown(IScrollEvent &event) { if (event.scrollBarWindow() != &verticalScrollBar) { return false; } LOGSECTION("AgDataView::lineDown"); moveScrollBox(event); repositionWindow(); return true; } Boolean AgDataView::lineLeft(IScrollEvent &event) { if (event.scrollBarWindow() != &horizontalScrollBar) { return false; } LOGSECTION("AgDataView::lineLeft"); moveScrollBox(event); repositionWindow(); return true; } Boolean AgDataView::lineRight(IScrollEvent &event) { if (event.scrollBarWindow() != &horizontalScrollBar) { return false; } LOGSECTION("AgDataView::lineRight"); LOGV(horizontalScrollBar.scrollBoxPosition()); moveScrollBox(event); repositionWindow(); LOGV(horizontalScrollBar.scrollBoxPosition()); return true; } Boolean AgDataView::lineUp(IScrollEvent &event) { if (event.scrollBarWindow() != &verticalScrollBar) { return false; } LOGSECTION("AgDataView::lineUp"); moveScrollBox(event); repositionWindow(); return true; } Boolean AgDataView::pageDown(IScrollEvent &event) { if (event.scrollBarWindow() != &verticalScrollBar) { return false; } LOGSECTION("AgDataView::pageDown"); moveScrollBox(event); repositionWindow(); return true; } Boolean AgDataView::pageLeft(IScrollEvent &event) { if (event.scrollBarWindow() != &horizontalScrollBar) { return false; } LOGSECTION("AgDataView::pageLeft"); moveScrollBox(event); repositionWindow(); return true; } Boolean AgDataView::pageRight(IScrollEvent &event) { if (event.scrollBarWindow() != &horizontalScrollBar) { return false; } LOGSECTION("AgDataView::pageRight"); moveScrollBox(event); repositionWindow(); return true; } Boolean AgDataView::pageUp(IScrollEvent &event) { if (event.scrollBarWindow() != &verticalScrollBar) { return false; } LOGSECTION("AgDataView::pageUp"); moveScrollBox(event); repositionWindow(); return true; } Boolean AgDataView::scrollBoxTrack(IScrollEvent &event) { LOGSECTION("AgDataView::scrollBoxTrack"); LOGV(verticalScrollBar.scrollBoxPosition()); LOGV(horizontalScrollBar.scrollBoxPosition()); moveScrollBox(event); //if (!event.controlWindow()->hasPointerCaptured()) { // event.controlWindow()->capturePointer(true); //} LOGV(verticalScrollBar.scrollBoxPosition()); LOGV(horizontalScrollBar.scrollBoxPosition()); repositionWindow(); return true; } Boolean AgDataView::scrollBoxTrackEnd(IScrollEvent &event) { //event.controlWindow()->releasePointer(); moveScrollBox(event); repositionWindow(); return true; } Boolean AgDataView::key(IKeyboardEvent &event) { return false; } Boolean AgDataView::virtualKeyPress(IKeyboardEvent &event) { LOGSECTION("AgDataView::virtualKeyPress"); LOGV((int) frameWindow); LOGV((int) event.virtualKey()); LOGV(event.isShiftDown()) LCV(event.isCtrlDown()) LCV(event.isAltDown()); switch (event.virtualKey()) { case IKeyboardEvent::newLine: case IKeyboardEvent::enter: { LOGSECTION("AgDataView::enter"); if (enterAction.exists()) { enterAction.performDeferred(); } return true; } case IKeyboardEvent::up: { int line = cursorLine; if (cursorLine > 0) { cursorLine--; } else { messageBeep(); } if (line != cursorLine) { windowData->synchCursor(cursorLine); selectAction.performDeferred(); } LOGV(cursorLine); if (cursorLine < verticalScrollBar.scrollBoxPosition()) { repaintLine(line); verticalScrollBar.moveScrollBoxTo(cursorLine); repositionWindow(); return true; } repaintLine(line); repaintLine(cursorLine); return true; } case IKeyboardEvent::down: { LOGSECTION("Cursor down one line"); int line = cursorLine; if (cursorLine < windowData->nLines() - 1) { cursorLine++; } else { messageBeep(); } if (line != cursorLine) { selectAction.performDeferred(); windowData->synchCursor(cursorLine); } LOGV(line) LCV(cursorLine); LOGV((int) this); LOGV((int) &cursorLine); LOGV(cursorLine); int bottomLine = verticalScrollBar.scrollBoxPosition() + verticalLineCount - 1; //+ verticalScrollBar.visibleCount() - 1; LOGV(line); LOGV(cursorLine); LOGV(bottomLine); if (cursorLine > bottomLine) { LOGS("scrolling"); verticalScrollBar.moveScrollBoxTo( cursorLine - verticalLineCount + 1 //- verticalScrollBar.visibleCount() + 1 ); repositionWindow(); } repaintLine(line); repaintLine(cursorLine); return true; } case IKeyboardEvent::pageUp: { int line = cursorLine; if (cursorLine == 0) { messageBeep(); return true; } //cursorLine -= verticalScrollBar.visibleCount(); cursorLine -= verticalLineCount; if (cursorLine < 0 || event.isCtrlDown()) { cursorLine = 0; repaintLine(line); repaintLine(cursorLine); } if (cursorLine < verticalScrollBar.scrollBoxPosition()) { verticalScrollBar.moveScrollBoxTo(cursorLine); repositionWindow(); } if (line != cursorLine) { windowData->synchCursor(cursorLine); selectAction.performDeferred(); } return true; } case IKeyboardEvent::home: { if (cursorLine && event.isCtrlDown()) { int line = cursorLine; cursorLine = 0; windowData->synchCursor(cursorLine); selectAction.performDeferred(); if (cursorLine < verticalScrollBar.scrollBoxPosition()) { repaintLine(line); verticalScrollBar.moveScrollBoxTo(cursorLine); repositionWindow(); return true; } repaintLine(line); repaintLine(cursorLine); return true; } else { messageBeep(); } return true; } case IKeyboardEvent::end: { int lastLine = windowData->nLines() - 1; if (cursorLine < lastLine && event.isCtrlDown()) { int line = cursorLine; cursorLine = lastLine; windowData->synchCursor(cursorLine); selectAction.performDeferred(); if (cursorLine < verticalScrollBar.scrollBoxPosition()-verticalLineCount) { repaintLine(line); verticalScrollBar.moveScrollBoxTo(cursorLine); repositionWindow(); return true; } repaintLine(line); repaintLine(cursorLine); return true; } else { messageBeep(); } return true; } case IKeyboardEvent::pageDown: { int line = cursorLine; cursorLine += verticalLineCount; int lastLine = windowData->nLines() - 1; if (cursorLine == lastLine) { messageBeep(); return true; } if (cursorLine > lastLine || event.isCtrlDown()) { cursorLine = lastLine; repaintLine(line); repaintLine(cursorLine); } if (cursorLine > verticalScrollBar.scrollBoxPosition()) { verticalScrollBar.moveScrollBoxTo( cursorLine - verticalLineCount + 1 ); repositionWindow(); } if (line != cursorLine) { windowData->synchCursor(cursorLine); selectAction.performDeferred(); } return true; } case IKeyboardEvent::left: { int position = horizontalScrollBar.scrollBoxPosition() - charWidth(); if (position >= 0) { horizontalScrollBar.moveScrollBoxTo(position); repositionWindow(); } else { messageBeep(); } return true; } case IKeyboardEvent::right: { int position = horizontalScrollBar.scrollBoxPosition() + charWidth(); if (position <= horizontalScrollBar.scrollableRange().upperBound()) { horizontalScrollBar.moveScrollBoxTo(position); repositionWindow(); } else { messageBeep(); } return true; } //default: return false; } return false; } Boolean AgDataView::mouseClicked(IMouseClickEvent &event) { //LOGSECTION("AgDataView::mouseClicked", Log::off); LOGSECTION_OFF("AgDataView::mouseClicked"); LOGV(frameWindow->activeFlag); unsigned line = event.mousePosition().y()/lineHeight(); line += verticalScrollBar.scrollBoxPosition(); unsigned nLines = windowData->nLines(); if (ControlPanel::helpCursorSet) { if (event.mouseButton() == IMouseClickEvent::button2) { return false; } if (event.mouseAction() == IMouseClickEvent::down) { if (line < nLines && line != cursorLine) { setCursorLine(line).synchCursor(line); selectAction.performDeferred(); } showHelp(event); ControlPanel::helpCursorSet = 0; ControlPanel::resetCursor(); } return true; } if (event.controlWindow() == &columnHeadTitle || event.controlWindow() == &verticalScrollBar || event.controlWindow() == &horizontalScrollBar) { if (event.mouseAction() == IMouseClickEvent::down) { dataArea.setFocus(); } return false; } LOGV(event.mouseButton()); LOGV(event.mouseAction()); LOGV(line); if (event.mouseButton() == IMouseClickEvent::button2) { if (!dataArea.hasFocus()) { dataArea.setFocus(); } if (line >= nLines) { return true; } /* if (event.mouseAction() == IMouseClickEvent::down) { rightButtonDown = true; } else if (event.mouseAction() == IMouseClickEvent::up) { rightButtonDown = false; } else if (event.mouseAction() == IMouseClickEvent::click) { LOGS("right click"); if (line == cursorLine) { //return true; return false; } setCursorLine(line).synchCursor(line); selectAction.performDeferred(); return false; } */ if (event.mouseAction() == IMouseClickEvent::down) { rightButtonState = buttonDown; } else if (event.mouseAction() == IMouseClickEvent::up) { rightButtonState = waitingForClick; if (line == cursorLine) { return false; } setCursorLine(line).synchCursor(line); selectAction.performDeferred(); return false; } else if (event.mouseAction() == IMouseClickEvent::click) { rightButtonState = buttonIdle; return false; } } if (line >= nLines && event.mouseAction() == IMouseClickEvent::down) { if (!dataArea.hasFocus()) { dataArea.setFocus(); } return false; } if (!mouseDown && line >= nLines) { return false; } if (event.mouseButton() != IMouseClickEvent::button1) { return false; } switch (event.mouseAction()) { case IMouseClickEvent::down: { if (event.windowUnderPointer() != dataArea.handle()) { return false; } LOGS("mouse down"); if (!dataArea.hasFocus()) { dataArea.setFocus(); } dataArea.capturePointer(true); mouseDownCursorLine = cursorLine; if (line != cursorLine) { setCursorLine(line).synchCursor(line); selectAction.performDeferred(); } mouseDown = true; return true; } case IMouseClickEvent::up: { LOGS("mouse up"); mouseDown = false; dataArea.capturePointer(false); return true; } case IMouseClickEvent::click: { if (event.windowUnderPointer() != dataArea.handle()) { return false; } LOGS("mouse click"); return true; } case IMouseClickEvent::doubleClick: { LOGS("double click"); enterAction.performDeferred(); return true; } } return false; } Boolean AgDataView::mouseMoved(IMouseEvent &event) { if (!mouseDown) { return false; } if (mouseTimer.isStarted()) { mouseTimer.stop(); } int mouseY = event.mousePosition().y(); if (mouseY < 0) { mouseY -= lineHeight(); } int mouseLine = mouseY/lineHeight(); int topLine = verticalScrollBar.scrollBoxPosition(); LOGSECTION("AgDataView::mouseMoved"); LOGV((int) frameWindow); LOGV(topLine) LCV(mouseLine); dragMouse(topLine, mouseLine); if (mouseLine >= 0 && mouseLine < verticalLineCount) { return true; } topLine = verticalScrollBar.scrollBoxPosition(); IReference<ITimerFn> timerFn(new MouseDragTimer(this, topLine, mouseLine)); mouseTimer.start(timerFn, 50); LOGS("timer started"); return true; } void AgDataView::dragMouse(int topLine, int mouseLine) { LOGSECTION("AgDataView::DragMouse"); LOGV((int) frameWindow); int bottomLine = topLine + verticalLineCount - 1; int line = topLine + mouseLine; if (line < 0) { line = 0; } if (line >= windowData->nLines()) { line = windowData->nLines() - 1; } if (line == cursorLine) { return; } int oldLine = cursorLine; cursorLine = line; windowData->synchCursor(cursorLine); selectAction.performDeferred(); LOGV(topLine); LOGV(mouseLine); LOGV(oldLine); LOGV(cursorLine); if (cursorLine < topLine) { repaintLine(oldLine); verticalScrollBar.moveScrollBoxTo(cursorLine); repositionWindow(); return; } //if (cursorLine > bottomLine + 1) { if (cursorLine > bottomLine) { repaintLine(oldLine); verticalScrollBar.moveScrollBoxTo(topLine + cursorLine - bottomLine); repositionWindow(); return; } else { repaintLine(oldLine); repaintLine(cursorLine); } LOGV(cursorLine); windowData->synchCursor(cursorLine); selectAction.performDeferred(); return; } void AgDataView::mouseDragTimerInterrupt(int &topLine, int mouseLine) { LOGSECTION("AgDataView::mouseDragTimerInterrupt"); LOGV((int) frameWindow); LOGV(topLine) LCV(mouseLine) LCV(cursorLine); if (!mouseDown || topLine + mouseLine == cursorLine) { mouseTimer.stop(); LOGV(mouseDown); LOGV(topLine) LCV(verticalScrollBar.scrollBoxPosition()); return; } if (topLine + mouseLine != cursorLine) { dragMouse(topLine, mouseLine); } topLine = verticalScrollBar.scrollBoxPosition(); } AgDataView::MouseDragTimer::MouseDragTimer(AgDataView * window_, int topLine_, int mouseLine_) : window(window_) , topLine(topLine_) , mouseLine(mouseLine_) {} void AgDataView::MouseDragTimer::timerExpired(unsigned long) { LOGSECTION("AgDataView::MouseDragTimer::timerExpired"); window->mouseDragTimerInterrupt(topLine, mouseLine); } Boolean AgDataView::command(ICommandEvent &event) { unsigned id = event.commandId() - 1; LOGSECTION("AgDataView::command"); LOGV((int) event.controlWindow()); LOGV((int) event.dispatchingWindow()); LOGV((int) frameWindow); LOGV((int) id); if (id >= auxMenu.size()) { return false; } LOGV(ControlPanel::helpCursorSet) LCV(AgFrame::menuShowingFlag); if (ControlPanel::helpCursorSet) { ControlPanel::helpCursorSet = 0; ControlPanel::resetCursor(); AgHelpWindow::showHelp(auxMenu[id].text); return true; } auxMenu[id].action.perform(); return true; } AgDataView &AgDataView::initPopUp() { if (popUpInitialized) { return *this; } popUpInitialized = 1; LOGSECTION("AgDataView::initPopUp"); LOGV(windowId); LOGV((int) this); LOGV((int) frameWindow); LOGV((int) &popUpMenu); int n = auxMenu.size(); int i; for (i = 0; i < n; i++) { char *text = auxMenu[i].text.pointer(); LOGV(text); LOGV((int) auxMenu[i].displayControl); popUpMenu.addText(i+1, text); } return *this; } AgDataView &AgDataView::validatePopUp() { LOGSECTION("AgDataView::validatePopUp"); LOGV(windowId) LCV((int) this); LOGV((int) frameWindow) LCV((int) windowData); LOGV(windowData->getCursorLine()); LOGV(ControlPanel::helpCursorSet) LCV(AgFrame::menuShowingFlag); if (ControlPanel::helpCursorSet) { return *this; } int n = auxMenu.size(); LOGV(n); int i; for (i = 0; i < n; i++) { //char *text = auxMenu[i].text.pointer(); //LOGV(text); dc *d = auxMenu[i].displayControl; LOGV((int) d); ok_ptr(d); dc::MenuOption **option = d->getAuxWinMenu(); #ifdef INCLUDE_LOGGING LOGV((int) option) LCV((int) option[i]); union { int(dc::*fun)(); int address; } kluge; kluge.fun = option[i]->ok_action; LOGV(kluge.address); #endif int flag = ((*d).*(option[i]->ok_action))(); LOGV(flag); popUpMenu.enableItem(i+1, flag); } return *this; } Boolean AgDataView::makePopUpMenu(IMenuEvent &event ) { LOGSECTION("AgDataView::makePopUpMenu"); LOGV(windowId); LOGV((int) this); LOGV((int) frameWindow); if (!auxMenu.exists()) { return false; } IPoint where = dataArea.position(); if (rightButtonState == waitingForClick) { LOGV(event.mousePosition().asString()); where = event.mousePosition(); } LOGV(auxMenu.exists()); int n = auxMenu.size(); int i; for (i = 0; i < n; i++) { popUpMenu.enableItem(i+1); } validatePopUp(); AgFrame::activeAuxMenu = auxMenu; LOGS("activeAuxMenu has been set"); AgFrame::activePopUpMenu = &popUpMenu; LOGS("activePopUpMenu has been set"); LOGS("ready to display popUpMenu"); //popUpMenu.show(event.mousePosition()); popUpMenu.show(where); LOGS("popUpMenu should be visible"); AgFrame::activeAuxMenu.discardData(); AgFrame::activePopUpMenu = 0; return true; } Boolean AgDataView::showHelp(IEvent &event) { showHelp(); return true; } void AgDataView::showHelp() { AgString topic; LOGSECTION("AgDataView::showHelp"); int n = popUpMenu.numberOfItems(); for (int i = 0; i++ < n;) { IMenuItem item = popUpMenu.menuItem(i); if (item.isHighlighted()) { topic = auxMenu[i-1].text; break; } } LOGV(i) LCV(n) LCV(topic); if (!topic.exists() && helpTopic != 0) { topic = helpTopic; } if (!topic.exists()) { topic = windowData->findHelpTopic(); } if (!topic.exists()) { topic = windowData->headTitle(); } AgHelpWindow::showHelp(topic); } Boolean AgDataView::menuEnded(IMenuEvent &event) { LOGSECTION("AgDataView::menuEnded"); LOGV((int) frameWindow); LOGV(ControlPanel::helpCursorSet) LCV(AgFrame::menuShowingFlag); if (!ControlPanel::helpCursorSet) { frameWindow->activeAuxMenu.discardData(); } return true; }