view anagram/vaclgui/dspar.cpp @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -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.
 *
 * dspar.cpp
 */

#include <ifontdlg.hpp>
#include <ifonthdr.hpp>
#include <windows.h>

#include "agcstack.h"
#include "cint.h"
#include "dspar.hpp"
#include "helpview.hpp"
#include "myalloc.h"
#include "vaclgui.hpp"

//#define INCLUDE_LOGGING
#include "log.h"


FontDialog::FontDialog()
  : AgFrame(  IFrameWindow::border
            | dialogBackground
            | IFrameWindow::systemMenu)
  , canvas(nextChildId(), this, this, IRectangle(),
	     IMultiCellCanvas::classDefaultStyle
	   | IWindow::clipChildren)
  , fontChoices(nextChildId(), &canvas, &canvas, IRectangle(),
		  ISetCanvas::horizontalDecks
		| ISetCanvas::packEven
		| ISetCanvas::rightAlign
		| ISetCanvas::centerVerticalAlign
		| IWindow::clipChildren
		| IWindow::visible)
  , buttons(nextChildId(), &canvas, &canvas, IRectangle(),
              ISetCanvas::horizontalDecks
	    | ISetCanvas::packExpanded
	    | ISetCanvas::rightAlign
	    | ISetCanvas::topAlign
	    | IWindow::clipChildren
	    | IWindow::visible)
  , undoButton(undoCommand, &buttons, &buttons)
  , defaultButton(defaultCommand, &buttons, &buttons)
  , cancelButton(cancelCommand, &buttons, &buttons)
  , helpButton(helpCommand, &buttons, &buttons)
  , fontDialogActive(0)
{
  LOGSECTION("FontDialog::FontDialog");
  IPaintHandler::handleEventsFor(&canvas);
  IPaintHandler::handleEventsFor(&fontChoices);
  IPaintHandler::handleEventsFor(&buttons);
  setClient(&canvas);
  {
    int i;
    IStaticText *text;
    IPushButton *button;

    for (i = 0; i < nFontSpecs; i++) {
      LOGV(i);
      text = new IStaticText(nextChildId(), &fontChoices, &fontChoices);
      LOGV((int) text);
      button = new IPushButton(i+1, &fontChoices, &fontChoices);
      LOGV((int) button);
      text->setText(specRecord[i].title);
      text->setAlignment(IStaticText::centerRight);

      LOGV(specRecord[i].title);
      button->setText(specRecord[i].pointer->description().pointer());
      button->enableTabStop();
      LOGV((int) &optionRecord[i]);
      optionRecord[i].text = text;
      optionRecord[i].button = button;
      LOGV((int) optionRecord[i].button);
    }
    optionRecord[0].button->setText("100 point New Times Roman bold italic");
    ISize buttonSize = optionRecord[0].button->minimumSize();
    LOGV(buttonSize.asString());
    optionRecord[0].button->setText(
      specRecord[0].pointer->description().pointer()
    );
    for (i = 0; i < nFontSpecs; i++) {
      LOGV(i);
      LOGV((int) optionRecord[i].button);
      optionRecord[i].button->setMinimumSize(buttonSize);
    }

    fontChoices.setDeckCount(nFontSpecs);
    buttons.setDeckCount(1);
    {
      undoButton.setText("Undo").enableTabStop();
      defaultButton.setText("Default").enableTabStop();
      cancelButton.setText("Close").enableTabStop();
      helpButton.setText("Help").enableTabStop();
    }
  }
  windowTitle.setText("AnaGram - Set Fonts");
  registerTitle("Set Fonts");
  int choicesWidth = fontChoices.size().width();
  int buttonsWidth = buttons.size().width();
  canvas.setColumnWidth(1, choicesWidth - buttonsWidth);
  canvas.setColumnWidth(2, buttonsWidth);
  canvas.addToCell(&fontChoices, 1, 1, 2);
  canvas.addToCell(&buttons, 2, 2);
  ISize minSize = canvas.minimumSize();
  sizeTo(frameRectFor(minSize).size());
  positionFrame();
  show().setFocus();
  LOGV(isVisible());
  LOGV(isShowing());
  LOGV(rect().asString());
}

