view anagram/vaclgui/dspar.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.
 *
 * 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());
}