FontDialog::~FontDialog() {
  IPaintHandler::stopHandlingEventsFor(&canvas);
  IPaintHandler::stopHandlingEventsFor(&fontChoices);
  IPaintHandler::stopHandlingEventsFor(&buttons);
}

Boolean FontDialog::paintWindow(IPaintEvent &event) {
  LOGSECTION("FontDialog::paintWindow");
  event.clearBackground(IGUIColor::dialogBgnd);
  return false;
}

RGBSelector::RGBSelector(IWindow *owner, IColor color)
  : ISetCanvas(nextChildId(), owner, owner, IRectangle(),
	         horizontalDecks
	       | centerAlign
	       | packEven
	       | visible)
  , redSpinner(nextChildId(), this, this)
  , greenSpinner(nextChildId(), this, this)
  , blueSpinner(nextChildId(), this, this)
  , redText(nextChildId(), this, this)
  , greenText(nextChildId(), this, this)
  , blueText(nextChildId(), this, this)
{
  LOGSECTION("RGBSelector::RGBSelector");
  redText.setText("Red").setAlignment(IStaticText::topCenter);
  greenText.setText("Green").setAlignment(IStaticText::topCenter);
  blueText.setText("Blue").setAlignment(IStaticText::topCenter);
  IRange range(0, 255);
  LOGV(color.redMix()) LCV(color.greenMix()) LCV(color.blueMix());
  redSpinner
   . setRange(range)
   . spinTo(color.redMix())
   . setLimit(3)
   . enableTabStop()
   ;

  greenSpinner
   . setRange(range)
   . spinTo(color.greenMix())
   . setLimit(3)
   . enableTabStop()
   ;

  blueSpinner
   . setRange(range)
   . spinTo(color.blueMix())
   . setLimit(3)
   . enableTabStop()
   ;

  setDeckCount(2);
  ISpinHandler::handleEventsFor(&redSpinner);
  ISpinHandler::handleEventsFor(&greenSpinner);
  ISpinHandler::handleEventsFor(&blueSpinner);
  IEditHandler::handleEventsFor(&redSpinner);
  IEditHandler::handleEventsFor(&greenSpinner);
  IEditHandler::handleEventsFor(&blueSpinner);
  show();
}

RGBSelector::~RGBSelector() {
  ISpinHandler::stopHandlingEventsFor(&redSpinner);
  ISpinHandler::stopHandlingEventsFor(&greenSpinner);
  ISpinHandler::stopHandlingEventsFor(&blueSpinner);
  IEditHandler::stopHandlingEventsFor(&redSpinner);
  IEditHandler::stopHandlingEventsFor(&greenSpinner);
  IEditHandler::stopHandlingEventsFor(&blueSpinner);
}

Boolean RGBSelector::edit(IControlEvent &event) {
  //controlWindow()->spinTo(controlWindow()->value());
  changeAction.perform();
  return false;
}


AgString ColorPair::string() {
  char buf[100];
  sprintf(buf, "(%x,%x)", fg.asRGBLong(), bg.asRGBLong());
  return buf;
}

void ColorPair::setValue(char *s) {
  sscanf(s, "(%d,%d)", &fg, &bg);
}


ColorSelector::ColorSelector(ColorDialog *owner_, ColorPair &colorPair_)
  : AgDialog(owner_)
  , ownerDialog(owner_)
  , colorPair(colorPair_)
  , canvas(nextChildId(), this, this, IRectangle(),
	     IMultiCellCanvas::classDefaultStyle
	   | IWindow::clipChildren)
  , workArea(nextChildId(), &canvas, &canvas, IRectangle(),
	       ISetCanvas::verticalDecks
	     | ISetCanvas::packEven
	     | ISetCanvas::centerAlign
	     | ISetCanvas::centerVerticalAlign
	     | IWindow::clipChildren
	     | IWindow::visible)
  , sampleText(nextChildId(), &workArea, &workArea)
  , selectorCanvas(nextChildId(), &workArea, &workArea, IRectangle(),
		     ISetCanvas::verticalDecks
		   | ISetCanvas::packEven
		   | ISetCanvas::leftAlign
		   | IWindow::clipChildren
		   | IWindow::visible)
  , foregroundSelector(&selectorCanvas, colorPair_.fg)
  , backgroundSelector(&selectorCanvas, colorPair_.bg)
  , buttonCanvas(&canvas)
  , okButton(okCommand, &buttonCanvas,
	       IPushButton::defaultButton
	     | IWindow::visible)
  , cancelButton(cancelCommand, &buttonCanvas)
{
  LOGSECTION("ColorSelector::ColorSelector");
  foregroundSelector.setText("Foreground:");
  backgroundSelector.setText("Background:");
  sampleText.setText("Sample Text").setAlignment(IStaticText::centerCenter);
  sampleText.setForegroundColor(colorPair.fg);
  sampleText.setBackgroundColor(colorPair.bg);
  sampleText.setMinimumSize(foregroundSelector.minimumSize());
  setClient(&canvas);
  selectorCanvas.setDeckCount(1);
  workArea.setDeckCount(1);

  cancelButton.setText("Cancel");

  int width = workArea.minimumSize().width();
  int buttonCanvasWidth = buttonCanvas.minimumSize().width();
  LOGV(width);
  LOGV(buttonCanvasWidth);
  canvas.setColumnWidth(1, width - buttonCanvasWidth);
  canvas.setColumnWidth(2, buttonCanvasWidth);
  canvas.addToCell(&workArea, 1, 1, 2);
  canvas.addToCell(&buttonCanvas, 2, 2, 1);


  foregroundSelector.setChangeAction(actionObject(this, changeForeground));
  backgroundSelector.setChangeAction(actionObject(this, changeBackground));

  removeDefaultHandler();
  IFrameHandler::handleEventsFor(this);
  IPaintHandler::handleEventsFor(&canvas);
  IPaintHandler::handleEventsFor(&workArea);
  IPaintHandler::handleEventsFor(&selectorCanvas);
  IPaintHandler::handleEventsFor(&buttonCanvas);

  ISize size = canvas.minimumSize();
  LOGV(size);
  sizeTo(frameRectFor(IRectangle(size)).size());
  setFocus();
}

ColorSelector::~ColorSelector() {
  IFrameHandler::stopHandlingEventsFor(this);
  IPaintHandler::stopHandlingEventsFor(&canvas);
  IPaintHandler::stopHandlingEventsFor(&workArea);
  IPaintHandler::stopHandlingEventsFor(&selectorCanvas);
  IPaintHandler::stopHandlingEventsFor(&buttonCanvas);
}

Boolean ColorSelector::paintWindow(IPaintEvent &event) {
  LOGSECTION("ColorSelector::paintWindow");
  event.clearBackground(IGUIColor::dialogBgnd);
  return false;
}


Boolean ColorSelector::command(ICommandEvent &event) {
  LOGSECTION("ColorSelector::command");
  switch (event.commandId()) {
    case okCommand:
      colorPair = ColorPair(foregroundSelector.value(),
			    backgroundSelector.value());
      dismiss(1);
      return true;
    case cancelCommand:
      dismiss(0);
      return true;
  }
  return false;
}

ColoredButton::ColoredButton(long id, IWindow *owner, 
			     ColorSpec *colorPair, char *text)
  : IPushButton(id, owner, owner)
  , fgColor(colorPair->fg())
  , bgColor(colorPair->bg())
{
  LOGSECTION("ColoredButton::ColoredButton");
  LOGV(fgColor.redMix()) LCV(fgColor.greenMix()) LCV(fgColor.blueMix());
  LOGV(bgColor.redMix()) LCV(bgColor.greenMix()) LCV(bgColor.blueMix());
  setText(text);
  enableTabStop();
}

ColorDialog::ColorDialog()
  : AgFrame(IFrameWindow::border | IFrameWindow::systemMenu)
  , canvas(nextChildId(), this, this, IRectangle(),
	     ISetCanvas::verticalDecks
	   | ISetCanvas::packEven
	   | ISetCanvas::rightAlign
	   | ISetCanvas::centerVerticalAlign
	   | IWindow:: clipChildren
	   | IWindow::visible)
  , colorChoices(nextChildId(), &canvas, &canvas, IRectangle(),
		   ISetCanvas::verticalDecks
		 | ISetCanvas::packExpanded
		 | ISetCanvas::centerAlign
		 | ISetCanvas::bottomAlign
		 | IWindow::clipChildren
		 | IWindow::visible)
  , buttons(&canvas)
  , undoButton(undoCommand, &buttons)
  , defaultButton(defaultCommand, &buttons)
  , cancelButton(cancelCommand, &buttons)
  , helpButton(helpCommand, &buttons)
  //, activeDialog(0)
{
  LOGSECTION("ColorDialog::ColorDialog");
  IPaintHandler::handleEventsFor(&colorChoices);
  IPaintHandler::handleEventsFor(&buttons);
  setClient(&canvas);
  int i;

  int maxWidth = 0;
  for (i = 0; i < nColorSpecs; i++) {
    LOGV(i);
    ColorSpec *colorSpec = specRecord[i].pointer;
    IColor fg = colorSpec->fg();
    IColor bg = colorSpec->bg();
    LOGV(fg.redMix()) LCV(fg.greenMix()) LCV(fg.blueMix());
    LOGV(bg.redMix()) LCV(bg.greenMix()) LCV(bg.blueMix());
    buttonList[i] = new ColoredButton(i+1, &colorChoices,
				      specRecord[i].pointer,
				      specRecord[i].title);
    int width = buttonList[i]->minimumSize().width();
    if (maxWidth < width) {
      maxWidth = width;
    }
  }
  canvas.setDeckCount(1);
  colorChoices.setDeckCount(2);
  windowTitle.setText("AnaGram - Set Colors");
  registerTitle("Set Colors");
  canvas.setBackgroundColor(IGUIColor(IGUIColor::dialogBgnd));
  ISize choicesSize = colorChoices.size();
  int choicesWidth = choicesSize.width();
  int buttonsWidth = buttons.size().width();
  if (choicesWidth < buttonsWidth) {
    choicesWidth = buttonsWidth;
    choicesSize.setWidth(choicesWidth);
    colorChoices.sizeTo(choicesSize);
  }
  LOGV(colorChoices.minimumSize());
  LOGV(buttons.minimumSize());
  ISize size = canvas.minimumSize();
  LOGV(size);
  sizeTo(frameRectFor(IRectangle(size)).size());
  positionFrame();
  show().setFocus();
  LOGV(isVisible());
  LOGV(isShowing());
  LOGV(rect().asString());
}

ColorDialog::~ColorDialog() {
  IPaintHandler::stopHandlingEventsFor(&canvas);
  IPaintHandler::stopHandlingEventsFor(&colorChoices);
  IPaintHandler::stopHandlingEventsFor(&buttons);
}

Boolean ColorDialog::paintWindow(IPaintEvent &event) {
  LOGSECTION("ColorDialog::paintWindow");
  event.clearBackground(IGUIColor::dialogBgnd);
  return false;
}


Boolean ColorSelector::activated(IFrameEvent &event) {
  AgFrame::windowRegistry.markActive(ownerDialog->windowId);
  return false;
}

Boolean ColorDialog::command(ICommandEvent &event) {
  LOGSECTION("ColorDialog::command");
  LOGV(event.commandId());
  switch (event.commandId()) {
    case undoCommand: {
      LOGS("undo");
      if (undoStack.size() == 0) {
        messageBeep();
        return true;
      }
      undoStack.pop(undoRecord);
      ColorSpec &colorSpec = *undoRecord.pointer;
      //int option = undoRecord.buttonNumber;
      ColorPair colorPair = undoRecord.colorPair;
      colorSpec = undoRecord.colorPair;
      return true;
    }
    case defaultCommand: {
      int i;
      for (i = 0; i < nColorSpecs; i++) {
        undoRecord.pointer = specRecord[i].pointer;
        undoRecord.colorPair = *undoRecord.pointer;
        undoRecord.buttonNumber =i;

        undoRecord.pointer->reset();
        undoStack.push(undoRecord);
      }
      return true;
    }
    case cancelCommand: {
      AgFrame::windowRegistry.remove(windowId);
      close();
      return true;
    }
    case helpCommand: {
      LOGSECTION("ColorDialog::helpCommand");
      AgHelpWindow::showHelp("Set Colors");
      return true;
    }
    default: if (event.commandId() <= nColorSpecs) {
      int option = event.commandId() - 1;
      LOGS(specRecord[option].title);
      undoRecord.pointer = specRecord[option].pointer;
      ColorPair colorPair= *undoRecord.pointer;
      undoRecord.colorPair = colorPair;
      undoRecord.buttonNumber = option;

      ColorSelector colorSelector(this, colorPair);
      char *title = specRecord[option].title;
      colorSelector.windowTitle.setText(title);
      LOGS("Ready to show modal dialog");
/*
  #ifdef AG_WINDOWS
      RECT r;
      SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
      ISize size(r.right - r.left, r.bottom - r.top);
  #else
      ISize size = IWindow::desktopWindow()->size();
  #endif
      IPoint where = (IPair) place(size, colorSelector.size(), 22);
*/
      IPoint where = placeOnDesktop(colorSelector.size(), 22);
      IPoint buttonWhere = buttonList[option]->position();
      int height = buttonList[option]->size().height();
      buttonWhere += position() + ISize(0,height);
      buttonWhere += canvas.position();
      buttonWhere += colorChoices.position();
      where = where.minimum(buttonWhere);
      colorSelector.moveTo(where);
      modalDialog = &colorSelector;
      int flag = colorSelector.showModally();
      modalDialog = 0;
      LOGV(flag);
      if (!flag) {
	return true;
      }
      *undoRecord.pointer = colorPair;


      undoStack.push(undoRecord);
    }
    else {
      return AgFrame::command(event);
    }
  }
  return true;
}

static IColor makeColor(int x) {
  LOGSECTION("makeColor");
  int red, green, blue;
  red = x & 0xff;
  x >>= 8;
  green = x & 0xff;
  x >>= 8;
  blue = x & 0xff;
  LOGV(x) LCV(red) LCV(green) LCV(blue);
  IColor value(red, green, blue);
  LOGV(value.asRGBLong());
  return value;
}

void ColorDialog::initColor(AgString name, cint p) {
  LOGSECTION("ColorDialog::initColor");
  //int f = p.x;
  IColor fg = makeColor(p.x);
  IColor bg = makeColor(p.y);
  LOGV(name) LCV(fg.asRGBLong()) LCV(bg.asRGBLong());
  for (int i = 0; i < nColorSpecs; i++) {
    if (name != specRecord[i].title) {
      continue;
    }
    specRecord[i].pointer->initialize(ColorPair(fg,bg));
    return;
  }
}

Boolean FontSpec::reset() {
  contents = defaultFont;
  notify();
  return 1;
}

Boolean ColorSpec::reset() {
  contents = defaultValue;
  notify();
  return 1;
}

FontDialog::SpecRecord FontDialog::specRecord[FontDialog::nFontSpecs] = {
  &FontSpec::dataTable,   "Data Tables",
  &FontSpec::columnHead,  "Column headings",
  &FontSpec::markedToken, "Marked tokens",
  &FontSpec::syntaxFile,  "Syntax file text",
  &FontSpec::traceFile,   "File trace text",
  &FontSpec::help,        "Help window text",
  &FontSpec::helpTitle,   "Help window titles"
};

class AFontDialogHandler
  : public IFontDialogHandler
  //, public IFrameHandler
{
private:
  FontDialog *dialog;

public:
  AFontDialogHandler(FontDialog *d) : dialog(d) {}
  Boolean dispatchHandlerEvent(IEvent &e);
  Boolean modelessResults(IFontDialog *);
  //Boolean activated(IFrameEvent &event);
};

/*
Boolean AFontDialogHandler::activated(IFrameEvent &event) {
  LOGSECTION("AFontDialogHandler::activated");
  LOGV((int) dialog) LCV(dialog->windowId);
  //AgFrame::windowRegistry.bubbleUp(dialog->windowId);
  AgFrame::windowRegistry.markActive(dialog->windowId);
  return false;
}
*/

Boolean AFontDialogHandler::dispatchHandlerEvent(IEvent &e) {
  LOGSECTION("AFontDialogHandler::dispatchHandlerEvent");
  //IWindow *pWindow = IWindow::windowWithHandle(dialog->dialogHandle);
  if (dialog->fontDialogActive == 1 && e.controlHandle().isValid()) {
    LOGS("Valid handle found");
    dialog->dialogHandle = e.controlHandle();
    dialog->fontDialogActive = 2;
    //IWindow *pWindow = IWindow::windowWithHandle(dialog->dialogHandle);
    //IFrameHandler::handleEventsFor(pWindow);
  }
  if (e.eventId() == WM_SETFOCUS || e.eventId() == WM_ACTIVATE) {
    //AgFrame::windowRegistry.bubbleUp(dialog->windowId);
    AgFrame::windowRegistry.markActive(dialog->windowId);
  }
  if (e.eventId() == WM_DESTROY) {
    LOGS("Destroy message seen");
    dialog->fontDialogActive = 3;
    //IWindow *pWindow = IWindow::windowWithHandle(dialog->dialogHandle);
    //IFrameHandler::stopHandlingEventsFor(pWindow);
  }
  LOGV(e.eventId()) LCV((int) e.parameter1());
  return IFontDialogHandler::dispatchHandlerEvent(e);
}

Boolean AFontDialogHandler::modelessResults(IFontDialog *) {
  LOGSECTION("AFontDialogHandler::modelessResults");
  assert(dialog->dialogHandle.isValid());
  IWindow *pWindow = IWindow::windowWithHandle(dialog->dialogHandle);
  LOGV((int) pWindow);
  IFontDialogHandler::stopHandlingEventsFor(pWindow);
  IFrameHandler::stopHandlingEventsFor(pWindow);
  return false;
}

FontDialog &FontDialog::closeModalDialog() {
  LOGSECTION("FontDialog::closeModalDialog");
  LOGV(fontDialogActive);
  if (fontDialogActive == 0) {
    return *this;
  }

  IWindow *pWindow = windowWithHandle(dialogHandle);
  LOGV((int) pWindow);
  if (pWindow) {
    //pWindow->sendEvent(WM_COMMAND, IDABORT);
    pWindow->sendEvent(WM_COMMAND, IDCANCEL);
    return *this;
  }
  return *this;
}

void FontDialog::closeFrame() {
  LOGSECTION("FontDialog::closeFrame");
  if (fontDialogActive) {
    closeAction.performDeferred();
    return;
  }
  close();
}

FontDialog &FontDialog::mySetFocus() {
  LOGSECTION("FontDialog::mySetFocus");
  switch (fontDialogActive) {
    case 0:
    case 3: {
      setFocus();
      return *this;
    }
    case 1:
    case 2: {
      IWindow *pWindow = windowWithHandle(dialogHandle);
      LOGV((int) pWindow);
      if (pWindow) {
        pWindow->setFocus();
        return *this;
      }
    }
  }
  return *this;
}

void FontDialog::popUp() {
  LOGSECTION("FontDialog::popUp");
  switch (fontDialogActive) {
    case 0:
    case 3: {
      if (isMinimized()) {
	restore();
      }
      show().setFocus();
      return;
    }
    case 1:
    case 2: {
      IWindow *pWindow = windowWithHandle(dialogHandle);
      LOGV((int) pWindow);
      if (pWindow) {
        pWindow->setFocus();
        return;
      }
    }
  }
}

Boolean FontDialog::command(ICommandEvent &event) {
  LOGSECTION("FontDialog::command");
  LOGV(event.commandId());
  switch (event.commandId()) {
    case undoCommand: {
      LOGS("undo");
      if (undoStack.size() == 0) {
        messageBeep();
        return true;
      }
      undoStack.pop(undoRecord);
      LOGV(undoRecord.pointer->description());
      FontSpec &fontSpec = *undoRecord.pointer;
      fontSpec = undoRecord.font;
      undoRecord.button->setText(fontSpec.description().pointer());
      LOGV(undoRecord.pointer->description());
      return true;
    }
    case defaultCommand: {
      int i;
      for (i = 0; i < nFontSpecs; i++) {
        undoRecord.pointer = specRecord[i].pointer;
        undoRecord.button = optionRecord[i].button;
        undoRecord.font = *undoRecord.pointer;

        LOGV(undoRecord.pointer->description());
        undoRecord.pointer->reset();
        LOGV(undoRecord.pointer->description());
        undoStack.push(undoRecord);
        undoRecord.button->setText(
	  undoRecord.pointer->description().pointer()
	);
      }
      return true;
    }
    case cancelCommand: {
      AgFrame::windowRegistry.remove(windowId);
      close();
      return true;
    }
    case helpCommand: {
      LOGSECTION("FontDialog::helpCommand");
      AgHelpWindow::showHelp("Set Fonts");
      return true;
    }
    default: if (event.commandId() <= nFontSpecs) {
      int option = event.commandId() - 1;
      LOGV(option);
      LOGV(specRecord[option].title);
      undoRecord.pointer = specRecord[option].pointer;
      undoRecord.button = optionRecord[option].button;
      IFont font = *undoRecord.pointer;
      undoRecord.font = font;
      LOGV(undoRecord.pointer->description());

      IFontDialog::Settings settings(&font);
      LOGS("Settings object created");
      AgString title = specRecord[option].title;
      LOGV(title);
      int n = title.size() - 1;
      LOGV(n);
      if (title[n] == ':') {
	title[n] = 0;
      }
      LOGV(title);
      settings.setTitle(AgString::format("AnaGram - Set Fonts - %s", 
					 title.pointer()).pointer());
      LOGS("Title set in settings object");
      fontDialogActive = 1;
      AFontDialogHandler handler(this);
      IFontDialog fontDialog(this, this, (IFontDialogHandler *) &handler,
			     IFontDialog::defaultStyle(), settings);
      fontDialogActive = 0;
      if (!fontDialog.pressedOK()) {
	return true;
      }
      LOGS("Return from font dialog");
      *undoRecord.pointer = font;
      LOGV(undoRecord.pointer->description());
      undoStack.push(undoRecord);
      undoRecord.button->setText(undoRecord.pointer->description().pointer());
    }
    else {
      return AgFrame::command(event);
    }
  }
  return true;
}

void FontDialog::initFont(int field, int flags, int size, AgString name) {
  LOGSECTION("FontDialog::initFont");
  LOGV(name) LCV(field) LCV(flags) LCV(size);
  if (field >= nFontSpecs) {
    return;
  }
  IFont f(name.pointer(), size);
  LOGV(name);
  if (flags & FontSpec::italic) f.setItalic();
  if (flags & FontSpec::bold) f.setBold();
  if (flags & FontSpec::strikeout) f.setStrikeout();
  if (flags & FontSpec::underscore) f.setUnderscore();
  specRecord[field].pointer->initialize(f);
  return;
}

int FontDialog::idField(AgString name) {
  int i;
  for (i = 0; i < nFontSpecs; i++) {
    if (name == specRecord[i].title) {
      break;
    }
  }
  return i;
}

ColorDialog::SpecRecord ColorDialog::specRecord[ColorDialog::nColorSpecs] = {
  &ColorSpec::syntaxFile,         "Syntax File",
  &ColorSpec::data,               "Data Tables",
  &ColorSpec::activeTitle,        "Active Pane Column Headings",
  &ColorSpec::inactiveTitle,      "Inactive Pane Column Headings",
  &ColorSpec::activeCursor,       "Active Pane Cursor Bar",
  &ColorSpec::inactiveCursor,     "Inactive Pane Cursor Bar",
  &ColorSpec::traceFileUnscanned, "File Trace Text (Unparsed)",
  &ColorSpec::traceFileScanned,   "File Trace Text (Parsed)",
  &ColorSpec::traceFileHilite,    "File Trace Text (Highlight)",
  &ColorSpec::helpText,           "Help Window",
  &ColorSpec::helpLink,           "Help Links",
  &ColorSpec::helpUsedLink,       "Traversed Links"
};

void ColorDialog::stackSettings(AgCharStack &stack) {
  for (int i = 0; i < nColorSpecs; i++) {
    stack << "Color:" << specRecord[i].title << '=';
    stack << specRecord[i].pointer->string() << '\n';
  }
}

AgString FontSpec::string() {
  AgCharStack stack;
  if (contents.isBold()) stack << 'B';
  if (contents.isItalic()) stack << 'I';
  if (contents.isStrikeout()) stack << 'S';
  if (contents. isUnderscore()) stack << 'U';
  char buf[20];
  itoa(contents.pointSize(), buf, 10);
  stack << buf;
  stack << '.' << (char *) contents.name();
  return stack.popString();
}

void FontDialog::stackSettings(AgCharStack &stack) {
  for (int i = 0; i < nFontSpecs; i++) {
    stack << "Font:" << specRecord[i].title << '=';
    stack << specRecord[i].pointer->string() << '\n';
  }
}

ColorSpec ColorSpec::defaultSetting(
  IColor(0,0,0), IColor(255,255,255));

#ifdef COLOR_SCHEME_1
// original scheme

ColorSpec ColorSpec::dialogBackground (
  IColor(0,0,0), IGUIColor(IGUIColor::dialogBgnd));

ColorSpec ColorSpec::syntaxFile(
  IColor(0,0,0), IColor(216,252,240));

ColorSpec ColorSpec::traceFileHilite(
  IColor(255,255,255), IColor(0,125,130));

ColorSpec ColorSpec::traceFileScanned(
  IColor(0,0,0), IColor(216,252,240));

ColorSpec ColorSpec::traceFileUnscanned(
  IColor(0,0,0),IColor(184,220,208));

ColorSpec ColorSpec::activeTitle(
  IColor(0,0,0), IColor(150,213,255));

ColorSpec ColorSpec::inactiveTitle(
  IColor(0,0,0), IColor(152,196,216));

ColorSpec ColorSpec::data(
  IColor(0,0,0), IColor(216,252,240));

ColorSpec ColorSpec::activeCursor(
  IColor(255,255,255), IColor(0, 125, 130));

ColorSpec ColorSpec::inactiveCursor(
  IColor(255,255,255), IColor(125,165,150));



ColorSpec ColorSpec::helpText(
  IColor(0,0,0), IColor(255,255,225));

ColorSpec ColorSpec::helpLink(
  IColor(0,115,240),IColor(255,255,225));

ColorSpec ColorSpec::helpUsedLink(
  IColor(0,140,30),IColor(255,255,225));

#else
// Renata's scheme 2

ColorSpec ColorSpec::dialogBackground (
  IColor(0,0,0), IGUIColor(IGUIColor::dialogBgnd));

ColorSpec ColorSpec::syntaxFile(
  IColor(0,0,0), IColor(220,245,250));

ColorSpec ColorSpec::traceFileHilite(
  IColor(255,255,255), IColor(120,45,45));

ColorSpec ColorSpec::traceFileScanned(
  IColor(0,0,0), IColor(245,245,235));

ColorSpec ColorSpec::traceFileUnscanned(
  IColor(0,0,0),IColor(222,220,208));

ColorSpec ColorSpec::activeTitle(
  IColor(0,0,0), IColor(150,213,255));

ColorSpec ColorSpec::inactiveTitle(
  IColor(0,0,0), IColor(171,203,228));

ColorSpec ColorSpec::data(
  IColor(0,0,0), IColor(220,245,250));

ColorSpec ColorSpec::activeCursor(
  IColor(255,255,255), IColor(120, 45, 45));

ColorSpec ColorSpec::inactiveCursor(
  IColor(255,255,255), IColor(155,110,115));



ColorSpec ColorSpec::helpText(
  IColor(0,0,0), IColor(255,255,225));

ColorSpec ColorSpec::helpLink(
  IColor(0,115,255),IColor(255,255,225));

ColorSpec ColorSpec::helpUsedLink(
  IColor(0,140,30),IColor(255,255,225));

#endif


FontSpec FontSpec::defaultSetting;
FontSpec FontSpec::syntaxFile("Courier", 10);
FontSpec FontSpec::traceFile("Courier", 10);

FontSpec FontSpec::help("MS Sans Serif", 10);
FontSpec FontSpec::helpTitle("MS Sans Serif", 12, FontSpec::bold);

FontSpec FontSpec::columnHead("MS Sans Serif", 10);

FontSpec FontSpec::dataTable("MS Sans Serif", 10);
FontSpec FontSpec::markedToken("MS Sans Serif", 10, FontSpec::boldItalic);


AgString FontSpec::description() {
  return AgString::format("%d point %s",
			  contents.pointSize(), contents.name());
}