home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / editordialogs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  397.5 KB  |  13,501 lines

  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /* 
  20.  *
  21.  *  editordialogs.c --- Editor-specific dialogs.
  22.  *  Should only be built for the editor.
  23.  *  Created: David Williams <djw@netscape.com>, Mar-12-1996
  24.  *
  25.  *  RCSID: "$Id: editordialogs.c,v 3.1 1998/03/28 03:20:03 ltabb Exp $"
  26.  */
  27.  
  28. #include "mozilla.h"
  29. #include "xfe.h"
  30. #include <X11/keysym.h>   /* for editor key translation */
  31. #include <XmL/Folder.h>   /* tab folder stuff */
  32. #include <Xm/Label.h> 
  33. #include <Xm/DrawnB.h> 
  34. #include <Xm/XmP.h>       /* required for _XmFontListGetDefaultFont() */
  35. #include "DtWidgets/ComboBox.h"
  36. #include <xpgetstr.h>     /* for XP_GetString() */
  37.  
  38. #include <Xfe/Xfe.h>        /* for xfe widgets and utilities */
  39.  
  40. #ifdef EDITOR
  41.  
  42. #include "edttypes.h"
  43. #include "edt.h"
  44. #include "menu.h"
  45. #include "xeditor.h"
  46. #include "il_icons.h"           /* Image icon enumeration. */
  47. #include "prefapi.h"   /* Need some publishing prefs for EDT_PublishFile */
  48. #include "felocale.h"
  49.  
  50. /* no security btn on prefs
  51. #define _SECURITY_BTN_ON_PREFS
  52. */
  53.  
  54. /*
  55.  *    I don't like this "fix" for MAXPATHLEN, but I cannot log onto
  56.  *    a SCO machine to find the right way to do this...djw
  57.  */
  58. #ifdef SCO_SV
  59. #include "mcom_db.h"    /* for MAXPATHLEN */
  60. #endif
  61.  
  62. void fe_browse_file_of_text (MWContext *context, Widget text_field, Boolean dirp);
  63.  
  64. extern int XFE_ERROR_SAVING_OPTIONS;
  65. extern int XFE_VALUES_OUT_OF_RANGE;
  66. extern int XFE_VALUE_OUT_OF_RANGE;
  67. extern int XFE_EDITOR_TABLE_ROW_RANGE;
  68. extern int XFE_EDITOR_TABLE_COLUMN_RANGE;
  69. extern int XFE_EDITOR_TABLE_BORDER_RANGE;
  70. extern int XFE_EDITOR_TABLE_SPACING_RANGE;
  71. extern int XFE_EDITOR_TABLE_PADDING_RANGE;
  72. extern int XFE_EDITOR_TABLE_WIDTH_RANGE;
  73. extern int XFE_EDITOR_TABLE_HEIGHT_RANGE;
  74. extern int XFE_EDITOR_TABLE_IMAGE_WIDTH_RANGE;
  75. extern int XFE_EDITOR_TABLE_IMAGE_HEIGHT_RANGE;
  76. extern int XFE_EDITOR_TABLE_IMAGE_SPACE_RANGE;
  77. extern int XFE_ENTER_NEW_VALUE;
  78. extern int XFE_ENTER_NEW_VALUES;
  79. extern int XFE_EDITOR_LINK_TEXT_LABEL_NEW;
  80. extern int XFE_EDITOR_LINK_TEXT_LABEL_IMAGE;
  81. extern int XFE_EDITOR_LINK_TEXT_LABEL_TEXT;
  82. extern int XFE_EDITOR_LINK_TARGET_LABEL_NO_TARGETS;
  83. extern int XFE_EDITOR_LINK_TARGET_LABEL_SPECIFIED;
  84. extern int XFE_EDITOR_LINK_TARGET_LABEL_CURRENT;
  85. extern int XFE_EDITOR_WARNING_REMOVE_LINK;
  86. extern int XFE_UNKNOWN;
  87. extern int XFE_EDITOR_TAG_UNOPENED;
  88. extern int XFE_EDITOR_TAG_UNCLOSED;
  89. extern int XFE_EDITOR_TAG_UNTERMINATED_STRING;
  90. extern int XFE_EDITOR_TAG_PREMATURE_CLOSE;
  91. extern int XFE_EDITOR_TAG_TAGNAME_EXPECTED;
  92. extern int XFE_EDITOR_TAG_UNKNOWN;
  93. extern int XFE_EDITOR_TAG_OK;
  94. extern int XFE_EDITOR_AUTOSAVE_PERIOD_RANGE;
  95. extern int XFE_EDITOR_PUBLISH_LOCATION_INVALID;
  96. extern int XFE_EDITOR_IMAGE_IS_REMOTE;
  97. extern int XFE_CANNOT_READ_FILE;
  98.  
  99. #define TABLE_MAX_ROWS 100
  100. #define TABLE_MIN_ROWS 1
  101. #define TABLE_MAX_COLUMNS 100
  102. #define TABLE_MIN_COLUMNS 1
  103. #define TABLE_MAX_BORDER 10000
  104. #define TABLE_MIN_BORDER 0
  105. #define TABLE_MAX_SPACING 10000
  106. #define TABLE_MIN_SPACING 0
  107. #define TABLE_MAX_PADDING 10000
  108. #define TABLE_MIN_PADDING 0
  109. #define TABLE_MAX_PIXEL_WIDTH  10000
  110. #define TABLE_MIN_PIXEL_WIDTH  1
  111. #define TABLE_MAX_PERCENT_WIDTH 100
  112. #define TABLE_MIN_PERCENT_WIDTH 1
  113. #define TABLE_MAX_PIXEL_HEIGHT  10000
  114. #define TABLE_MIN_PIXEL_HEIGHT  1
  115. #define TABLE_MAX_PERCENT_HEIGHT 100
  116. #define TABLE_MIN_PERCENT_HEIGHT 1
  117. #define TABLE_MAX_CELL_NROWS 100
  118. #define TABLE_MIN_CELL_NROWS 1
  119. #define TABLE_MAX_CELL_NCOLUMNS 100
  120. #define TABLE_MIN_CELL_NCOLUMNS 1
  121.  
  122. #define IMAGE_MIN_WIDTH  1
  123. #define IMAGE_MAX_WIDTH  10000
  124. #define IMAGE_MIN_HEIGHT 1
  125. #define IMAGE_MAX_HEIGHT 10000
  126. #define IMAGE_MIN_HSPACE 0
  127. #define IMAGE_MAX_HSPACE 10000
  128. #define IMAGE_MIN_VSPACE 0
  129. #define IMAGE_MAX_VSPACE 10000
  130. #define IMAGE_MIN_BORDER 0
  131. #define IMAGE_MAX_BORDER 10000
  132.  
  133. #define HRULE_MIN_HEIGHT 1
  134. #define HRULE_MAX_HEIGHT 10000
  135. #define HRULE_MAX_PIXEL_WIDTH  10000
  136. #define HRULE_MIN_PIXEL_WIDTH  1
  137. #define HRULE_MAX_PERCENT_WIDTH 100
  138. #define HRULE_MIN_PERCENT_WIDTH 1
  139.  
  140. #define AUTOSAVE_MIN_PERIOD 0
  141. #define AUTOSAVE_MAX_PERIOD 600
  142.  
  143. #define RANGE_CHECK(o, a, b) ((o) < (a) || (o) > (b))
  144.  
  145. #define XFE_INVALID_TABLE_NROWS     1
  146. #define XFE_INVALID_TABLE_NCOLUMNS  2
  147. #define XFE_INVALID_TABLE_BORDER    3
  148. #define XFE_INVALID_TABLE_SPACING   4
  149. #define XFE_INVALID_TABLE_PADDING   5
  150. #define XFE_INVALID_TABLE_WIDTH     6
  151. #define XFE_INVALID_TABLE_HEIGHT    7
  152. #define XFE_INVALID_CELL_NROWS      8
  153. #define XFE_INVALID_CELL_NCOLUMNS   9
  154. #define XFE_INVALID_CELL_WIDTH      10
  155. #define XFE_INVALID_CELL_HEIGHT     11
  156.  
  157. #define XFE_INVALID_IMAGE_WIDTH     12
  158. #define XFE_INVALID_IMAGE_HEIGHT    13
  159. #define XFE_INVALID_IMAGE_HSPACE    14
  160. #define XFE_INVALID_IMAGE_VSPACE    15
  161. #define XFE_INVALID_IMAGE_BORDER    16
  162.  
  163. #define XFE_INVALID_HRULE_WIDTH     17
  164. #define XFE_INVALID_HRULE_HEIGHT    18
  165.  
  166. static void
  167. fe_error_dialog(MWContext* context, Widget parent, char* s)
  168. {
  169.     while (!XtIsWMShell(parent) && (XtParent(parent)!=0))
  170.         parent = XtParent(parent);
  171.  
  172.     fe_dialog(parent, "error", s, FALSE, 0, FALSE, FALSE, 0);
  173. }
  174.  
  175. static void
  176. fe_message_dialog(MWContext* context, Widget parent, char* s)
  177. {
  178.     Widget mainw;
  179.  
  180.     while (!XtIsWMShell(parent) && (XtParent(parent)!=0))
  181.         parent = XtParent(parent);
  182.  
  183.     /* yuck */
  184.     mainw = CONTEXT_WIDGET(context);
  185.     CONTEXT_WIDGET(context) = parent;
  186.  
  187.     fe_Message(context, s);
  188.  
  189.     CONTEXT_WIDGET(context) = mainw;
  190. }
  191.  
  192. static void
  193. fe_editor_range_error_dialog(MWContext* context, Widget parent,
  194.                              unsigned* errors, unsigned nerrors)
  195. {
  196.     unsigned i;
  197.     int      id;
  198.     char     be_lazy[8192];
  199.  
  200.     if (nerrors > 1)
  201.         id = XFE_VALUES_OUT_OF_RANGE; /* Some values are out of range: */
  202.     else if (nerrors == 1)
  203.         id = XFE_VALUE_OUT_OF_RANGE; /* The following value is out of range: */
  204.     else
  205.         return;
  206.  
  207.     strcpy(be_lazy, XP_GetString(id));
  208.     strcat(be_lazy, "\n\n");
  209.  
  210.     for (i = 0; i < nerrors; i++) {
  211.         switch (errors[i]) {
  212.         case XFE_INVALID_TABLE_NROWS:
  213.         case XFE_INVALID_CELL_NROWS:
  214.             id = XFE_EDITOR_TABLE_ROW_RANGE;
  215.             /* You can have between 1 and 100 rows. */
  216.             break;
  217.         case XFE_INVALID_TABLE_NCOLUMNS:
  218.         case XFE_INVALID_CELL_NCOLUMNS:
  219.             id = XFE_EDITOR_TABLE_COLUMN_RANGE;
  220.             /* You can have between 1 and 100 columns. */
  221.             break;
  222.         case XFE_INVALID_TABLE_BORDER:
  223.             id = XFE_EDITOR_TABLE_BORDER_RANGE;
  224.             /* For border width, you can have 0 to 10000 pixels. */
  225.             break;
  226.         case XFE_INVALID_TABLE_SPACING:
  227.             id = XFE_EDITOR_TABLE_SPACING_RANGE;
  228.             /* For cell spacing, you can have 0 to 10000 pixels. */
  229.             break;
  230.         case XFE_INVALID_TABLE_PADDING:
  231.             id = XFE_EDITOR_TABLE_PADDING_RANGE;
  232.             /* For cell padding, you can have 0 to 10000 pixels. */
  233.             break;
  234.         case XFE_INVALID_TABLE_WIDTH:
  235.         case XFE_INVALID_CELL_WIDTH:
  236.         case XFE_INVALID_HRULE_WIDTH:
  237.             id = XFE_EDITOR_TABLE_WIDTH_RANGE;
  238.             /* For width, you can have between 1 and 10000 pixels, */
  239.             /* or between 1 and 100%.                              */
  240.             break;
  241.         case XFE_INVALID_TABLE_HEIGHT:
  242.         case XFE_INVALID_CELL_HEIGHT:
  243.             id = XFE_EDITOR_TABLE_HEIGHT_RANGE;
  244.             /* For height, you can have between 1 and 10000 pixels, */
  245.             /* or between 1 and 100%.                               */
  246.             break;
  247.         case XFE_INVALID_IMAGE_WIDTH:
  248.             id = XFE_EDITOR_TABLE_IMAGE_WIDTH_RANGE;
  249.             /* For width, you can have between 1 and 10000 pixels. */
  250.             break;
  251.         case XFE_INVALID_IMAGE_HEIGHT:
  252.         case XFE_INVALID_HRULE_HEIGHT:
  253.             id = XFE_EDITOR_TABLE_IMAGE_HEIGHT_RANGE;
  254.             /* For height, you can have between 1 and 10000 pixels. */
  255.             break;
  256.         case XFE_INVALID_IMAGE_HSPACE:
  257.         case XFE_INVALID_IMAGE_VSPACE:
  258.         case XFE_INVALID_IMAGE_BORDER:
  259.             id = XFE_EDITOR_TABLE_IMAGE_SPACE_RANGE;
  260.             /* For space, you can have between 1 and 10000 pixels. */
  261.             break;
  262.         }
  263.  
  264.         strcat(be_lazy, XP_GetString(id));
  265.         strcat(be_lazy, "\n");
  266.     }
  267.  
  268.     if (nerrors > 1) {
  269.         id = XFE_ENTER_NEW_VALUES;
  270.         /* Please enter new values and try again. */
  271.     } else if (nerrors == 1) {
  272.         id = XFE_ENTER_NEW_VALUE;
  273.         /* Please enter a new value and try again. */
  274.     }
  275.  
  276.     strcat(be_lazy, "\n");
  277.     strcat(be_lazy, XP_GetString(id));
  278.  
  279.     fe_error_dialog(context, parent, be_lazy);
  280. }
  281.  
  282. #endif  /* EDITOR */
  283.  
  284. Widget
  285. fe_CreateTabForm(Widget parent, char* name, Arg* args, Cardinal n)
  286. {
  287.     Widget form;
  288.     Widget tab;
  289.     Pixel  bg;
  290.     char*    string;
  291.     XmString xm_string;
  292.  
  293.     XtVaGetValues(parent, XmNbackground, &bg, 0);
  294.     form = XtVaCreateWidget(name, xmFormWidgetClass, parent, XmNbackground, bg, NULL);
  295.  
  296.     string = XfeSubResourceGetWidgetStringValue(form, "tabLabelString", XmCXmString);
  297.     if (!string)
  298.         string = name;
  299.     xm_string = XmStringCreateSimple(string);
  300.     tab = XmLFolderAddTab(parent, xm_string);
  301.     XtVaSetValues(tab, XmNtabManagedWidget, form, NULL);
  302.  
  303.     return form;
  304. }
  305.  
  306. #ifdef EDITOR
  307.  
  308. void
  309. fe_WidgetSetSensitive(Widget widget, Boolean sensitive)
  310. {
  311.     XtVaSetValues(widget, XmNsensitive, sensitive, 0);
  312. }
  313.  
  314. #define SWATCH_SIZE 60
  315.  
  316. Widget
  317. fe_CreateSwatch(Widget parent, char* name, Arg* p_args, Cardinal p_n)
  318. {
  319.     return XmCreateDrawnButton(parent, name, p_args, p_n);
  320. }
  321.  
  322. void
  323. fe_SwatchSetSensitive(Widget widget, Boolean sensitive)
  324. {
  325.     XtVaSetValues(widget, XmNsensitive, sensitive, 0);
  326. }
  327.  
  328. #endif  /* EDITOR */
  329.  
  330. void
  331. fe_SwatchSetColor(Widget widget, LO_Color* color)
  332. {
  333.     MWContext* context = fe_WidgetToMWContext(widget);
  334.     Pixel      pixel;
  335.  
  336.     if (color != NULL) {
  337.         pixel = fe_GetPixel(context, color->red, color->green, color->blue);
  338.     } else {
  339.         XtVaGetValues(XtParent(widget), XmNbackground, &pixel, 0);
  340.     }
  341.     
  342.     XtVaSetValues(widget, XmNbackground, pixel, 0);
  343. }
  344.  
  345. #ifdef EDITOR
  346.  
  347. Widget
  348. fe_CreatePasswordField(Widget parent, char* name, Arg* args, Cardinal n)
  349. {
  350.     Widget widget;
  351.     int    max_length;
  352.  
  353.     widget = fe_CreateTextField(parent, name, args, n);
  354.  
  355.     XtVaGetValues(widget, XmNmaxLength, &max_length, 0);
  356.  
  357.     fe_SetupPasswdText(widget, max_length);
  358.  
  359.     return widget;
  360. }
  361.  
  362. #endif  /* EDITOR */
  363.  
  364. void
  365. fe_TextFieldSetString(Widget widget, char* value, Boolean notify)
  366. {
  367.     XtCallbackRec buf[32]; /* hope that's enough! */
  368.     XtCallbackList callbacks;
  369.     int i;
  370.     if (notify == FALSE) {
  371.         XtVaGetValues(widget, XmNvalueChangedCallback, &callbacks, 0);
  372.         for (i = 0; callbacks[i].callback != NULL; i++) {
  373.             buf[i] = callbacks[i];
  374.         }
  375.         buf[i].callback = NULL;
  376.         buf[i].closure = NULL;
  377.         
  378.         XtRemoveAllCallbacks(widget, XmNvalueChangedCallback);
  379.     }
  380.     fe_SetTextFieldAndCallBack(widget, value);
  381.     if (notify == FALSE) {
  382.         XtAddCallbacks(widget, XmNvalueChangedCallback, buf);
  383.     }
  384. }
  385.  
  386. #ifdef EDITOR
  387.  
  388. static char*
  389. fe_TextFieldGetString(Widget widget)
  390. {
  391.     return fe_GetTextField(widget);
  392. }
  393.  
  394. static Pixel
  395. fe_get_text_field_background(Widget widget)
  396. {
  397.     return XfeSubResourceGetPixelValue(widget,
  398.                                        XtName(widget),
  399.                                        XfeClassNameForWidget(widget),
  400.                                        XmNbackground,
  401.                                        XmCBackground,
  402.                                        WhitePixelOfScreen(XtScreen(widget)));
  403. }
  404.  
  405. void
  406. fe_TextFieldSetEditable(MWContext* context, Widget widget, Boolean editable)
  407. {
  408.     Pixel bg_pixel;
  409.     Arg   args[16];
  410.     Cardinal n;
  411.  
  412.     /*
  413.      *    The TextField is so losing, it doesn't set the
  414.      *    background color to indicate the field is not-editable.
  415.      *    The Gods of Motif style say thou shalt bestow unto thine
  416.      *    non-editable TextField thine color of select color-ness.
  417.      *
  418.      *    Hmmm this looks butt ugly, maybe have to use a label instead.
  419.      */
  420.     if (editable) {
  421.         bg_pixel = fe_get_text_field_background(widget);
  422.     } else {
  423.         n = 0;
  424.         XtSetArg(args[n], XmNbackground, &bg_pixel); n++;
  425.         XtGetValues(XtParent(widget), args, n);
  426.  
  427. #if 0
  428.         /* use select color as background color */
  429.         XmGetColors(XtScreen(widget), fe_cmap(context),
  430.                     bg_pixel,
  431.                     NULL, /* foreground */
  432.                     NULL, /* top shadow */
  433.                     NULL, /* bottom shadow */
  434.                     &select_pixel);
  435.  
  436.         bg_pixel = select_pixel;
  437. #endif
  438.     }
  439.  
  440.     n = 0;
  441.     XtSetArg(args[n], XmNeditable, editable); n++;
  442.     XtSetArg(args[n], XmNcursorPositionVisible, editable); n++;
  443.     XtSetArg(args[n], XmNtraversalOn, editable); n++;
  444.     XtSetArg(args[n], XmNbackground, bg_pixel); n++;
  445.     XtSetValues(widget, args, n);
  446. }
  447.  
  448. Widget
  449. fe_CreateFrame(Widget parent, char* name,  Arg* p_args, Cardinal p_n)
  450. {
  451.     Widget   frame;
  452.     Widget   title;
  453.     char     namebuf[256];
  454.     Arg      args[16];
  455.     Cardinal n;
  456.  
  457.     for (n = 0; n < p_n; n++) {
  458.     XtSetArg(args[n], p_args[n].name, p_args[n].value);
  459.     }
  460.  
  461.     strcpy(namebuf, name);
  462.     strcat(namebuf, "Frame");
  463.  
  464.     XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++;
  465.     frame = XmCreateFrame(parent, namebuf, args, n);
  466.     XtManageChild(frame);
  467.  
  468.     strcpy(namebuf, name);
  469.     strcat(namebuf, "Title");
  470.  
  471.     n = 0;
  472.     XtSetArg(args[n], XmNlabelType, XmSTRING); n++;
  473.     XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++;
  474.     XtSetArg(args[n], XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING); n++;
  475.     XtSetArg(args[n], XmNchildVerticalAlignment, XmALIGNMENT_CENTER); n++;
  476.     title = XmCreateLabelGadget(frame, namebuf, args, n);
  477.     XtManageChild(title);
  478.  
  479.     return frame;
  480. }
  481.  
  482. Widget
  483. fe_CreateFramedForm(Widget parent, char* name, Arg* p_args, Cardinal p_n)
  484. {
  485.     Widget   frame;
  486.     Widget   form;
  487.     Arg      args[16];
  488.     Cardinal n;
  489.  
  490.     n = 0;
  491.     frame = fe_CreateFrame(parent, name, args, n);
  492.     XtManageChild(frame);
  493.  
  494.     for (n = 0; n < p_n; n++) {
  495.     XtSetArg(args[n], p_args[n].name, p_args[n].value);
  496.     }
  497.  
  498.     form = XmCreateForm(frame, name, args, n);
  499.  
  500.     return form;
  501. }
  502.  
  503. Widget
  504. fe_CreateFramedRowColumn(Widget parent, char* name, Arg* p_args, Cardinal p_n)
  505. {
  506.     Widget   frame;
  507.     Widget   rowcol;
  508.     Arg      args[16];
  509.     Cardinal n;
  510.  
  511.     n = 0;
  512.     frame = fe_CreateFrame(parent, name, args, n);
  513.     XtManageChild(frame);
  514.  
  515.     for (n = 0; n < p_n; n++) {
  516.     XtSetArg(args[n], p_args[n].name, p_args[n].value);
  517.     }
  518.     rowcol = XmCreateRowColumn(frame, name, args, n);
  519.  
  520.     return rowcol;
  521. }
  522.  
  523. static Widget
  524. fe_CreateToggleButtonGadget(Widget parent, char* name,
  525.                 Arg* p_args, Cardinal p_nargs)
  526. {
  527.     Arg      args[16];
  528.     Cardinal n = 0;
  529.     Widget   widget;
  530.  
  531.     for (n = 0; n < p_nargs; n++) {
  532.     XtSetArg(args[n], p_args[n].name, p_args[n].value); n++;
  533.     }
  534.  
  535.     XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
  536.     widget = XmCreateToggleButtonGadget(parent, name, args, n);
  537.     return widget;
  538. }
  539.  
  540.  
  541. static Widget
  542. fe_CreateRadioButtonGadget(Widget parent, char* name,
  543.                 Arg* p_args, Cardinal p_nargs)
  544. {
  545.     Arg      args[16];
  546.     Cardinal n = 0;
  547.     Widget   widget;
  548.  
  549.     for (n = 0; n < p_nargs; n++) {
  550.     XtSetArg(args[n], p_args[n].name, p_args[n].value); n++;
  551.     }
  552.  
  553.     XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  554.     widget = XmCreateToggleButtonGadget(parent, name, args, n);
  555.     return widget;
  556. }
  557.  
  558. #endif  /* EDITOR */
  559.  
  560. Widget
  561. fe_CreatePulldownMenu(Widget parent, char* name, Arg* p_argv, Cardinal p_argc)
  562. {
  563.   unsigned i;
  564.   Widget   popup_menu;
  565.   Arg      argv[8];
  566.   Cardinal argc;
  567.   Visual*  v = 0;
  568.   Colormap cmap = 0;
  569.   Cardinal depth = 0;
  570.   Widget   widget;
  571.  
  572.   XtCallbackRec* button_callback_rec = NULL;
  573.  
  574.   for (i = 0; i < p_argc; i++) {
  575.       if (p_argv[i].name == XmNactivateCallback)
  576.       button_callback_rec = (XtCallbackRec*)p_argv[i].value;
  577.   }
  578.  
  579.   for (widget = parent; !XtIsWMShell(widget); widget = XtParent(widget))
  580.       ;
  581.  
  582.   XtVaGetValues(widget, XtNvisual, &v, XtNcolormap, &cmap,
  583.     XtNdepth, &depth, 0);
  584.  
  585.   argc = 0;
  586.   XtSetArg (argv[argc], XmNvisual, v); argc++;
  587.   XtSetArg (argv[argc], XmNdepth, depth); argc++;
  588.   XtSetArg (argv[argc], XmNcolormap, cmap); argc++;
  589.  
  590.   popup_menu = XmCreatePulldownMenu(parent, name, argv, argc);
  591.  
  592.   return popup_menu;
  593. }
  594.  
  595. #ifdef EDITOR
  596.  
  597. static Widget
  598. fe_CreateOptionMenuNoLabel(Widget widget, char* name, Arg* args, Cardinal n)
  599. {
  600.     Widget menu = fe_CreateOptionMenu(widget, name, args, n);
  601.     fe_UnmanageChild_safe(XmOptionLabelGadget(menu));
  602.     return menu;
  603. }
  604.  
  605. /*
  606.  *    This dialog builder stuff was a wishful attempt at doing declarative
  607.  *    dialogs for XFE. I only got as far as using them for the simplest of
  608.  *    dialogs - the Horizontal Rule pref dialog. That's all that uses it,
  609.  *    so it could be ripped and replaced by some simple code for that dialog.
  610.  *    We really should spend the time to do some kind of easier dialog
  611.  *    builder for XFE. One day....djw
  612.  */
  613. typedef struct fe_DialogBuilderCreator {
  614.     char*   name;
  615.     Widget (*func)(Widget parent, char* name, ArgList args, Cardinal argcount);
  616.     Boolean recurse;
  617. } fe_DialogBuilderCreator;
  618.  
  619. static char XFE_DB_PUSHBUTTONGADGET[] = "XmPushButtonGadget";
  620. static char XFE_DB_LABELGADGET[] = "XmLabelGadget";
  621. static char XFE_DB_FRAME[] = "XmFrame";
  622. static char XFE_DB_FORM[] = "XmForm";
  623. static char XFE_DB_TEXTFIELD[] = "XmTextField";
  624. static char XFE_DB_OPTIONMENU[] = "XmOptionMenu";
  625. static char XFE_DB_PULLDOWNMENU[] = "fe_PulldownMenu";
  626. static char XFE_DB_ROWCOL[] = "XmRowColumn";
  627. static char XFE_DB_FRAMEDFORM[] = "fe_FramedForm";
  628. static char XFE_DB_TOGGLEGADGET[] = "fe_ToggleButtonGadget";
  629. static char XFE_DB_RADIOGADGET[] = "fe_RadioButtonGadget";
  630. static char XFE_DB_FRAMEDROWCOL[] = "fe_FramedRowCol";
  631.  
  632. static fe_DialogBuilderCreator fe_DialogBuilderDefaultCreators[] = {
  633.     { XFE_DB_PUSHBUTTONGADGET, XmCreatePushButtonGadget, FALSE },
  634.     { XFE_DB_LABELGADGET, XmCreateLabelGadget, FALSE },
  635.     { XFE_DB_TEXTFIELD, fe_CreateTextField, FALSE },
  636.     { XFE_DB_TOGGLEGADGET, fe_CreateToggleButtonGadget, FALSE },
  637.     { XFE_DB_RADIOGADGET, fe_CreateRadioButtonGadget, FALSE },
  638.  
  639.     { XFE_DB_FRAME, XmCreateFrame, TRUE },
  640.     { XFE_DB_FORM, XmCreateForm, TRUE },
  641.     { XFE_DB_PULLDOWNMENU, fe_CreatePulldownMenu, TRUE },
  642.     { XFE_DB_OPTIONMENU, fe_CreateOptionMenuNoLabel, FALSE },
  643.     { XFE_DB_ROWCOL, XmCreateRowColumn, TRUE },
  644.     { XFE_DB_FRAMEDFORM, fe_CreateFramedForm, TRUE },
  645.     { XFE_DB_FRAMEDROWCOL, fe_CreateFramedRowColumn, TRUE },
  646.     { 0 }
  647. };
  648.  
  649. static char XFE_DB_END[] = "end";
  650. static char XFE_DB_PUSH[] = "push";
  651. static char XFE_DB_POP[] = "pop";
  652. static char XFE_DB_WIDGETCALLED[] = "widgetcalled";
  653. static char XFE_DB_WIDEST[] = "widest";
  654. static char XFE_DB_TALLEST[] = "tallest";
  655. static char XFE_DB_SETVAL[] = "setval";
  656. static char XFE_DB_SETDATA[] = "setdata";
  657. static char XFE_DB_SETVALCALLED[] = "setvalcalled";
  658. static char XFE_DB_CALLBACK[] = "callback";
  659.  
  660. typedef struct fe_DialogBuilderArg {
  661.     char*     name;
  662.     XtPointer value;
  663. } fe_DialogBuilderArg;
  664.  
  665.  
  666. static fe_DialogBuilderCreator*
  667. find_creator(fe_DialogBuilderCreator* creators, char* name)
  668. {
  669.  
  670.     int i;
  671.     
  672.     for (i = 0; creators[i].name; i++) {
  673.     if (creators[i].name == name || strcmp(creators[i].name, name) == 0)
  674.         return &creators[i];
  675.     }
  676.     return NULL;
  677. }
  678.  
  679. Widget
  680. db_do_work(
  681.        MWContext* context,
  682.        Widget parent,
  683.        fe_DialogBuilderCreator* creators,
  684.        fe_DialogBuilderArg** instructions_a,
  685.        void* data)
  686. {
  687. #define MACHINE_NARGS     16
  688. #define MACHINE_NSTACK    16
  689. #define MACHINE_NCALLBACK 16
  690. #define MACHINE_NWIDGETS  32
  691.     Arg           args[MACHINE_NARGS];
  692.     XtPointer     stack[MACHINE_NSTACK];
  693.     XtCallbackRec callbacks[MACHINE_NCALLBACK];
  694.     Cardinal      stackposn;
  695. #define POP()   (stack[--stackposn])
  696. #define PUSH(x) (stack[stackposn++] = (XtPointer)(x))
  697.     Cardinal      nargs;
  698.     Cardinal      ncallbacks;
  699.     Widget        children[MACHINE_NWIDGETS];
  700.     Cardinal      nchildren;
  701.     char*         name;
  702.     XtPointer     value;
  703.     Dimension     width;
  704.     Dimension     max_width;
  705.     Dimension     height;
  706.     Dimension     max_height;
  707.     Widget widget = NULL;
  708.     Widget max_widget;
  709.     int i;
  710.     fe_DialogBuilderCreator* creator;
  711.  
  712.     nargs = 0;
  713.     stackposn = 0;
  714.     ncallbacks = 0;
  715.     nchildren = 0;
  716.  
  717.     for (; (*instructions_a)->name != XFE_DB_END; (*instructions_a)++) {
  718.     name = (*instructions_a)->name;
  719.     value = (*instructions_a)->value;
  720.  
  721.     if (value == (XtPointer)XFE_DB_POP) /* pop is only ever a value */
  722.         value = POP();
  723.  
  724.     if (name == XFE_DB_PUSH) {
  725.         /* push is only ever a name */
  726.         PUSH(value);
  727.     } else if (name == XFE_DB_WIDGETCALLED) {
  728.         for (i = 0; i < nchildren; i++) {
  729.         if (strcmp(XtName(children[i]), (char*)value) == 0) {
  730.             PUSH(children[i]);
  731.             break;
  732.         }
  733.         }
  734.         XP_ASSERT(i < nchildren);
  735.     } else if (name == XFE_DB_WIDEST) {
  736.         max_width = 0;
  737.         max_widget = 0;
  738.         for (i = 0; i < (unsigned)value; i++) {
  739.         widget = (Widget)POP();
  740.         XtVaGetValues(widget, XtNwidth, &width, 0);
  741.         if (width > max_width) {
  742.             max_width = width;
  743.             max_widget = widget;
  744.         }
  745.         }
  746.         PUSH(max_widget);
  747.     } else if (name == XFE_DB_TALLEST) {
  748.         max_height = 0;
  749.         max_widget = 0;
  750.         for (i = 0; i < (unsigned)value; i++) {
  751.         widget = (Widget)POP();
  752.         XtVaGetValues(widget, XtNheight, &height, 0);
  753.         if (height > max_height) {
  754.             max_height = height;
  755.             max_widget = widget;
  756.         }
  757.         }
  758.         PUSH(max_widget);
  759.     } else if (name == XFE_DB_SETVAL) {
  760.         widget = (Widget)POP();
  761.         XtSetValues(widget, args, nargs);
  762.         nargs = 0;
  763.     } else if (name == XFE_DB_SETVALCALLED) {
  764.         for (i = 0; i < nchildren; i++) {
  765.         if (strcmp(XtName(children[i]), (char*)value) == 0) {
  766.             XtSetValues(children[i], args, nargs);
  767.             nargs = 0;
  768.             break;
  769.         }
  770.         }
  771.         XP_ASSERT(i < nchildren);
  772.     } else if (name == XFE_DB_SETDATA) {
  773.         Widget* foo = (Widget*)(((char*) data) + (int) (value));
  774.         *foo = (Widget)POP();
  775.     } else if (name == XFE_DB_CALLBACK) {
  776.         callbacks[ncallbacks].callback = (XtCallbackProc)POP();
  777.         callbacks[ncallbacks].closure = (XtPointer)POP();
  778.         PUSH(&callbacks[ncallbacks++]);
  779.  
  780.         /*
  781.          *    See if it's a creator.
  782.          */
  783.     } else if ((creator = find_creator(creators, name))) {
  784.  
  785.         widget = (*creator->func)(
  786.                      parent,
  787.                      (char*)value,
  788.                      args,
  789.                      nargs
  790.                      );
  791.         /*
  792.          *    Hack, hack, hack for menus which get managed by cascades.
  793.          */
  794.         if (creator->name != XFE_DB_PULLDOWNMENU)
  795.             XtManageChild(widget);
  796.         children[nchildren++] = widget;
  797.         nargs = 0;
  798.         /* if (XtIsSubclass(widget, compositeWidgetClass)) { */
  799.         if (creator->recurse) {
  800.         (*instructions_a)++;
  801.         db_do_work(
  802.                context,
  803.                widget,
  804.                creators,
  805.                instructions_a,
  806.                data);
  807.         /* call ourselves */
  808.         }
  809.     } else { 
  810.         /*
  811.          *    Must be an argument.
  812.          */
  813.         args[nargs].name = name;
  814.         args[nargs].value = (XtArgVal)value;
  815.         nargs++;
  816.     }
  817.     }
  818.  
  819. #if 0
  820.     XtManageChildren(children, nchildren);
  821. #endif
  822.  
  823.     return children[0];
  824. }
  825.  
  826. /*
  827.  *    Stuff for dialogs.
  828.  */
  829. typedef struct fe_HorizontalRulePropertiesDialogData {
  830.     MWContext* context;
  831.     Widget height;
  832.     Widget width;
  833.     Widget width_menu;
  834.     Widget width_units;
  835.     Widget width_pixels;
  836.     Widget width_percent;
  837.     Widget align_left;
  838.     Widget align_center;
  839.     Widget align_right;
  840.     Widget three_d_shading;
  841. } fe_HorizontalRulePropertiesDialogData;
  842.  
  843. /*
  844.  *    DB program to build Horizontal Rule properties Dialog.
  845.  */
  846. static fe_DialogBuilderArg fe_HorizontalRulePropertiesDialogProgram[] = {
  847.  
  848. #define OFFSET(x) XtOffset(fe_HorizontalRulePropertiesDialogData *, x)
  849.  
  850.     { XmNorientation, (XtPointer)XmVERTICAL },
  851.     { XFE_DB_ROWCOL, (XtPointer)"rowcol" },
  852.  
  853.         { XFE_DB_FRAMEDFORM, "dimensions" },
  854.             { XFE_DB_LABELGADGET, "heightLabel" },
  855.             { XFE_DB_TEXTFIELD, "heightText" },
  856.             { XFE_DB_LABELGADGET, "pixels" },
  857.             { XFE_DB_LABELGADGET, "widthLabel" },
  858.             { XFE_DB_TEXTFIELD, "widthText" },
  859.             { XFE_DB_PULLDOWNMENU, "widthUnitsPulldown" },
  860.                 { XFE_DB_PUSHBUTTONGADGET, "percent" },
  861.                 { XFE_DB_PUSHBUTTONGADGET, "pixels" },
  862.  
  863.                 { XFE_DB_WIDGETCALLED, "percent" },
  864.                  { XFE_DB_SETDATA, (XtPointer)OFFSET(width_percent) },
  865.                 { XFE_DB_WIDGETCALLED, "pixels" },
  866.                  { XFE_DB_SETDATA, (XtPointer)OFFSET(width_pixels) },
  867.  
  868.                 { XFE_DB_END, "widthUnitsPulldown" },
  869.             { XFE_DB_WIDGETCALLED, "widthUnitsPulldown" },
  870.             { XmNsubMenuId, XFE_DB_POP },
  871.             { XFE_DB_OPTIONMENU, "widthUnits" },
  872.  
  873.             /* now do computed attachments, oh boy, we need a compiler */
  874.             { XmNtopAttachment, (XtPointer)XmATTACH_FORM },
  875.             { XmNleftAttachment, (XtPointer)XmATTACH_FORM },
  876.             { XFE_DB_SETVALCALLED, "heightLabel" }, /* set heightLabel */
  877.  
  878.             { XmNtopAttachment, (XtPointer)XmATTACH_FORM },
  879.             { XmNleftAttachment, (XtPointer)XmATTACH_WIDGET },
  880.             { XFE_DB_WIDGETCALLED, "heightLabel" },
  881.             { XFE_DB_WIDGETCALLED, "widthLabel" },
  882.             { XFE_DB_WIDEST, (XtPointer)2 },
  883.             { XmNleftWidget, XFE_DB_POP },
  884.             { XFE_DB_SETVALCALLED, "heightText" }, /* set heightText */
  885.  
  886.             { XmNtopAttachment, (XtPointer)XmATTACH_FORM },
  887.             { XmNleftAttachment, (XtPointer)XmATTACH_WIDGET },
  888.             { XFE_DB_WIDGETCALLED, "heightText" },
  889.             { XmNleftWidget, XFE_DB_POP },
  890.             { XFE_DB_SETVALCALLED, "pixels" },     /* set pixel */
  891.  
  892.             { XmNtopAttachment, (XtPointer)XmATTACH_WIDGET },
  893.             { XFE_DB_WIDGETCALLED, "heightText" },
  894.             { XmNtopWidget, XFE_DB_POP },
  895.             { XmNleftAttachment, (XtPointer)XmATTACH_FORM },
  896.             { XFE_DB_SETVALCALLED, "widthLabel" }, /* set widthLabel */
  897.  
  898.             { XmNtopAttachment, (XtPointer)XmATTACH_WIDGET },
  899.             { XFE_DB_WIDGETCALLED, "heightText" },
  900.             { XmNtopWidget, XFE_DB_POP },
  901.             { XmNleftAttachment, (XtPointer)XmATTACH_WIDGET },
  902.             { XFE_DB_WIDGETCALLED, "heightLabel" },
  903.             { XFE_DB_WIDGETCALLED, "widthLabel" },
  904.             { XFE_DB_WIDEST, (XtPointer)2 },
  905.             { XmNleftWidget, XFE_DB_POP },
  906.             { XFE_DB_SETVALCALLED, "widthText" }, /* set widthText */
  907.  
  908.             { XmNtopAttachment, (XtPointer)XmATTACH_WIDGET },
  909.             { XFE_DB_WIDGETCALLED, "heightText" },
  910.             { XmNtopWidget, XFE_DB_POP },
  911.             { XmNleftAttachment, (XtPointer)XmATTACH_WIDGET },
  912.             { XFE_DB_WIDGETCALLED, "widthText" },
  913.             { XmNleftWidget, XFE_DB_POP },
  914. #if 0
  915.             { XmNrightAttachment, (XtPointer)XmATTACH_FORM },
  916. #endif
  917.             { XFE_DB_SETVALCALLED, "widthUnits" }, /* set widthUnits */
  918.  
  919.              /* do offsets */
  920.             { XFE_DB_WIDGETCALLED, "widthText" },
  921.              { XFE_DB_SETDATA, (XtPointer)OFFSET(width) },
  922.             { XFE_DB_WIDGETCALLED, "heightText" },
  923.              { XFE_DB_SETDATA, (XtPointer)OFFSET(height) },
  924.             { XFE_DB_WIDGETCALLED, "widthUnitsPulldown" },
  925.              { XFE_DB_SETDATA, (XtPointer)OFFSET(width_menu) },
  926.             { XFE_DB_WIDGETCALLED, "widthUnits" },
  927.              { XFE_DB_SETDATA, (XtPointer)OFFSET(width_units) },
  928.  
  929.             { XFE_DB_END, "dimensions" },
  930.  
  931.         { XmNorientation, (XtPointer)XmHORIZONTAL },
  932.         { XmNradioBehavior, (XtPointer)TRUE },
  933.         { XFE_DB_FRAMEDROWCOL, "align" },
  934.             { XFE_DB_RADIOGADGET, "left" },
  935.             { XFE_DB_RADIOGADGET, "center" },
  936.             { XFE_DB_RADIOGADGET, "right" },
  937.  
  938.             { XFE_DB_WIDGETCALLED, "left" },
  939.              { XFE_DB_SETDATA, (XtPointer)OFFSET(align_left) },
  940.             { XFE_DB_WIDGETCALLED, "center" },
  941.              { XFE_DB_SETDATA, (XtPointer)OFFSET(align_center) },
  942.             { XFE_DB_WIDGETCALLED, "right" },
  943.              { XFE_DB_SETDATA, (XtPointer)OFFSET(align_right) },
  944.  
  945.             { XFE_DB_END, "align" },
  946.         { XFE_DB_TOGGLEGADGET, "threeDShading" },
  947.  
  948.         { XFE_DB_WIDGETCALLED, "threeDShading" },
  949.         { XFE_DB_SETDATA, (XtPointer)OFFSET(three_d_shading) },
  950.  
  951.         { XFE_DB_END, "rowcol" },
  952.  
  953.      { XFE_DB_END, "program" }
  954.  
  955. #undef OFFSET
  956.  
  957. };
  958.  
  959. #endif  /* EDITOR */
  960.  
  961. Widget
  962. fe_CreatePromptDialog(MWContext *context, char* name,
  963.               Boolean ok, Boolean cancel, Boolean apply, Boolean separator, Boolean modal)
  964. {
  965.   Widget mainw = CONTEXT_WIDGET(context);
  966.   Widget dialog;
  967.   Visual *v = 0;
  968.   Colormap cmap = 0;
  969.   Cardinal depth = 0;
  970.   Arg av [20];
  971.   int ac;
  972.  
  973.   XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap,
  974.                  XtNdepth, &depth, 0);
  975.   ac = 0;
  976.   XtSetArg (av[ac], XmNvisual, v); ac++;
  977.   XtSetArg (av[ac], XmNdepth, depth); ac++;
  978.   XtSetArg (av[ac], XmNcolormap, cmap); ac++;
  979.   XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++;
  980.   XtSetArg (av[ac], XmNtransientFor, mainw); ac++;
  981.   if (modal) {
  982.       XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++;
  983.   }
  984.   XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++;
  985.   XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++;
  986.   XtSetArg (av[ac], XmNautoUnmanage, False); ac++;
  987.   XtSetArg (av[ac], XmNnoResize, True); ac++;
  988.  
  989.   dialog = XmCreatePromptDialog (mainw, name, av, ac);
  990.  
  991.   if (!separator)
  992.       fe_UnmanageChild_safe(XmSelectionBoxGetChild(dialog,
  993.                                                    XmDIALOG_SEPARATOR));
  994.  
  995.   fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT));
  996.   fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog,
  997.                                                 XmDIALOG_SELECTION_LABEL));
  998.   if (!ok)
  999.       fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON));
  1000.   if (!cancel)
  1001.       fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog,
  1002.                              XmDIALOG_CANCEL_BUTTON));
  1003. #ifdef NO_HELP
  1004.   fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
  1005. #endif
  1006.  
  1007.   if (apply)
  1008.       XtManageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_APPLY_BUTTON));
  1009.  
  1010.   return dialog;
  1011. }
  1012.  
  1013. #ifdef EDITOR
  1014.  
  1015. static int
  1016. fe_get_numeric_text_field(Widget widget)
  1017. {
  1018.     char* p = XmTextFieldGetString(widget); /* numeric so no JIS fix */
  1019.     char* q;
  1020.     if (p) {
  1021.         while (isspace(*p))
  1022.             p++;
  1023.         if (*p == '\0') return -1;
  1024.         for (q = p; *q != '\0'; q++) {
  1025.             if (!(isdigit(*q) || isspace(*q)))
  1026.                 return -1; /* force error */
  1027.         }
  1028.         return atoi(p);
  1029.     } else {
  1030.         return -1;
  1031.     }
  1032. }
  1033.  
  1034. static void
  1035. fe_editor_hrule_properties_common(MWContext* context,
  1036.                                   EDT_HorizRuleData* data,
  1037.                               fe_HorizontalRulePropertiesDialogData* w_data)
  1038. {
  1039.     Widget widget;
  1040.     
  1041.     /* height */
  1042.     data->size = fe_get_numeric_text_field(w_data->height);
  1043.  
  1044.     /* width */
  1045.     XtVaGetValues(w_data->width_menu, XmNmenuHistory, &widget, 0);
  1046.  
  1047.     if (widget == w_data->width_pixels)
  1048.         data->bWidthPercent = FALSE;
  1049.     else
  1050.         data->bWidthPercent = TRUE;
  1051.     data->iWidth = fe_get_numeric_text_field(w_data->width);
  1052.  
  1053.     /* align */
  1054.     if (XmToggleButtonGadgetGetState(w_data->align_right) == TRUE)
  1055.         data->align = ED_ALIGN_RIGHT;
  1056.     else  if (XmToggleButtonGadgetGetState(w_data->align_left) == TRUE)
  1057.         data->align = ED_ALIGN_LEFT;
  1058.     else
  1059.         data->align = ED_ALIGN_CENTER;
  1060.  
  1061.     /* shading */
  1062.     if (XmToggleButtonGadgetGetState(w_data->three_d_shading) == TRUE)
  1063.         data->bNoShade = FALSE;
  1064.     else
  1065.         data->bNoShade = TRUE;
  1066.  
  1067.     data->pExtra = 0;
  1068. }
  1069.  
  1070. static Boolean
  1071. fe_editor_hrule_properties_validate(MWContext* context,
  1072.                               fe_HorizontalRulePropertiesDialogData* w_data)
  1073. {
  1074.     EDT_HorizRuleData  data;
  1075.     EDT_HorizRuleData* h = &data;
  1076.     unsigned       errors[16];
  1077.     unsigned       nerrors = 0;
  1078.  
  1079.     fe_editor_hrule_properties_common(context, &data, w_data);
  1080.     
  1081.     if (RANGE_CHECK(h->size, HRULE_MIN_HEIGHT, HRULE_MAX_HEIGHT))
  1082.         errors[nerrors++] = XFE_INVALID_HRULE_HEIGHT;
  1083.  
  1084.     if (h->bWidthPercent == TRUE) {
  1085.         if (RANGE_CHECK(h->iWidth,
  1086.                         HRULE_MIN_PERCENT_WIDTH, HRULE_MAX_PERCENT_WIDTH))
  1087.             errors[nerrors++] = XFE_INVALID_HRULE_WIDTH;
  1088.     } else {
  1089.         if (RANGE_CHECK(h->iWidth,
  1090.                         HRULE_MIN_PIXEL_WIDTH, HRULE_MAX_PIXEL_WIDTH))
  1091.             errors[nerrors++] = XFE_INVALID_HRULE_WIDTH;
  1092.     }
  1093.  
  1094.     if (nerrors > 0) {
  1095.         fe_editor_range_error_dialog(context, w_data->width,
  1096.                                      errors, nerrors);
  1097.         return FALSE;
  1098.     }
  1099.  
  1100.     return TRUE;
  1101. }
  1102.  
  1103. static void
  1104. fe_HorizontalRulePropertiesDialogSet(MWContext* context,
  1105.                                  fe_HorizontalRulePropertiesDialogData* w_data)
  1106. {
  1107.     EDT_HorizRuleData e_data;
  1108.  
  1109.     EDT_BeginBatchChanges(context);
  1110.     fe_editor_hrule_properties_common(context, &e_data, w_data);
  1111.  
  1112.     e_data.pExtra = 0;
  1113.     
  1114.     fe_EditorHorizontalRulePropertiesSet(context, &e_data);
  1115.     EDT_EndBatchChanges(context);
  1116. }
  1117.  
  1118. static void
  1119. fe_table_percent_label_set(Widget widget, Boolean nested);
  1120.  
  1121. static void
  1122. fe_HorizontalRulePropertiesDialogDataGet(
  1123.                 MWContext* context,
  1124.                 fe_HorizontalRulePropertiesDialogData* w_data
  1125. )
  1126. {
  1127.     EDT_HorizRuleData e_data;
  1128.     char buf[16];
  1129.     Boolean left;
  1130.     Boolean center;
  1131.     Boolean right;
  1132.     Boolean shading;
  1133.     Widget widget;
  1134.     Boolean is_nested;
  1135.  
  1136.     fe_EditorHorizontalRulePropertiesGet(context, &e_data);
  1137.     
  1138.     /* height */
  1139.     sprintf(buf, "%d", e_data.size);
  1140.     fe_SetTextFieldAndCallBack(w_data->height, buf);
  1141.  
  1142.     /* width */
  1143.     sprintf(buf, "%d", e_data.iWidth);
  1144.     fe_SetTextFieldAndCallBack(w_data->width, buf);
  1145.  
  1146.     if (e_data.bWidthPercent)
  1147.         widget = w_data->width_percent;
  1148.     else
  1149.         widget = w_data->width_pixels;
  1150.  
  1151.     is_nested = EDT_IsInsertPointInTable(context);
  1152.     fe_table_percent_label_set(w_data->width_percent, is_nested);
  1153.  
  1154.     XtVaSetValues(w_data->width_units, XmNmenuHistory, widget, 0);
  1155.  
  1156.     /* align */
  1157.     if (e_data.align == ED_ALIGN_RIGHT) {
  1158.         left = FALSE;
  1159.         center = FALSE;
  1160.         right = TRUE;
  1161.     } else if (e_data.align == ED_ALIGN_LEFT) {
  1162.         left = TRUE;
  1163.         center = FALSE;
  1164.         right = FALSE;
  1165.     } else {
  1166.         left = FALSE;
  1167.         center = TRUE;
  1168.         right = FALSE;
  1169.     }
  1170.     XmToggleButtonGadgetSetState(w_data->align_right, right, FALSE);
  1171.     XmToggleButtonGadgetSetState(w_data->align_left, left, FALSE);
  1172.     XmToggleButtonGadgetSetState(w_data->align_center, center, FALSE);
  1173.  
  1174.     if (e_data.bNoShade)
  1175.         shading = FALSE;
  1176.     else
  1177.         shading = TRUE;
  1178.     XmToggleButtonGadgetSetState(w_data->three_d_shading, shading, FALSE);
  1179. }
  1180.  
  1181. Widget
  1182. fe_EditorHorizontalRulePropertiesCreate(
  1183.                   MWContext* context,
  1184.                   fe_HorizontalRulePropertiesDialogData* data
  1185.                   )
  1186. {
  1187.   fe_DialogBuilderArg* code;
  1188.   Widget dialog;
  1189.  
  1190.   /*
  1191.    *     Make shell.
  1192.    */
  1193.   dialog = fe_CreatePromptDialog(context, "horizontalLineProperties",
  1194.                    TRUE, TRUE, FALSE, TRUE, TRUE);
  1195.  
  1196.   /*
  1197.    *   Make the rowcol, because we want to manage it.
  1198.    */
  1199.   code = fe_HorizontalRulePropertiesDialogProgram;
  1200.  
  1201.   db_do_work(context, dialog,
  1202.               fe_DialogBuilderDefaultCreators,
  1203.               &code,
  1204.               data);
  1205.  
  1206.   return dialog;
  1207. }
  1208.  
  1209. static void
  1210. fe_hrule_destroy_cb (Widget widget, XtPointer closure, XtPointer call_data)
  1211. {
  1212.     int* done = (int*)closure;
  1213.  
  1214.     *done = XFE_DIALOG_DESTROY_BUTTON;
  1215. }
  1216.  
  1217. static void
  1218. fe_hrule_ok_cb (Widget widget, XtPointer closure, XtPointer call_data)
  1219. {
  1220.     int* done = (int*)closure;
  1221.  
  1222.     *done = XmDIALOG_OK_BUTTON;
  1223. }
  1224.  
  1225. static void
  1226. fe_hrule_apply_cb (Widget widget, XtPointer closure, XtPointer call_data)
  1227. {
  1228.     int* done = (int*)closure;
  1229.  
  1230.     *done = XmDIALOG_APPLY_BUTTON;
  1231. }
  1232.  
  1233. static void
  1234. fe_hrule_cancel_cb (Widget widget, XtPointer closure, XtPointer call_data)
  1235. {
  1236.     int* done = (int*)closure;
  1237.  
  1238.     *done = XmDIALOG_CANCEL_BUTTON;
  1239. }
  1240.  
  1241. void
  1242. fe_EditorHorizontalRulePropertiesDialogDo(MWContext* context)
  1243. {
  1244.     fe_HorizontalRulePropertiesDialogData widgets;
  1245.     int done;
  1246.     Widget dialog;
  1247.  
  1248. #if 0
  1249.     if (!fe_EditorHorizontalRulePropertiesCanDo(context)) {
  1250.         XBell(XtDisplay(CONTEXT_WIDGET(context)), 0);
  1251.         return;
  1252.     }
  1253. #endif
  1254.  
  1255.     dialog = fe_EditorHorizontalRulePropertiesCreate(context, &widgets);
  1256.  
  1257.     /*
  1258.      *   Add a bunch of callbacks to the buttons.
  1259.      */
  1260.     XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done);
  1261.     XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  1262.     XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  1263.  
  1264.     /*
  1265.      *    Load values.
  1266.      */
  1267.     fe_HorizontalRulePropertiesDialogDataGet(context, &widgets);
  1268.     
  1269.     /*
  1270.      *    Popup.
  1271.      */
  1272.     XtManageChild(dialog);
  1273.  
  1274.     /*
  1275.      *    Wait.
  1276.      */
  1277.     fe_NukeBackingStore(dialog); /* what does this do? */
  1278.     done = XmDIALOG_NONE;
  1279.     while (done == XmDIALOG_NONE) {
  1280.         fe_EventLoop();
  1281.  
  1282.         /*
  1283.          *    Unload data.
  1284.          */
  1285.         if (done == XmDIALOG_OK_BUTTON
  1286.             &&
  1287.             !fe_editor_hrule_properties_validate(context, &widgets)) {
  1288.             done = XmDIALOG_NONE;
  1289.         }
  1290.     }
  1291.  
  1292.     if (done == XmDIALOG_OK_BUTTON)
  1293.         fe_HorizontalRulePropertiesDialogSet(context, &widgets);
  1294.  
  1295.     if (done != XFE_DIALOG_DESTROY_BUTTON)
  1296.         XtDestroyWidget(dialog);
  1297. }
  1298.  
  1299. static void
  1300. fe_destroy_cleanup_cb(Widget widget, XtPointer closure, XtPointer cb)
  1301. {
  1302.     if (closure)
  1303.         XtFree(closure);
  1304. }
  1305.  
  1306. void
  1307. fe_DependentListAddDependent(fe_DependentList** list_a,
  1308.                       Widget widget, fe_Dependency mask,
  1309.                       XtCallbackProc proc, XtPointer closure)
  1310. {
  1311.     fe_DependentList* list = XtNew(fe_DependentList);
  1312.  
  1313.     list->next = *list_a;
  1314.     list->widget = widget;
  1315.     list->mask = mask;
  1316.     list->callback.callback = proc;
  1317.     list->callback.closure = closure;
  1318.  
  1319.     *list_a = list;
  1320. }
  1321.         
  1322. void
  1323. fe_DependentListDestroy(fe_DependentList* list)
  1324. {
  1325.     fe_DependentList* next;
  1326.  
  1327.     for (; list; list = next) {
  1328.         next = list->next;
  1329.         XtFree((XtPointer)list);
  1330.     }
  1331. }
  1332.  
  1333. typedef struct fe_DependentListCallbackStruct
  1334. {
  1335.     int     reason;
  1336.     XEvent  *event;
  1337.     fe_Dependency mask;
  1338.     Widget  caller;
  1339.     XtPointer callers_data;
  1340. } fe_DependentListCallbackStruct;
  1341.  
  1342. void
  1343. fe_DependentListCallDependents(Widget caller,
  1344.                                fe_DependentList* list,
  1345.                                fe_Dependency mask,
  1346.                                XtPointer callers_data)
  1347. {
  1348.     fe_DependentListCallbackStruct call_data;
  1349.  
  1350.     call_data.reason = 0;
  1351.     call_data.event = 0;
  1352.     call_data.mask = mask;
  1353.     call_data.caller = caller;
  1354.     call_data.callers_data = callers_data;
  1355.  
  1356.     for (; list; list = list->next) {
  1357.         if ((list->mask & mask) != 0)
  1358.             (*list->callback.callback)(list->widget, list->callback.closure,
  1359.                                        &call_data);
  1360.     }
  1361. }
  1362.  
  1363. void
  1364. fe_MakeDependent(Widget widget, fe_Dependency mask, 
  1365.                  XtCallbackProc proc, XtPointer closure)
  1366. {
  1367.     MWContext* context = (MWContext *)fe_WidgetToMWContext(widget);
  1368.  
  1369.     fe_DependentListAddDependent(
  1370.                                  &(CONTEXT_DATA(context)->dependents),
  1371.                                  widget,
  1372.                                  mask,
  1373.                                  proc,
  1374.                                  closure);
  1375. }
  1376.     
  1377. void
  1378. fe_CallDependents(MWContext* context, fe_Dependency mask)
  1379. {
  1380.     fe_DependentListCallDependents(NULL, CONTEXT_DATA(context)->dependents,
  1381.                                    mask, NULL);
  1382. }
  1383.  
  1384. struct fe_EditorParagraphPropertiesWidgets;
  1385. struct fe_EditorCharacterPropertiesWidgets;
  1386. struct fe_EditorLinkPropertiesWidgets;
  1387. struct fe_EditorImagePropertiesWidgets;
  1388.  
  1389. typedef struct fe_EditorPropertiesWidgets {
  1390.     MWContext*                                  context;
  1391.     fe_DependentList*                           dependents;
  1392.     struct fe_EditorCharacterPropertiesWidgets* character;
  1393.     struct fe_EditorLinkPropertiesWidgets*      link;
  1394.     struct fe_EditorParagraphPropertiesWidgets* paragraph;
  1395.     struct fe_EditorImagePropertiesWidgets*     image;
  1396.     fe_Dependency                               changed;
  1397. } fe_EditorPropertiesWidgets;
  1398.  
  1399. typedef struct fe_EditorParagraphPropertiesWidgets {
  1400.     fe_EditorPropertiesWidgets* properties;
  1401.     Widget style_menu;
  1402.     Widget additional_menu;
  1403.     Widget list_style_menu;
  1404.     Widget bullet_style_menu;
  1405.     Widget start_text;
  1406.  
  1407.     Widget  numbering_pulldown;
  1408.     Widget  bullet_pulldown;
  1409.     TagType paragraph_style;
  1410.     TagType additional_style;
  1411.     TagType list_style;
  1412.     ED_ListType bullet_style;
  1413.     ED_Alignment align;
  1414.     unsigned start;
  1415. } fe_EditorParagraphPropertiesWidgets;
  1416.  
  1417. typedef enum fe_JavaScriptModes
  1418. {
  1419.     JAVASCRIPT_NONE = 0,
  1420.     JAVASCRIPT_SERVER,
  1421.     JAVASCRIPT_CLIENT
  1422. } fe_JavaScriptModes;
  1423.  
  1424. typedef struct fe_EditorCharacterPropertiesWidgets {
  1425.     fe_EditorPropertiesWidgets* properties;
  1426.     Widget form;
  1427.     Widget color_default;
  1428.     Widget color_custom;
  1429.     Widget color_swatch;
  1430.     /* something else to hold custom color I guess */
  1431.  
  1432.     Widget bold;
  1433.     Widget italic;
  1434.     Widget fixed;
  1435.     Widget strike_thru;
  1436.     Widget super_script;
  1437.     Widget sub_script;
  1438.     Widget blink;
  1439.     
  1440.     ED_FontSize font_size;
  1441.     ED_TextFormat text_attributes;
  1442.     ED_TextFormat changed_mask;
  1443.     LO_Color      color;
  1444.     Boolean is_custom_color;
  1445.     fe_JavaScriptModes js_mode;
  1446. } fe_EditorCharacterPropertiesWidgets;
  1447.  
  1448. typedef char* EDT_LtabbList_t;
  1449.  
  1450. typedef struct fe_EditorLinkPropertiesWidgets {
  1451.     fe_EditorPropertiesWidgets* properties;
  1452.     Widget form;
  1453.     Widget displayed_label;
  1454.     Widget displayed_text;
  1455.     Widget link_text;
  1456.     /* others I don't understand */
  1457.     Widget target_list;
  1458.     EDT_LtabbList_t target_list_data;
  1459.     Widget target_current_doc;
  1460.     Widget target_selected_file;
  1461.     Widget target_label;
  1462.     char* selected_filename;
  1463.     char* url;
  1464.     char* text;
  1465. } fe_EditorLinkPropertiesWidgets;
  1466.  
  1467. typedef struct fe_EditorImagePropertiesWidgets {
  1468.     fe_EditorPropertiesWidgets* properties;
  1469.     EDT_ImageData               image_data;
  1470.     Widget main_image;
  1471.     Widget alt_image;
  1472.     Widget alt_text;
  1473.     Widget image_height;
  1474.     Widget image_width;
  1475.     Widget margin_height;
  1476.     Widget margin_width;
  1477.     Widget margin_solid;
  1478.     Widget constrain;
  1479.     Boolean  existing_image; /* means there was an image when we loaded */
  1480.     Boolean  new_image;      /* means a new image gets loaded */
  1481.     Boolean  do_constrain;
  1482.     Boolean  do_custom_size;
  1483.     Boolean  default_border; /* Don't output a BORDER attribute at all. */
  1484. } fe_EditorImagePropertiesWidgets;
  1485.  
  1486. #define PROP_CHAR_BOLD    (0x1<<0)
  1487. #define PROP_CHAR_ITALIC  (0x1<<1)
  1488. #define PROP_CHAR_FIXED   (0x1<<2)
  1489. #define PROP_CHAR_SUPER   (0x1<<3)
  1490. #define PROP_CHAR_SUB     (0x1<<4)
  1491. #define PROP_CHAR_STRIKE  (0x1<<5)
  1492. #define PROP_CHAR_BLINK   (0x1<<6)
  1493. #define PROP_CHAR_COLOR   (0x1<<7)
  1494. #define PROP_CHAR_SIZE    (0x1<<8)
  1495.  
  1496. #define PROP_CHAR_SERVER    (0x1<<10)
  1497. #define PROP_CHAR_CLIENT    (0x1<<11)
  1498. #define PROP_CHAR_UNDERLINE (0x1<<12)
  1499.  
  1500. #define PROP_PARA_STYLE   (0x1<<13)
  1501. #define PROP_PARA_LIST    (0x1<<14)
  1502. #define PROP_PARA_BULLET  (0x1<<15)
  1503. #define PROP_PARA_ALIGN   (0x1<<16)
  1504. #define PROP_LINK_TEXT    (0x1<<17)
  1505. #define PROP_LINK_HREF    (0x1<<18)
  1506. #define PROP_IMAGE_MAIN_IMAGE (0x1<<19)
  1507. #define PROP_IMAGE_ALT_IMAGE  (0x1<<20)
  1508. #define PROP_IMAGE_ALT_TEXT   (0x1<<21)
  1509. #define PROP_IMAGE_ALIGN      (0x1<<22)
  1510. #define PROP_IMAGE_HEIGHT     (0x1<<23)
  1511. #define PROP_IMAGE_WIDTH      (0x1<<24)
  1512. #define PROP_IMAGE_MARGIN_HEIGHT (0x1<<25)
  1513. #define PROP_IMAGE_MARGIN_WIDTH  (0x1<<26)
  1514. #define PROP_IMAGE_MARGIN_BORDER (0x1<<27)
  1515. #define PROP_IMAGE_COPY       (0x1<<28)
  1516. #define PROP_IMAGE_IMAP       (0x1<<29)
  1517. #define PROP_LINK_LIST    (0x1<<30)
  1518.  
  1519. #define PROP_CHAR_STYLE   \
  1520. (PROP_CHAR_BOLD|PROP_CHAR_ITALIC|PROP_CHAR_UNDERLINE|PROP_CHAR_FIXED| \
  1521.  PROP_CHAR_STRIKE|PROP_CHAR_SUPER|PROP_CHAR_SUB|PROP_CHAR_BLINK)
  1522. #define PROP_CHAR_JAVASCRIPT (PROP_CHAR_CLIENT|PROP_CHAR_SERVER)
  1523. #define PROP_CHAR_ALL     \
  1524. (PROP_CHAR_STYLE|PROP_CHAR_COLOR|PROP_CHAR_SIZE|PROP_CHAR_JAVASCRIPT)
  1525. #define PROP_PARA_ALL     \
  1526. (PROP_PARA_STYLE|PROP_PARA_LIST|PROP_PARA_BULLET|PROP_PARA_ALIGN)
  1527. #define PROP_LINK_ALL     \
  1528. (PROP_LINK_TEXT|PROP_LINK_HREF|PROP_LINK_LIST)
  1529. #define PROP_IMAGE_DIMENSIONS (PROP_IMAGE_HEIGHT|PROP_IMAGE_WIDTH)
  1530. #define PROP_IMAGE_SPACE      \
  1531. (PROP_IMAGE_MARGIN_HEIGHT|PROP_IMAGE_MARGIN_WIDTH|PROP_IMAGE_MARGIN_BORDER)
  1532. #define PROP_IMAGE_ALL    \
  1533. (PROP_IMAGE_MAIN_IMAGE|PROP_IMAGE_ALT_IMAGE|PROP_IMAGE_ALT_TEXT|  \
  1534.  PROP_IMAGE_ALIGN|PROP_IMAGE_DIMENSIONS|PROP_IMAGE_SPACE|         \
  1535.  PROP_IMAGE_COPY|PROP_IMAGE_IMAP)
  1536.  
  1537. static void
  1538. fe_update_dependents(Widget caller,
  1539.                      fe_EditorPropertiesWidgets* p_data, fe_Dependency mask)
  1540. {
  1541.     p_data->changed |= mask;
  1542.     fe_DependentListCallDependents(caller, p_data->dependents, mask, NULL);
  1543. }
  1544.  
  1545. static void
  1546. fe_register_dependent(fe_EditorPropertiesWidgets* p_data, Widget widget,
  1547.                       fe_Dependency mask, XtCallbackProc proc, XtPointer closure)
  1548. {
  1549.     fe_DependentListAddDependent(&p_data->dependents,
  1550.                                  widget,
  1551.                                  mask,
  1552.                                  proc,
  1553.                                  closure);
  1554. }
  1555.  
  1556. typedef struct fe_style_data {
  1557.     char* name;
  1558.     unsigned data;
  1559. } fe_style_data;
  1560.  
  1561. static struct fe_style_data fe_paragraph_style[] = {
  1562.     { "normal",          P_NSDT       },
  1563.     { "headingOne",      P_HEADER_1   },
  1564.     { "headingTwo",      P_HEADER_2   },
  1565.     { "headingThree",    P_HEADER_3   },
  1566.     { "headingFour",     P_HEADER_4   },
  1567.     { "headingFive",     P_HEADER_5   },
  1568.     { "headingSix",      P_HEADER_6   },
  1569.     { "address",         P_ADDRESS    },
  1570.     { "formatted",       P_PREFORMAT  },
  1571.     { "listItem",        P_LIST_ITEM  },
  1572.     { "descriptionItem", P_DESC_TITLE },
  1573.     { "descriptionText", P_DESC_TEXT  },
  1574.     { 0 }
  1575. };
  1576.  
  1577. static struct fe_style_data fe_additional_style[] = {
  1578.     { "default",         P_NSDT       },
  1579.     { "list",            P_LIST_ITEM  },
  1580.     { "blockQuote",      P_BLOCKQUOTE },
  1581.     { 0 }
  1582. };
  1583.  
  1584. static struct fe_style_data fe_list_style[] = {
  1585.     { "unnumbered",      P_UNUM_LIST  },
  1586.     { "numbered",        P_NUM_LIST   },
  1587.     { "directory",       P_DIRECTORY  },
  1588.     { "menu",            P_MENU       },
  1589.     { "description",     P_DESC_LIST  },
  1590.     { 0 }
  1591. };
  1592.  
  1593. static struct fe_style_data fe_bullet_style[] = {
  1594.     { "automatic",       ED_LIST_TYPE_DEFAULT },
  1595.     { "solidCircle",     ED_LIST_TYPE_DISC    },
  1596.     { "openSquare",      ED_LIST_TYPE_SQUARE  },
  1597.     { "openCircle",      ED_LIST_TYPE_CIRCLE  },
  1598.     { 0 }
  1599. };
  1600.  
  1601. static struct fe_style_data fe_numbering_style[] = {
  1602.     { "automatic",       ED_LIST_TYPE_DEFAULT        },
  1603.     { "digital",         ED_LIST_TYPE_DIGIT          },
  1604.     { "upperRoman",      ED_LIST_TYPE_BIG_ROMAN      },
  1605.     { "lowerRoman",      ED_LIST_TYPE_SMALL_ROMAN    },
  1606.     { "upperAlpha",      ED_LIST_TYPE_BIG_LETTERS    },
  1607.     { "lowerAlpha",      ED_LIST_TYPE_SMALL_LETTERS  },
  1608.     { 0 }
  1609. };
  1610.  
  1611. static struct fe_style_data fe_align_style[] = {
  1612.     { "left",       ED_ALIGN_LEFT   },
  1613.     { "center",     ED_ALIGN_ABSCENTER },
  1614.     { "right",      ED_ALIGN_RIGHT  },
  1615.     { 0 }
  1616. };
  1617.  
  1618. static unsigned
  1619. fe_convert_value_to_index(fe_style_data* style_data, unsigned value)
  1620. {
  1621.     unsigned i;
  1622.  
  1623.     for (i = 0; style_data[i].name; i++) {
  1624.         if (style_data[i].data == value)
  1625.             return i;
  1626.     }
  1627.     /* maybe should assert */
  1628.     return 0;
  1629. }
  1630.  
  1631. static void
  1632. fe_paragraph_style_menu_update_cb(Widget widget, XtPointer closure,
  1633.                                   XtPointer call_data)
  1634. {
  1635.     fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure;
  1636.  
  1637.     TagType  type = w_data->paragraph_style;
  1638.     unsigned index = fe_convert_value_to_index(fe_paragraph_style, type);
  1639.  
  1640.     fe_OptionMenuSetHistory(widget, index);
  1641. }
  1642.  
  1643. static void
  1644. fe_paragraph_style_cb(Widget widget, XtPointer closure, XtPointer call_data)
  1645. {
  1646.     fe_EditorParagraphPropertiesWidgets* w_data
  1647.         = (fe_EditorParagraphPropertiesWidgets*)closure;
  1648.     unsigned foo = (unsigned)fe_GetUserData(widget);
  1649.     TagType  type = (TagType)foo;
  1650.  
  1651.     w_data->paragraph_style = type;
  1652.     if (type == P_LIST_ITEM) {
  1653.         w_data->additional_style = P_LIST_ITEM;
  1654.     } else if (w_data->additional_style == P_LIST_ITEM) {
  1655.         w_data->additional_style = P_NSDT; /* default */
  1656.     }
  1657.  
  1658.     fe_update_dependents(widget, w_data->properties, PROP_PARA_STYLE|PROP_PARA_LIST);
  1659. }
  1660.  
  1661. static void
  1662. fe_additional_style_menu_update_cb(Widget widget, XtPointer closure,
  1663.                                   XtPointer call_data)
  1664. {
  1665.     fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure;
  1666.  
  1667.     TagType  type = w_data->additional_style;
  1668.     unsigned index = fe_convert_value_to_index(fe_additional_style, type);
  1669.  
  1670.     fe_OptionMenuSetHistory(widget, index);
  1671. }
  1672.  
  1673. static void
  1674. fe_additional_style_cb(Widget widget, XtPointer closure, XtPointer call_data)
  1675. {
  1676.     fe_EditorParagraphPropertiesWidgets* w_data
  1677.         = (fe_EditorParagraphPropertiesWidgets*)closure;
  1678.     unsigned foo = (unsigned)fe_GetUserData(widget);
  1679.     TagType  type = (TagType)foo;
  1680.  
  1681.     w_data->additional_style = type;
  1682.     if (type == P_LIST_ITEM)
  1683.         w_data->paragraph_style = P_LIST_ITEM;
  1684.  
  1685.     fe_update_dependents(widget, w_data->properties, PROP_PARA_STYLE|PROP_PARA_LIST);
  1686. }
  1687.  
  1688. static void
  1689. fe_list_style_menu_update_cb(Widget widget, XtPointer closure,
  1690.                                   XtPointer call_data)
  1691. {
  1692.     fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure;
  1693.  
  1694.     TagType  type = w_data->additional_style;
  1695.     Boolean  enabled = FALSE;
  1696.     unsigned index;
  1697.  
  1698.     if (type == P_LIST_ITEM) {
  1699.         type = w_data->list_style;
  1700.         index = fe_convert_value_to_index(fe_list_style, type);
  1701.         enabled = TRUE;
  1702.  
  1703.         fe_OptionMenuSetHistory(widget, index);
  1704.     }
  1705.  
  1706.     XtVaSetValues(XmOptionButtonGadget(widget), XmNsensitive, enabled, 0);
  1707. }
  1708.  
  1709. static void
  1710. fe_list_style_cb(Widget widget, XtPointer closure, XtPointer call_data)
  1711. {
  1712.     fe_EditorParagraphPropertiesWidgets* w_data
  1713.         = (fe_EditorParagraphPropertiesWidgets*)closure;
  1714.     unsigned foo = (unsigned)fe_GetUserData(widget);
  1715.     TagType  type = (TagType)foo;
  1716.  
  1717.     w_data->list_style = type;
  1718.     
  1719.     fe_update_dependents(widget, w_data->properties, PROP_PARA_LIST|PROP_PARA_BULLET);
  1720. }
  1721.  
  1722. static void
  1723. fe_bullet_style_menu_update_cb(Widget widget, XtPointer closure,
  1724.                                   XtPointer call_data)
  1725. {
  1726.     fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure;
  1727.  
  1728.     TagType  type = w_data->additional_style;
  1729.     Boolean  enabled = FALSE;
  1730.     unsigned index = 0;         /* keep -O happy */
  1731.     Widget   cascade = XmOptionButtonGadget(widget);
  1732.     Widget   pulldown = NULL;   /* keep -O happy */
  1733.  
  1734.     if (type == P_LIST_ITEM) {
  1735.         type = w_data->list_style;
  1736.         if (type == P_NUM_LIST) {
  1737.             enabled = TRUE;
  1738.             index = fe_convert_value_to_index(fe_numbering_style,
  1739.                                               w_data->bullet_style);
  1740.             pulldown = w_data->numbering_pulldown;
  1741.         } else if (type == P_UNUM_LIST) {
  1742.             enabled = TRUE;
  1743.             index = fe_convert_value_to_index(fe_bullet_style,
  1744.                                               w_data->bullet_style);
  1745.             pulldown = w_data->bullet_pulldown;
  1746.         }
  1747.  
  1748.         if (enabled) {
  1749.             XtVaSetValues(cascade, XmNsubMenuId, pulldown, 0);
  1750.             fe_OptionMenuSetHistory(widget, index);
  1751.         }
  1752.     }
  1753.  
  1754.     XtVaSetValues(cascade, XmNsensitive, enabled, 0);
  1755. }
  1756.  
  1757. static void
  1758. fe_bullet_style_cb(Widget widget, XtPointer closure, XtPointer call_data)
  1759. {
  1760.     fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure;
  1761.  
  1762.     ED_ListType    type = (ED_ListType)fe_GetUserData(widget);
  1763.  
  1764.     w_data->bullet_style = type;
  1765.  
  1766.     fe_update_dependents(widget, w_data->properties, PROP_PARA_BULLET);
  1767. }
  1768.  
  1769. static Widget
  1770. fe_create_style_pulldown(Widget parent, char* name, fe_style_data* style_data,
  1771.                      Arg* p_args, Cardinal p_n)
  1772. {
  1773.     Cardinal nchildren;
  1774.     Widget   children[16];
  1775.     Widget   pulldown;
  1776.     Arg      args[8];
  1777.     Cardinal n;
  1778.     Cardinal m;
  1779.     XtCallbackRec* button_callback_rec = 0;
  1780.     XtCallbackRec* update_callback_rec = 0;
  1781.  
  1782.     for (n = m = 0; n < p_n; n++) {
  1783.         if (p_args[n].name == XmNactivateCallback)
  1784.             button_callback_rec = (XtCallbackRec*)p_args[n].value;
  1785.         else if (p_args[n].name == XmNvalueChangedCallback)
  1786.             update_callback_rec = (XtCallbackRec*)p_args[n].value;
  1787.         else {
  1788.             XtSetArg(args[m], p_args[n].name, p_args[n].value); m++;
  1789.         }
  1790.     }
  1791.  
  1792.     n = m;
  1793.     pulldown = fe_CreatePulldownMenu(parent, name, args, n);
  1794.  
  1795.     for (nchildren = 0; style_data[nchildren].name; nchildren++) {
  1796.  
  1797.         n = 0;
  1798.         XtSetArg(args[n], XmNuserData, style_data[nchildren].data); n++;
  1799.         children[nchildren] = XmCreatePushButtonGadget(
  1800.                                                        pulldown,
  1801.                                                        style_data[nchildren].name,
  1802.                                                        args,
  1803.                                                        n
  1804.                                                        );
  1805.         if (button_callback_rec) {
  1806.             XtAddCallback(children[nchildren],
  1807.                           XmNactivateCallback,
  1808.                           button_callback_rec->callback,
  1809.                           (XtPointer)button_callback_rec->closure);
  1810.         }
  1811.     }
  1812.     XtManageChildren(children, nchildren);
  1813.     
  1814.     return pulldown;
  1815. }
  1816.  
  1817. static Widget
  1818. fe_create_style_menu(Widget parent, char* name, fe_style_data* style_data,
  1819.                      Arg* p_args, Cardinal p_n)
  1820. {
  1821.     Widget   pulldown;
  1822.     Widget   option;
  1823.     Arg      args[8];
  1824.     Arg      rc_args[8];
  1825.     Cardinal n;
  1826.     Cardinal my_n;
  1827.     Cardinal rc_n;
  1828.  
  1829.     for (my_n = rc_n = n = 0; n < p_n; n++) {
  1830.         if (
  1831.             p_args[n].name == XmNactivateCallback
  1832.             ||
  1833.             p_args[n].name == XmNvalueChangedCallback
  1834.         ) {
  1835.             XtSetArg(rc_args[rc_n], p_args[n].name, p_args[n].value); rc_n++;
  1836.         } else {
  1837.             XtSetArg(args[my_n], p_args[n].name, p_args[n].value); my_n++;
  1838.         }
  1839.     }
  1840.  
  1841.     pulldown = fe_create_style_pulldown(parent, name, style_data, rc_args, rc_n);
  1842.  
  1843.     XtSetArg(args[my_n], XmNsubMenuId, pulldown); my_n++;
  1844.     option = fe_CreateOptionMenu(parent,    name, args, my_n);
  1845.     fe_UnmanageChild_safe(XmOptionLabelGadget(option));
  1846.  
  1847.     return option;
  1848. }
  1849.  
  1850. static void
  1851. fe_paragraph_align_cb(Widget widget, XtPointer closure, XtPointer call_data)
  1852. {
  1853.     fe_EditorParagraphPropertiesWidgets* w_data =
  1854.         (fe_EditorParagraphPropertiesWidgets*)closure;
  1855.     XmToggleButtonCallbackStruct* info =
  1856.         (XmToggleButtonCallbackStruct*)call_data;
  1857.  
  1858.     /*
  1859.      *    We get a callback on both the unset of the old toggle,
  1860.      *    and the set of the new, so ignore the former, it's not
  1861.      *    interesting.
  1862.      */
  1863.     if (info->set) {
  1864.  
  1865.         w_data->align = (ED_Alignment)fe_GetUserData(widget);    
  1866.  
  1867.         fe_update_dependents(widget, w_data->properties, PROP_PARA_ALIGN);
  1868.     }
  1869. }
  1870.  
  1871. static void
  1872. fe_paragraph_align_update_cb(Widget widget,
  1873.                              XtPointer closure, XtPointer call_data)
  1874. {
  1875.     fe_EditorParagraphPropertiesWidgets* w_data =
  1876.         (fe_EditorParagraphPropertiesWidgets*)closure;
  1877.     ED_Alignment align = (ED_Alignment)fe_GetUserData(widget);
  1878.     ED_Alignment w_align = w_data->align;
  1879.  
  1880.     if (w_align == ED_ALIGN_DEFAULT)
  1881.         w_align = ED_ALIGN_LEFT;
  1882.  
  1883.     if (w_align == ED_ALIGN_CENTER) /* just in case the BE changes */
  1884.         w_align = ED_ALIGN_ABSCENTER;
  1885.  
  1886.     XmToggleButtonGadgetSetState(widget, (w_align == align), FALSE);
  1887. }
  1888.  
  1889. static void
  1890. fe_set_text_field(Widget widget, char* value,
  1891.                   XtCallbackProc cb, XtPointer closure)
  1892. {
  1893.     if (cb)
  1894.         XtRemoveCallback(widget, XmNvalueChangedCallback,
  1895.                          cb, closure);
  1896.  
  1897.     if (!value)
  1898.         value = "";
  1899.  
  1900.     fe_SetTextFieldAndCallBack(widget, value);
  1901.     
  1902.     if (cb)
  1903.         XtAddCallback(widget, XmNvalueChangedCallback,
  1904.                       cb, closure);
  1905. }
  1906.  
  1907. static void
  1908. fe_set_numeric_text_field(Widget widget, unsigned value)
  1909. {
  1910.     char buf[32];
  1911.  
  1912.     sprintf(buf, "%d", value);
  1913.  
  1914.     fe_TextFieldSetString(widget, buf, FALSE);
  1915. }
  1916.  
  1917. static void
  1918. fe_paragraph_start_cb(Widget widget, XtPointer closure, XtPointer call_data)
  1919. {
  1920.     fe_EditorParagraphPropertiesWidgets* w_data =
  1921.         (fe_EditorParagraphPropertiesWidgets*)closure;
  1922.  
  1923.     fe_update_dependents(widget, w_data->properties, PROP_PARA_BULLET);
  1924. }
  1925.  
  1926. #if 0
  1927. static unsigned
  1928. fe_aztoui(char* s, Boolean upper)
  1929. {
  1930.     char* p;
  1931.     unsigned rv = 0;
  1932.     unsigned high;
  1933.     unsigned low;
  1934.     if (upper) {
  1935.       low = 'A';
  1936.       high = 'Z';
  1937.     } else {
  1938.       low = 'a';
  1939.       high = 'z';
  1940.     }
  1941.     for (p = s; *p >= low && *p <= high; p++) {
  1942.         rv *= 26;
  1943.         rv += (*p - low) + 1;
  1944.     }
  1945.     return rv;
  1946.  
  1947. static int
  1948. fe_uitoaz(char* buf, unsigned value, Boolean upper)
  1949. {
  1950.     char* p;
  1951.     unsigned base = 26;
  1952.     unsigned low;
  1953.     if (upper) {
  1954.       low = 'A';
  1955.     } else {
  1956.       low = 'a';
  1957.     }
  1958.  
  1959.     if (value == 0) {
  1960.         buf[0] = '\0';
  1961.         return 0;
  1962.     }
  1963.     value--;
  1964.  
  1965.     for (p = buf; base < value; p++)
  1966.         base = base * 26;
  1967.  
  1968.     p[1] = '\0';
  1969.  
  1970.  
  1971.     for (; p >= buf; p--) {
  1972.         *p = (value % 26) + low;
  1973.         value /= 26;
  1974.     }
  1975.     return strlen(buf);
  1976. }
  1977. #endif
  1978.  
  1979. static void
  1980. fe_paragraph_start_update_cb(Widget widget,
  1981.                              XtPointer closure, XtPointer call_data)
  1982. {
  1983.     fe_EditorParagraphPropertiesWidgets* w_data =
  1984.         (fe_EditorParagraphPropertiesWidgets*)closure;
  1985.     fe_DependentListCallbackStruct* info = 
  1986.         (fe_DependentListCallbackStruct*)call_data;
  1987.     char buf[256];
  1988.     Boolean enabled;
  1989.  
  1990.     if (info->caller == widget)
  1991.         return; /* don't call ourselves */
  1992.  
  1993.     if (w_data->paragraph_style == P_LIST_ITEM
  1994.         &&
  1995.         w_data->list_style==P_NUM_LIST) {
  1996. #if 0
  1997.         if (
  1998.             w_data->bullet_style == ED_LIST_TYPE_DIGIT
  1999.             ||
  2000.             w_data->bullet_style == ED_LIST_TYPE_BIG_ROMAN
  2001.             ||
  2002.             w_data->bullet_style == ED_LIST_TYPE_SMALL_ROMAN
  2003.         ) {
  2004.             sprintf(buf, "%d", w_data->start);
  2005.         } else if (w_data->bullet_style == ED_LIST_TYPE_BIG_LETTERS) {
  2006.             fe_uitoaz(buf, w_data->start, TRUE);
  2007.         } else  if (w_data->bullet_style == ED_LIST_TYPE_SMALL_LETTERS) {
  2008.             fe_uitoaz(buf, w_data->start, FALSE);
  2009.         }
  2010. #else
  2011.         if (w_data->start < 1)
  2012.             w_data->start = 1;
  2013.         sprintf(buf, "%d", w_data->start);
  2014. #endif
  2015.         enabled = TRUE;
  2016.     } else {
  2017.         buf[0] = '\0';
  2018.         enabled = FALSE;
  2019.     }
  2020.  
  2021.     fe_TextFieldSetEditable(w_data->properties->context, widget, enabled);
  2022.     fe_set_text_field(widget, buf, fe_paragraph_start_cb, (XtPointer)w_data);
  2023. }
  2024.  
  2025. static void
  2026. fe_EditorParagraphPropertiesDialogDataGet(
  2027.                                   MWContext* context,
  2028.                                   fe_EditorParagraphPropertiesWidgets* w_data)
  2029. {
  2030.     EDT_ListData list_data;
  2031.  
  2032.     fe_EditorParagraphPropertiesGetAll(context,
  2033.                                        &w_data->paragraph_style,
  2034.                                        &list_data,
  2035.                                        &w_data->align);
  2036.     
  2037.     switch (list_data.iTagType) {
  2038.     case P_BLOCKQUOTE: /* block quotes */
  2039.         w_data->additional_style = P_BLOCKQUOTE;
  2040.         w_data->list_style = P_UNUM_LIST;
  2041.         w_data->bullet_style = ED_LIST_TYPE_DEFAULT;
  2042.         break;
  2043.  
  2044.     case P_NUM_LIST: /* lists */
  2045.         w_data->start = list_data.iStart;
  2046.         if (w_data->start < 1)
  2047.             w_data->start = 1;
  2048.         /*FALLTHRU*/
  2049.     case P_UNUM_LIST:
  2050.     case P_DIRECTORY:
  2051.     case P_MENU:
  2052.     case P_DESC_LIST:
  2053.         w_data->additional_style = P_LIST_ITEM;
  2054.         w_data->list_style = list_data.iTagType;
  2055.         w_data->bullet_style = list_data.eType;
  2056.         break;
  2057.  
  2058.     default:
  2059.         w_data->additional_style = P_NSDT;
  2060.         w_data->list_style = P_UNUM_LIST;
  2061.         w_data->bullet_style = ED_LIST_TYPE_DEFAULT;
  2062.         break;
  2063.     }
  2064.  
  2065.     /*
  2066.      *    Update the display.
  2067.      */
  2068.     fe_update_dependents(NULL, w_data->properties, PROP_PARA_ALL);
  2069. }
  2070.  
  2071. static void
  2072. fe_EditorParagraphPropertiesDialogSet(
  2073.                                  MWContext* context,
  2074.                                  fe_EditorParagraphPropertiesWidgets* w_data)
  2075. {
  2076.     EDT_ListData list_data;
  2077.     char* p = NULL;
  2078.  
  2079.     memset(&list_data, 0, sizeof(EDT_ListData));
  2080.  
  2081.     if (w_data->paragraph_style == P_LIST_ITEM) { /* do list stuff */
  2082.         list_data.iTagType = w_data->list_style;
  2083.         list_data.bCompact = 0; /* ??? */
  2084.         list_data.eType = w_data->bullet_style;
  2085.         p = fe_TextFieldGetString(w_data->start_text);
  2086.         list_data.iStart = atoi(p);
  2087.         if (p)
  2088.             XtFree(p);
  2089.  
  2090.         fe_EditorParagraphPropertiesSetAll(context,
  2091.                                            w_data->paragraph_style,
  2092.                                            &list_data,
  2093.                                            w_data->align);
  2094.         
  2095.     } else if (w_data->additional_style == P_BLOCKQUOTE) { /* do quote */
  2096.         
  2097.         list_data.iTagType = P_BLOCKQUOTE;
  2098.         list_data.bCompact = 0; /* ??? */
  2099.         list_data.eType = ED_LIST_TYPE_DEFAULT;
  2100.  
  2101.         fe_EditorParagraphPropertiesSetAll(context,
  2102.                                            w_data->paragraph_style,
  2103.                                            &list_data,
  2104.                                            w_data->align);
  2105.     } else {
  2106.         fe_EditorParagraphPropertiesSetAll(context,
  2107.                                            w_data->paragraph_style,
  2108.                                            NULL,
  2109.                                            w_data->align);
  2110.     }
  2111.     
  2112.  
  2113. }
  2114.  
  2115. static void
  2116. fe_make_paragraph_page(
  2117.                        MWContext *context,
  2118.                        Widget parent,
  2119.                        fe_EditorParagraphPropertiesWidgets* w_data)
  2120. {
  2121.     Arg args[16];
  2122.     Cardinal n;
  2123.     Widget form;
  2124.     Widget paragraph_label;
  2125.     Widget paragraph_option;
  2126.     Widget additional_label;
  2127.     Widget additional_option;
  2128.     Widget list_frame;
  2129.     Widget list_form;
  2130.     Widget list_style_label;
  2131.     Widget list_style_option;
  2132.     Widget bullet_style_option;
  2133.     Widget starting_text;
  2134.     Widget starting_label;
  2135.     Widget align_frame;
  2136.     Widget align_rc;
  2137.     Widget children[16];
  2138.     Cardinal nchildren;
  2139.     XtCallbackRec callback;
  2140.  
  2141. #if 0
  2142.     n = 0;
  2143.     form = XmCreateForm(parent, "paragraphProperties", args, n);
  2144.     XtManageChild(form);
  2145. #else
  2146.     form = parent;
  2147. #endif
  2148.  
  2149.     /*
  2150.      *    Paragraph Style.
  2151.      */
  2152.     n = 0;
  2153.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2154.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2155.     paragraph_label = XmCreateLabelGadget(form, "styleLabel", args, n);
  2156.     XtManageChild(paragraph_label);
  2157.  
  2158.     n = 0;
  2159.     callback.callback = fe_paragraph_style_cb;
  2160.     callback.closure = (XtPointer)w_data;
  2161.     XtSetArg(args[n], XmNactivateCallback, &callback); n++;
  2162.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2163.     XtSetArg(args[n], XmNtopWidget, paragraph_label); n++;
  2164.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2165.     paragraph_option = fe_create_style_menu(form, "style", fe_paragraph_style,
  2166.                                             args, n);
  2167.     XtManageChild(paragraph_option);
  2168.  
  2169.     fe_register_dependent(w_data->properties, paragraph_option,
  2170.                           FE_MAKE_DEPENDENCY(PROP_PARA_STYLE|PROP_PARA_LIST),
  2171.                           fe_paragraph_style_menu_update_cb, (XtPointer)w_data);
  2172.  
  2173.     /*
  2174.      *    Additional Style.
  2175.      */
  2176.     n = 0;
  2177.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2178.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  2179.     XtSetArg(args[n], XmNleftWidget, paragraph_option); n++;
  2180.     additional_label = XmCreateLabelGadget(form, "additionalLabel", args, n);
  2181.     XtManageChild(additional_label);
  2182.  
  2183.     n = 0;
  2184.     callback.callback = fe_additional_style_cb;
  2185.     callback.closure = (XtPointer)w_data;
  2186.     XtSetArg(args[n], XmNactivateCallback, &callback); n++;
  2187.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2188.     XtSetArg(args[n], XmNtopWidget, paragraph_label); n++;
  2189.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  2190.     XtSetArg(args[n], XmNleftWidget, paragraph_option); n++;
  2191.     additional_option = fe_create_style_menu(form, "additional", fe_additional_style,
  2192.                                             args, n);
  2193.     XtManageChild(additional_option);
  2194.  
  2195.     fe_register_dependent(w_data->properties, additional_option,
  2196.                           FE_MAKE_DEPENDENCY(PROP_PARA_STYLE|PROP_PARA_LIST),
  2197.                           fe_additional_style_menu_update_cb, (XtPointer)w_data);
  2198.     /*
  2199.      *    List frame and friends. THIS IS SO BORING!!!!!!!!!!!!!
  2200.      */
  2201.     n = 0;
  2202.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2203.     XtSetArg(args[n], XmNtopWidget, paragraph_option); n++;
  2204.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2205.     list_frame = fe_CreateFrame(form, "list", args, n);
  2206.     XtManageChild(list_frame);
  2207.     
  2208.     n = 0;
  2209.     list_form = XmCreateForm(list_frame, "list", args, n);
  2210.     XtManageChild(list_form);
  2211.  
  2212.     n = 0;
  2213.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2214.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2215.     list_style_label = XmCreateLabelGadget(list_form, "listLabel", args, n);
  2216.     XtManageChild(list_style_label);
  2217.  
  2218.     n = 0;
  2219.     callback.callback = fe_list_style_cb;
  2220.     callback.closure = (XtPointer)w_data;
  2221.     XtSetArg(args[n], XmNactivateCallback, &callback); n++;
  2222.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2223.     XtSetArg(args[n], XmNtopWidget, list_style_label); n++;
  2224.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2225.     list_style_option = fe_create_style_menu(list_form, "listStyle", fe_list_style,
  2226.                                             args, n);
  2227.     XtManageChild(list_style_option);
  2228.  
  2229.     fe_register_dependent(w_data->properties, list_style_option,
  2230.                           FE_MAKE_DEPENDENCY(PROP_PARA_LIST),
  2231.                           fe_list_style_menu_update_cb, (XtPointer)w_data);
  2232.  
  2233.     n = 0;
  2234.     callback.callback = fe_bullet_style_cb;
  2235.     callback.closure = (XtPointer)w_data;
  2236.     XtSetArg(args[n], XmNactivateCallback, &callback); n++;
  2237.     w_data->numbering_pulldown = fe_create_style_pulldown(list_form,
  2238.                                                           "bulletStyle",
  2239.                                                           fe_numbering_style,
  2240.                                                           args, n);
  2241.     w_data->bullet_pulldown = fe_create_style_pulldown(list_form,
  2242.                                                        "bulletStyle",
  2243.                                                        fe_bullet_style,
  2244.                                                        args, n);
  2245.  
  2246.     n = 0;
  2247.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2248.     XtSetArg(args[n], XmNtopWidget, list_style_label); n++;
  2249.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  2250.     XtSetArg(args[n], XmNleftWidget, list_style_option); n++;
  2251.     XtSetArg(args[n], XmNsubMenuId, w_data->bullet_pulldown); n++;
  2252.     bullet_style_option = fe_CreateOptionMenu(list_form, "bulletStyle", args, n);
  2253.     fe_UnmanageChild_safe(XmOptionLabelGadget(bullet_style_option));
  2254.     XtManageChild(bullet_style_option);
  2255.  
  2256.     fe_register_dependent(w_data->properties, bullet_style_option,
  2257.                           FE_MAKE_DEPENDENCY(PROP_PARA_BULLET|PROP_PARA_LIST),
  2258.                           fe_bullet_style_menu_update_cb, (XtPointer)w_data);
  2259.  
  2260.     n = 0;
  2261.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2262.     XtSetArg(args[n], XmNtopWidget, bullet_style_option); n++;
  2263.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  2264.     XtSetArg(args[n], XmNrightWidget, bullet_style_option); n++;
  2265.     w_data->start_text = starting_text = 
  2266.         fe_CreateTextField(list_form, "startText", args, n);
  2267.     XtManageChild(starting_text);
  2268.  
  2269.     XtAddCallback(starting_text, XmNvalueChangedCallback,
  2270.                   fe_paragraph_start_cb, (XtPointer)w_data);
  2271.     fe_register_dependent(w_data->properties, starting_text,
  2272.                           FE_MAKE_DEPENDENCY(PROP_PARA_BULLET|PROP_PARA_LIST),
  2273.                           fe_paragraph_start_update_cb, (XtPointer)w_data);
  2274.  
  2275.     n = 0;
  2276.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2277.     XtSetArg(args[n], XmNtopWidget, bullet_style_option); n++;
  2278.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  2279.     XtSetArg(args[n], XmNrightWidget, starting_text); n++;
  2280.     starting_label = XmCreateLabelGadget(list_form, "startLabel", args, n);
  2281.     XtManageChild(starting_label);
  2282.  
  2283.     /*
  2284.      *    Align.
  2285.      */
  2286.     n = 0;
  2287.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2288.     XtSetArg(args[n], XmNtopWidget, list_frame); n++;
  2289.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2290.     align_frame = fe_CreateFrame(form, "align", args, n);
  2291.     XtManageChild(align_frame);
  2292.  
  2293.     n = 0;
  2294.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  2295.     XtSetArg(args[n], XmNradioBehavior, TRUE); n++;
  2296.     align_rc = XmCreateRowColumn(align_frame, "align", args, n);
  2297.     XtManageChild(align_rc);
  2298.  
  2299.     for (nchildren = 0; fe_align_style[nchildren].name; nchildren++) {
  2300.         n = 0;
  2301.         XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  2302.         XtSetArg(args[n], XmNuserData, fe_align_style[nchildren].data); n++;
  2303.         children[nchildren] = XmCreateToggleButtonGadget(
  2304.                                              align_rc,
  2305.                                              fe_align_style[nchildren].name,
  2306.                                              args, n);
  2307.  
  2308.         XtAddCallback(children[nchildren], XmNvalueChangedCallback,
  2309.                       fe_paragraph_align_cb, (XtPointer)w_data);
  2310.         fe_register_dependent(w_data->properties,
  2311.                              children[nchildren], 
  2312.                              FE_MAKE_DEPENDENCY(PROP_PARA_ALIGN),
  2313.                              fe_paragraph_align_update_cb, (XtPointer)w_data);
  2314.     }
  2315.  
  2316.     XtManageChildren(children, nchildren);
  2317.  
  2318. #if 0
  2319.     /* Humour for Beta */
  2320.     /* Apparently our testers have no humour - oh well */
  2321.     n = 0;
  2322.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2323.     XtSetArg(args[n], XmNtopWidget, align_frame); n++;
  2324.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2325.     align_rc = XmCreateLabelGadget(form, "spaceAvailable", args, n);
  2326.     XtManageChild(align_rc);
  2327. #endif
  2328. }
  2329.  
  2330. static void
  2331. fe_link_text_changed_cb(Widget widget, XtPointer closure, XtPointer call_data)
  2332. {
  2333.     fe_EditorLinkPropertiesWidgets* w_data =
  2334.         (fe_EditorLinkPropertiesWidgets*)closure;
  2335.     
  2336.     fe_update_dependents(widget, w_data->properties, PROP_LINK_TEXT);
  2337. }
  2338.  
  2339. static char*
  2340. fe_image_get_name(fe_EditorImagePropertiesWidgets* w_data)
  2341. {
  2342.     char* p = NULL;
  2343.  
  2344.     if (w_data->main_image)
  2345.         p = fe_TextFieldGetString(w_data->main_image);
  2346.     
  2347.     if (!p && w_data->alt_image)
  2348.         p = fe_TextFieldGetString(w_data->alt_image);
  2349.  
  2350.     if (!p && w_data->alt_text)
  2351.         p = fe_TextFieldGetString(w_data->alt_text);
  2352.  
  2353.     return p;
  2354. }
  2355.  
  2356. static void
  2357. fe_link_text_update_cb(Widget widget, XtPointer closure, XtPointer call_data)
  2358. {
  2359.     fe_EditorLinkPropertiesWidgets* w_data =
  2360.         (fe_EditorLinkPropertiesWidgets*)closure;
  2361.     fe_DependentListCallbackStruct* info = 
  2362.         (fe_DependentListCallbackStruct*)call_data;
  2363.     Boolean enabled = FALSE;
  2364.     char*   text;
  2365.     char* free_text = NULL;
  2366.     char* label_string;
  2367.     int   id;
  2368.     XmString xm_string;
  2369.  
  2370.     if (info->caller == widget)
  2371.         return; /* don't call ourselves */
  2372.  
  2373.     /*
  2374.      *    If we have an image, use the image name as the current
  2375.      *    displayed text.
  2376.      */
  2377.     if (w_data->properties->image != NULL) {
  2378.         free_text = text = fe_image_get_name(w_data->properties->image);
  2379.         enabled = FALSE;
  2380.         id = XFE_EDITOR_LINK_TEXT_LABEL_IMAGE;
  2381.         /* Linked image: */
  2382.     } else if (w_data->text) {
  2383.         text = w_data->text;
  2384.         enabled = FALSE;
  2385.         id = XFE_EDITOR_LINK_TEXT_LABEL_TEXT;
  2386.         /* Linked text: */
  2387.     } else {
  2388.         text = "";
  2389.         enabled = TRUE;
  2390.         id = XFE_EDITOR_LINK_TEXT_LABEL_NEW;
  2391.         /* Enter the text of the link: */
  2392.     }
  2393.  
  2394.     fe_set_text_field(widget, text, fe_link_text_changed_cb,(XtPointer)w_data);
  2395.     fe_TextFieldSetEditable(w_data->properties->context, widget, enabled);
  2396.     
  2397.     /*
  2398.      *    While we are here set the label also.
  2399.      */
  2400.     label_string = XP_GetString(id);
  2401.     xm_string = XmStringCreateLocalized(label_string);
  2402.     XtVaSetValues(w_data->displayed_label, XmNlabelString, xm_string, 0);
  2403.     XmStringFree(xm_string);
  2404.  
  2405.     if (free_text)
  2406.         XtFree(free_text);
  2407. }
  2408.  
  2409. static void
  2410. fe_link_href_changed_cb(Widget widget, XtPointer closure, XtPointer call_data)
  2411. {
  2412.     
  2413.     fe_EditorLinkPropertiesWidgets* w_data =
  2414.         (fe_EditorLinkPropertiesWidgets*)closure;
  2415.  
  2416.     fe_update_dependents(widget, w_data->properties, PROP_LINK_HREF);
  2417. }
  2418.  
  2419. static void
  2420. fe_link_href_update_cb(Widget widget, XtPointer closure, XtPointer call_data)
  2421. {
  2422.     fe_EditorLinkPropertiesWidgets* w_data =
  2423.         (fe_EditorLinkPropertiesWidgets*)closure;
  2424.     fe_DependentListCallbackStruct* info = 
  2425.         (fe_DependentListCallbackStruct*)call_data;
  2426.     char*   text;
  2427.  
  2428.     if (info->caller == widget)
  2429.         return; /* don't call ourselves */
  2430.  
  2431.     /*
  2432.      *    If we have an image, use the image name as the current
  2433.      *    displayed text.
  2434.      */
  2435.     if (w_data->url) {
  2436.         text = w_data->url;
  2437.     } else {
  2438.         text = "";
  2439.     }
  2440.  
  2441.     fe_set_text_field(widget, text, fe_link_href_changed_cb,(XtPointer)w_data);
  2442.     w_data->url = NULL;
  2443. }
  2444.  
  2445. static char*
  2446. fe_basename(char* target, char* source)
  2447. {
  2448.     char* p;
  2449.             
  2450.     p = strrchr(source, '/'); /* find last slash */
  2451.  
  2452.     if (p) { /* should be */
  2453.         strcpy(target, p+1);
  2454.     } else {
  2455.         strcpy(target, source);
  2456.     }
  2457.     return target;
  2458. }
  2459.  
  2460. static char*
  2461. fe_dirname(char* target, char* source)
  2462. {
  2463.     char* p;
  2464.             
  2465.     p = strrchr(source, '/'); /* find last slash */
  2466.  
  2467.     if (p) { /* should be */
  2468.         if (p == source) {
  2469.             strcpy(target, "/");
  2470.         } else {
  2471.             memcpy(target, source, p - source);
  2472.             target[p - source] = '\0';
  2473.         }
  2474.     } else {
  2475.         strcpy(target, ".");
  2476.     }
  2477.     return target;
  2478. }
  2479.  
  2480. static Boolean
  2481. fe_file_has_same_directory(MWContext* context, char* pathname)
  2482. {
  2483.     char my_dirname[MAXPATHLEN];
  2484.     char your_dirname[MAXPATHLEN];
  2485.  
  2486.     fe_EditorMakeName(context, your_dirname, sizeof(your_dirname));
  2487.     fe_dirname(my_dirname, your_dirname);
  2488.     fe_dirname(your_dirname, pathname);
  2489.  
  2490.     return (strcmp(my_dirname, your_dirname) == 0);
  2491. }
  2492.  
  2493. static void
  2494. fe_link_properties_list_update(fe_EditorLinkPropertiesWidgets*, Boolean);
  2495.  
  2496. static void
  2497. fe_editor_browse_file_of_text(MWContext* context, Widget text_field)
  2498. {
  2499.     char* before_save;
  2500.     char* before_changed = NULL;
  2501.     char* after;
  2502.     char* p;
  2503.  
  2504.     /*
  2505.      *    Strip #target from the browse default filename.
  2506.      */
  2507.     before_save = fe_TextFieldGetString(text_field);
  2508.  
  2509.     /*
  2510.      *    If the text field is a http: form URL, then zero it,
  2511.      *    because we are not browsing for a file.
  2512.      */
  2513.     if (before_save != NULL) {
  2514.         fe_StringTrim(before_save);
  2515.  
  2516.         if ((p = strchr(before_save, ':')) != NULL) {
  2517.             if (NET_IsLocalFileURL(before_save)) {
  2518.                 before_changed = XtNewString(&p[1]);
  2519.             } else {
  2520.                 before_changed = XtNewString("");
  2521.             }
  2522.         } else if ((p = strchr(before_save, '#')) != NULL) {
  2523.             *p = '\0';
  2524.             before_changed = XtNewString(before_save);
  2525.             *p = '#';
  2526.         }
  2527.         if (before_changed != NULL)
  2528.             fe_TextFieldSetString(text_field, before_changed, FALSE);
  2529.     }
  2530.     
  2531.     fe_browse_file_of_text(context, text_field, FALSE);
  2532.  
  2533.     after = fe_TextFieldGetString(text_field);
  2534.     fe_StringTrim(after);
  2535.  
  2536.     /*
  2537.      *    If we zapped it, and there was no change by the user,
  2538.      *    put it back the way it was.
  2539.      */
  2540.     if (before_changed != NULL && strcmp(after, before_changed) == 0) {
  2541.         fe_TextFieldSetString(text_field, before_save, FALSE);
  2542.     }
  2543.     /*
  2544.      *    Or, if the main file, and the link file are in the same
  2545.      *    directory, simplfy the name.
  2546.      */
  2547.     else if (fe_file_has_same_directory(context, after)) {
  2548.         char  basename[MAXPATHLEN];
  2549.         fe_basename(basename, after);
  2550.         fe_TextFieldSetString(text_field, basename, FALSE);
  2551.     }
  2552.  
  2553.     if (before_save)
  2554.         XtFree(before_save);
  2555.     if (before_changed)
  2556.         XtFree(before_changed);
  2557.     if (after)
  2558.         XtFree(after);
  2559. }
  2560.  
  2561. static void
  2562. fe_link_href_browse_cb(Widget widget, XtPointer closure, XtPointer call_data)
  2563. {
  2564.     fe_EditorLinkPropertiesWidgets* w_data =
  2565.         (fe_EditorLinkPropertiesWidgets*)closure;
  2566.     MWContext* context = w_data->properties->context;
  2567.     Widget text_field = w_data->link_text;
  2568.  
  2569.     fe_editor_browse_file_of_text(context, text_field);
  2570.  
  2571.     fe_update_dependents(widget, w_data->properties, PROP_LINK_LIST);
  2572.  
  2573.     /*
  2574.      *    Set the toggle to selected file, and update.
  2575.      */
  2576.     XmToggleButtonGadgetSetState(w_data->target_current_doc, FALSE, FALSE);
  2577.     XmToggleButtonGadgetSetState(w_data->target_selected_file, TRUE, FALSE);
  2578.  
  2579.     fe_link_properties_list_update(w_data, FALSE);
  2580. }
  2581.  
  2582. static void
  2583. fe_browse_to_text_field_cb(Widget widget,
  2584.                            XtPointer closure, XtPointer call_data)
  2585. {
  2586.     MWContext* context = (MWContext*)closure;
  2587.     Widget     text_field = (Widget)fe_GetUserData(widget);
  2588.  
  2589.     fe_browse_file_of_text(context, text_field, FALSE);
  2590. }
  2591.  
  2592. static void
  2593. fe_link_tab_remove_link(fe_EditorLinkPropertiesWidgets* w_data)
  2594. {
  2595.     w_data->url = NULL;
  2596.  
  2597.     fe_update_dependents(NULL, w_data->properties, PROP_LINK_HREF);
  2598. }
  2599.  
  2600. static void
  2601. fe_link_href_remove_cb(Widget widget, XtPointer closure, XtPointer call_data)
  2602. {
  2603.     fe_EditorLinkPropertiesWidgets* w_data =
  2604.         (fe_EditorLinkPropertiesWidgets*)closure;
  2605.  
  2606.     fe_link_tab_remove_link(w_data);
  2607. }
  2608.  
  2609. static Boolean
  2610. fe_link_tab_has_link(fe_EditorLinkPropertiesWidgets* w_data)
  2611. {
  2612.     char*   link_text;
  2613.     Boolean rv = FALSE;
  2614.  
  2615.     if (w_data != NULL) {
  2616.         /* 
  2617.          *    get the link text, to see if there any.
  2618.          */
  2619.         link_text = fe_TextFieldGetString(w_data->link_text);
  2620.  
  2621.         if (link_text != NULL) {
  2622.             if (link_text[0] != '\0') /* has a link */
  2623.                 rv = TRUE;
  2624.             XP_FREEIF(link_text);
  2625.         }
  2626.     }
  2627.     
  2628.     return rv;
  2629. }
  2630.  
  2631. static void
  2632. fe_link_href_remove_update_cb(Widget widget,
  2633.                               XtPointer closure, XtPointer call_data)
  2634. {
  2635.     fe_EditorLinkPropertiesWidgets* w_data =
  2636.         (fe_EditorLinkPropertiesWidgets*)closure;
  2637.     Boolean sensitive = fe_link_tab_has_link(w_data);
  2638.  
  2639.     fe_WidgetSetSensitive(widget, sensitive);
  2640. }
  2641.  
  2642. #if 0
  2643. static void
  2644. fe_ListAddItems(Widget widget, char** items, unsigned nitems)
  2645. {
  2646.     unsigned i;
  2647.     XmString xm_string;
  2648.  
  2649.     XmListDeleteAllItems(widget);
  2650.  
  2651.     for (i = 0; i < nitems; i++) {
  2652.         xm_string = XmStringCreateLocalized(items[i]);
  2653.         XmListAddItem(widget, xm_string, i + 1); /* MOTIFism */
  2654.         XmStringFree(xm_string);
  2655.     }
  2656. }
  2657. #endif
  2658.  
  2659. static void
  2660. fe_ListSetFromLtabbList(Widget widget, EDT_LtabbList_t ltabb_list)
  2661. {
  2662.     char*    p;
  2663.     XmString xm_string;
  2664.     unsigned len;
  2665.     unsigned i;
  2666.  
  2667.     XmListDeleteAllItems(widget);
  2668.  
  2669.     if (ltabb_list) {
  2670.         for (p = ltabb_list, i = 0; (len = XP_STRLEN(p)) > 0; i++) {
  2671.             xm_string = XmStringCreateLocalized(p);
  2672.             XmListAddItem(widget, xm_string, i + 1); /* MOTIFism */
  2673.             XmStringFree(xm_string);
  2674.             p += len + 1;
  2675.         }
  2676.     }
  2677. }
  2678.  
  2679. static char*
  2680. fe_LtabbListGetItem(EDT_LtabbList_t ltabb_list, unsigned index)
  2681. {
  2682.     unsigned i;
  2683.     char* p;
  2684.     unsigned len;
  2685.  
  2686.     if (ltabb_list) {
  2687.         for (p = ltabb_list, i = 0; (len = XP_STRLEN(p)) > 0; i++) {
  2688.             if (i == index)
  2689.                 return p;
  2690.             p += len + 1;
  2691.         }
  2692.     }
  2693.     return NULL;
  2694. }
  2695.  
  2696. static void
  2697. fe_link_properties_list_cb(Widget widget, XtPointer closure,
  2698.                                     XtPointer foo)
  2699. {
  2700.     fe_EditorLinkPropertiesWidgets* w_data = 
  2701.       (fe_EditorLinkPropertiesWidgets*)closure;
  2702.     XmListCallbackStruct* cb_data = (XmListCallbackStruct*)foo;
  2703.     char  basename[MAXPATHLEN];
  2704.     char  buf[MAXPATHLEN];
  2705.     char* pathname;
  2706.     char* p;
  2707.     char* target_name;
  2708.     Boolean current_doc;
  2709.  
  2710.     current_doc = XmToggleButtonGadgetGetState(w_data->target_current_doc);
  2711.     
  2712.     if (cb_data->reason != XmCR_SINGLE_SELECT)
  2713.           return;
  2714.  
  2715.     if (cb_data->item_position > 0) {
  2716.         target_name = fe_LtabbListGetItem(w_data->target_list_data,
  2717.                                           cb_data->item_position - 1);
  2718.     } else {
  2719.         target_name = NULL;
  2720.     }
  2721.  
  2722.     if (current_doc) {
  2723.         pathname = NULL;
  2724.     } else {
  2725.         pathname = fe_TextFieldGetString(w_data->link_text);
  2726.  
  2727.         if ((p = strchr(pathname, '#')) != NULL) {
  2728.             memcpy(basename, pathname, p - pathname);
  2729.             basename[p - pathname] = '\0';
  2730.         } else {
  2731.             strcpy(basename, pathname);
  2732.         }
  2733.  
  2734.         XtFree(pathname);
  2735.         pathname = basename;
  2736.  
  2737.         if (pathname[0] == '\0')
  2738.             pathname = NULL;
  2739.     }
  2740.     
  2741.     if (pathname != NULL && target_name != NULL) {
  2742.         strcpy(buf, pathname);
  2743.         strcat(buf, "#");
  2744.         strcat(buf, target_name);
  2745.     } else if (target_name != NULL) {
  2746.         strcpy(buf, "#");
  2747.         strcat(buf, target_name);
  2748.     } else {
  2749.         buf[0] = '\0';
  2750.     }
  2751.  
  2752.     fe_TextFieldSetString(w_data->link_text, buf, FALSE);
  2753.     w_data->properties->changed |= PROP_LINK_HREF;
  2754. }
  2755.  
  2756. static void
  2757. fe_link_properties_list_update(fe_EditorLinkPropertiesWidgets* w_data,
  2758.                                   Boolean current_file)
  2759. {
  2760.     MWContext* context = w_data->properties->context;
  2761.     char* link_text;
  2762.     EDT_LtabbList_t list_data = NULL;
  2763.     char* crazy;
  2764.     XmString xm_string;
  2765.     int id;
  2766.  
  2767.     if (w_data->target_list_data)
  2768.         XP_FREE(w_data->target_list_data);
  2769.     
  2770.     if (current_file) {
  2771.         list_data = EDT_GetAllDocumentTargets(context);
  2772.     } else {
  2773.         link_text = fe_TextFieldGetString(w_data->link_text);
  2774.         if (link_text && link_text[0] != '\0') {
  2775.             list_data =    EDT_GetAllDocumentTargetsInFile(context, link_text);
  2776.         }
  2777.         XtFree(link_text);
  2778.     }
  2779.  
  2780.     if (list_data && XP_STRLEN(list_data) == 0) {
  2781.         XP_FREE(list_data);
  2782.         list_data = NULL;
  2783.     }
  2784.  
  2785.     if (list_data && current_file)
  2786.         id = XFE_EDITOR_LINK_TARGET_LABEL_CURRENT;
  2787.          /* Link to a named target in the current document (optional.) */
  2788.     else if (list_data && !current_file)
  2789.         id = XFE_EDITOR_LINK_TARGET_LABEL_SPECIFIED;
  2790.         /* Link to a named target in the specified document (optional.) */
  2791.     else
  2792.         id = XFE_EDITOR_LINK_TARGET_LABEL_NO_TARGETS;
  2793.         /* No targets in the selected document */
  2794.  
  2795.     crazy = XP_GetString(id);
  2796.     xm_string = XmStringCreateLocalized(crazy);
  2797.     XtVaSetValues(w_data->target_label, XmNlabelString, xm_string, 0);
  2798.     XmStringFree(xm_string);
  2799.     
  2800.     w_data->target_list_data = list_data;
  2801.  
  2802.     fe_ListSetFromLtabbList(w_data->target_list, w_data->target_list_data);
  2803.     XmToggleButtonGadgetSetState(w_data->target_current_doc,
  2804.                                  current_file, FALSE);
  2805.     XmToggleButtonGadgetSetState(w_data->target_selected_file,
  2806.                                  !current_file, FALSE);
  2807. }
  2808.  
  2809. static void
  2810. fe_link_properties_list_update_cb(Widget widget, XtPointer closure,
  2811.                                     XtPointer cb_data)
  2812. {
  2813.     fe_EditorLinkPropertiesWidgets* w_data = 
  2814.         (fe_EditorLinkPropertiesWidgets*)closure;
  2815.     Boolean set = XmToggleButtonGadgetGetState(w_data->target_current_doc);
  2816.  
  2817.     fe_link_properties_list_update(w_data, set);
  2818. }
  2819.  
  2820. static void
  2821. fe_link_properties_target_toggle_cb(Widget widget, XtPointer closure,
  2822.                                     XtPointer cb_data)
  2823. {
  2824.     fe_EditorLinkPropertiesWidgets* w_data = 
  2825.         (fe_EditorLinkPropertiesWidgets*)closure;
  2826.     Boolean current_file = (widget == w_data->target_current_doc);
  2827.     Boolean set = XmToggleButtonGadgetGetState(widget);
  2828.     
  2829.     fe_link_properties_list_update(w_data, (set == current_file));
  2830. }
  2831.  
  2832. /*
  2833.  *   Load the form context.
  2834.  */
  2835. static void
  2836. fe_editor_link_properties_dialog_data_init(
  2837.                                      MWContext* context,
  2838.                                      fe_EditorLinkPropertiesWidgets* w_data)
  2839. {
  2840.     char* text;
  2841.     char* href;
  2842.     char* p;
  2843.     Boolean text_exists;
  2844.  
  2845.     /*
  2846.      *    If we are on something a link, we display the text that is
  2847.      *    selected, or nothing. Text is read only. If we are not on
  2848.      *    a link, text field is editable.
  2849.      *
  2850.      *    If we are on a link, we display that link, this field
  2851.      *    is always editable.
  2852.      */
  2853.     text_exists = fe_EditorHrefGet(context, &text, &href);
  2854.  
  2855.     /* if (!text_exists)    
  2856.         return;
  2857.      */
  2858.  
  2859.     /*
  2860.      *   Replace CR/LF with spaces to avoid ugly break in static display
  2861.      */
  2862.     if (text) {
  2863.         for (p = text; *p; p++) {
  2864.             if (*p == '\n' || *p == '\r')
  2865.                 *p = ' ';
  2866.         }
  2867.         w_data->text = text;
  2868.     } else {
  2869.         w_data->text = NULL;
  2870.     }
  2871.  
  2872.     if (href) {
  2873.         w_data->url = href;
  2874.         if (w_data->text == NULL)
  2875.             w_data->text = "";
  2876.     } else {
  2877.         w_data->url = NULL;
  2878.     }
  2879.  
  2880.     fe_update_dependents(NULL, w_data->properties, PROP_LINK_ALL);
  2881.  
  2882.     /*
  2883.      *    Don't know what these are yet.
  2884.      */
  2885.     w_data->selected_filename = NULL;
  2886.     fe_link_properties_list_update(w_data, TRUE);
  2887.  
  2888.     if (text)
  2889.         XtFree(text);
  2890.     if (href)
  2891.         XtFree(href);
  2892. }
  2893.  
  2894. static void
  2895. fe_editor_link_properties_dialog_set(
  2896.                                      MWContext* context,
  2897.                                      fe_EditorLinkPropertiesWidgets* w_data)
  2898. {
  2899.     char* displayed_text;
  2900.     char* link_text;
  2901.  
  2902.     displayed_text = fe_TextFieldGetString(w_data->displayed_text);
  2903.     link_text = fe_TextFieldGetString(w_data->link_text);
  2904.     
  2905.     /*
  2906.      *    If the text field was editable, then we are creating a new
  2907.      *    link. I don't really like carrying state around in the
  2908.      *    values of the widgets, but this should work ok...djw.
  2909.      */
  2910.     if (XmTextFieldGetEditable(w_data->displayed_text)) {
  2911.         if (link_text && (link_text[0] != '\0')) /* don't anything if no link! */
  2912.             fe_EditorHrefInsert(context, displayed_text, link_text);
  2913.     } else { /* modify exiting link/text */
  2914.         if (link_text && link_text[0] == '\0')
  2915.             fe_EditorHrefSetUrl(context, NULL);
  2916.         else
  2917.             fe_EditorHrefSetUrl(context, link_text);
  2918.     }
  2919.     
  2920.     if (displayed_text)
  2921.         XP_FREEIF(displayed_text);
  2922.     if (link_text)
  2923.         XP_FREEIF(link_text);
  2924. }
  2925.  
  2926. static void
  2927. fe_make_link_page(
  2928.                   MWContext* context,
  2929.                   Widget     parent,
  2930.                   fe_EditorLinkPropertiesWidgets* w_data
  2931.                   )
  2932. {
  2933.   Arg av [50];
  2934.   int ac;
  2935.   Widget form;
  2936.   Widget linkSourceLabel, sourceFrame, sourceForm;
  2937.   Widget linkToLabel, linkToFrame, linkToForm;
  2938.   Widget sourceTextLabel;
  2939.   Widget linkedTextLabel;
  2940.   Widget linkToTarget;
  2941.   Widget linkToBrowseFile;
  2942.   Widget linkToRemoveLink;
  2943.   Widget linkPageTextField;
  2944.   Widget sourceTextField;
  2945.   Widget target_list;
  2946.   Widget SelectedFileToggle;
  2947.   Widget currentDocToggle;
  2948.   Widget linkToShowTargets;
  2949.   Widget kids [100];
  2950.   Widget target_rc;
  2951.   Widget list_parent;
  2952.   Pixel  parent_bg;
  2953.  
  2954.   int i;
  2955.  
  2956.   XtVaGetValues(parent, XmNbackground, &parent_bg, 0);
  2957.  
  2958. #if 0
  2959.   ac = 0;
  2960.   XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  2961.   XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  2962.   XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  2963.   XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  2964.   form = XmCreateForm(parent, "linkProperties", av, ac);
  2965.   XtManageChild (form);
  2966. #else
  2967.   form = parent;
  2968. #endif
  2969.   w_data->form = form;
  2970.     
  2971.   /**********************************************************************/
  2972.   /*  Create the Link source frame and form 28FEB96RCJ            */
  2973.   /**********************************************************************/
  2974.   ac = 0;
  2975.   XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  2976.   XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  2977.   XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  2978.   XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  2979.   sourceFrame = XmCreateFrame (form, "linkSourceFrame", av, ac);
  2980.   ac = 0;
  2981.   XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  2982.   XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  2983.   XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  2984.   XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  2985.   sourceForm = XmCreateForm (sourceFrame, "linkSourceForm", av, ac);
  2986.  
  2987.   /**********************************************************************/
  2988.   /*  Create the Link To frame and form 28FEB96RCJ            */
  2989.   /**********************************************************************/
  2990.   ac = 0;
  2991.   XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  2992.   XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  2993.   XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  2994.   XtSetArg (av [ac], XmNtopWidget, sourceFrame); ac++;
  2995. #if 0
  2996.   XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  2997. #endif
  2998.   linkToFrame = XmCreateFrame (form, "linkToFrame", av, ac);
  2999.  
  3000.   ac = 0;
  3001.   XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  3002.   XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  3003.   XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  3004.   XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  3005.   linkToForm = XmCreateForm (linkToFrame, "linkToForm", av, ac);
  3006.  
  3007.   /**********************************************************************/
  3008.   /*  Create the titles for the frames 28FEB96RCJ            */
  3009.   /**********************************************************************/
  3010.   ac = 0;
  3011.   XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++;
  3012.   linkSourceLabel = XmCreateLabelGadget (sourceFrame, "linkSourceTitle", av, ac);
  3013.   linkToLabel = XmCreateLabelGadget (linkToFrame, "linkToTitle", av, ac);
  3014.  
  3015.   /**********************************************************************/
  3016.   /*  Create and manage the contents of the source form and frame    */
  3017.   /**********************************************************************/
  3018.   ac = 0;
  3019.   i = 0;
  3020.   XtSetArg (av [ac], XmNtopAttachment,   XmATTACH_FORM); ac++;
  3021.   XtSetArg (av [ac], XmNleftAttachment,   XmATTACH_FORM); ac++;
  3022.   kids [i++] = sourceTextLabel = XmCreateLabelGadget (sourceForm, 
  3023.                                                       "linkSourceLabel",
  3024.                               av, ac);
  3025.   w_data->displayed_label = sourceTextLabel;
  3026.  
  3027.   ac = 0;
  3028.   XtSetArg (av [ac], XmNtopAttachment,   XmATTACH_WIDGET); ac++;
  3029.   XtSetArg (av [ac], XmNtopWidget,       sourceTextLabel); ac++;
  3030.   XtSetArg (av [ac], XmNleftAttachment,  XmATTACH_FORM);   ac++;
  3031.   XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM);   ac++;
  3032.   kids [i++] = sourceTextField = fe_CreateTextField (sourceForm, 
  3033.                                                      "linkSourceText", 
  3034.                                                      av, ac);
  3035.   w_data->displayed_text = sourceTextField;
  3036.  
  3037.   XtAddCallback(sourceTextField, XmNvalueChangedCallback,
  3038.                 fe_link_text_changed_cb, (XtPointer)w_data);
  3039.   fe_register_dependent(w_data->properties, sourceTextField,
  3040.                         FE_MAKE_DEPENDENCY(PROP_LINK_TEXT),
  3041.                         fe_link_text_update_cb, (XtPointer)w_data);
  3042.  
  3043.   XtManageChildren (kids, i);
  3044.   XtManageChild (linkSourceLabel);
  3045.   XtManageChild (sourceForm);
  3046.  
  3047.   /**********************************************************************/
  3048.   /*  Create and manage the contents of the Link to form and frame    */
  3049.   /**********************************************************************/
  3050.   ac = 0;
  3051.   i = 0;
  3052.   XtSetArg (av [ac], XmNleftAttachment,   XmATTACH_FORM);   ac++;
  3053.   XtSetArg (av [ac], XmNtopAttachment,    XmATTACH_FORM);   ac++;
  3054.   kids [i++] = linkedTextLabel = XmCreateLabelGadget (linkToForm, 
  3055.                                                     "linkToLabel",
  3056.                             av, ac);
  3057.   ac = 0;
  3058.   XtSetArg (av [ac], XmNleftAttachment,   XmATTACH_WIDGET); ac++;
  3059.   XtSetArg (av [ac], XmNleftWidget,       linkedTextLabel); ac++;
  3060.   XtSetArg (av [ac], XmNtopAttachment,    XmATTACH_FORM);   ac++;
  3061.   kids [i++] = linkToBrowseFile = XmCreatePushButtonGadget (linkToForm,
  3062.                                                "browseFile",
  3063.                                                av, ac);
  3064.   XtAddCallback(linkToBrowseFile, XmNactivateCallback,
  3065.                 fe_link_href_browse_cb, (XtPointer)w_data);
  3066.  
  3067.   ac = 0;
  3068.   XtSetArg (av [ac], XmNleftAttachment,   XmATTACH_WIDGET);  ac++;
  3069.   XtSetArg (av [ac], XmNleftWidget,       linkToBrowseFile); ac++;
  3070.   XtSetArg (av [ac], XmNtopAttachment,    XmATTACH_FORM);    ac++;
  3071.   kids [i++] = linkToRemoveLink = XmCreatePushButtonGadget (linkToForm,
  3072.                                                "removeLink",
  3073.                                                av, ac);
  3074.   XtAddCallback(linkToRemoveLink, XmNactivateCallback,
  3075.                 fe_link_href_remove_cb, (XtPointer)w_data);
  3076.   fe_register_dependent(w_data->properties, linkToRemoveLink,
  3077.                         FE_MAKE_DEPENDENCY(PROP_LINK_HREF),
  3078.                         fe_link_href_remove_update_cb, (XtPointer)w_data);
  3079.   
  3080.   ac = 0;
  3081.   XtSetArg (av [ac], XmNtopAttachment,   XmATTACH_WIDGET); ac++;
  3082.   XtSetArg (av [ac], XmNtopWidget,       linkedTextLabel); ac++;
  3083.   XtSetArg (av [ac], XmNtopOffset,       10);              ac++;
  3084.   XtSetArg (av [ac], XmNleftAttachment,  XmATTACH_FORM);   ac++;
  3085.   XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM);   ac++;
  3086.   kids [i++] = linkPageTextField = fe_CreateTextField (linkToForm, 
  3087.                                                        "linkPageTextField", 
  3088.                                                        av, ac);
  3089.   w_data->link_text = linkPageTextField;
  3090.   XtAddCallback(linkPageTextField, XmNvalueChangedCallback,
  3091.                 fe_link_href_changed_cb, (XtPointer)w_data);
  3092.   fe_register_dependent(w_data->properties, linkPageTextField,
  3093.                         FE_MAKE_DEPENDENCY(PROP_LINK_HREF),
  3094.                         fe_link_href_update_cb, (XtPointer)w_data);
  3095.  
  3096.   ac = 0;
  3097.   XtSetArg (av [ac], XmNtopAttachment,   XmATTACH_WIDGET);   ac++;
  3098.   XtSetArg (av [ac], XmNtopWidget,       linkPageTextField); ac++;
  3099.   XtSetArg (av [ac], XmNleftAttachment,  XmATTACH_FORM);     ac++;
  3100.   XtSetArg (av [ac], XmNalignment, XmALIGNMENT_BEGINNING);   ac++;
  3101.   kids [i++] = linkToTarget = XmCreateLabelGadget (linkToForm,
  3102.                                                    "linkTarget",
  3103.                                                    av, ac);
  3104.   w_data->target_label = linkToTarget;
  3105.  
  3106.   /*
  3107.    *    RowColumn to hold the buttons to right of target text.
  3108.    */
  3109.   ac = 0;
  3110.   XtSetArg (av [ac], XmNorientation, XmVERTICAL);   ac++;
  3111.   XtSetArg (av [ac], XmNtopAttachment,   XmATTACH_WIDGET);   ac++;
  3112.   XtSetArg (av [ac], XmNtopWidget,       linkToTarget);      ac++;
  3113.   XtSetArg (av [ac], XmNrightAttachment,  XmATTACH_FORM);     ac++;
  3114.   XtSetArg (av [ac], XmNpacking,  XmPACK_TIGHT);     ac++;
  3115.   kids[i++] = target_rc = XmCreateRowColumn(linkToForm,
  3116.                                             "targetRowColumn", av, ac);
  3117.  
  3118.   ac = 0;
  3119.   XtSetArg (av [ac], XmNtopAttachment,   XmATTACH_WIDGET);   ac++;
  3120.   XtSetArg (av [ac], XmNtopWidget,       linkToTarget);      ac++;
  3121.   XtSetArg (av [ac], XmNleftAttachment,  XmATTACH_FORM);     ac++;
  3122.   XtSetArg (av [ac], XmNrightAttachment,  XmATTACH_WIDGET);     ac++;
  3123.   XtSetArg (av [ac], XmNrightWidget,  target_rc);     ac++;
  3124. #if 0
  3125.   XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM);    ac++;
  3126. #endif
  3127.   XtSetArg(av[ac], XmNvisibleItemCount, 6); ac++;
  3128.   XtSetArg(av[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
  3129.   XtSetArg(av[ac], XmNbackground, parent_bg); ac++;
  3130.   target_list = XmCreateScrolledList(linkToForm, "targetList",
  3131.                                              av, ac);
  3132.   XtManageChild(target_list);
  3133.   kids [i++] = list_parent = XtParent(target_list);
  3134.  
  3135.   XtAddCallback(target_list, XmNsingleSelectionCallback,
  3136.                 fe_link_properties_list_cb, (XtPointer)w_data);
  3137.   fe_register_dependent(w_data->properties, target_list,
  3138.                         FE_MAKE_DEPENDENCY(PROP_LINK_LIST),
  3139.                         fe_link_properties_list_update_cb, (XtPointer)w_data);
  3140.  
  3141.   w_data->target_list = target_list;
  3142.  
  3143.   XtManageChildren (kids, i); /* children of form */
  3144.   XtManageChild (linkToLabel);
  3145.   XtManageChild (linkToForm);
  3146.  
  3147.   i = 0; /* no kids */
  3148.   ac = 0;
  3149.   XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
  3150.   kids [i++] = linkToShowTargets = XmCreateLabelGadget(target_rc,
  3151.                                                        "showTargets",
  3152.                                                        av, ac);
  3153.  
  3154.   ac = 0;
  3155.   XtSetArg (av [ac], XmNalignment, XmALIGNMENT_BEGINNING);     ac++;
  3156.   XtSetArg(av[ac], XmNset, TRUE); ac++;
  3157.   XtSetArg(av[ac], XmNindicatorType, XmONE_OF_MANY); ac++;
  3158.   kids [i++] = currentDocToggle =
  3159.     XmCreateToggleButtonGadget(target_rc, "currentDocument", av, ac);
  3160.  
  3161.   w_data->target_current_doc = currentDocToggle;
  3162.  
  3163.   ac = 0;
  3164.   XtSetArg (av [ac], XmNalignment, XmALIGNMENT_BEGINNING);     ac++;
  3165.   XtSetArg(av[ac], XmNset, FALSE); ac++;
  3166.   XtSetArg(av[ac], XmNindicatorType, XmONE_OF_MANY); ac++;
  3167.   kids [i++] = SelectedFileToggle =
  3168.     XmCreateToggleButtonGadget (target_rc, "selectedFile", av, ac);
  3169.  
  3170.   w_data->target_selected_file = SelectedFileToggle;
  3171.   XtManageChildren (kids, i); /* children of rc */
  3172.  
  3173.   XtAddCallback(currentDocToggle, XmNvalueChangedCallback,
  3174.               fe_link_properties_target_toggle_cb, (XtPointer)w_data);
  3175.   XtAddCallback(SelectedFileToggle, XmNvalueChangedCallback,
  3176.               fe_link_properties_target_toggle_cb, (XtPointer)w_data);
  3177.  
  3178.   /**********************************************************************/
  3179.   /*  Manage all of the frame comprising the Link dialog box        */
  3180.   /**********************************************************************/
  3181.  
  3182.   i = 0;
  3183.   kids [i++] = sourceFrame;
  3184.   kids [i++] = linkToFrame;
  3185.   XtManageChildren (kids, i);
  3186.  
  3187. } /* end fe_make_link_page */
  3188.  
  3189. static struct fe_style_data fe_style_types[] = {
  3190.     { "bold",   TF_BOLD },
  3191.     { "italic", TF_ITALIC }, 
  3192.     { "underline", TF_UNDERLINE },
  3193.     { "fixed",  TF_FIXED },
  3194.     { "strikethrough", TF_STRIKEOUT },
  3195.     { "superscript",  TF_SUPER },
  3196.     { "subscript",    TF_SUB   },
  3197.     { "blink",  TF_BLINK },
  3198.     { 0 }
  3199. };
  3200.  
  3201. static struct fe_style_data fe_font_size_types[] = {
  3202.     { "minusTwo",  ED_FONTSIZE_MINUS_TWO },
  3203.     { "minusOne",  ED_FONTSIZE_MINUS_ONE },
  3204.     { "plusZero",  ED_FONTSIZE_ZERO      },
  3205.     { "plusOne",   ED_FONTSIZE_PLUS_ONE  },
  3206.     { "plusTwo",   ED_FONTSIZE_PLUS_TWO  },
  3207.     { "plusThree", ED_FONTSIZE_PLUS_THREE },
  3208.     { "plusFour",  ED_FONTSIZE_PLUS_FOUR },
  3209.     { NULL }
  3210. };
  3211.  
  3212. static void
  3213. fe_font_size_update_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3214. {
  3215.     fe_EditorCharacterPropertiesWidgets* w_data
  3216.         = (fe_EditorCharacterPropertiesWidgets*)closure;
  3217.  
  3218.     if (w_data->js_mode == JAVASCRIPT_NONE) {
  3219.         fe_OptionMenuSetHistory(widget, w_data->font_size - 1);
  3220.         fe_WidgetSetSensitive(XmOptionButtonGadget(widget), TRUE);
  3221.     } else {
  3222.         fe_OptionMenuSetHistory(widget, ED_FONTSIZE_ZERO - 1);
  3223.         fe_WidgetSetSensitive(XmOptionButtonGadget(widget), FALSE);
  3224.     }
  3225.     /*FIXME*/ /* fix sensitivity */
  3226. }
  3227.  
  3228. static void
  3229. fe_font_size_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3230. {
  3231.     fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure;
  3232.  
  3233.     ED_FontSize size = (ED_FontSize)fe_GetUserData(widget);
  3234.  
  3235.     w_data->font_size = size;
  3236.     w_data->changed_mask |= TF_FONT_SIZE;
  3237.  
  3238.     fe_update_dependents(widget, w_data->properties, PROP_CHAR_SIZE);
  3239. }
  3240.  
  3241. static void
  3242. fe_style_update_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3243. {
  3244.     fe_EditorCharacterPropertiesWidgets* w_data
  3245.         = (fe_EditorCharacterPropertiesWidgets*)closure;
  3246.     ED_TextFormat type;
  3247.     Boolean set;
  3248.     Boolean enabled;
  3249.     unsigned foo;
  3250.  
  3251.     if (w_data->js_mode == JAVASCRIPT_NONE) {
  3252.  
  3253.         foo = (unsigned)fe_GetUserData(widget);
  3254.         type = foo;
  3255.  
  3256.         if ((type &    w_data->text_attributes) != 0)
  3257.             set = TRUE;
  3258.         else
  3259.             set = FALSE;
  3260.  
  3261.         enabled = TRUE;
  3262.     } else {
  3263.         set = FALSE;
  3264.         enabled = FALSE;
  3265.     }
  3266.  
  3267.     XmToggleButtonGadgetSetState(widget, set, FALSE);
  3268.     fe_WidgetSetSensitive(widget, enabled);
  3269. }
  3270.                          
  3271. static void
  3272. fe_style_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3273. {
  3274.     fe_EditorCharacterPropertiesWidgets* w_data =
  3275.         (fe_EditorCharacterPropertiesWidgets*)closure;
  3276.     XmToggleButtonCallbackStruct* info =
  3277.         (XmToggleButtonCallbackStruct*)call_data;
  3278.     ED_TextFormat type;
  3279.     unsigned foo;
  3280.  
  3281.     foo = (unsigned)fe_GetUserData(widget);
  3282.     type = foo;
  3283.     
  3284.     if (info->set) {
  3285.         w_data->text_attributes |= type;
  3286.  
  3287.         /*
  3288.          *    Super and Sub should be mutually exclusive.
  3289.          */
  3290.         if (type == TF_SUPER)
  3291.             w_data->text_attributes &= ~TF_SUB;
  3292.         else if (type == TF_SUB)
  3293.             w_data->text_attributes &= ~TF_SUPER;
  3294.     } else {
  3295.         w_data->text_attributes &= ~type;
  3296.     }
  3297.  
  3298.     w_data->changed_mask |= type;
  3299.  
  3300.     fe_update_dependents(widget, w_data->properties, PROP_CHAR_STYLE);
  3301. }
  3302.  
  3303. static void
  3304. fe_clear_style_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3305. {
  3306.     fe_EditorCharacterPropertiesWidgets*
  3307.         w_data = (fe_EditorCharacterPropertiesWidgets*)closure;
  3308.  
  3309.     w_data->text_attributes &= ~TF_ALL_MASK;
  3310.     w_data->changed_mask |= TF_ALL_MASK;
  3311.  
  3312.     fe_update_dependents(widget, w_data->properties, PROP_CHAR_STYLE);
  3313. }
  3314.  
  3315. static void
  3316. fe_clearall_settings_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3317. {
  3318.     fe_EditorCharacterPropertiesWidgets* w_data
  3319.         = (fe_EditorCharacterPropertiesWidgets*)closure;
  3320.     MWContext* context;
  3321.     char* link_text;
  3322.  
  3323.     if (w_data->properties->link != NULL) {
  3324.         /* 
  3325.          *    get the link text, to see if there any.
  3326.          */
  3327.         link_text = fe_TextFieldGetString(w_data->properties->link->link_text);
  3328.  
  3329.         if (link_text != NULL && link_text[0] != '\0') { /* has a link */
  3330.             context = w_data->properties->context;
  3331.             /* Do you want to remove the link? */
  3332.             if (XFE_Confirm(context,
  3333.                             XP_GetString(XFE_EDITOR_WARNING_REMOVE_LINK)))
  3334.                 fe_link_tab_remove_link(w_data->properties->link);
  3335.         }
  3336.  
  3337.         if (link_text != NULL)
  3338.             XP_FREEIF(link_text);
  3339.     }
  3340.  
  3341.     w_data->js_mode = JAVASCRIPT_NONE;
  3342.     w_data->text_attributes &= ~TF_ALL_MASK;
  3343.     w_data->is_custom_color = FALSE;
  3344.     w_data->font_size = ED_FONTSIZE_ZERO;
  3345.     w_data->changed_mask |= TF_FONT_COLOR|TF_FONT_SIZE|TF_ALL_MASK|\
  3346.                             PROP_CHAR_CLIENT|PROP_CHAR_SERVER;
  3347.  
  3348.     fe_update_dependents(widget, w_data->properties, PROP_CHAR_ALL);
  3349. }
  3350.  
  3351. static int
  3352. fe_color_do_work(MWContext* context, LO_Color* color_rv)
  3353. {
  3354.     Widget mainw = CONTEXT_WIDGET(context);
  3355.     Widget dialog;
  3356.     Arg args[8];
  3357.     Cardinal n;
  3358.     int done;
  3359.  
  3360.     n = 0;
  3361.     dialog = fe_CreateColorPickerDialog(mainw, "setColors", args, n);
  3362.     fe_ColorPickerDialogSetColor(dialog, color_rv);
  3363.     
  3364.     /*
  3365.      *   Add a bunch of callbacks to the buttons.
  3366.      */
  3367.     XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done);
  3368.     XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  3369.     XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  3370.  
  3371.     /*
  3372.      *    Popup.
  3373.      */
  3374.     XtManageChild(dialog);
  3375.  
  3376.     /*
  3377.      *    Wait.
  3378.      */
  3379.     fe_NukeBackingStore(dialog); /* what does this do? */
  3380.  
  3381.     done = XmDIALOG_NONE;
  3382.     while (done == XmDIALOG_NONE) {
  3383.         fe_EventLoop();
  3384.     }
  3385.  
  3386.     if (done == XmDIALOG_OK_BUTTON)
  3387.         fe_ColorPickerDialogGetColor(dialog, color_rv);
  3388.     
  3389.     if (done != XFE_DIALOG_DESTROY_BUTTON)
  3390.         XtDestroyWidget(dialog);
  3391.     
  3392.     if (done == XmDIALOG_OK_BUTTON)
  3393.         return XmDIALOG_OK_BUTTON;
  3394.     else
  3395.         return XmDIALOG_NONE;
  3396. }
  3397.  
  3398. static void
  3399. fe_color_swatch_update_cb(Widget widget, XtPointer closure,
  3400.                           XtPointer call_data)
  3401. {
  3402.     fe_EditorCharacterPropertiesWidgets* w_data
  3403.         = (fe_EditorCharacterPropertiesWidgets*)closure;
  3404.     LO_Color pooh;
  3405.     LO_Color* color;
  3406.     Boolean sensitive = FALSE;
  3407.  
  3408.     /*FIXME*/
  3409.     /*
  3410.      *    I'm not sure how to generate these colors.
  3411.      */
  3412.     if (w_data->js_mode == JAVASCRIPT_CLIENT) {
  3413.         pooh.red = 255;
  3414.         pooh.blue = 0;
  3415.         pooh.green = 0;
  3416.         color = &pooh;
  3417.     } else if (w_data->js_mode == JAVASCRIPT_SERVER) {
  3418.         pooh.red = 0;
  3419.         pooh.blue = 255;
  3420.         pooh.green = 0;
  3421.         color = &pooh;
  3422.     } else { /* JAVASCRIPT_NONE */
  3423.  
  3424.         if (w_data->is_custom_color) {
  3425.             color = &w_data->color;
  3426.             sensitive = TRUE;
  3427.         } else {
  3428.             MWContext* context = (MWContext *)fe_WidgetToMWContext(widget);
  3429.  
  3430.             fe_EditorDocumentGetColors(context,
  3431.                                        NULL, /* bg image */
  3432.                                        NULL,
  3433.                                        NULL, /* bg color */
  3434.                                        &pooh,/* normal color */
  3435.                                        NULL, /* link color */
  3436.                                        NULL, /* active color */
  3437.                                        NULL); /* followed color */
  3438.             color = &pooh;
  3439.         }
  3440.     } 
  3441.  
  3442.     fe_SwatchSetColor(widget, color);
  3443.     fe_SwatchSetSensitive(widget, sensitive);
  3444. }
  3445.  
  3446. Boolean
  3447. fe_ColorPicker(MWContext* context, LO_Color* in_out)
  3448. {
  3449.     LO_Color color = *in_out;
  3450.  
  3451.     if (fe_color_do_work(context, &color) == XmDIALOG_OK_BUTTON) {
  3452.         *in_out = color;
  3453.         return TRUE;
  3454.     }
  3455.     return FALSE;
  3456. }
  3457.  
  3458. static void
  3459. fe_editor_props_color_picker_cb(Widget widget,
  3460.                                 XtPointer closure, XtPointer call_data)
  3461. {
  3462.     fe_EditorCharacterPropertiesWidgets* w_data
  3463.         = (fe_EditorCharacterPropertiesWidgets*)closure;
  3464.     LO_Color color;
  3465.  
  3466.     color = w_data->color;
  3467.     if (fe_ColorPicker(w_data->properties->context, &color)) {
  3468.         w_data->color = color;
  3469.         w_data->is_custom_color = TRUE;
  3470.         w_data->changed_mask |= TF_FONT_COLOR;
  3471.     }
  3472.     fe_update_dependents(widget, w_data->properties, PROP_CHAR_COLOR);
  3473. }
  3474.  
  3475. static void
  3476. fe_color_default_update_cb(Widget widget, XtPointer closure,
  3477.                            XtPointer call_data)
  3478. {
  3479.     fe_EditorCharacterPropertiesWidgets* w_data
  3480.         = (fe_EditorCharacterPropertiesWidgets*)closure;
  3481.     Boolean sensitive = (w_data->js_mode == JAVASCRIPT_NONE);
  3482.     Boolean set = !sensitive || (w_data->is_custom_color == FALSE);
  3483.  
  3484.     XmToggleButtonSetState(widget, set, FALSE);
  3485.     fe_WidgetSetSensitive(widget, sensitive);
  3486. }
  3487.  
  3488. static void
  3489. fe_color_default_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3490. {
  3491.     fe_EditorCharacterPropertiesWidgets* w_data =
  3492.         (fe_EditorCharacterPropertiesWidgets*)closure;
  3493.     XmToggleButtonCallbackStruct* info =
  3494.         (XmToggleButtonCallbackStruct*)call_data;
  3495.  
  3496.     if (info->set) {
  3497.         w_data->changed_mask |= TF_FONT_COLOR;
  3498.         w_data->is_custom_color = FALSE;
  3499.         fe_update_dependents(widget, w_data->properties, PROP_CHAR_COLOR);
  3500.     }
  3501. }
  3502.  
  3503. static void
  3504. fe_color_custom_update_cb(Widget widget, XtPointer closure,
  3505.                           XtPointer call_data)
  3506. {
  3507.     fe_EditorCharacterPropertiesWidgets* w_data
  3508.         = (fe_EditorCharacterPropertiesWidgets*)closure;
  3509.     Boolean sensitive = (w_data->js_mode == JAVASCRIPT_NONE);
  3510.     Boolean set = sensitive && (w_data->is_custom_color == TRUE);
  3511.  
  3512.     XmToggleButtonSetState(widget, set, FALSE);
  3513.     fe_WidgetSetSensitive(widget, sensitive);
  3514. }
  3515.  
  3516. static void
  3517. fe_choose_color_update_cb(Widget widget, XtPointer closure,
  3518.                           XtPointer call_data)
  3519. {
  3520.     fe_EditorCharacterPropertiesWidgets* w_data
  3521.         = (fe_EditorCharacterPropertiesWidgets*)closure;
  3522.     Boolean sensitive = (w_data->js_mode == JAVASCRIPT_NONE) &&
  3523.                         (w_data->is_custom_color == TRUE);
  3524.  
  3525.     fe_WidgetSetSensitive(widget, sensitive);
  3526. }
  3527.  
  3528. static void
  3529. fe_clear_styles_update_cb(Widget widget, XtPointer closure,
  3530.                           XtPointer call_data)
  3531. {
  3532.     fe_EditorCharacterPropertiesWidgets* w_data
  3533.         = (fe_EditorCharacterPropertiesWidgets*)closure;
  3534.     Boolean sensitive = (w_data->js_mode == JAVASCRIPT_NONE);
  3535.  
  3536.     fe_WidgetSetSensitive(widget, sensitive);
  3537. }
  3538.  
  3539. static void
  3540. fe_color_custom_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3541. {
  3542.     fe_EditorCharacterPropertiesWidgets* w_data =
  3543.         (fe_EditorCharacterPropertiesWidgets*)closure;
  3544.     XmToggleButtonCallbackStruct* info =
  3545.         (XmToggleButtonCallbackStruct*)call_data;
  3546.  
  3547.     if (info->set) {
  3548.         w_data->changed_mask |= TF_FONT_COLOR;
  3549.         w_data->is_custom_color = TRUE;
  3550.         fe_update_dependents(widget, w_data->properties, PROP_CHAR_COLOR);
  3551.     }
  3552. }
  3553.  
  3554. static void
  3555. fe_javascript_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3556. {
  3557.     fe_EditorCharacterPropertiesWidgets* w_data =
  3558.         (fe_EditorCharacterPropertiesWidgets*)closure;
  3559.     XmToggleButtonCallbackStruct* info =
  3560.         (XmToggleButtonCallbackStruct*)call_data;
  3561.     Boolean is_server = (fe_GetUserData(widget) != NULL);
  3562.  
  3563.     if (info->set) {
  3564.         if (is_server) {
  3565.             w_data->js_mode = JAVASCRIPT_SERVER;
  3566.         } else {
  3567.             w_data->js_mode = JAVASCRIPT_CLIENT;
  3568.         }
  3569.  
  3570.         /*
  3571.          *    Javascript text doesn't have links, clear it..
  3572.          */
  3573.         if (w_data->properties->link != NULL)
  3574.             fe_link_tab_remove_link(w_data->properties->link);
  3575.         
  3576.     } else {
  3577.         w_data->js_mode = JAVASCRIPT_NONE;
  3578.     }
  3579.     w_data->changed_mask |= PROP_CHAR_CLIENT|PROP_CHAR_SERVER;
  3580.  
  3581.     fe_update_dependents(widget, w_data->properties, PROP_CHAR_ALL);
  3582. }
  3583.  
  3584. static void
  3585. fe_javascript_update_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3586. {
  3587.     fe_EditorCharacterPropertiesWidgets* w_data =
  3588.         (fe_EditorCharacterPropertiesWidgets*)closure;
  3589.     Boolean is_server = (fe_GetUserData(widget) != NULL);
  3590.     Boolean set = FALSE;
  3591.  
  3592.     if (is_server && (w_data->js_mode == JAVASCRIPT_SERVER))
  3593.         set = TRUE;
  3594.     else if (!is_server && (w_data->js_mode == JAVASCRIPT_CLIENT))
  3595.         set = TRUE;
  3596.     
  3597.     XmToggleButtonGadgetSetState(widget, set, FALSE);
  3598. }
  3599.  
  3600. static void
  3601. fe_EditorCharacterPropertiesDialogDataGet(
  3602.                                  MWContext* context,
  3603.                                  fe_EditorCharacterPropertiesWidgets* w_data)
  3604. {
  3605.     w_data->text_attributes = fe_EditorCharacterPropertiesGet(context);
  3606.     w_data->font_size = fe_EditorFontSizeGet(context);
  3607.     w_data->changed_mask = 0;
  3608.  
  3609.     if ((w_data->text_attributes & TF_SERVER))
  3610.         w_data->js_mode = JAVASCRIPT_SERVER;
  3611.     else if ((w_data->text_attributes & TF_SCRIPT))
  3612.         w_data->js_mode = JAVASCRIPT_CLIENT;
  3613.     else
  3614.         w_data->js_mode = JAVASCRIPT_NONE;
  3615.     w_data->text_attributes &= ~(TF_SERVER|TF_SCRIPT);
  3616.  
  3617.     if (fe_EditorColorGet(context, &w_data->color))
  3618.         w_data->is_custom_color = TRUE;
  3619.     else
  3620.         w_data->is_custom_color = FALSE;
  3621.  
  3622.     fe_update_dependents(NULL, w_data->properties, PROP_CHAR_ALL);
  3623. }
  3624.  
  3625. static void
  3626. fe_EditorCharacterPropertiesDialogSet(
  3627.                                  MWContext* context,
  3628.                                  fe_EditorCharacterPropertiesWidgets* w_data)
  3629. {
  3630.     LO_Color* color;
  3631.  
  3632.     if ((w_data->js_mode == JAVASCRIPT_SERVER)) {
  3633.         fe_EditorCharacterPropertiesSet(context, TF_SERVER);
  3634.     } else if ((w_data->js_mode == JAVASCRIPT_CLIENT)) {
  3635.         fe_EditorCharacterPropertiesSet(context, TF_SCRIPT);
  3636.     } else {
  3637.  
  3638.         /* clear javascript */
  3639.         if (w_data->changed_mask & (PROP_CHAR_CLIENT|PROP_CHAR_SERVER)) {
  3640.             fe_EditorCharacterPropertiesSet(context, (TF_SERVER|TF_SCRIPT));
  3641.             w_data->changed_mask = ~0;
  3642.         }
  3643.  
  3644.         if ((w_data->changed_mask & TF_ALL_MASK)!= 0) {
  3645.             fe_EditorCharacterPropertiesSet(context, 
  3646.                                     (w_data->text_attributes & TF_ALL_MASK));
  3647.         }
  3648.  
  3649.         if ((w_data->changed_mask & TF_FONT_SIZE)!= 0)
  3650.             fe_EditorFontSizeSet(context, w_data->font_size);
  3651.  
  3652.         if ((w_data->changed_mask & TF_FONT_COLOR)!= 0) {
  3653.             
  3654.             if (w_data->is_custom_color)
  3655.                 color = &w_data->color;
  3656.             else
  3657.                 color = NULL;
  3658.  
  3659.             fe_EditorColorSet(context, color);
  3660.         }
  3661.     }
  3662. }
  3663.  
  3664. static void
  3665. fe_make_character_page(
  3666.                        MWContext *context,
  3667.                        Widget parent,
  3668.                        fe_EditorCharacterPropertiesWidgets* w_data)
  3669. {
  3670.     Arg    args[32];
  3671.     Cardinal n;
  3672.     Widget form;
  3673.     Widget color_frame;
  3674.     Widget color_form;
  3675.     Widget color_label;
  3676.     Widget color_swatch;
  3677.     Widget color_default;
  3678.     Widget color_custom;
  3679.     Widget color_choose;
  3680.     Widget color_text;
  3681.  
  3682.     Widget size_frame;
  3683.     Widget size_form;
  3684.     Widget size_menu;
  3685.     Widget size_text;
  3686.     Widget size_cascade;
  3687.  
  3688.     Widget style_frame;
  3689.     Widget style_outer_rc;
  3690.     Widget style_inner_rc;
  3691.     Widget style_clear;
  3692.  
  3693.     Widget java_frame;
  3694.     Widget java_rc;
  3695.     
  3696.     Widget clear_all;
  3697.  
  3698.     Dimension width;
  3699.     Dimension height;
  3700.  
  3701.     Widget children[16];
  3702.     Cardinal nchildren;
  3703.  
  3704. #if 0
  3705.     n = 0;
  3706.     form = XmCreateForm(parent, "characterProperties", args, n);
  3707.     XtManageChild(form);
  3708. #else
  3709.     form = parent;
  3710. #endif
  3711.     w_data->form = form;
  3712.  
  3713.     /*
  3714.      *    Color group.
  3715.      */
  3716.     n = 0;
  3717.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  3718.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3719.     color_frame = fe_CreateFrame(form, "color", args, n);
  3720.     XtManageChild(color_frame);
  3721.  
  3722.     n = 0;
  3723.     color_form = XmCreateForm(color_frame, "color", args, n);
  3724.     XtManageChild(color_form);
  3725.  
  3726.     nchildren = 0;
  3727.     n = 0;
  3728.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  3729.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3730.     children[nchildren++] = color_label = XmCreateLabelGadget(color_form, "colorLabel", args, n);
  3731.     
  3732.     n = 0;
  3733.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  3734.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  3735.     XtSetArg(args[n], XmNleftWidget, color_label); n++;
  3736.     XtSetArg(args[n], XmNshadowThickness, 2); n++; /* make it look like label */
  3737.     children[nchildren++] = color_swatch = fe_CreateSwatch(color_form, "colorSwatch", args, n);
  3738.     w_data->color_swatch = color_swatch;
  3739.  
  3740.     fe_register_dependent(w_data->properties, color_swatch,
  3741.                                  FE_MAKE_DEPENDENCY(PROP_CHAR_COLOR),
  3742.                                  fe_color_swatch_update_cb, (XtPointer)w_data);
  3743.     XtAddCallback(color_swatch, XmNactivateCallback,
  3744.                   fe_editor_props_color_picker_cb, (XtPointer)w_data);
  3745.  
  3746.     n = 0;
  3747.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3748.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3749.     XtSetArg(args[n], XmNtopWidget, color_label); n++;
  3750.     XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  3751.     XtSetArg(args[n], XmNset, TRUE); n++;
  3752.     children[nchildren++] = color_default = XmCreateToggleButtonGadget(color_form, "default", args, n);
  3753.  
  3754.     XtAddCallback(color_default, XmNvalueChangedCallback,
  3755.                                  fe_color_default_cb, (XtPointer)w_data);
  3756.  
  3757.     fe_register_dependent(w_data->properties, color_default,
  3758.                                  FE_MAKE_DEPENDENCY(PROP_CHAR_COLOR),
  3759.                                  fe_color_default_update_cb, (XtPointer)w_data);
  3760.     
  3761.     n = 0;
  3762.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3763.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3764.     XtSetArg(args[n], XmNtopWidget, color_default); n++;
  3765.     XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  3766.     XtSetArg(args[n], XmNset, FALSE); n++;
  3767.     children[nchildren++] = color_custom = XmCreateToggleButtonGadget(color_form, "custom", args, n);
  3768.     
  3769.     XtAddCallback(color_custom, XmNvalueChangedCallback,
  3770.                                  fe_color_custom_cb, (XtPointer)w_data);
  3771.  
  3772.     fe_register_dependent(w_data->properties, color_custom,
  3773.                                  FE_MAKE_DEPENDENCY(PROP_CHAR_COLOR),
  3774.                                  fe_color_custom_update_cb, (XtPointer)w_data);
  3775.  
  3776.     n = 0;
  3777.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3778.     XtSetArg(args[n], XmNtopWidget, color_default); n++;
  3779.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  3780.     XtSetArg(args[n], XmNleftWidget, color_custom); n++;
  3781.     children[nchildren++] = color_choose = XmCreatePushButtonGadget(color_form, "chooseColor", args, n);
  3782.      
  3783.     XtAddCallback(color_choose, XmNactivateCallback,
  3784.                   fe_editor_props_color_picker_cb, (XtPointer)w_data);
  3785.     fe_register_dependent(w_data->properties, color_choose,
  3786.                           FE_MAKE_DEPENDENCY(PROP_CHAR_COLOR),
  3787.                           fe_choose_color_update_cb, (XtPointer)w_data);
  3788.  
  3789.     n = 0;
  3790.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3791.     XtSetArg(args[n], XmNtopWidget, color_custom); n++;
  3792.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3793.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  3794.     children[nchildren++] = color_text = XmCreateLabelGadget(color_form, "colorText", args, n);
  3795.  
  3796.     XtManageChildren(children, nchildren); /* children of color form */
  3797.  
  3798.     /*
  3799.      *    Set the swatch to be same height as label, and width as
  3800.      *    choose button.
  3801.      */
  3802.     XtVaGetValues(color_label, XmNheight, &height, 0);
  3803.     XtVaGetValues(color_choose, XmNwidth, &width, 0);
  3804.     n = 0;
  3805.     XtSetArg(args[n], XmNwidth, width); n++;
  3806.     XtSetArg(args[n], XmNheight, height); n++;
  3807.     XtSetValues(color_swatch, args, n);
  3808.  
  3809.     /*
  3810.      *    Size group.
  3811.      */
  3812.     n = 0;
  3813.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  3814.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  3815.     XtSetArg(args[n], XmNleftWidget, color_frame); n++;
  3816.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  3817.     XtSetArg(args[n], XmNbottomWidget, color_frame); n++;
  3818.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3819.     size_frame = fe_CreateFrame(form, "size", args, n);
  3820.     XtManageChild(size_frame);
  3821.  
  3822.     n = 0;
  3823.     size_form = XmCreateForm(size_frame, "size", args, n);
  3824.     XtManageChild(size_form);
  3825.     
  3826.     nchildren = 0;
  3827.     n = 0;
  3828.     size_menu = fe_CreatePulldownMenu(size_form,
  3829.                                       "fontSize",
  3830.                                       args, n);
  3831.  
  3832.     nchildren = 0;
  3833.     for (nchildren = 0; fe_font_size_types[nchildren].name; nchildren++) {
  3834.         n = 0;
  3835.         XtSetArg(args[n], XmNuserData, fe_font_size_types[nchildren].data); n++;
  3836.         children[nchildren] = XmCreatePushButtonGadget(
  3837.                                                    size_menu,
  3838.                                                    fe_font_size_types[nchildren].name,
  3839.                                                    args,
  3840.                                                    n
  3841.                                                    );
  3842.         XtAddCallback(children[nchildren], XmNactivateCallback,
  3843.                       fe_font_size_cb, (XtPointer)w_data);
  3844.                                                                
  3845.     }
  3846.     XtManageChildren(children, nchildren); /* size buttons */
  3847.     
  3848.     n = 0;
  3849.     XtSetArg(args[n], XmNsubMenuId, size_menu); n++;
  3850.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  3851.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3852.     size_cascade = fe_CreateOptionMenu(
  3853.                                       size_form,
  3854.                                       "fontSizeOptionMenu",
  3855.                                       args, n);
  3856.     fe_UnmanageChild_safe(XmOptionLabelGadget(size_cascade));
  3857.     fe_register_dependent(w_data->properties, size_cascade,
  3858.                      FE_MAKE_DEPENDENCY(PROP_CHAR_SIZE),
  3859.                      fe_font_size_update_cb, (XtPointer)w_data);
  3860.  
  3861.     XtManageChild(size_cascade);
  3862.  
  3863.     n = 0;
  3864.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3865.     XtSetArg(args[n], XmNtopWidget, size_cascade); n++;
  3866.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3867.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  3868.     size_text = XmCreateLabelGadget(size_form, "sizeText",
  3869.                                     args, n);
  3870.     XtManageChild(size_text);
  3871.  
  3872.     /*
  3873.      *    Style group.
  3874.      */
  3875.     n = 0;
  3876.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3877.     XtSetArg(args[n], XmNtopWidget, color_frame); n++;
  3878.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3879.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  3880.     XtSetArg(args[n], XmNrightWidget, color_frame); n++;
  3881.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  3882.     style_frame = fe_CreateFrame(form, "style", args, n);
  3883.     XtManageChild(style_frame);
  3884.  
  3885.     n = 0;
  3886.     style_outer_rc = XmCreateForm(style_frame, "style", args, n);
  3887.     XtManageChild(style_outer_rc);
  3888.  
  3889.     n = 0;
  3890.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  3891.     XtSetArg(args[n], XmNnumColumns, 2); n++;
  3892.     XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++;
  3893.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3894.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  3895.     style_inner_rc = XmCreateRowColumn(style_outer_rc, "charProperties", args, n);
  3896.     XtManageChild(style_inner_rc);
  3897.  
  3898.     for (nchildren = 0; fe_style_types[nchildren].name; nchildren++) {
  3899.         n = 0;
  3900.         XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
  3901.         XtSetArg(args[n], XmNuserData, fe_style_types[nchildren].data); n++;
  3902.         children[nchildren] = XmCreateToggleButtonGadget(
  3903.                                              style_inner_rc,
  3904.                                              fe_style_types[nchildren].name,
  3905.                                              args,
  3906.                                              n);
  3907.                                                                
  3908.         XtAddCallback(children[nchildren], XmNvalueChangedCallback,
  3909.                       fe_style_cb, (XtPointer)w_data);
  3910.  
  3911.         fe_register_dependent(w_data->properties, children[nchildren],
  3912.                           FE_MAKE_DEPENDENCY(fe_style_types[nchildren].data),
  3913.                           fe_style_update_cb, (XtPointer)w_data);
  3914.     }
  3915.     XtManageChildren(children, nchildren); /* style toggles */
  3916.  
  3917.     n = 0;
  3918.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  3919.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3920.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3921.     XtSetArg(args[n], XmNtopWidget, style_inner_rc); n++;
  3922.     style_clear = XmCreatePushButtonGadget(style_outer_rc, "clearStyles",
  3923.                                            args, n);
  3924.     XtAddCallback(style_clear, XmNactivateCallback,
  3925.                   fe_clear_style_cb, (XtPointer)w_data);
  3926.     fe_register_dependent(w_data->properties, style_clear,
  3927.                           FE_MAKE_DEPENDENCY(PROP_CHAR_JAVASCRIPT),
  3928.                           fe_clear_styles_update_cb, (XtPointer)w_data);
  3929.  
  3930.     XtManageChild(style_clear);
  3931.  
  3932.     /*
  3933.      *    Java group.
  3934.      */
  3935.     n = 0;
  3936.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3937.     XtSetArg(args[n], XmNtopWidget, color_frame); n++;
  3938.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  3939.     XtSetArg(args[n], XmNleftWidget, color_frame); n++;
  3940.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  3941.     java_frame = fe_CreateFrame(form, "java", args, n);
  3942.     XtManageChild(java_frame);
  3943.  
  3944.     n = 0;
  3945.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  3946.     java_rc = XmCreateRowColumn(java_frame, "java", args, n);
  3947.     XtManageChild(java_rc);
  3948.  
  3949.     nchildren = 0;
  3950.     n = 0;
  3951.     XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
  3952.     XtSetArg(args[n], XmNuserData, FALSE); n++;
  3953.     children[nchildren] = XmCreateToggleButtonGadget(java_rc, "client",
  3954.                                                      args, n);
  3955.     
  3956.     XtAddCallback(children[nchildren], XmNvalueChangedCallback,
  3957.                   fe_javascript_cb, (XtPointer)w_data);
  3958.     fe_register_dependent(w_data->properties, children[nchildren],
  3959.                           FE_MAKE_DEPENDENCY(PROP_CHAR_JAVASCRIPT), /* lazy */
  3960.                           fe_javascript_update_cb, (XtPointer)w_data);
  3961.     nchildren++;
  3962.  
  3963.     n = 0;
  3964.     XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
  3965.     XtSetArg(args[n], XmNuserData, TRUE); n++;
  3966.     children[nchildren] = XmCreateToggleButtonGadget(java_rc, "server",
  3967.                                                        args, n);
  3968.     XtAddCallback(children[nchildren], XmNvalueChangedCallback,
  3969.                   fe_javascript_cb, (XtPointer)w_data);
  3970.     fe_register_dependent(w_data->properties, children[nchildren],
  3971.                           FE_MAKE_DEPENDENCY(PROP_CHAR_JAVASCRIPT), /* lazy */
  3972.                           fe_javascript_update_cb, (XtPointer)w_data);
  3973.     nchildren++;
  3974.  
  3975.     XtManageChildren(children, nchildren); /* java toggles */
  3976.  
  3977.     n = 0;
  3978.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  3979.     XtSetArg(args[n], XmNtopWidget, java_frame); n++;
  3980.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  3981.     XtSetArg(args[n], XmNleftWidget, java_frame); n++;
  3982.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  3983.     XtSetArg(args[n], XmNrightWidget, java_frame); n++;
  3984.     clear_all = XmCreatePushButtonGadget(form, "clearAll", args, n);
  3985.     XtManageChild(clear_all);
  3986.  
  3987.     XtAddCallback(clear_all, XmNactivateCallback,
  3988.                   fe_clearall_settings_cb, (XtPointer)w_data);
  3989. }
  3990.  
  3991. static void
  3992. fe_image_main_image_cb(Widget widget, XtPointer closure, XtPointer call_data)
  3993. {
  3994.     fe_EditorImagePropertiesWidgets* w_data =
  3995.         (fe_EditorImagePropertiesWidgets*)closure;
  3996.  
  3997.     /*
  3998.      *    Update changed tag, but don't call dependents (that's us).
  3999.      *    Well we have to, so that we update the copy button.
  4000.      *    No, we don't we'll set the tag here, but we'll only
  4001.      *    call update_dependents from the browse cb. That way
  4002.      *    we won't be *busy*. No, we have to, oh too bad!
  4003.      */
  4004.     w_data->new_image = TRUE;
  4005.     fe_update_dependents(widget, w_data->properties, 
  4006.                          PROP_IMAGE_MAIN_IMAGE|PROP_IMAGE_COPY|PROP_LINK_TEXT);
  4007. }
  4008.  
  4009. static void
  4010. fe_image_main_image_update_cb(Widget widget,
  4011.                               XtPointer closure, XtPointer call_data)
  4012. {
  4013.     fe_EditorImagePropertiesWidgets* w_data =
  4014.         (fe_EditorImagePropertiesWidgets*)closure;
  4015.     fe_DependentListCallbackStruct* info = 
  4016.         (fe_DependentListCallbackStruct*)call_data;
  4017.  
  4018.     if (info->caller == widget)
  4019.         return; /* don't call ourselves */
  4020.     
  4021.     fe_set_text_field(widget, w_data->image_data.pSrc,
  4022.                       fe_image_main_image_cb, (XtPointer)w_data);
  4023. }
  4024.  
  4025. static void
  4026. fe_url_browse_file_of_text(MWContext* context, Widget text_field)
  4027. {
  4028.     char* before_save;
  4029.     char* after;
  4030.     char* p = NULL;
  4031.     int type;
  4032.  
  4033.     before_save = fe_TextFieldGetString(text_field);
  4034.  
  4035.     if (before_save != NULL)
  4036.         fe_StringTrim(before_save);
  4037.  
  4038.     type = NET_URL_Type(before_save);
  4039.  
  4040.     if (type == 0) { /* unknown, might be file path */
  4041.         History_entry* hist_ent;
  4042.  
  4043.         if (!EDT_IS_NEW_DOCUMENT(context)) { /* don't bother looking */
  4044.             hist_ent = SHIST_GetCurrent(&context->hist);
  4045.  
  4046.             if (hist_ent != NULL
  4047.                 &&
  4048.                 hist_ent->address != NULL
  4049.                 &&
  4050.                 NET_IsLocalFileURL(hist_ent->address)) {
  4051.                 if (before_save[0] == '/' && before_save[1] != '/')
  4052.                     p = before_save;
  4053.             }
  4054.         }
  4055.     } else if (type == FILE_TYPE_URL) {
  4056.  
  4057.         if (XP_STRNCASECMP(before_save, "file:///", 8) == 0)
  4058.             p = &before_save[7];
  4059.         else if (XP_STRNCASECMP(before_save, "file://", 7) == 0)
  4060.             p = &before_save[6];
  4061.         else if (XP_STRNCASECMP(before_save, "file:/", 6) == 0)
  4062.             p = &before_save[5];
  4063.     }
  4064.  
  4065.     if (p == NULL)
  4066.         p = "";
  4067.  
  4068.     if (p != before_save)
  4069.         fe_TextFieldSetString(text_field, p, FALSE);
  4070.     
  4071.     fe_browse_file_of_text(context, text_field, FALSE);
  4072.  
  4073.     after = fe_TextFieldGetString(text_field);
  4074.     fe_StringTrim(after);
  4075.  
  4076.     if (XP_STRCMP(after, before_save) != 0) {
  4077.  
  4078.         p = (char*)XP_ALLOC(XP_STRLEN(after) + 8);
  4079.  
  4080.         XP_STRCPY(p, "file://");
  4081.         XP_STRCAT(p, after);
  4082.  
  4083.         fe_TextFieldSetString(text_field, p, FALSE);
  4084.  
  4085.         XP_FREE(p);
  4086.     }
  4087.  
  4088.     if (before_save)
  4089.         XtFree(before_save);
  4090.     if (after)
  4091.         XtFree(after);
  4092. }
  4093.  
  4094. static void
  4095. fe_image_main_image_browse_cb(Widget widget,
  4096.                               XtPointer closure, XtPointer call_data)
  4097. {
  4098.     fe_EditorImagePropertiesWidgets* w_data =
  4099.         (fe_EditorImagePropertiesWidgets*)closure;
  4100.  
  4101.     fe_url_browse_file_of_text(w_data->properties->context,
  4102.                                w_data->main_image);
  4103. }
  4104.  
  4105. static void
  4106. fe_image_alt_image_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4107. {
  4108.     fe_EditorImagePropertiesWidgets* w_data =
  4109.         (fe_EditorImagePropertiesWidgets*)closure;
  4110.  
  4111.     /*
  4112.      *    See discussion for main above.
  4113.      */
  4114.     w_data->new_image = TRUE;
  4115.     fe_update_dependents(widget, w_data->properties, 
  4116.                          PROP_IMAGE_ALT_IMAGE|PROP_IMAGE_COPY|PROP_LINK_TEXT);
  4117. }
  4118.  
  4119. static void
  4120. fe_image_alt_image_update_cb(Widget widget,
  4121.                               XtPointer closure, XtPointer call_data)
  4122. {
  4123.     fe_EditorImagePropertiesWidgets* w_data =
  4124.         (fe_EditorImagePropertiesWidgets*)closure;
  4125.     fe_DependentListCallbackStruct* info = 
  4126.         (fe_DependentListCallbackStruct*)call_data;
  4127.  
  4128.     if (info->caller == widget)
  4129.         return; /* don't call ourselves */
  4130.     
  4131.     fe_set_text_field(w_data->alt_image, w_data->image_data.pLowSrc,
  4132.                       fe_image_alt_image_cb, (XtPointer)w_data);
  4133. }
  4134.  
  4135. static void
  4136. fe_image_alt_image_browse_cb(Widget widget,
  4137.                               XtPointer closure, XtPointer call_data)
  4138. {
  4139.     fe_EditorImagePropertiesWidgets* w_data =
  4140.         (fe_EditorImagePropertiesWidgets*)closure;
  4141.  
  4142.     fe_url_browse_file_of_text(w_data->properties->context,
  4143.                                w_data->alt_image);
  4144. }
  4145.  
  4146. static void
  4147. fe_image_alt_text_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4148. {
  4149.     fe_EditorImagePropertiesWidgets* w_data =
  4150.         (fe_EditorImagePropertiesWidgets*)closure;
  4151.  
  4152.     fe_update_dependents(widget, w_data->properties,
  4153.                          PROP_IMAGE_ALT_TEXT|PROP_IMAGE_COPY|PROP_LINK_TEXT);
  4154. }
  4155.  
  4156. static void
  4157. fe_image_alt_text_update_cb(Widget widget,
  4158.                               XtPointer closure, XtPointer call_data)
  4159. {
  4160.     fe_EditorImagePropertiesWidgets* w_data =
  4161.         (fe_EditorImagePropertiesWidgets*)closure;
  4162.     fe_DependentListCallbackStruct* info = 
  4163.         (fe_DependentListCallbackStruct*)call_data;
  4164.  
  4165.     if (info->caller == widget)
  4166.         return; /* don't call ourselves */
  4167.     
  4168.     fe_set_text_field(w_data->alt_text, w_data->image_data.pAlt,
  4169.                       fe_image_alt_text_cb, (XtPointer)w_data);
  4170. }
  4171.  
  4172. static void
  4173. fe_image_align_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4174. {
  4175.     fe_EditorImagePropertiesWidgets* w_data =
  4176.         (fe_EditorImagePropertiesWidgets*)closure;
  4177.     XmToggleButtonCallbackStruct* info =
  4178.         (XmToggleButtonCallbackStruct*)call_data;
  4179.  
  4180.     /*
  4181.      *    We get a callback on both the unset of the old toggle,
  4182.      *    and the set of the new, so ignore the former, it's not
  4183.      *    interesting.
  4184.      */
  4185.     if (info->set) {
  4186.  
  4187.         w_data->image_data.align = (ED_Alignment)fe_GetUserData(widget);    
  4188.  
  4189.         fe_update_dependents(widget, w_data->properties, PROP_IMAGE_ALIGN);
  4190.     }
  4191. }
  4192.  
  4193. static void
  4194. fe_image_align_update_cb(Widget widget,
  4195.                          XtPointer closure, XtPointer call_data)
  4196. {
  4197.     fe_EditorImagePropertiesWidgets* w_data =
  4198.         (fe_EditorImagePropertiesWidgets*)closure;
  4199.     ED_Alignment align = (ED_Alignment)fe_GetUserData(widget);    
  4200.  
  4201.     XmToggleButtonGadgetSetState(widget, 
  4202.                                  (w_data->image_data.align == align),
  4203.                                  FALSE);
  4204. }
  4205.  
  4206. static void
  4207. fe_image_dimensions_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4208. {
  4209.     fe_EditorImagePropertiesWidgets* w_data =
  4210.         (fe_EditorImagePropertiesWidgets*)closure;
  4211.     Boolean constrainable =    !(w_data->image_data.bHeightPercent ||
  4212.                               w_data->image_data.bWidthPercent);
  4213.  
  4214.     w_data->properties->changed |= PROP_IMAGE_DIMENSIONS;
  4215.  
  4216.     /*
  4217.      *    If constrain is on, adjust the other value.
  4218.      */
  4219.     if (w_data->do_constrain && constrainable) {
  4220.         unsigned long new_value = fe_get_numeric_text_field(widget);
  4221.         unsigned long tmp;
  4222.         unsigned long foo;
  4223.         if (widget == w_data->image_width) { /* adjusting width, do height */
  4224.             w_data->image_data.iWidth = new_value;
  4225.             foo = w_data->image_data.iOriginalWidth;
  4226.             if (foo == 0)
  4227.                 foo++;
  4228.             tmp = new_value * w_data->image_data.iOriginalHeight;
  4229.             tmp = tmp / foo;
  4230.             w_data->image_data.iHeight = tmp;
  4231.         } else { /* adjusting height, do width */
  4232.             w_data->image_data.iHeight = new_value;
  4233.             foo = w_data->image_data.iOriginalHeight;
  4234.             if (foo == 0)
  4235.                 foo++;
  4236.             tmp = new_value * w_data->image_data.iOriginalWidth;
  4237.             tmp = tmp / foo;
  4238.             w_data->image_data.iWidth = tmp;
  4239.         }
  4240.         fe_update_dependents(widget, w_data->properties,
  4241.                              PROP_IMAGE_DIMENSIONS);
  4242.     }
  4243. }
  4244.  
  4245. static void
  4246. fe_image_dimensions_height_update_cb(Widget widget,
  4247.                                      XtPointer closure, XtPointer call_data)
  4248. {
  4249.     fe_EditorImagePropertiesWidgets* w_data =
  4250.         (fe_EditorImagePropertiesWidgets*)closure;
  4251.     fe_DependentListCallbackStruct* info = 
  4252.         (fe_DependentListCallbackStruct*)call_data;
  4253.     Boolean enabled = w_data->do_custom_size;
  4254.     unsigned height; 
  4255.  
  4256.     if (info->caller == widget)
  4257.         return; /* don't call ourselves */
  4258.  
  4259.     if (enabled)
  4260.         height = w_data->image_data.iHeight;
  4261.     else
  4262.         height = w_data->image_data.iOriginalHeight;
  4263.     
  4264.     fe_set_numeric_text_field(widget, height);
  4265.     fe_TextFieldSetEditable(w_data->properties->context, widget, enabled);
  4266. }
  4267.  
  4268. static void
  4269. fe_image_dimensions_width_update_cb(Widget widget,
  4270.                                      XtPointer closure, XtPointer call_data)
  4271. {
  4272.     fe_EditorImagePropertiesWidgets* w_data =
  4273.         (fe_EditorImagePropertiesWidgets*)closure;
  4274.     fe_DependentListCallbackStruct* info = 
  4275.         (fe_DependentListCallbackStruct*)call_data;
  4276.     Boolean enabled = w_data->do_custom_size;
  4277.     unsigned width;
  4278.  
  4279.     if (info->caller == widget)
  4280.         return; /* don't call ourselves */
  4281.     
  4282.     if (enabled)
  4283.         width = w_data->image_data.iWidth;
  4284.     else
  4285.         width = w_data->image_data.iOriginalWidth;
  4286.     
  4287.     fe_set_numeric_text_field(widget, width);
  4288.     fe_TextFieldSetEditable(w_data->properties->context, widget, enabled);
  4289. }
  4290.  
  4291. static void
  4292. fe_image_margin_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4293. {
  4294.     fe_EditorImagePropertiesWidgets* w_data =
  4295.         (fe_EditorImagePropertiesWidgets*)closure;
  4296.  
  4297.     w_data->properties->changed |= PROP_IMAGE_SPACE;
  4298. }
  4299.  
  4300. static void
  4301. fe_image_margin_height_update_cb(Widget widget,
  4302.                                      XtPointer closure, XtPointer call_data)
  4303. {
  4304.     fe_EditorImagePropertiesWidgets* w_data =
  4305.         (fe_EditorImagePropertiesWidgets*)closure;
  4306.     fe_DependentListCallbackStruct* info = 
  4307.         (fe_DependentListCallbackStruct*)call_data;
  4308.  
  4309.     if (info->caller == widget)
  4310.         return; /* don't call ourselves */
  4311.     
  4312.     fe_set_numeric_text_field(widget, w_data->image_data.iVSpace);
  4313. }
  4314.  
  4315. static void
  4316. fe_image_margin_width_update_cb(Widget widget,
  4317.                                      XtPointer closure, XtPointer call_data)
  4318. {
  4319.     fe_EditorImagePropertiesWidgets* w_data =
  4320.         (fe_EditorImagePropertiesWidgets*)closure;
  4321.     fe_DependentListCallbackStruct* info = 
  4322.         (fe_DependentListCallbackStruct*)call_data;
  4323.  
  4324.     if (info->caller == widget)
  4325.         return; /* don't call ourselves */
  4326.  
  4327.     fe_set_numeric_text_field(widget,
  4328.                               w_data->image_data.iHSpace);
  4329. }
  4330.  
  4331. static void
  4332. fe_image_margin_border_update_cb(Widget widget,
  4333.                                  XtPointer closure, XtPointer call_data)
  4334. {
  4335.     fe_EditorImagePropertiesWidgets* w_data =
  4336.         (fe_EditorImagePropertiesWidgets*)closure;
  4337.     fe_DependentListCallbackStruct* info = 
  4338.         (fe_DependentListCallbackStruct*)call_data;
  4339.  
  4340.     if (info->caller == widget)
  4341.         return; /* don't call ourselves */
  4342.  
  4343.     /* Logic for dealing with w_data->image_data.iBorder possibly being -1
  4344.        is now in fe_EditorImagePropertiesDialogDataGet. */
  4345.  
  4346.     fe_set_numeric_text_field(widget, w_data->image_data.iBorder);
  4347. }
  4348.  
  4349. static void
  4350. fe_image_original_size_cb(Widget widget,
  4351.                           XtPointer closure, XtPointer call_data)
  4352. {
  4353.     fe_EditorImagePropertiesWidgets* w_data =
  4354.         (fe_EditorImagePropertiesWidgets*)closure;
  4355.     XmToggleButtonCallbackStruct* info =
  4356.         (XmToggleButtonCallbackStruct*)call_data;
  4357.  
  4358.     w_data->do_custom_size = (info->set == FALSE);
  4359.     fe_update_dependents(widget, w_data->properties, PROP_IMAGE_DIMENSIONS);
  4360. }
  4361.  
  4362. static void
  4363. fe_image_original_size_update_cb(Widget widget,
  4364.                           XtPointer closure, XtPointer call_data)
  4365. {
  4366.     fe_EditorImagePropertiesWidgets* w_data =
  4367.         (fe_EditorImagePropertiesWidgets*)closure;
  4368.     Boolean set  = !w_data->do_custom_size;
  4369.     Boolean enabled = w_data->existing_image || w_data->new_image;
  4370.  
  4371.     XtVaSetValues(widget, XmNset, set, XmNsensitive, enabled, 0);
  4372. }
  4373.  
  4374. static void
  4375. fe_image_custom_size_cb(Widget widget,
  4376.                           XtPointer closure, XtPointer call_data)
  4377. {
  4378.     fe_EditorImagePropertiesWidgets* w_data =
  4379.         (fe_EditorImagePropertiesWidgets*)closure;
  4380.     XmToggleButtonCallbackStruct* info =
  4381.         (XmToggleButtonCallbackStruct*)call_data;
  4382.  
  4383.     w_data->do_custom_size = info->set;
  4384.     fe_update_dependents(widget, w_data->properties, PROP_IMAGE_DIMENSIONS);
  4385. }
  4386.  
  4387. static void
  4388. fe_image_custom_size_update_cb(Widget widget,
  4389.                           XtPointer closure, XtPointer call_data)
  4390. {
  4391.     fe_EditorImagePropertiesWidgets* w_data =
  4392.         (fe_EditorImagePropertiesWidgets*)closure;
  4393.     Boolean set  = w_data->do_custom_size;
  4394.     Boolean enabled = w_data->existing_image || w_data->new_image;
  4395.  
  4396.     XtVaSetValues(widget, XmNset, set, XmNsensitive, enabled, 0);
  4397. }
  4398.  
  4399. static void
  4400. fe_image_copy_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4401. {
  4402.     fe_EditorImagePropertiesWidgets* w_data =
  4403.         (fe_EditorImagePropertiesWidgets*)closure;
  4404.     XmToggleButtonCallbackStruct* info =
  4405.         (XmToggleButtonCallbackStruct*)call_data;
  4406.  
  4407.     w_data->image_data.bNoSave = info->set;
  4408.     fe_update_dependents(widget, w_data->properties, PROP_IMAGE_COPY);
  4409. }
  4410.  
  4411. static void
  4412. fe_image_copy_update_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4413. {
  4414.     fe_EditorImagePropertiesWidgets* w_data =
  4415.         (fe_EditorImagePropertiesWidgets*)closure;
  4416.     Arg args[8];
  4417.     Cardinal n;
  4418.  
  4419.     n = 0;
  4420.     XtSetArg(args[n], XmNset, (w_data->image_data.bNoSave)); n++;
  4421.     XtSetValues(widget, args, n);
  4422. }
  4423.  
  4424. static void
  4425. fe_image_remove_imap_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4426. {
  4427.     fe_EditorImagePropertiesWidgets* w_data =
  4428.         (fe_EditorImagePropertiesWidgets*)closure;
  4429.  
  4430.     w_data->image_data.bIsMap = FALSE;
  4431.     fe_update_dependents(widget, w_data->properties, PROP_IMAGE_IMAP);
  4432. }
  4433.  
  4434. static void
  4435. fe_image_remove_imap_update_cb(Widget widget,
  4436.                                XtPointer closure, XtPointer call_data)
  4437. {
  4438.     fe_EditorImagePropertiesWidgets* w_data =
  4439.         (fe_EditorImagePropertiesWidgets*)closure;
  4440.     Arg args[8];
  4441.     Cardinal n;
  4442.  
  4443.     n = 0;
  4444.     XtSetArg(args[n], XmNsensitive, (w_data->image_data.bIsMap != FALSE)); n++;
  4445.     XtSetValues(widget, args, n);
  4446. }
  4447.  
  4448. static void
  4449. fe_image_edit_image_do(MWContext* context,
  4450.                        Widget widget,
  4451.                        Widget image_widget)
  4452. {
  4453.     History_entry* hist_ent = SHIST_GetCurrent(&(context->hist));
  4454.     char* image;
  4455.     char* url;
  4456.     char* local_name;
  4457.     char buf[512];
  4458.  
  4459.     if (hist_ent == NULL || hist_ent->address == NULL)
  4460.         return; /* should not happen */
  4461.  
  4462.     image = fe_TextFieldGetString(image_widget);
  4463.  
  4464.     if (image == NULL || image[0] == '\0')
  4465.         return; /* also shouldn't happen */
  4466.  
  4467.     if (NET_IsHTTP_URL(image)) { /* remote url */
  4468.         fe_error_dialog(context, widget,
  4469.                         XP_GetString(XFE_EDITOR_IMAGE_IS_REMOTE));
  4470.         return;
  4471.     }
  4472.  
  4473.     url = NET_MakeAbsoluteURL(hist_ent->address, image); /* alloc */
  4474.     if (XP_ConvertUrlToLocalFile(url, &local_name)) {
  4475.         fe_EditorEditImage(context, local_name);
  4476.     } else {
  4477.         sprintf(buf, XP_GetString(XFE_CANNOT_READ_FILE), image);
  4478.  
  4479.         fe_error_dialog(context, widget, buf);
  4480.     }
  4481.  
  4482.     if (image)
  4483.         XP_FREEIF(image);
  4484.     if (url)
  4485.         XtFree(url);
  4486.     if (local_name)
  4487.         XtFree(local_name);
  4488. }
  4489.  
  4490. static void
  4491. fe_image_edit_image_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4492. {
  4493.     fe_EditorImagePropertiesWidgets* w_data =
  4494.         (fe_EditorImagePropertiesWidgets*)closure;
  4495.     MWContext* context = w_data->properties->context;
  4496.  
  4497.     fe_image_edit_image_do(context, widget, w_data->main_image);
  4498. }
  4499.  
  4500. static void
  4501. fe_image_edit_image_update_cb(Widget widget,
  4502.                                XtPointer closure, XtPointer call_data)
  4503. {
  4504.     fe_EditorImagePropertiesWidgets* w_data =
  4505.         (fe_EditorImagePropertiesWidgets*)closure;
  4506.     Boolean sensitive = XmTextFieldGetLastPosition(w_data->main_image) != 0;
  4507.  
  4508.     XtVaSetValues(widget, XmNsensitive, sensitive, 0);
  4509. }
  4510.  
  4511. static void
  4512. fe_image_edit_alt_image_cb(Widget widget,
  4513.                            XtPointer closure, XtPointer call_data)
  4514. {
  4515.     fe_EditorImagePropertiesWidgets* w_data =
  4516.         (fe_EditorImagePropertiesWidgets*)closure;
  4517.     MWContext* context = w_data->properties->context;
  4518.  
  4519.     fe_image_edit_image_do(context, widget, w_data->alt_image);
  4520. }
  4521.  
  4522. static void
  4523. fe_image_edit_alt_image_update_cb(Widget widget,
  4524.                                   XtPointer closure, XtPointer call_data)
  4525. {
  4526.     fe_EditorImagePropertiesWidgets* w_data =
  4527.         (fe_EditorImagePropertiesWidgets*)closure;
  4528.     Boolean sensitive = XmTextFieldGetLastPosition(w_data->alt_image) != 0;
  4529.  
  4530.     XtVaSetValues(widget, XmNsensitive, sensitive, 0);
  4531. }
  4532.  
  4533. static void
  4534. fe_image_height_pixel_percent_cb(Widget widget,
  4535.                                  XtPointer closure, XtPointer call_data)
  4536. {
  4537.     fe_EditorImagePropertiesWidgets* w_data =
  4538.         (fe_EditorImagePropertiesWidgets*)closure;
  4539.     XP_Bool percent = (strcmp(XtName(widget), "percent") == 0);
  4540.  
  4541.     w_data->image_data.bHeightPercent = percent;
  4542.     fe_update_dependents(widget, w_data->properties, PROP_IMAGE_HEIGHT);
  4543. }
  4544.  
  4545. static void
  4546. fe_image_width_pixel_percent_cb(Widget widget,
  4547.                                 XtPointer closure, XtPointer call_data)
  4548. {
  4549.     fe_EditorImagePropertiesWidgets* w_data =
  4550.         (fe_EditorImagePropertiesWidgets*)closure;
  4551.     XP_Bool percent = (strcmp(XtName(widget), "percent") == 0);
  4552.  
  4553.     w_data->image_data.bWidthPercent = percent;
  4554.     fe_update_dependents(widget, w_data->properties, PROP_IMAGE_WIDTH);
  4555. }
  4556.  
  4557. /*
  4558.  *    Forward decalres for stuff used around here, because I'm just too
  4559.  *    tired to move stuff aorund.
  4560.  */
  4561. char* fe_SimpleOptionPixelPercent[];
  4562. Widget fe_CreateSimpleOptionMenu(Widget, char*, Arg*, Cardinal);
  4563.                                   
  4564. static void
  4565. fe_image_height_pixel_percent_update_cb(Widget widget,
  4566.                                 XtPointer closure, XtPointer call_data)
  4567. {
  4568.     fe_EditorImagePropertiesWidgets* w_data =
  4569.         (fe_EditorImagePropertiesWidgets*)closure;
  4570.     unsigned index = 0;
  4571.     Boolean enabled = w_data->do_custom_size;
  4572.  
  4573.     if (enabled && w_data->image_data.bHeightPercent)
  4574.         index = 1;
  4575.  
  4576.     XfeOptionMenuSetItem(widget, index);
  4577.     XtVaSetValues(widget, XmNsensitive, enabled, 0);
  4578. }
  4579.  
  4580. static void
  4581. fe_image_width_pixel_percent_update_cb(Widget widget,
  4582.                                 XtPointer closure, XtPointer call_data)
  4583. {
  4584.     fe_EditorImagePropertiesWidgets* w_data =
  4585.         (fe_EditorImagePropertiesWidgets*)closure;
  4586.     unsigned index = 0;
  4587.     Boolean enabled = w_data->do_custom_size;
  4588.  
  4589.     if (enabled && w_data->image_data.bWidthPercent)
  4590.         index = 1;
  4591.  
  4592.     XfeOptionMenuSetItem(widget, index);
  4593.     XtVaSetValues(widget, XmNsensitive, enabled, 0);
  4594. }
  4595.  
  4596. static void
  4597. fe_image_constrain_cb(Widget widget,
  4598.                       XtPointer closure, XtPointer call_data)
  4599. {
  4600.     fe_EditorImagePropertiesWidgets* w_data =
  4601.         (fe_EditorImagePropertiesWidgets*)closure;
  4602.     XmToggleButtonCallbackStruct* info =
  4603.         (XmToggleButtonCallbackStruct*)call_data;
  4604.  
  4605.     w_data->do_constrain = info->set;
  4606. }
  4607.  
  4608. static void
  4609. fe_image_constrain_update_cb(Widget widget,
  4610.                              XtPointer closure, XtPointer call_data)
  4611. {
  4612.     fe_EditorImagePropertiesWidgets* w_data =
  4613.         (fe_EditorImagePropertiesWidgets*)closure;
  4614.     Boolean enabled = w_data->do_custom_size;
  4615.     Boolean sensitive =    !(w_data->image_data.bHeightPercent ||
  4616.                           w_data->image_data.bWidthPercent);
  4617.     Boolean set = (w_data->do_constrain) && sensitive;
  4618.  
  4619. #if 0
  4620.     if (info->caller == widget)
  4621.         return; /* don't call ourselves */
  4622. #endif
  4623.  
  4624.     XtVaSetValues(widget,
  4625.                   XmNsensitive, (sensitive && enabled),
  4626.                   XmNset, set,
  4627.                   0);
  4628. }
  4629.  
  4630. static void
  4631. fe_EditorImagePropertiesDialogDataGet(MWContext* context,
  4632.                                   fe_EditorImagePropertiesWidgets* w_data)
  4633. {
  4634.     EDT_ImageData* old = NULL;
  4635.  
  4636.     if (EDT_GetCurrentElementType(context) == ED_ELEMENT_IMAGE) {
  4637.         old = EDT_GetImageData(context);
  4638.         memcpy(&w_data->image_data, old, sizeof(EDT_ImageData));
  4639.  
  4640.         if (w_data->image_data.iOriginalWidth != w_data->image_data.iWidth
  4641.             ||
  4642.             w_data->image_data.iOriginalHeight != w_data->image_data.iHeight)
  4643.             w_data->do_custom_size = TRUE;
  4644.         else
  4645.             w_data->do_custom_size = FALSE;
  4646.         w_data->existing_image = TRUE;
  4647.  
  4648.     } else {
  4649.         old = EDT_NewImageData();
  4650.         memcpy(&w_data->image_data, old, sizeof(EDT_ImageData));
  4651.         w_data->do_custom_size = FALSE;
  4652.         w_data->existing_image = FALSE;
  4653.     }
  4654.  
  4655.     w_data->new_image = FALSE;
  4656.     w_data->do_constrain = TRUE; /* ooo, we like this */
  4657.  
  4658.     if (w_data->image_data.iBorder == -1) {
  4659.         w_data->default_border = TRUE;
  4660.         w_data->image_data.iBorder = EDT_GetDefaultBorderWidth(context);
  4661.     }
  4662.     else {
  4663.         w_data->default_border = FALSE;
  4664.     }
  4665.  
  4666.     fe_update_dependents(NULL, w_data->properties, PROP_IMAGE_ALL);
  4667.     /* yes, that's all sally */
  4668.  
  4669.     if (old)
  4670.         EDT_FreeImageData(old);
  4671. }
  4672.  
  4673. static void
  4674. fe_copy_string_over(char** tgt, Widget widget)
  4675. {
  4676.     char* p = fe_TextFieldGetString(widget);
  4677.     
  4678.     if (*tgt)
  4679.         XP_FREE(*tgt);
  4680.     if (p && *p != '\0')
  4681.         *tgt = XP_STRDUP(p);
  4682.     else
  4683.         *tgt = NULL;
  4684.     if (p)
  4685.         XtFree(p);
  4686. }
  4687.  
  4688.  
  4689. static void
  4690. fe_editor_image_properties_common_set(MWContext* context,
  4691.                                       EDT_ImageData* data,
  4692.                                       fe_EditorImagePropertiesWidgets* w_data)
  4693. {
  4694.     if (w_data->do_custom_size) {
  4695.         /*
  4696.          *    probably don't nee dto do this now, as the valueChanged
  4697.          *    callbacks keep this up to date.
  4698.          */
  4699.         data->iWidth = fe_get_numeric_text_field(w_data->image_width);
  4700.         data->iHeight = fe_get_numeric_text_field(w_data->image_height);
  4701.         data->bWidthPercent = w_data->image_data.bWidthPercent;;
  4702.         data->bHeightPercent = w_data->image_data.bHeightPercent;
  4703.     } else {
  4704.         data->iWidth = w_data->image_data.iOriginalWidth;
  4705.         data->iHeight = w_data->image_data.iOriginalHeight;
  4706.         data->bWidthPercent = FALSE;
  4707.         data->bHeightPercent = FALSE;
  4708.     }
  4709.     data->iHSpace = fe_get_numeric_text_field(w_data->margin_width);
  4710.     data->iVSpace = fe_get_numeric_text_field(w_data->margin_height);
  4711.     data->iBorder = fe_get_numeric_text_field(w_data->margin_solid);
  4712. }
  4713.  
  4714. static Boolean
  4715. fe_editor_image_properties_validate(MWContext* context,
  4716.                                   fe_EditorImagePropertiesWidgets* w_data)
  4717. {
  4718.     EDT_ImageData  image_data;
  4719.     EDT_ImageData* i = &image_data;
  4720.     unsigned       errors[16];
  4721.     unsigned       nerrors = 0;
  4722.     
  4723.     fe_editor_image_properties_common_set(context, &image_data, w_data);
  4724.  
  4725.     if (w_data->do_custom_size) {
  4726.         
  4727.         unsigned low;
  4728.         unsigned high;
  4729.     
  4730.         if (i->bWidthPercent) {
  4731.             low = TABLE_MIN_PERCENT_WIDTH;
  4732.             high = TABLE_MAX_PERCENT_WIDTH;
  4733.         } else {
  4734.             low = IMAGE_MIN_WIDTH;
  4735.             high = IMAGE_MAX_WIDTH;
  4736.         }
  4737.     
  4738.         if (RANGE_CHECK(i->iWidth, low, high))
  4739.             errors[nerrors++] = XFE_EDITOR_TABLE_WIDTH_RANGE;
  4740.  
  4741.         if (i->bHeightPercent) {
  4742.             low = TABLE_MIN_PERCENT_HEIGHT;
  4743.             high = TABLE_MAX_PERCENT_HEIGHT;
  4744.         } else {
  4745.             low = IMAGE_MIN_HEIGHT;
  4746.             high = IMAGE_MAX_HEIGHT;
  4747.         }
  4748.  
  4749.         if (RANGE_CHECK(i->iHeight, low, high))
  4750.             errors[nerrors++] = XFE_EDITOR_TABLE_HEIGHT_RANGE;
  4751.     }
  4752.     
  4753.     if (RANGE_CHECK(i->iHSpace, IMAGE_MIN_HSPACE, IMAGE_MAX_HSPACE))
  4754.         errors[nerrors++] = XFE_INVALID_IMAGE_HSPACE;
  4755.     if (RANGE_CHECK(i->iVSpace, IMAGE_MIN_VSPACE, IMAGE_MAX_VSPACE))
  4756.         errors[nerrors++] = XFE_INVALID_IMAGE_VSPACE;
  4757.     if (RANGE_CHECK(i->iBorder, IMAGE_MIN_BORDER, IMAGE_MAX_BORDER))
  4758.         errors[nerrors++] = XFE_INVALID_IMAGE_BORDER;
  4759.  
  4760.     if (nerrors > 0) {
  4761.         fe_editor_range_error_dialog(context, w_data->image_width,
  4762.                                      errors, nerrors);
  4763.         return FALSE;
  4764.     }
  4765.  
  4766.     return TRUE;
  4767. }
  4768.  
  4769. static void
  4770. fe_editor_image_properties_set(MWContext* context,
  4771.                                   fe_EditorImagePropertiesWidgets* w_data)
  4772. {
  4773.     EDT_ImageData* old;
  4774.  
  4775.     if (w_data->existing_image)
  4776.         old = EDT_GetImageData(context);
  4777.     else
  4778.         old = EDT_NewImageData();
  4779.  
  4780.     if ((w_data->properties->changed & PROP_IMAGE_MAIN_IMAGE) != 0)
  4781.         fe_copy_string_over(&old->pSrc, w_data->main_image);
  4782.     
  4783.     if ((w_data->properties->changed & PROP_IMAGE_ALT_IMAGE) != 0)
  4784.         fe_copy_string_over(&old->pLowSrc, w_data->alt_image);
  4785.  
  4786.     if ((w_data->properties->changed & PROP_IMAGE_ALT_TEXT) != 0)
  4787.         fe_copy_string_over(&old->pAlt, w_data->alt_text);
  4788.     
  4789.     fe_editor_image_properties_common_set(context, old, w_data);
  4790.  
  4791.     old->align = w_data->image_data.align;
  4792.     old->bIsMap = w_data->image_data.bIsMap;
  4793.     old->bNoSave = w_data->image_data.bNoSave;
  4794.  
  4795.     if (w_data->default_border && old->iBorder == w_data->image_data.iBorder) {
  4796.         old->iBorder = -1;
  4797.     }
  4798.  
  4799.  
  4800.     /*
  4801.      *    We don't handle the link data here, let the link sheet
  4802.      *    do that.
  4803.      */
  4804.     if (old->pSrc != NULL) {
  4805.         if (w_data->existing_image)
  4806.             EDT_SetImageData(context, old, !w_data->image_data.bNoSave);
  4807.         else
  4808.             EDT_InsertImage(context, old, !w_data->image_data.bNoSave);
  4809.     }
  4810.  
  4811.     EDT_FreeImageData(old);
  4812. }
  4813.  
  4814. static struct fe_style_data fe_image_button_names[] = {
  4815.      { "alignTop",       ED_ALIGN_TOP       },
  4816.     { "alignAbsCenter", ED_ALIGN_ABSCENTER },
  4817.     { "alignCenter",    ED_ALIGN_CENTER    },
  4818.     { "alignBaseline",  ED_ALIGN_BASELINE  },
  4819.     { "alignAbsBottom", ED_ALIGN_ABSBOTTOM },
  4820.     { "alignLeft",      ED_ALIGN_LEFT      },
  4821.     { "alignRight",     ED_ALIGN_RIGHT     },
  4822.     { 0 }
  4823.  
  4824. #if 0
  4825.     { "alignAbsTop",    ED_ALIGN_ABSTOP    },
  4826.     { "alignBottom",    ED_ALIGN_BOTTOM    },
  4827. #endif
  4828. };
  4829.  
  4830. static void
  4831. fe_make_image_icons(MWContext *context, Widget parent,
  4832.                     fe_EditorImagePropertiesWidgets* w_data)
  4833. {
  4834.     Pixmap   p;
  4835.     Arg      args[16];
  4836.     Cardinal n;
  4837.     Cardinal i;
  4838.     Widget   children[16];
  4839.     char*    name;
  4840.  
  4841.     for (i = 0; fe_image_button_names[i].name; i++) {
  4842.       
  4843.         MWContextType old = context->type;
  4844.  
  4845.         context->type = MWContextEditor;
  4846.         p  = fe_ToolbarPixmap(context, IL_ALIGN1_RAISED+(2*i), False, False);
  4847.         context->type = old;
  4848.  
  4849.         name = fe_image_button_names[i].name;
  4850.  
  4851.         n = 0;
  4852.         XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++;
  4853.         XtSetArg(args[n], XmNlabelPixmap, p); n++;
  4854.         XtSetArg(args[n], XmNuserData, fe_image_button_names[i].data); n++;
  4855.         XtSetArg(args[n], XmNindicatorOn, FALSE); n++; /* Windows-esk */
  4856. #if 0
  4857.         /* looks ugly */
  4858.         XtSetArg(args[n], XmNmarginHeight, 0); n++;
  4859.         XtSetArg(args[n], XmNmarginWidth, 0); n++;
  4860. #endif
  4861.         children[i] = XmCreateToggleButtonGadget(parent, name, args, n);
  4862.  
  4863.         XtAddCallback(children[i], XmNvalueChangedCallback,
  4864.                       fe_image_align_cb, (XtPointer)w_data);
  4865.         fe_register_dependent(w_data->properties, children[i],
  4866.                               FE_MAKE_DEPENDENCY(PROP_IMAGE_ALIGN),
  4867.                               fe_image_align_update_cb, (XtPointer)w_data);
  4868.     }
  4869.     
  4870.     XtManageChildren(children, i);
  4871. }
  4872.  
  4873. static void
  4874. fe_make_image_page(MWContext *context, Widget parent,
  4875.                    fe_EditorImagePropertiesWidgets* w_data)
  4876. {
  4877.     Arg av [32];
  4878.     int ac;
  4879.     Widget form;
  4880.     Widget kids[32];
  4881.     Widget main_image_frame;
  4882.     Widget main_image_form;
  4883.     Widget main_image_text;
  4884.     Widget main_image_browse;
  4885.     Widget main_image_edit;
  4886.     Widget main_image_leave;
  4887.     Widget alt_frame;
  4888.     Widget alt_form;
  4889.     Widget alt_image_label;
  4890.     Widget alt_image_text;
  4891.     Widget alt_image_browse;
  4892.     Widget alt_image_edit;
  4893.     Widget alt_text_label;
  4894.     Widget alt_text_text;
  4895.     Widget align_frame;
  4896.     Widget align_form;
  4897.     Widget align_rc;
  4898.     Widget align_info;
  4899.     Widget dimensions_frame;
  4900.     Widget dimensions_form;
  4901.     Widget original_radio;
  4902.     Widget custom_radio;
  4903.     Widget height_label;
  4904.     Widget height_text;
  4905.     Widget height_pixels;
  4906.     Widget width_label;
  4907.     Widget width_text;    
  4908.     Widget width_pixels;
  4909.     Widget constrain;
  4910.     Widget space_frame;
  4911.     Widget space_form;
  4912.     Widget left_right_label;
  4913.     Widget left_right_text;
  4914.     Widget left_right_pixels;
  4915.     Widget top_bottom_label;
  4916.     Widget top_bottom_text;
  4917.     Widget top_bottom_pixels;
  4918.     Widget solid_border_label;
  4919.     Widget solid_text;
  4920.     Widget solid_pixels;
  4921.     Widget remove_image_map;
  4922.     Dimension width;
  4923.     Dimension height;
  4924.     Widget wide_guy;
  4925.     int i;
  4926.     XtCallbackRec callback;
  4927.  
  4928. #if 0
  4929.     ac = 0;
  4930.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  4931.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  4932.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  4933.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  4934.     form = XmCreateForm(parent, "imageProperties", av, ac);
  4935. #else
  4936.     form = parent;
  4937. #endif
  4938.  
  4939.     /**********************************************************************/
  4940.     /*  Define the Image file name Frame and its form 4MAR96RCJ        */
  4941.     /**********************************************************************/
  4942.     ac = 0;
  4943.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  4944.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  4945.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  4946.     main_image_frame = fe_CreateFrame(form, "imageFile", av, ac);
  4947.  
  4948.     ac = 0;
  4949.     main_image_form = XmCreateForm(main_image_frame, "form", av, ac);
  4950.  
  4951.     i  = 0; /* number of children */
  4952.  
  4953.     /* top row: text, browse, edit */
  4954.     ac = 0;
  4955.     kids[i++] = main_image_text = fe_CreateTextField(main_image_form,
  4956.                                                      "imageFile",
  4957.                                                      av, ac);
  4958.     w_data->main_image = main_image_text;
  4959.     XtAddCallback(main_image_text, XmNvalueChangedCallback,
  4960.                   fe_image_main_image_cb,(XtPointer)w_data);
  4961.  
  4962.     ac = 0;
  4963.     kids[i++] = main_image_browse = XmCreatePushButtonGadget(main_image_form,
  4964.                                                              "browse", 
  4965.                                                              av, ac);
  4966.     XtAddCallback(main_image_browse, XmNactivateCallback,
  4967.                   fe_image_main_image_browse_cb, (XtPointer)w_data);
  4968.  
  4969.     ac = 0;
  4970.     XtSetArg(av[ac], XmNsensitive,        False);           ac++;
  4971.     kids[i++] = main_image_edit = XmCreatePushButtonGadget(main_image_form,
  4972.                                                            "editImage",
  4973.                                                            av, ac);
  4974.     XtAddCallback(main_image_edit, XmNactivateCallback,
  4975.                   fe_image_edit_image_cb, (XtPointer)w_data);
  4976.     fe_register_dependent(w_data->properties, main_image_edit,
  4977.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_MAIN_IMAGE),
  4978.                           fe_image_edit_image_update_cb, (XtPointer)w_data);
  4979.  
  4980.     /* attachments */
  4981.     ac = 0;
  4982.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  4983.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  4984.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
  4985.     XtSetArg(av[ac], XmNrightWidget, main_image_browse); ac++;
  4986.     XtSetValues(main_image_text, av, ac);
  4987.  
  4988.     XtVaGetValues(main_image_text, XmNheight, &height, NULL);
  4989.   
  4990.     ac = 0;
  4991.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  4992.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
  4993.     XtSetArg(av[ac], XmNrightWidget, main_image_edit); ac++;
  4994.     XtSetArg(av[ac], XmNheight, height); ac++;
  4995.     XtSetValues(main_image_browse, av, ac);
  4996.   
  4997.     ac = 0;
  4998.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  4999.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  5000.     XtSetArg(av[ac], XmNheight, height); ac++;
  5001.     XtSetValues(main_image_edit, av, ac);
  5002.  
  5003.     /* next row: leave at original location, use as background */
  5004.     ac = 0;
  5005.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET);   ac++;
  5006.     XtSetArg(av[ac], XmNtopWidget, main_image_browse); ac++;
  5007.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM);   ac++;
  5008.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM);   ac++;
  5009.     kids[i++] = main_image_leave = XmCreateToggleButtonGadget(main_image_form,
  5010.                                                               "leaveImage",
  5011.                                                               av, ac);
  5012.     XtAddCallback(main_image_leave, XmNvalueChangedCallback,
  5013.                   fe_image_copy_cb, (XtPointer)w_data);
  5014.  
  5015.     fe_register_dependent(w_data->properties,
  5016.                           main_image_leave, 
  5017.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_COPY),
  5018.                           fe_image_copy_update_cb, (XtPointer)w_data);
  5019.  
  5020. #if 0
  5021.     Widget use_as_background;
  5022.  
  5023.     ac = 0;
  5024.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET);   ac++;
  5025.     XtSetArg(av[ac], XmNtopWidget, main_image_browse); ac++;
  5026.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET);   ac++;
  5027.     XtSetArg(av[ac], XmNleftWidget, main_image_leave); ac++;
  5028.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  5029.     XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
  5030.     use_as_background = XmCreateToggleButtonGadget(main_image_form,
  5031.                                                    "useAsBackground",
  5032.                                                    av, ac);
  5033.     kids[i++] = use_as_background;
  5034.  
  5035.     XtAddCallback(use_as_background, XmNvalueChangedCallback,
  5036.                   fe_image_copy_cb, (XtPointer)w_data);
  5037.  
  5038.     fe_register_dependent(w_data->properties,
  5039.                           use_as_background, 
  5040.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_COPY),
  5041.                           fe_image_copy_update_cb, (XtPointer)w_data);
  5042. #endif
  5043.     XtManageChildren(kids, i);
  5044.  
  5045.     /* alternative frame */
  5046.     ac = 0;
  5047.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  5048.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  5049.     XtSetArg(av[ac], XmNtopAttachment,  XmATTACH_WIDGET);  ac++;
  5050.     XtSetArg(av[ac], XmNtopWidget,      main_image_frame);  ac++;
  5051.     alt_frame = fe_CreateFrame(form, "alternativeImage", av, ac);
  5052.     XtManageChild(alt_frame);
  5053.  
  5054.     ac = 0;
  5055.     alt_form = XmCreateForm(alt_frame, "form", av, ac);
  5056.     XtManageChild(alt_form);
  5057.  
  5058.     i  = 0; /* number of children */
  5059.  
  5060.     /* next row: alternative label, text, browse, edit */
  5061.     ac = 0;
  5062.     XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
  5063.     kids[i++] = alt_image_label = XmCreateLabelGadget(alt_form, 
  5064.                                                       "alternativeImageLabel",
  5065.                                                       av, ac);
  5066.  
  5067.     ac = 0;
  5068.     kids[i++] = alt_image_text = fe_CreateTextField(alt_form,
  5069.                                                     "alternativeImage",
  5070.                                                     av, ac);
  5071.     w_data->alt_image = alt_image_text;
  5072.     XtAddCallback(alt_image_text, XmNvalueChangedCallback,
  5073.                   fe_image_alt_image_cb, (XtPointer)w_data);
  5074.     fe_register_dependent(w_data->properties, alt_image_text,
  5075.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_ALT_IMAGE),
  5076.                           fe_image_alt_image_update_cb, (XtPointer)w_data);
  5077.  
  5078.     ac = 0;
  5079.     kids[i++] = alt_image_browse = XmCreatePushButtonGadget(alt_form,
  5080.                                                             "browse",
  5081.                                                             av, ac);
  5082.     XtAddCallback(alt_image_browse, XmNactivateCallback,
  5083.                   fe_image_alt_image_browse_cb, (XtPointer)w_data);
  5084.  
  5085.     ac = 0;
  5086.     XtSetArg(av[ac], XmNsensitive,        False);           ac++;
  5087.     kids[i++] = alt_image_edit = XmCreatePushButtonGadget(alt_form,
  5088.                                                           "editImage",
  5089.                                                           av, ac);
  5090.     XtAddCallback(alt_image_edit, XmNactivateCallback,
  5091.                   fe_image_edit_alt_image_cb, (XtPointer)w_data);
  5092.     fe_register_dependent(w_data->properties, alt_image_edit,
  5093.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_ALT_IMAGE),
  5094.                           fe_image_edit_alt_image_update_cb, 
  5095.                           (XtPointer)w_data);
  5096.  
  5097.     /* attachments */
  5098.     ac = 0;
  5099.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  5100.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  5101.     XtSetArg(av[ac], XmNleftWidget, alt_image_label); ac++;
  5102.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
  5103.     XtSetArg(av[ac], XmNrightWidget, alt_image_browse); ac++;
  5104.     XtSetValues(alt_image_text, av, ac);
  5105.  
  5106.     XtVaGetValues(alt_image_text, XmNheight, &height, NULL);
  5107.  
  5108.     ac = 0;
  5109.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  5110.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM);    ac++;
  5111.     XtSetArg(av[ac], XmNheight, height); ac++;
  5112.     XtSetValues(alt_image_label, av, ac);
  5113.  
  5114.     ac = 0;
  5115.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  5116.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
  5117.     XtSetArg(av[ac], XmNrightWidget, alt_image_edit); ac++;
  5118.     XtSetArg(av[ac], XmNheight, height); ac++;
  5119.     XtSetValues(alt_image_browse, av, ac);
  5120.  
  5121.     ac = 0;
  5122.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  5123.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  5124.     XtSetArg(av[ac], XmNheight, height); ac++;
  5125.     XtSetValues(alt_image_edit, av, ac);
  5126.  
  5127.     /* next row: alternative text label, text */
  5128.     ac = 0;
  5129.     XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
  5130.     kids[i++] = alt_text_label = XmCreateLabelGadget(alt_form, 
  5131.                                                      "alternativeTextLabel",
  5132.                                                      av, ac);
  5133.     ac = 0;
  5134.     kids[i++] = alt_text_text = fe_CreateTextField(alt_form,
  5135.                                                    "alternativeText",
  5136.                                                    av, ac);
  5137.     w_data->alt_text = alt_text_text;
  5138.  
  5139.     XtAddCallback(alt_text_text, XmNvalueChangedCallback,
  5140.                   fe_image_alt_text_cb, (XtPointer)w_data);
  5141.     fe_register_dependent(w_data->properties, alt_text_text,
  5142.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_ALT_TEXT),
  5143.                           fe_image_alt_text_update_cb, (XtPointer)w_data);
  5144.  
  5145.     /* attachments */
  5146.     ac = 0;
  5147.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  5148.     XtSetArg(av[ac], XmNtopWidget, alt_image_text); ac++;
  5149.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  5150.     XtSetArg(av[ac], XmNleftWidget, alt_image_label); ac++;
  5151.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  5152.     XtSetValues(alt_text_text, av, ac);
  5153.  
  5154.     XtVaGetValues(alt_text_text, XmNheight, &height, NULL);
  5155.  
  5156.     ac = 0;
  5157.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  5158.     XtSetArg(av[ac], XmNtopWidget, alt_image_text); ac++;
  5159.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  5160.     XtSetArg(av[ac], XmNheight, height); ac++;
  5161.     XtSetValues(alt_text_label, av, ac);
  5162.  
  5163.     XtManageChildren(kids, i);
  5164.  
  5165.     /**********************************************************************/
  5166.     /*  Define the Alignment Frame and its form    4MAR96RCJ        */
  5167.     /**********************************************************************/
  5168.     ac = 0;
  5169.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM);   ac++;
  5170.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
  5171.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET);  ac++;
  5172.     XtSetArg(av[ac], XmNtopWidget, alt_frame);       ac++;
  5173.     align_frame = fe_CreateFrame(form, "alignment", av, ac);
  5174.  
  5175.     ac = 0;
  5176.     align_form = XmCreateForm(align_frame, "alignmentForm", av, ac);
  5177.  
  5178.     ac = 0;
  5179.     XtSetArg(av[ac], XmNorientation, XmHORIZONTAL); ac++;
  5180.     XtSetArg(av[ac], XmNradioBehavior, TRUE); ac++;
  5181.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM);   ac++;
  5182.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
  5183.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
  5184.     XtSetArg(av[ac], XmNspacing, 0);  ac++;
  5185.     align_rc = XmCreateRowColumn(align_form, "alignmentRowColumn", av, ac);
  5186.     XtManageChild(align_rc);
  5187.  
  5188.     fe_make_image_icons(context, align_rc, w_data);
  5189.  
  5190.     ac = 0;
  5191.     XtSetArg(av[ac], XmNalignment,         XmALIGNMENT_END); ac++;
  5192.     XtSetArg(av[ac], XmNrightAttachment,   XmATTACH_FORM);   ac++;
  5193.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  5194.     XtSetArg(av[ac], XmNtopWidget,     align_rc);      ac++;
  5195. #if 0
  5196.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  5197. #endif
  5198.     align_info = XmCreateLabelGadget(align_form, "alignmentInfoLabel", av, ac);
  5199.     XtManageChild(align_info);
  5200.  
  5201.     /**********************************************************************/
  5202.     /*  Define the Buttons at bottom of Image Properties Tab Panel    */
  5203.     /**********************************************************************/
  5204.     i  = 0;
  5205.  
  5206.     ac = 0;
  5207.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM);   ac++;
  5208.     XtSetArg(av[ac], XmNleftAttachment,  XmATTACH_FORM); ac++;
  5209.     XtSetArg(av[ac], XmNsensitive,        False);           ac++;
  5210.     kids[i++] = remove_image_map = XmCreatePushButtonGadget(form,
  5211.                                                             "removeImageMap",
  5212.                                                             av, ac);
  5213.     XtAddCallback(remove_image_map, XmNactivateCallback,
  5214.                   fe_image_remove_imap_cb, (XtPointer)w_data);
  5215.     fe_register_dependent(w_data->properties, remove_image_map,
  5216.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_IMAP),
  5217.                           fe_image_remove_imap_update_cb, (XtPointer)w_data);
  5218.  
  5219.     XtManageChildren(kids, i);
  5220.  
  5221.     /**********************************************************************/
  5222.     /*  Define the Dimensions Frame and its form    4MAR96RCJ        */
  5223.     /**********************************************************************/
  5224.     ac = 0;
  5225.     XtSetArg(av[ac], XmNleftAttachment,   XmATTACH_FORM);   ac++;
  5226.     XtSetArg(av[ac], XmNtopAttachment,    XmATTACH_WIDGET); ac++;
  5227.     XtSetArg(av[ac], XmNtopWidget,        align_frame);      ac++;
  5228.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
  5229.     XtSetArg(av[ac], XmNbottomWidget,     remove_image_map);  ac++;
  5230.     dimensions_frame = fe_CreateFrame(form, "dimensions", av, ac);
  5231.  
  5232.     ac = 0;
  5233.     dimensions_form = XmCreateForm(dimensions_frame, 
  5234.                                    "dimensionsForm", av, ac);
  5235.     i  = 0;
  5236.  
  5237.     ac = 0;
  5238.     kids[i++] = height_label = XmCreateLabelGadget(dimensions_form, 
  5239.                                                    "heightLabel",
  5240.                                                    av, ac);
  5241.  
  5242.     ac = 0;
  5243.     kids[i++] = width_label = XmCreateLabelGadget(dimensions_form, 
  5244.                                                   "widthLabel",
  5245.                                                   av, ac);
  5246.  
  5247. #define PROP_DIM_UPDATE (PROP_IMAGE_COPY|PROP_IMAGE_DIMENSIONS)
  5248.  
  5249.     ac = 0;
  5250.     XtSetArg(av[ac], XmNuserData, FALSE); ac++;
  5251.     XtSetArg(av[ac], XmNindicatorType, XmONE_OF_MANY); ac++;
  5252.     kids[i++] = original_radio = XmCreateToggleButtonGadget(dimensions_form, 
  5253.                                                             "originalSize",
  5254.                                                             av, ac);
  5255.     XtAddCallback(original_radio, XmNvalueChangedCallback,
  5256.                   fe_image_original_size_cb, (XtPointer)w_data);
  5257.     fe_register_dependent(w_data->properties, original_radio,
  5258.                           FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE),
  5259.                           fe_image_original_size_update_cb, (XtPointer)w_data);
  5260.  
  5261.     ac = 0;
  5262.     XtSetArg(av[ac], XmNuserData, TRUE); ac++;
  5263.     XtSetArg(av[ac], XmNindicatorType, XmONE_OF_MANY); ac++;
  5264.     kids[i++] = custom_radio = XmCreateToggleButtonGadget(dimensions_form, 
  5265.                                                           "customSize",
  5266.                                                           av, ac);
  5267.  
  5268.     XtAddCallback(custom_radio, XmNvalueChangedCallback,
  5269.                   fe_image_custom_size_cb, (XtPointer)w_data);
  5270.     fe_register_dependent(w_data->properties, custom_radio,
  5271.                           FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE),
  5272.                           fe_image_custom_size_update_cb, (XtPointer)w_data);
  5273.  
  5274.     ac = 0;
  5275.     XtSetArg(av[ac], XmNcolumns, 4); ac++;
  5276.     kids[i++] = height_text = fe_CreateTextField(dimensions_form,
  5277.                                                  "imageHeight",
  5278.                                                  av, ac);
  5279.     w_data->image_height = height_text;
  5280.  
  5281.     XtAddCallback(height_text, XmNvalueChangedCallback,
  5282.                   fe_image_dimensions_cb, (XtPointer)w_data);
  5283.     fe_register_dependent(w_data->properties, height_text,
  5284.                           FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE),
  5285.                           fe_image_dimensions_height_update_cb,
  5286.                           (XtPointer)w_data);
  5287.  
  5288.     callback.callback = fe_image_height_pixel_percent_cb;
  5289.     callback.closure = (XtPointer)w_data;
  5290.  
  5291.     ac = 0;
  5292.     XtSetArg(av[ac], XmNsimpleCallback, &callback); ac++;
  5293.     XtSetArg(av[ac], XmNbuttons, fe_SimpleOptionPixelPercent); ac++;
  5294.     XtSetArg(av[ac], XmNmarginHeight, 0); ac++;
  5295.     XtSetArg(av[ac], XmNmarginWidth, 0); ac++;
  5296.     height_pixels = fe_CreateSimpleOptionMenu(dimensions_form, "heightUnits",
  5297.                                               av, ac);
  5298.     fe_register_dependent(w_data->properties, height_pixels,
  5299.                           FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE),
  5300.                           fe_image_height_pixel_percent_update_cb,
  5301.                           (XtPointer)w_data);
  5302.     kids[i++] = height_pixels;
  5303.  
  5304.     ac = 0;
  5305.     kids[i++] = width_text = fe_CreateTextField(dimensions_form,
  5306.                                                 "imageWidth",
  5307.                                                 av, ac);
  5308.     w_data->image_width = width_text;
  5309.  
  5310.     XtAddCallback(width_text, XmNvalueChangedCallback,
  5311.                   fe_image_dimensions_cb, (XtPointer)w_data);
  5312.     fe_register_dependent(w_data->properties, width_text,
  5313.                           FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE),
  5314.                           fe_image_dimensions_width_update_cb,
  5315.                           (XtPointer)w_data);
  5316.  
  5317.     callback.callback = fe_image_width_pixel_percent_cb;
  5318.     callback.closure = (XtPointer)w_data;
  5319.  
  5320.     ac = 0;
  5321.     XtSetArg(av[ac], XmNsimpleCallback, &callback); ac++;
  5322.     XtSetArg(av[ac], XmNbuttons, fe_SimpleOptionPixelPercent); ac++;
  5323.     XtSetArg(av[ac], XmNmarginHeight, 0); ac++;
  5324.     XtSetArg(av[ac], XmNmarginWidth, 0); ac++;
  5325.     width_pixels = fe_CreateSimpleOptionMenu(dimensions_form, "widthUnits",
  5326.                                              av, ac);
  5327.     fe_register_dependent(w_data->properties, width_pixels,
  5328.                           FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE),
  5329.                           fe_image_width_pixel_percent_update_cb,
  5330.                           (XtPointer)w_data);
  5331.     kids[i++] = width_pixels;
  5332.  
  5333.     ac = 0;
  5334.     kids[i++] = constrain = XmCreateToggleButtonGadget(dimensions_form,
  5335.                                                        "constrain",
  5336.                                                        av, ac);
  5337.     XtAddCallback(constrain, XmNvalueChangedCallback,
  5338.                   fe_image_constrain_cb, (XtPointer)w_data);
  5339.     fe_register_dependent(w_data->properties, constrain,
  5340.                           FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE),
  5341.                           fe_image_constrain_update_cb, (XtPointer)w_data);
  5342.  
  5343.     /* do attachments */
  5344.     ac = 0;
  5345.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  5346.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  5347.     XtSetValues(original_radio, av, ac);
  5348.  
  5349.     ac = 0;
  5350.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  5351.     XtSetArg(av[ac], XmNtopWidget, original_radio); ac++;
  5352.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  5353.     XtSetValues(custom_radio, av, ac);
  5354.  
  5355.     wide_guy = XfeBiggestWidget(TRUE, kids, 2); /* the two labels */
  5356.     XtVaGetValues(wide_guy, XmNwidth, &width, 0);
  5357.   
  5358.     ac = 0;
  5359.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  5360.     XtSetArg(av[ac], XmNtopWidget, custom_radio); ac++;
  5361.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  5362.     XtSetArg(av[ac], XmNwidth, width); ac++;
  5363.     XtSetValues(height_label, av, ac);
  5364.  
  5365.     ac = 0;
  5366.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++;
  5367.     XtSetArg(av[ac], XmNtopWidget, height_label); ac++;
  5368.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  5369.     XtSetArg(av[ac], XmNleftWidget, wide_guy); ac++;
  5370.     XtSetValues(height_text, av, ac);
  5371.  
  5372.     ac = 0;
  5373.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++;
  5374.     XtSetArg(av[ac], XmNtopWidget, height_label); ac++;
  5375.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  5376.     XtSetArg(av[ac], XmNleftWidget, height_text); ac++;
  5377.     XtSetValues(height_pixels, av, ac);
  5378.  
  5379.     ac = 0;
  5380.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  5381.     XtSetArg(av[ac], XmNtopWidget, height_text); ac++;
  5382.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  5383.     XtSetArg(av[ac], XmNwidth, width); ac++;
  5384.     XtSetValues(width_label, av, ac);
  5385.  
  5386.     ac = 0;
  5387.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++;
  5388.     XtSetArg(av[ac], XmNtopWidget, width_label); ac++;
  5389.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  5390.     XtSetArg(av[ac], XmNleftWidget, wide_guy); ac++;
  5391.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); ac++;
  5392.     XtSetArg(av[ac], XmNrightWidget, height_text); ac++;
  5393.     XtSetValues(width_text, av, ac);
  5394.  
  5395.     ac = 0;
  5396.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++;
  5397.     XtSetArg(av[ac], XmNtopWidget, width_label); ac++;
  5398.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  5399.     XtSetArg(av[ac], XmNleftWidget, height_text); ac++;
  5400.     XtSetValues(width_pixels, av, ac);
  5401.  
  5402.     ac = 0;
  5403.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  5404.     XtSetArg(av[ac], XmNtopWidget, width_text); ac++;
  5405.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  5406.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  5407.     XtSetValues(constrain, av, ac);
  5408.  
  5409.     XtManageChildren(kids, i);
  5410.  
  5411.     /**********************************************************************/
  5412.     /*  Create Space Around Image Frame, Form, Contents 6MAR96RCJ        */
  5413.     /**********************************************************************/
  5414.     ac = 0;
  5415.     i  = 0;
  5416.     XtSetArg(av[ac], XmNleftAttachment,   XmATTACH_WIDGET); ac++;
  5417.     XtSetArg(av[ac], XmNleftWidget,       dimensions_frame); ac++;
  5418.     XtSetArg(av[ac], XmNrightAttachment,  XmATTACH_FORM);   ac++;
  5419.     XtSetArg(av[ac], XmNtopAttachment,    XmATTACH_WIDGET); ac++;
  5420.     XtSetArg(av[ac], XmNtopWidget,        align_frame);      ac++;
  5421.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
  5422.     XtSetArg(av[ac], XmNbottomWidget,     remove_image_map);  ac++;
  5423.     space_frame = fe_CreateFrame(form, "imageSpace", av, ac);
  5424.  
  5425.     ac = 0;
  5426.     XtSetArg(av[ac], XmNleftAttachment,   XmATTACH_FORM); ac++;
  5427.     XtSetArg(av[ac], XmNrightAttachment,  XmATTACH_FORM); ac++;
  5428.     XtSetArg(av[ac], XmNtopAttachment,    XmATTACH_FORM); ac++;
  5429.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  5430.     space_form = XmCreateForm(space_frame, 
  5431.                               "imageSpaceForm", av, ac);
  5432.  
  5433.     ac = 0;
  5434.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM);    ac++;
  5435.     XtSetArg(av[ac], XmNtopAttachment,  XmATTACH_FORM);    ac++;
  5436.     XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
  5437.     kids[i++] = left_right_label = XmCreateLabelGadget(space_form, 
  5438.                                                        "leftRightLabel",
  5439.                                                        av, ac);
  5440.     ac = 0;
  5441.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM);   ac++;
  5442.     kids[i++] = top_bottom_label = XmCreateLabelGadget(space_form, 
  5443.                                                        "topBottomLabel",
  5444.                                                        av, ac);
  5445.  
  5446.     XtVaGetValues(top_bottom_label, XmNwidth,&width,NULL);
  5447.     XtVaSetValues(left_right_label, XmNwidth, width,NULL);
  5448.  
  5449.     ac = 0;
  5450.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
  5451.     XtSetArg(av[ac], XmNtopAttachment,   XmATTACH_FORM);  ac++;
  5452.     kids[i++] = left_right_pixels = XmCreateLabelGadget(space_form, 
  5453.                                                         "pixels",
  5454.                                                         av, ac);
  5455.     ac = 0;
  5456.     XtSetArg(av[ac], XmNtopAttachment,   XmATTACH_FORM);   ac++;
  5457.     XtSetArg(av[ac], XmNleftAttachment,  XmATTACH_WIDGET); ac++;
  5458.     XtSetArg(av[ac], XmNleftWidget,      left_right_label);  ac++;
  5459.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
  5460.     XtSetArg(av[ac], XmNrightWidget,     left_right_pixels);   ac++;
  5461.     XtSetArg(av[ac], XmNcolumns,     3);    ac++;
  5462.     kids[i++] = left_right_text = fe_CreateTextField(space_form,
  5463.                                                      "spaceWidth",
  5464.                                                      av, ac);
  5465.     w_data->margin_width = left_right_text;
  5466.  
  5467.     XtAddCallback(left_right_text, XmNvalueChangedCallback,
  5468.                   fe_image_margin_cb, (XtPointer)w_data);
  5469.     fe_register_dependent(w_data->properties, left_right_text,
  5470.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_MARGIN_WIDTH),
  5471.                           fe_image_margin_width_update_cb, (XtPointer)w_data);
  5472.  
  5473.     XtVaSetValues(top_bottom_label,
  5474.                   XmNtopAttachment,  XmATTACH_WIDGET,
  5475.                   XmNtopWidget,      left_right_text,
  5476.                   NULL);
  5477.     ac = 0;
  5478.     XtSetArg(av[ac], XmNtopAttachment,   XmATTACH_WIDGET); ac++;
  5479.     XtSetArg(av[ac], XmNtopWidget,       left_right_text);   ac++;
  5480.     XtSetArg(av[ac], XmNleftAttachment,  XmATTACH_WIDGET); ac++;
  5481.     XtSetArg(av[ac], XmNleftWidget,      top_bottom_label);  ac++;
  5482.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
  5483.     XtSetArg(av[ac], XmNrightWidget,     left_right_pixels);      ac++;
  5484.     XtSetArg(av[ac], XmNcolumns,     3);    ac++;
  5485.     kids[i++] = top_bottom_text = fe_CreateTextField(space_form,
  5486.                                                      "spaceHeight",
  5487.                                                      av, ac);
  5488.     w_data->margin_height = top_bottom_text;
  5489.     XtAddCallback(top_bottom_text, XmNvalueChangedCallback,
  5490.                   fe_image_margin_cb, (XtPointer)w_data);
  5491.     fe_register_dependent(w_data->properties, top_bottom_text,
  5492.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_MARGIN_HEIGHT),
  5493.                           fe_image_margin_height_update_cb, (XtPointer)w_data);
  5494.  
  5495.     ac = 0;
  5496.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM);   ac++;
  5497.     XtSetArg(av[ac], XmNtopAttachment,  XmATTACH_WIDGET); ac++;
  5498.     XtSetArg(av[ac], XmNtopWidget,      top_bottom_text);    ac++;
  5499.     kids[i++] = solid_border_label = XmCreateLabelGadget(space_form, 
  5500.                                                          "solidBorderLabel",
  5501.                                                          av, ac);
  5502.     ac = 0;
  5503.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM);   ac++;
  5504.     XtSetArg(av[ac], XmNtopAttachment,   XmATTACH_WIDGET); ac++;
  5505.     XtSetArg(av[ac], XmNtopWidget,       left_right_text);   ac++;
  5506.     kids[i++] = top_bottom_pixels = XmCreateLabelGadget(space_form, 
  5507.                                                         "pixels",
  5508.                                                         av, ac);
  5509.     ac = 0;
  5510.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM);   ac++;
  5511.     XtSetArg(av[ac], XmNtopAttachment,   XmATTACH_WIDGET); ac++;
  5512.     XtSetArg(av[ac], XmNtopWidget,       top_bottom_text);    ac++;
  5513.     kids[i++] = solid_pixels = XmCreateLabelGadget(space_form, 
  5514.                                                    "pixels",
  5515.                                                    av, ac);
  5516.     ac = 0;
  5517.     XtSetArg(av[ac], XmNtopAttachment,   XmATTACH_WIDGET); ac++;
  5518.     XtSetArg(av[ac], XmNtopWidget,       top_bottom_text);    ac++;
  5519.     XtSetArg(av[ac], XmNleftAttachment,  XmATTACH_WIDGET); ac++;
  5520.     XtSetArg(av[ac], XmNleftWidget,      top_bottom_label);  ac++;
  5521.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
  5522.     XtSetArg(av[ac], XmNrightWidget,     left_right_pixels);      ac++;
  5523.     XtSetArg(av[ac], XmNcolumns,     3);    ac++;
  5524.     kids[i++] = solid_text = fe_CreateTextField(space_form,
  5525.                                                 "spaceBorder",
  5526.                                                 av, ac);
  5527.     w_data->margin_solid = solid_text;
  5528.     XtAddCallback(solid_text, XmNvalueChangedCallback,
  5529.                   fe_image_margin_cb, (XtPointer)w_data);
  5530.     /*
  5531.      *    Note border is dependent on link href, as it effects the
  5532.      *    default value.
  5533.      */
  5534.     fe_register_dependent(w_data->properties, solid_text,
  5535.                   FE_MAKE_DEPENDENCY(PROP_LINK_HREF|PROP_IMAGE_MARGIN_BORDER),
  5536.                           fe_image_margin_border_update_cb, (XtPointer)w_data);
  5537.  
  5538.     XtManageChildren(kids, i);
  5539.  
  5540.     /*
  5541.      *    Add this last, as other update methoda are dependent on it
  5542.      *    having run during init.
  5543.      */
  5544.     fe_register_dependent(w_data->properties, main_image_text,
  5545.                           FE_MAKE_DEPENDENCY(PROP_IMAGE_MAIN_IMAGE),
  5546.                           fe_image_main_image_update_cb, (XtPointer)w_data);
  5547.  
  5548.     /**********************************************************************/
  5549.     /*  Display form by managing all of the Manager widgets 6MAR96RCJ    */
  5550.     /**********************************************************************/
  5551.     XtManageChild(space_form);
  5552.     XtManageChild(space_frame);
  5553.     XtManageChild(main_image_form);
  5554.     XtManageChild(main_image_frame);
  5555.     XtManageChild(align_form);
  5556.     XtManageChild(align_frame);
  5557.     XtManageChild(dimensions_form);
  5558.     XtManageChild(dimensions_frame);
  5559.     XtManageChild(form);
  5560. } /* end fe_make_image_page */
  5561.  
  5562. Widget
  5563. fe_EditorPropertiesDialogCreate(
  5564.                                 MWContext *context, 
  5565.                                 fe_EditorPropertiesWidgets* p_data,
  5566.                                 Boolean is_image
  5567. )
  5568. {
  5569.     Widget   dialog;
  5570.     Widget   form;
  5571.     Widget   tab_form;
  5572.     char*    name = (is_image)?    "imagePropertiesDialog":
  5573.                                 "textPropertiesDialog";
  5574.     
  5575.     /*
  5576.      *    Make prompt with ok, apply, cancel, no separator.
  5577.      */
  5578.     dialog = fe_CreatePromptDialog(context, name,
  5579.                                    TRUE, TRUE, TRUE, FALSE, TRUE);
  5580.  
  5581.     form = XtVaCreateManagedWidget(
  5582.                                    "folder",
  5583.                                    xmlFolderWidgetClass, dialog,
  5584.                                    XmNshadowThickness, 2,
  5585.                                    XmNtopAttachment, XmATTACH_FORM,
  5586.                                    XmNleftAttachment, XmATTACH_FORM,
  5587.                                    XmNrightAttachment, XmATTACH_FORM,
  5588.                                    XmNbottomAttachment, XmATTACH_FORM,
  5589. #ifdef ALLOW_TAB_ROTATE
  5590.                                    XmNtabPlacement, XmFOLDER_LEFT,
  5591.                                    XmNrotateWhenLeftRight, FALSE,
  5592. #endif /* ALLOW_TAB_ROTATE */
  5593.                                    XmNbottomOffset, 3,
  5594.                                    XmNspacing, 1,
  5595.                                    NULL);
  5596.  
  5597.     if (is_image) {
  5598.         tab_form = fe_CreateTabForm(form, "imageProperties", NULL, 0);
  5599.         fe_make_image_page(context, tab_form, p_data->image);
  5600.     } else {
  5601.         tab_form = fe_CreateTabForm(form, "characterProperties", NULL, 0);
  5602.         fe_make_character_page(context, tab_form, p_data->character);
  5603.     }
  5604.  
  5605.     tab_form = fe_CreateTabForm(form, "linkProperties", NULL, 0);
  5606.     fe_make_link_page(context, tab_form, p_data->link);
  5607.  
  5608.     tab_form = fe_CreateTabForm(form, "paragraphProperties", NULL, 0);
  5609.     fe_make_paragraph_page(context, tab_form, p_data->paragraph);
  5610.  
  5611.     XtManageChild(dialog);
  5612.  
  5613.     return form;
  5614. }
  5615.  
  5616. void
  5617. fe_EditorPropertiesDialogDo(MWContext* context, fe_EditorPropertiesDialogType tab_type)
  5618. {
  5619.     fe_EditorPropertiesWidgets          properties;
  5620.     fe_EditorParagraphPropertiesWidgets paragraph;
  5621.     fe_EditorLinkPropertiesWidgets      link;
  5622.     fe_EditorCharacterPropertiesWidgets character;
  5623.     fe_EditorImagePropertiesWidgets     image;
  5624.     int done;
  5625.     Widget dialog;
  5626.     Widget form;
  5627.     Widget apply_button;
  5628.     Boolean apply_sensitized;
  5629.     unsigned tab_number;
  5630.     Boolean is_image;
  5631.  
  5632.     is_image = fe_EditorPropertiesDialogCanDo(context, XFE_EDITOR_PROPERTIES_IMAGE);
  5633.  
  5634.     /*
  5635.      *    Pick the tab.
  5636.      */
  5637.     switch (tab_type) {
  5638.     case XFE_EDITOR_PROPERTIES_TARGET:
  5639.         fe_EditorTargetPropertiesDialogDo(context);
  5640.         return;
  5641.     case XFE_EDITOR_PROPERTIES_HTML_TAG:
  5642.         fe_EditorHtmlPropertiesDialogDo(context);
  5643.         return;
  5644.     case XFE_EDITOR_PROPERTIES_TABLE:
  5645.         fe_EditorTablePropertiesDialogDo(context, XFE_EDITOR_PROPERTIES_TABLE);
  5646.         return;
  5647.     case XFE_EDITOR_PROPERTIES_IMAGE:
  5648.         if (!is_image)
  5649.             return;
  5650.         /*FALLTHRU*/
  5651.     case XFE_EDITOR_PROPERTIES_IMAGE_INSERT:
  5652.         is_image = TRUE;
  5653.         tab_number = 0;
  5654.         break;
  5655.     case XFE_EDITOR_PROPERTIES_CHARACTER:
  5656.         is_image = FALSE;
  5657.         tab_number = 0;
  5658.         break;
  5659.     case XFE_EDITOR_PROPERTIES_LINK_INSERT:
  5660.     case XFE_EDITOR_PROPERTIES_LINK:     
  5661.         tab_number = 1;
  5662.         break;
  5663.     case XFE_EDITOR_PROPERTIES_PARAGRAPH:
  5664.         tab_number = 2;
  5665.         break;
  5666.     case XFE_EDITOR_PROPERTIES_HRULE:
  5667.         fe_EditorHorizontalRulePropertiesDialogDo(context);
  5668.         return;
  5669.     default:
  5670.         return;
  5671.     }
  5672.  
  5673.     memset(&properties, 0, sizeof(fe_EditorPropertiesWidgets));
  5674.     memset(¶graph, 0, sizeof(fe_EditorParagraphPropertiesWidgets));
  5675.     memset(&link, 0, sizeof(fe_EditorLinkPropertiesWidgets));
  5676.     memset(&character, 0, sizeof(fe_EditorCharacterPropertiesWidgets));
  5677.     memset(&image, 0, sizeof(fe_EditorImagePropertiesWidgets));
  5678.  
  5679.     /*
  5680.      *    I'll show you mine if you show me yours.
  5681.      */
  5682.     link.properties = &properties;
  5683.     paragraph.properties = &properties;
  5684.     image.properties = &properties;
  5685.     character.properties = &properties;
  5686.  
  5687.     properties.link = &link;
  5688.     properties.paragraph = ¶graph;
  5689.     if (is_image)
  5690.         properties.image = ℑ
  5691.     else 
  5692.         properties.character = &character;
  5693.  
  5694.     properties.context = context;
  5695.     form = fe_EditorPropertiesDialogCreate(context, &properties, is_image);
  5696.     dialog = XtParent(form);
  5697.  
  5698.     /*
  5699.      *   Add a bunch of callbacks to the buttons.
  5700.      */
  5701.     XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done);
  5702.     XtAddCallback(dialog, XmNapplyCallback, fe_hrule_apply_cb, &done);
  5703.     XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  5704.     XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  5705.  
  5706.     /*
  5707.      *    Load values.
  5708.      */
  5709.     if (is_image)
  5710.         fe_EditorImagePropertiesDialogDataGet(context, &image);
  5711.     else
  5712.         fe_EditorCharacterPropertiesDialogDataGet(context, &character);
  5713.     fe_editor_link_properties_dialog_data_init(context, &link);
  5714.     fe_EditorParagraphPropertiesDialogDataGet(context, ¶graph);
  5715.  
  5716.     /*
  5717.      *    We toggle the sensitivity of the apply button on/off
  5718.      *    depending if there are changes to apply. It would be
  5719.      *    nice to use the depdency meahcnism, but it might get
  5720.      *    very busy.
  5721.      */
  5722.     apply_button = XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON);
  5723.     XtVaSetValues(apply_button, XmNsensitive, FALSE, 0);
  5724.     apply_sensitized = FALSE;
  5725.     properties.changed = 0;
  5726.  
  5727.     /*
  5728.      *    Popup.
  5729.      */
  5730.     XtManageChild(form);
  5731.  
  5732.     XmLFolderSetActiveTab(form, tab_number, True);
  5733.  
  5734.     /*
  5735.      *    Wait.
  5736.      */
  5737.     fe_NukeBackingStore(dialog); /* what does this do? */
  5738.  
  5739.     done = XmDIALOG_NONE;
  5740.     EDT_BeginBatchChanges(context);
  5741.     while (done == XmDIALOG_NONE) {
  5742.  
  5743.         Boolean new_image_override = FALSE;
  5744.  
  5745.         fe_EventLoop();
  5746.         
  5747.         if (done == XFE_DIALOG_DESTROY_BUTTON||done == XmDIALOG_CANCEL_BUTTON)
  5748.             break;
  5749.  
  5750.         /*
  5751.          *    This is a horrible crock to get around the fact
  5752.          *    that imageinsert() moves the context away from
  5753.          *    the image. Better solutions???
  5754.          */
  5755.         new_image_override = (properties.image && image.new_image);
  5756.         
  5757.         if (new_image_override) {
  5758.             if (apply_sensitized == TRUE) {
  5759.                 XtVaSetValues(apply_button, XmNsensitive, FALSE, 0);
  5760.                 apply_sensitized = TRUE;
  5761.             }
  5762.         } else {
  5763.             if (apply_sensitized == FALSE && properties.changed != 0) {
  5764.                 XtVaSetValues(apply_button, XmNsensitive, TRUE, 0);
  5765.                 apply_sensitized = TRUE;
  5766.             }
  5767.         }
  5768.  
  5769.         if (done == XmDIALOG_APPLY_BUTTON || done == XmDIALOG_OK_BUTTON) {
  5770.             /* apply */
  5771.  
  5772.             if ((properties.changed & PROP_IMAGE_ALL) != 0
  5773.                 &&
  5774.                 !fe_editor_image_properties_validate(context, &image)) {
  5775.                 done = XmDIALOG_NONE;
  5776.                 continue;
  5777.             }
  5778.  
  5779.             if (properties.changed != 0) {
  5780.                 if ((properties.changed & PROP_CHAR_ALL) != 0) 
  5781.                     fe_EditorCharacterPropertiesDialogSet(context, &character);
  5782.                 if ((properties.changed & PROP_IMAGE_ALL) != 0)
  5783.                     fe_editor_image_properties_set(context, &image);
  5784.                 if ((properties.changed & PROP_LINK_ALL) != 0)
  5785.                     fe_editor_link_properties_dialog_set(context, &link);
  5786.                 if ((properties.changed & PROP_PARA_ALL) != 0) 
  5787.                     fe_EditorParagraphPropertiesDialogSet(context, ¶graph);
  5788.             }
  5789.  
  5790.             if (done == XmDIALOG_APPLY_BUTTON) {
  5791.                 properties.changed = 0;
  5792.                 XtVaSetValues(apply_button, XmNsensitive, FALSE, 0);
  5793.                 apply_sensitized = FALSE;
  5794.                 done = XmDIALOG_NONE; /* keep looping */
  5795.             }
  5796.         }
  5797.     }
  5798.     EDT_EndBatchChanges(context);
  5799.  
  5800.     /*
  5801.      *    Unload data.
  5802.      */
  5803.     fe_DependentListDestroy(properties.dependents);
  5804.  
  5805.     if (done != XFE_DIALOG_DESTROY_BUTTON)
  5806.         XtDestroyWidget(dialog);
  5807. }
  5808.  
  5809. void
  5810. fe_EditorSetColorsDialogDo(MWContext* context)
  5811. {
  5812.     LO_Color color;
  5813.     
  5814.     fe_EditorColorGet(context, &color);
  5815.  
  5816.     if (fe_ColorPicker(context, &color))
  5817.         fe_EditorColorSet(context, &color);
  5818. }
  5819.  
  5820. Widget
  5821. fe_CreateCombo(Widget parent, char* name, Arg* p_args, Cardinal p_n)
  5822. {
  5823.   Widget pulldown;
  5824.   Arg args[8];
  5825.   Cardinal n;
  5826.   Widget button;
  5827.   char buf[64];
  5828.  
  5829.   sprintf(buf, "%sMenu", name);
  5830.  
  5831.   n = 0;
  5832.   pulldown = fe_CreatePulldownMenu(parent, buf, args, n);
  5833.  
  5834.   n = 0;
  5835.   button = XmCreatePushButtonGadget(pulldown, "emptyList", args, n);
  5836.   XtManageChild(button);
  5837.  
  5838.   n = 0;
  5839.   XtSetArg(args[n], XmNsubMenuId, pulldown); n++;
  5840.  
  5841.   return fe_CreateOptionMenuNoLabel(parent, name, args, n);
  5842. }
  5843.  
  5844. struct fe_EditorDocumentPropertiesStruct;
  5845.  
  5846. typedef struct fe_EditorDocumentGeneralPropertiesStruct
  5847. {
  5848.     struct fe_EditorDocumentPropertiesStruct* properties;
  5849.     
  5850.     Widget location;
  5851.     Widget title;
  5852.     Widget author;
  5853.     Widget description;
  5854. #ifdef EDITOR_SHOW_CREATE_DATE
  5855.     Widget created;
  5856.     Widget updated;
  5857. #endif /*EDITOR_SHOW_CREATE_DATE*/
  5858.     Widget keywords;
  5859.     Widget classification;
  5860.  
  5861.     unsigned changed;
  5862.     
  5863. } fe_EditorDocumentGeneralPropertiesStruct;
  5864.  
  5865. #if 0
  5866. static LO_Color**
  5867. fe_document_appearance_color_configure(
  5868.                fe_EditorDocumentAppearancePropertiesStruct* w_data,
  5869.                ED_EColor  c_type,
  5870.                LO_Color** def_color_r)
  5871. {
  5872.     LO_Color** result_addr;
  5873.  
  5874.     *def_color_r = &w_data->colors[c_type];
  5875.  
  5876.     switch (c_type) {
  5877.     case DOCUMENT_BACKGROUND_COLOR:
  5878.       result_addr = &w_data->page_data.pColorBackground;
  5879.       break;
  5880.     case DOCUMENT_LINK_TEXT_COLOR:
  5881.       result_addr = &w_data->page_data.pColorLink;
  5882.       break;
  5883.     case DOCUMENT_NORMAL_TEXT_COLOR:
  5884.       result_addr = &w_data->page_data.pColorText;
  5885.       break;
  5886.     case DOCUMENT_FOLLOWED_TEXT_COLOR:
  5887.       result_addr = &w_data->page_data.pColorFollowedLink;
  5888.       break;
  5889.     default:
  5890.       result_addr = &w_data->page_data.pColorActiveLink;
  5891.       break;
  5892.     }
  5893.  
  5894.     return result_addr;
  5895. }
  5896. #endif
  5897.  
  5898. #if 0
  5899.  
  5900. static void
  5901. fe_PreviewPanelSetColors(Widget widget,
  5902.                          MWContext* context,
  5903.                          unsigned mask,
  5904.                          Pixmap bg_pixmap,
  5905.                          LO_Color* colors)
  5906. {
  5907.     LO_Color* color;
  5908.     Pixel pixel;
  5909.     Pixel bg_pixel;
  5910.     WidgetList children;
  5911.     Cardinal num_children;
  5912.     Arg args[2];
  5913.     Cardinal n;
  5914.     int color_n;
  5915.     Boolean set_bg = FALSE;
  5916.     Boolean set_fg;
  5917.  
  5918.     XtVaGetValues(widget,
  5919.                   XmNchildren, &children,
  5920.                   XmNnumChildren, &num_children,
  5921.                   0);
  5922.  
  5923.     if ((mask & DOCUMENT_USE_CUSTOM_MASK) != 0)
  5924.         mask = ~0; /* do everything */
  5925.  
  5926.     if ((mask & DOCUMENT_BACKGROUND_COLOR_MASK) != 0) {
  5927.         color = &colors[DOCUMENT_BACKGROUND_COLOR];
  5928.  
  5929.         bg_pixel = fe_GetPixel(context,
  5930.                             color->red,
  5931.                             color->green,
  5932.                             color->blue);
  5933.  
  5934.         XtVaSetValues(widget, XmNbackground, bg_pixel, 0);
  5935.         set_bg = TRUE;
  5936.     }
  5937.  
  5938.     for (color_n = 0; color_n < 4; color_n++) {
  5939.           n = 0;
  5940.         set_fg = FALSE;
  5941.         if ((mask & (1<<color_n)) != 0) {
  5942.             color = &colors[color_n];
  5943.             pixel = fe_GetPixel(context,color->red,color->green,color->blue);
  5944.             XtSetArg(args[n], XmNforeground, pixel); n++;
  5945.             set_fg = TRUE;
  5946.         }
  5947.         if (set_bg || set_fg) {
  5948.             if (set_bg)
  5949.                 XtSetArg(args[n], XmNbackground, bg_pixel); n++;
  5950.             XtSetValues(children[color_n], args, n);
  5951.         }
  5952.     }
  5953. }
  5954.  
  5955. static char* fe_PreviewPanelCreate_names[] =
  5956. { "normal", "link", "active", "followed", 0 };
  5957.  
  5958. static Widget
  5959. fe_PreviewPanelCreate(Widget parent, char* name, Arg* p_args, Cardinal p_n)
  5960. {
  5961.     Widget rc;
  5962.     Widget children[4];
  5963.     Cardinal nchildren;
  5964.     Arg args[8];
  5965.     Cardinal n;
  5966.     
  5967.     XtSetArg(p_args[p_n], XmNorientation, XmVERTICAL); n++;
  5968.     rc = XmCreateRowColumn(parent, name, p_args, p_n);
  5969.  
  5970.     for (nchildren = 0; nchildren < 4; nchildren++) {
  5971.       name = fe_PreviewPanelCreate_names[nchildren];
  5972.       n = 0;
  5973.       children[nchildren] = XmCreateLabel(rc, name, args, n);
  5974.     }
  5975.  
  5976.     XtManageChildren(children, nchildren);
  5977.  
  5978.     return rc;
  5979. }
  5980.  
  5981. #else
  5982.  
  5983. typedef struct fe_PreviewPanelStruct
  5984. {
  5985.     Pixmap     bg_pixmap;
  5986.     Pixel      bg_pixel;
  5987.     Pixel      string_pixels[4];
  5988.     XmString   strings[4];
  5989.     XmFontList fontList;
  5990.     Dimension  margin_height;
  5991.     Dimension  margin_width;
  5992.     Dimension  height;
  5993.     Dimension  width;
  5994.     Dimension  shadow_thickness;
  5995.     Dimension  highlight_thickness;
  5996.     Dimension  spacing;
  5997. } fe_PreviewPanelStruct;
  5998.  
  5999. static void
  6000. fe_preview_draw_string(Display* display, Drawable window,
  6001.                        Pixel bg, Pixel fg,
  6002.                        XmFontList fontList, XmString string,
  6003.                        Position x, Position y,
  6004.                        Dimension width,    Dimension height,
  6005.                        Boolean underline)
  6006. {
  6007.     XGCValues    gc_values;
  6008.     XtGCMask     gc_mask;
  6009.     GC           gc;
  6010.     XRectangle   clip_rect;
  6011.     XFontStruct* font = NULL;
  6012.  
  6013.     memset (&gc_values, ~0, sizeof (gc_values));
  6014.     gc_values.foreground = fg;
  6015.     gc_values.background = bg;
  6016.  
  6017.     _XmFontListGetDefaultFont(fontList, &font); /* must include XmP.h */
  6018.  
  6019.     gc_mask = GCForeground|GCBackground;
  6020.  
  6021.     if (font != NULL) {
  6022.         gc_values.font = font->fid;
  6023.         gc_mask |= GCFont;
  6024.     }
  6025.  
  6026.     gc = fe_GetGCfromDW(display, window, gc_mask, &gc_values, NULL);
  6027.  
  6028.     clip_rect.x = x;
  6029.     clip_rect.y = y;
  6030.     clip_rect.width = width;
  6031.     clip_rect.height = height;
  6032.  
  6033.     if (underline) {
  6034.       XmStringDrawUnderline(display, window, fontList,
  6035.                             string,
  6036.                             gc,
  6037.                             x, y, width,
  6038.                             XmALIGNMENT_BEGINNING, 0, /* layout direction */
  6039.                             &clip_rect, /*clip_rectangle*/
  6040.                             string);
  6041.     } else {
  6042.       XmStringDraw(display, window, fontList,
  6043.                    string,
  6044.                    gc,
  6045.                    x, y, width,
  6046.                    XmALIGNMENT_BEGINNING, 0, /* layout direction */
  6047.                    &clip_rect /*clip_rectangle*/);
  6048.     }
  6049. }
  6050.                        
  6051. static void
  6052. fe_preview_panel_paint(Display* display, Drawable window, 
  6053.                        fe_PreviewPanelStruct* stuff)
  6054. {
  6055.     Position  x;
  6056.     Position  y;
  6057.     Dimension height;
  6058.     Dimension width;
  6059.     Dimension height_delta;
  6060.     Dimension margin_height;
  6061.     XmString  string;
  6062.     Pixel     fg_pixel;
  6063.     int i;
  6064.  
  6065.     /* use background color instead */
  6066.     XClearArea(display, window, 0, 0, 0, 0, FALSE); /* no expose */
  6067.  
  6068.     for (height = stuff->height; (height % 4) != 0; height++)
  6069.         ;
  6070.     height_delta = height/4;
  6071.  
  6072.     margin_height = stuff->highlight_thickness +
  6073.                     stuff->shadow_thickness +
  6074.                     stuff->margin_height;
  6075.     x = stuff->highlight_thickness +
  6076.         stuff->shadow_thickness +
  6077.         stuff->margin_width;
  6078.     y = margin_height;
  6079.  
  6080.     for (i = DOCUMENT_NORMAL_TEXT_COLOR;
  6081.          i <= DOCUMENT_FOLLOWED_TEXT_COLOR;
  6082.          i++) {
  6083.  
  6084.         fg_pixel = stuff->string_pixels[i];
  6085.         string = stuff->strings[i];
  6086.  
  6087.         XmStringExtent(stuff->fontList, string, &width, &height);
  6088.  
  6089.         fe_preview_draw_string(display, window,
  6090.                                stuff->bg_pixel, fg_pixel,
  6091.                                stuff->fontList, string,
  6092.                                x, y, width, height,
  6093.                                (i != DOCUMENT_NORMAL_TEXT_COLOR));
  6094.         y += height + (2*margin_height) + stuff->spacing; /* note: spacing */
  6095.     }
  6096. }
  6097.  
  6098. static void
  6099. fe_preview_panel_expose_cb(Widget widget, XtPointer closure, XtPointer cb)
  6100. {
  6101.     XmDrawingAreaCallbackStruct* cb_data = (XmDrawingAreaCallbackStruct*)cb;
  6102.     fe_PreviewPanelStruct* stuff = 
  6103.       (fe_PreviewPanelStruct*)fe_GetUserData(widget);
  6104.  
  6105.     fe_preview_panel_paint(XtDisplay(widget), cb_data->window, stuff);
  6106. }
  6107.  
  6108. static void
  6109. fe_PreviewPanelSetColors(Widget widget,
  6110.                          MWContext* context,
  6111.                          unsigned mask,
  6112.                          Pixmap bg_pixmap,
  6113.                          LO_Color* colors)
  6114. {
  6115.     fe_PreviewPanelStruct* stuff = 
  6116.       (fe_PreviewPanelStruct*)fe_GetUserData(widget);
  6117.     LO_Color* color;
  6118.     Pixel pixel;
  6119.     int color_n;
  6120.     Boolean set_bg = FALSE;
  6121.     Boolean set_fg;
  6122.  
  6123.     set_fg = FALSE;
  6124.  
  6125.     if ((mask & DOCUMENT_BACKGROUND_COLOR_MASK) != 0) {
  6126.         color = &colors[DOCUMENT_BACKGROUND_COLOR];
  6127.  
  6128.         pixel = fe_GetPixel(context,
  6129.                             color->red,
  6130.                             color->green,
  6131.                             color->blue);
  6132.         if (pixel != stuff->bg_pixel) {
  6133.             stuff->bg_pixel = pixel;
  6134.             /* this will generate an expose event -> cb */
  6135.             XtVaSetValues(widget, XmNbackground, stuff->bg_pixel, 0);
  6136.             set_bg = TRUE;
  6137.         }
  6138.     }
  6139.  
  6140.     for (color_n = 0; color_n < 4; color_n++) {
  6141.         if ((mask & (1<<color_n)) != 0) {
  6142.             color = &colors[color_n];
  6143.             pixel = fe_GetPixel(context,color->red,color->green,color->blue);
  6144.             stuff->string_pixels[color_n] = pixel;
  6145.             set_fg = TRUE;
  6146.         }
  6147.     }
  6148.  
  6149.     if (set_fg && !set_bg) /* if we set bg, we'll get an expose anyway */
  6150.       fe_preview_panel_paint(XtDisplay(widget), XtWindow(widget), stuff);
  6151. }
  6152.  
  6153. /* static */ char* fe_PreviewPanelCreate_names[] =
  6154. { "normal", "link", "active", "followed", "background", 0 };
  6155.  
  6156. static XtResource fe_PreviewPanelResources [] =
  6157. {
  6158.   {
  6159.     "normalLabelString", XmCXmString, XmRXmString, sizeof(XmString),
  6160.     XtOffset(fe_PreviewPanelStruct*, strings[DOCUMENT_NORMAL_TEXT_COLOR]),
  6161.     XmRImmediate,  (XtPointer)NULL
  6162.   },
  6163.   {
  6164.     "linkLabelString", XmCXmString, XmRXmString, sizeof(XmString),
  6165.     XtOffset(fe_PreviewPanelStruct*, strings[DOCUMENT_LINK_TEXT_COLOR]),
  6166.     XmRImmediate,  (XtPointer)NULL
  6167.   },
  6168.   {
  6169.     "activeLabelString", XmCXmString, XmRXmString, sizeof(XmString),
  6170.     XtOffset(fe_PreviewPanelStruct*, strings[DOCUMENT_ACTIVE_TEXT_COLOR]),
  6171.     XmRImmediate,  (XtPointer)NULL
  6172.   },
  6173.   {
  6174.     "followedLabelString", XmCXmString, XmRXmString, sizeof(XmString),
  6175.     XtOffset(fe_PreviewPanelStruct*, strings[DOCUMENT_FOLLOWED_TEXT_COLOR]),
  6176.     XmRImmediate,  (XtPointer)NULL
  6177.   },
  6178.   {
  6179.     XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList),
  6180.     XtOffset(fe_PreviewPanelStruct*, fontList),
  6181.     XmRImmediate, (XtPointer)NULL
  6182.   },
  6183.   {
  6184.     XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension, sizeof(Dimension),
  6185.     XtOffset(fe_PreviewPanelStruct*, margin_height),
  6186.     XmRImmediate, (XtPointer)2
  6187.   },
  6188.   {
  6189.     XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, sizeof(Dimension),
  6190.     XtOffset(fe_PreviewPanelStruct*, margin_width),
  6191.     XmRImmediate, (XtPointer)2
  6192.   },
  6193.   {
  6194.      XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension,
  6195.      sizeof (Dimension),
  6196.      XtOffset(fe_PreviewPanelStruct*, highlight_thickness),
  6197.      XmRImmediate, (XtPointer) 0 /* makes up for frame around us */
  6198.   },
  6199.   {
  6200.      XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
  6201.      sizeof (Dimension), 
  6202.      XtOffset(fe_PreviewPanelStruct*, shadow_thickness),
  6203.      XmRImmediate, (XtPointer) 0
  6204.   },
  6205.   {
  6206.      XmNspacing, XmCSpacing, XmRVerticalDimension,
  6207.      sizeof (Dimension), 
  6208.      XtOffset(fe_PreviewPanelStruct*, spacing),
  6209.      XmRImmediate, (XtPointer)4
  6210.   }
  6211. };
  6212.  
  6213. /* static */ Widget
  6214. fe_PreviewPanelCreate(Widget parent, char* name, Arg* p_args, Cardinal p_n)
  6215. {
  6216.     Widget drawing_area;
  6217.     XmString xm_string;
  6218.     char* resource_name;
  6219.     Pixel bg;
  6220.     XtResource copy_resources[XtNumber(fe_PreviewPanelResources)];
  6221.     Dimension height;
  6222.     Dimension width;
  6223.     Dimension total_height;
  6224.     Dimension max_width;
  6225.     fe_PreviewPanelStruct* stuff = XtNew(fe_PreviewPanelStruct);
  6226.     int i;
  6227.     
  6228.     XtSetArg(p_args[p_n], XmNuserData, stuff); p_n++;
  6229.     drawing_area = XmCreateDrawingArea(parent, name, p_args, p_n);
  6230.  
  6231.     XtVaGetValues(drawing_area,
  6232.                   XmNbackground, &bg,
  6233.                   XmNheight, &stuff->height,
  6234.                   XmNwidth, &stuff->width,
  6235.                   0);
  6236.  
  6237.     stuff->bg_pixel = bg;
  6238.  
  6239.     /*
  6240.      *    Get resources.
  6241.      */
  6242.     memcpy(copy_resources, fe_PreviewPanelResources,
  6243.            sizeof(fe_PreviewPanelResources));
  6244.     XtGetSubresources(drawing_area, (XtPointer)stuff,
  6245.                       name, "NsPreviewPanel",
  6246.                       copy_resources,
  6247.                       XtNumber(fe_PreviewPanelResources),
  6248.                       NULL, 0);
  6249.  
  6250.     max_width = 0;
  6251.     total_height = 0;
  6252.  
  6253.     for (i = 0; i < 4; i++) {
  6254.  
  6255.       if (stuff->strings[i] == NULL) { /* not set in resources */
  6256.           resource_name = fe_PreviewPanelResources[i].resource_name;
  6257.           xm_string = XmStringCreateLocalized(resource_name);
  6258.           stuff->strings[i] = xm_string;
  6259.       }
  6260.  
  6261.       XmStringExtent(stuff->fontList, stuff->strings[i], &width, &height);
  6262.       if (width > max_width)
  6263.           max_width = width;
  6264.       total_height += height;
  6265.  
  6266.       stuff->string_pixels[i] = bg;
  6267.     }
  6268.  
  6269.     max_width += 2 * (stuff->highlight_thickness +
  6270.                       stuff->shadow_thickness + stuff->margin_width);
  6271.     if (stuff->width < max_width) {
  6272.         stuff->width = max_width;
  6273.         XtVaSetValues(drawing_area, XmNwidth, stuff->width, 0);
  6274.     }
  6275.  
  6276.     total_height += (2 * stuff->highlight_thickness) +
  6277.                     (8 * (stuff->shadow_thickness + stuff->margin_height)) +
  6278.                     (3 * stuff->spacing);
  6279.     if (stuff->height < total_height) {
  6280.         stuff->height = total_height;
  6281.         XtVaSetValues(drawing_area, XmNheight, stuff->height, 0);
  6282.     }
  6283.  
  6284.     XtAddCallback(drawing_area, XmNexposeCallback, fe_preview_panel_expose_cb,
  6285.                   (XtPointer)stuff);
  6286.     XtAddCallback(drawing_area, XmNdestroyCallback, fe_destroy_cleanup_cb,
  6287.                   (XtPointer)stuff);
  6288.  
  6289.     return drawing_area;
  6290. }
  6291. #endif
  6292.  
  6293. /* static */ void
  6294. fe_document_appearance_preview_update_cb(Widget widget, XtPointer closure,
  6295.                                 XtPointer cb_data)
  6296. {
  6297.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6298.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6299.     fe_DependentListCallbackStruct* cb = 
  6300.       (fe_DependentListCallbackStruct*)cb_data;
  6301.     fe_Dependency mask = cb->mask;
  6302.     LO_Color* colors;
  6303.  
  6304.     if (w_data->use_custom)
  6305.         colors = w_data->colors;
  6306.     else
  6307.         colors = w_data->default_colors;
  6308.  
  6309.     if ((mask & DOCUMENT_USE_CUSTOM_MASK) != 0)
  6310.         mask = ~0; /* do all colors */
  6311.  
  6312.     fe_PreviewPanelSetColors(widget,
  6313.                              w_data->context,
  6314.                              mask,
  6315.                              0, /*Pixmap bg_pixmap*/
  6316.                              colors);
  6317. }
  6318.  
  6319. /* static */ void
  6320. fe_document_appearance_swatch_update_cb(Widget widget, XtPointer closure,
  6321.                                 XtPointer cb_data)
  6322. {
  6323.     ED_EColor c_type = (ED_EColor)fe_GetUserData(widget);
  6324.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6325.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6326.     LO_Color* default_color;
  6327.     LO_Color* colors;
  6328.     Boolean sensitive;
  6329.  
  6330.     if (w_data->use_custom)
  6331.         colors = w_data->colors;
  6332.     else
  6333.         colors = w_data->default_colors;
  6334.  
  6335.     default_color = &colors[c_type];
  6336.  
  6337.     sensitive = w_data->use_custom;
  6338.  
  6339.     fe_SwatchSetColor(widget, default_color);
  6340.     fe_SwatchSetSensitive(widget, sensitive);
  6341. }
  6342.  
  6343. static void
  6344. fe_document_appearance_color_picker_do(
  6345.                        MWContext* context,
  6346.                        Widget widget,
  6347.                        fe_EditorDocumentAppearancePropertiesStruct* w_data,
  6348.                        unsigned which)
  6349. {
  6350.     LO_Color default_color;
  6351.     LO_Color* colors;
  6352.     fe_Dependency mask;
  6353.  
  6354.     if (w_data->use_custom)
  6355.         colors = w_data->colors;
  6356.     else
  6357.         colors = w_data->default_colors;
  6358.  
  6359.     default_color = colors[which];
  6360.  
  6361.     mask = (1 << which);
  6362.  
  6363.     if (fe_ColorPicker(w_data->context, &default_color)) {
  6364.         w_data->colors[which] = default_color;
  6365.         w_data->changed |= mask;
  6366.         fe_DependentListCallDependents(widget,
  6367.                                        w_data->dependents,
  6368.                                        mask,
  6369.                                        (XtPointer)w_data);
  6370.     }
  6371. }
  6372.  
  6373. /* static */ void
  6374. fe_document_appearance_color_cb(Widget widget, XtPointer closure,
  6375.                                 XtPointer cb_data)
  6376. {
  6377.     fe_Dependency mask;
  6378.     ED_EColor c_type = (ED_EColor)fe_GetUserData(widget);
  6379.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6380.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6381.     LO_Color default_color;
  6382.     LO_Color* colors;
  6383.  
  6384.     if (w_data->use_custom)
  6385.         colors = w_data->colors;
  6386.     else
  6387.         colors = w_data->default_colors;
  6388.  
  6389.     default_color = colors[c_type];
  6390.  
  6391.     mask = (1 << ((unsigned)c_type));
  6392.  
  6393.     if (fe_ColorPicker(w_data->context, &default_color)) {
  6394.         w_data->colors[c_type] = default_color;
  6395.         w_data->changed |= mask;
  6396.         fe_DependentListCallDependents(widget,
  6397.                                        w_data->dependents,
  6398.                                        mask,
  6399.                                        closure);
  6400.     }
  6401. }
  6402.  
  6403. /* static */void
  6404. fe_preview_panel_click_cb(Widget widget, XtPointer closure, XtPointer cb)
  6405. {
  6406.     XmDrawingAreaCallbackStruct* cb_data = (XmDrawingAreaCallbackStruct*)cb;
  6407.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6408.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6409.     Dimension height;
  6410.     Dimension height_delta;
  6411.     int i;
  6412.  
  6413.     if (!w_data->use_custom) /* hack, hack, hack */
  6414.         return;
  6415.  
  6416.     if (cb_data->event->type == ButtonRelease) {
  6417.  
  6418.         unsigned y = cb_data->event->xbutton.y;
  6419.  
  6420.         XtVaGetValues(widget, XmNheight, &height, 0);
  6421.  
  6422.         for (; (height % 4) != 0; height++)
  6423.             ;
  6424.         height_delta = height/4;
  6425.  
  6426.         for (i = 0 ; i < 3; i++) {
  6427.             if (y < ((i+1)*height_delta))
  6428.                 break;
  6429.         }
  6430.         fe_document_appearance_color_picker_do(w_data->context,
  6431.                                                widget, w_data, i);
  6432.     }
  6433. }
  6434.  
  6435.  
  6436. /* static */ void
  6437. fe_document_appearance_use_custom_update_cb(Widget widget, XtPointer closure,
  6438.                                      XtPointer cb_data)
  6439. {
  6440.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6441.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6442.     Boolean is_custom_button = (fe_GetUserData(widget) != NULL);
  6443.     Boolean set = (is_custom_button == w_data->use_custom);
  6444.  
  6445.     XmToggleButtonGadgetSetState(widget, set, FALSE);
  6446. }
  6447.  
  6448. /* static */ void
  6449. fe_document_appearance_use_custom_cb(Widget widget, XtPointer closure,
  6450.                                      XtPointer cb_data)
  6451. {
  6452.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6453.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6454.     Boolean is_custom_button = (fe_GetUserData(widget) != NULL);
  6455.     Boolean set = XmToggleButtonGadgetGetState(widget);
  6456.  
  6457.     w_data->use_custom = (set == is_custom_button);
  6458.     w_data->changed |= DOCUMENT_USE_CUSTOM_MASK;
  6459.  
  6460.     fe_DependentListCallDependents(widget,
  6461.                                    w_data->dependents,
  6462.                                    DOCUMENT_USE_CUSTOM_MASK,
  6463.                                    closure);
  6464. }
  6465.  
  6466. /* static */ void
  6467. fe_document_appearance_use_image_update_cb(Widget widget, XtPointer closure,
  6468.                                      XtPointer cb_data)
  6469. {
  6470.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6471.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6472.     
  6473.     XmToggleButtonGadgetSetState(widget, w_data->use_image, FALSE);
  6474. }
  6475.  
  6476. /* static */ void
  6477. fe_document_appearance_use_image_cb(Widget widget, XtPointer closure,
  6478.                                      XtPointer cb_data)
  6479. {
  6480.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6481.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6482.     Boolean set = XmToggleButtonGadgetGetState(widget);
  6483.  
  6484.     w_data->use_image = set;
  6485.     w_data->changed |= DOCUMENT_USE_IMAGE_MASK;
  6486.  
  6487.     fe_DependentListCallDependents(widget,
  6488.                                    w_data->dependents,
  6489.                                    DOCUMENT_USE_IMAGE_MASK,
  6490.                                    closure);
  6491. }
  6492.  
  6493. static void
  6494. fe_document_appearance_leave_image_cb(Widget widget, XtPointer closure,
  6495.                                       XtPointer cbs)
  6496. {
  6497.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6498.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6499.     XmToggleButtonCallbackStruct* cb
  6500.         = (XmToggleButtonCallbackStruct*)cbs;
  6501.  
  6502.     w_data->leave_image = cb->set;
  6503.     w_data->changed |= DOCUMENT_USE_IMAGE_MASK;
  6504. }
  6505.  
  6506. static void
  6507. fe_document_appearance_leave_image_update_cb(Widget widget, XtPointer closure,
  6508.                                      XtPointer cb_data)
  6509. {
  6510.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6511.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6512.     
  6513.     XmToggleButtonGadgetSetState(widget, w_data->leave_image, FALSE);
  6514. }
  6515.  
  6516. /* static */ void
  6517. fe_document_appearance_sensitized_update_cb(Widget widget, XtPointer closure,
  6518.                                      XtPointer cb_data)
  6519. {
  6520.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6521.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6522.     Boolean sensitive;
  6523.     
  6524.     sensitive = w_data->use_custom;
  6525.  
  6526.     XtVaSetValues(widget, XmNsensitive, sensitive, 0);
  6527. }
  6528.  
  6529. /* static */ void
  6530. fe_document_appearance_image_text_cb(Widget widget, XtPointer closure,
  6531.                                      XtPointer cb_data)
  6532. {
  6533.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6534.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6535.  
  6536.     w_data->changed |= DOCUMENT_BACKGROUND_IMAGE_MASK;
  6537. }
  6538.  
  6539. /* static */ void
  6540. fe_document_appearance_image_text_update_cb(Widget widget, XtPointer closure,
  6541.                                      XtPointer cb_data)
  6542. {
  6543.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6544.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6545.     fe_DependentListCallbackStruct* info = 
  6546.         (fe_DependentListCallbackStruct*)cb_data;
  6547.     Boolean sensitive = w_data->use_image;
  6548.  
  6549.     if (info->caller == widget)
  6550.         return; /* don't call ourselves */
  6551.     
  6552.     if ((info->mask & DOCUMENT_BACKGROUND_IMAGE_MASK) != 0)
  6553.       fe_set_text_field(widget, w_data->image_path,
  6554.                         fe_document_appearance_image_text_cb, (XtPointer)w_data);
  6555.  
  6556.     fe_TextFieldSetEditable(w_data->context, widget, sensitive);
  6557. }
  6558.  
  6559. /* static */ void
  6560. fe_document_appearance_image_text_browse_cb(Widget widget, XtPointer closure,
  6561.                                      XtPointer cb_data)
  6562. {
  6563.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6564.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6565.     Widget image_text = (Widget)fe_GetUserData(widget);
  6566.  
  6567.     fe_editor_browse_file_of_text(w_data->context, image_text);
  6568. }
  6569.  
  6570. /* static */ void
  6571. fe_document_appearance_use_image_button_update_cb(Widget widget,
  6572.                                                    XtPointer closure,
  6573.                                                    XtPointer cb_data)
  6574. {
  6575.     fe_EditorDocumentAppearancePropertiesStruct* w_data
  6576.       = (fe_EditorDocumentAppearancePropertiesStruct*)closure;
  6577.     Boolean sensitive = w_data->use_image;
  6578.  
  6579.     XtVaSetValues(widget, XmNsensitive, sensitive, 0);
  6580. }
  6581.  
  6582. /* static */ void
  6583. fe_document_appearance_set(
  6584.                           MWContext* context,
  6585.                           fe_EditorDocumentAppearancePropertiesStruct* w_data)
  6586. {
  6587.     LO_Color* bg_color;
  6588.     LO_Color* normal_color;
  6589.     LO_Color* link_color;
  6590.     LO_Color* active_color;
  6591.     LO_Color* followed_color;
  6592.     char*     bg_image;
  6593.     char*     p;
  6594.     char      buf[MAXPATHLEN];
  6595.     char      docname[MAXPATHLEN];
  6596.     XP_Bool   leave_image = FALSE;
  6597.  
  6598.     if (w_data->use_custom) {
  6599.         bg_color = &w_data->colors[DOCUMENT_BACKGROUND_COLOR];
  6600.         normal_color = &w_data->colors[DOCUMENT_NORMAL_TEXT_COLOR];
  6601.         link_color = &w_data->colors[DOCUMENT_LINK_TEXT_COLOR];
  6602.         active_color = &w_data->colors[DOCUMENT_ACTIVE_TEXT_COLOR];
  6603.         followed_color = &w_data->colors[DOCUMENT_FOLLOWED_TEXT_COLOR];
  6604.     } else {
  6605.         bg_color = NULL;
  6606.         normal_color = link_color = active_color = followed_color = NULL;
  6607.     }
  6608.  
  6609.     if (w_data->use_image) {
  6610.         bg_image = fe_TextFieldGetString(w_data->image_text);
  6611.  
  6612.         /*
  6613.          *    Make sure bg image is fully qualified URL.
  6614.          */
  6615.         if (bg_image != NULL) {
  6616.             fe_StringTrim(bg_image);
  6617.  
  6618.             if ((p = strchr(bg_image, ':')) == NULL) {
  6619.                 if (bg_image[0] != '/' && !w_data->is_editor_preferences) {
  6620.                     strcpy(buf, "file:");
  6621.                     fe_EditorMakeName(context, docname, sizeof(buf) - 5);
  6622.                     fe_dirname(&buf[5], docname);
  6623.                     strcat(buf, "/");
  6624.                     strcat(buf, bg_image);
  6625.                 } else {
  6626.                     sprintf(buf, "file:%s", bg_image);
  6627.                 }
  6628.                 XtFree(bg_image);
  6629.                 bg_image = XtNewString(buf);
  6630.             }
  6631.         }
  6632.  
  6633.         leave_image = w_data->leave_image;
  6634.  
  6635.     } else {
  6636.         bg_image = NULL;
  6637.     }
  6638.  
  6639.     if (w_data->is_editor_preferences)
  6640.         fe_EditorPreferencesSetColors(context,
  6641.                                       bg_image,
  6642.                                       bg_color,
  6643.                                       normal_color,
  6644.                                       link_color,
  6645.                                       active_color,
  6646.                                       followed_color);
  6647.     else
  6648.         fe_EditorDocumentSetColors(context,
  6649.                                    bg_image,
  6650.                                    leave_image,
  6651.                                    bg_color,
  6652.                                    normal_color,
  6653.                                    link_color,
  6654.                                    active_color,
  6655.                                    followed_color);
  6656.  
  6657.     if (bg_image)
  6658.         XtFree(bg_image);
  6659. }
  6660.  
  6661. /* static */ void
  6662. fe_document_appearance_init(
  6663.                           MWContext* context,
  6664.                           fe_EditorDocumentAppearancePropertiesStruct* w_data)
  6665. {
  6666.     Boolean use_custom;
  6667.     Boolean leave_image = FALSE;
  6668.     char    bg_image[MAXPATHLEN];
  6669.  
  6670.     w_data->context = context;
  6671.  
  6672.     fe_EditorDefaultGetColors(
  6673.                       &w_data->default_colors[DOCUMENT_BACKGROUND_COLOR],
  6674.                       &w_data->default_colors[DOCUMENT_NORMAL_TEXT_COLOR],
  6675.                       &w_data->default_colors[DOCUMENT_LINK_TEXT_COLOR],
  6676.                       &w_data->default_colors[DOCUMENT_ACTIVE_TEXT_COLOR],
  6677.                       &w_data->default_colors[DOCUMENT_FOLLOWED_TEXT_COLOR]);
  6678.  
  6679.     if (w_data->is_editor_preferences)
  6680.           use_custom = fe_EditorPreferencesGetColors(context,
  6681.                         bg_image,
  6682.                         &w_data->colors[DOCUMENT_BACKGROUND_COLOR],
  6683.                         &w_data->colors[DOCUMENT_NORMAL_TEXT_COLOR],
  6684.                         &w_data->colors[DOCUMENT_LINK_TEXT_COLOR],
  6685.                         &w_data->colors[DOCUMENT_ACTIVE_TEXT_COLOR],
  6686.                         &w_data->colors[DOCUMENT_FOLLOWED_TEXT_COLOR]);
  6687.     else
  6688.         use_custom = fe_EditorDocumentGetColors(context,
  6689.                         bg_image,
  6690.                         &leave_image,
  6691.                         &w_data->colors[DOCUMENT_BACKGROUND_COLOR],
  6692.                         &w_data->colors[DOCUMENT_NORMAL_TEXT_COLOR],
  6693.                         &w_data->colors[DOCUMENT_LINK_TEXT_COLOR],
  6694.                         &w_data->colors[DOCUMENT_ACTIVE_TEXT_COLOR],
  6695.                         &w_data->colors[DOCUMENT_FOLLOWED_TEXT_COLOR]);
  6696.  
  6697.     w_data->use_custom = use_custom;
  6698.  
  6699.     if (bg_image[0] != '\0') {
  6700.       w_data->use_image = TRUE;
  6701.       w_data->leave_image = leave_image;
  6702.       w_data->image_path = bg_image;
  6703.     } else {
  6704.       w_data->use_image = FALSE;
  6705.       w_data->leave_image = FALSE;
  6706.       w_data->image_path = NULL;
  6707.     }
  6708.  
  6709.     fe_DependentListCallDependents(NULL,
  6710.                                    w_data->dependents,
  6711.                                    ~0,
  6712.                                    (XtPointer)w_data);
  6713.     w_data->image_path = NULL; /* held in TextField */
  6714. }
  6715.  
  6716. static Dimension
  6717. fe_get_offset_from_widest(Widget* children, Cardinal nchildren)
  6718. {
  6719.     Dimension width;
  6720.     Dimension margin_width;
  6721.  
  6722.     Widget fat_guy = XfeBiggestWidget(TRUE, children, nchildren);
  6723.     XtVaGetValues(fat_guy, XmNwidth, &width, 0);
  6724.     XtVaGetValues(XtParent(fat_guy), XmNmarginWidth, &margin_width, 0);
  6725.  
  6726.     return width + margin_width;
  6727. }
  6728.  
  6729. static Widget
  6730. fe_document_appearance_create(
  6731.                           MWContext* context,
  6732.                           Widget parent,
  6733.                           fe_EditorDocumentAppearancePropertiesStruct* w_data)
  6734. {
  6735.     Arg args[16];
  6736.     Cardinal n;
  6737.     Widget main_rc;
  6738.  
  6739.     Widget colors_frame;
  6740.     Widget colors_rc;
  6741.  
  6742.     Widget strategy_rc;
  6743.     Widget strategy_custom;
  6744.     Widget strategy_browser;
  6745.  
  6746. #ifdef DOCUMENT_COLOR_SCHEMES
  6747.     Widget schemes_frame;
  6748.     Widget schemes_form;
  6749.     Widget schemes_combo;
  6750.     Widget schemes_save;
  6751.     Widget schemes_remove;
  6752. #endif
  6753.  
  6754.     Widget custom_form;
  6755.     Widget custom_frame;
  6756.     Widget custom_preview_rc;
  6757.     Widget background_info;
  6758.     Widget fat_guy;
  6759.     Widget top_guy;
  6760.     Widget bottom_guy;
  6761.     Widget children[6];
  6762.     Widget swatches[6];
  6763.     Cardinal nchildren;
  6764.     Cardinal nswatch;
  6765.     Dimension width;
  6766.     int i;
  6767.  
  6768.     Widget background_frame;
  6769.     Widget background_form;
  6770.     Widget background_image_toggle;
  6771.     Widget background_image_text;
  6772.     Widget background_image_leave;
  6773.     Widget background_image_button;
  6774.  
  6775.     Widget info_label;
  6776.  
  6777.     n = 0;
  6778.     XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_CENTER); n++;
  6779.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  6780.     main_rc = XmCreateRowColumn(parent, "appearance", args, n);
  6781.     XtManageChild(main_rc);
  6782.  
  6783.     /*
  6784.      *    Custom colors.
  6785.      */
  6786.     n = 0;
  6787.     colors_frame = fe_CreateFrame(main_rc, "documentColors", args, n);
  6788.     XtManageChild(colors_frame);
  6789.  
  6790.     n = 0;
  6791.     XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_CENTER); n++;
  6792.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  6793.     colors_rc = XmCreateRowColumn(colors_frame, "colors", args, n);
  6794.     XtManageChild(colors_rc);
  6795.  
  6796.     /*
  6797.      *    Top row.
  6798.      */
  6799.     n = 0;
  6800.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  6801.     XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); n++;
  6802.     XtSetArg(args[n], XmNentryVerticalAlignment, XmALIGNMENT_BASELINE_TOP); n++;
  6803.     strategy_rc = XmCreateRowColumn(colors_rc, "strategy", args, n);
  6804.     XtManageChild(strategy_rc);
  6805.  
  6806.     n = 0;
  6807.     XtSetArg(args[n], XmNuserData, TRUE); n++;
  6808.     XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  6809.     strategy_custom = XmCreateToggleButtonGadget(strategy_rc,
  6810.                                                  "custom", args, n);
  6811.     XtManageChild(strategy_custom);
  6812.  
  6813.     XtAddCallback(strategy_custom, XmNvalueChangedCallback,
  6814.                   fe_document_appearance_use_custom_cb, (XtPointer)w_data);
  6815.  
  6816.     fe_DependentListAddDependent(&w_data->dependents,
  6817.                                  strategy_custom,
  6818.                                  DOCUMENT_USE_CUSTOM_MASK,
  6819.                                  fe_document_appearance_use_custom_update_cb,
  6820.                                  (XtPointer)w_data);
  6821.  
  6822.     n = 0;
  6823.     XtSetArg(args[n], XmNuserData, FALSE); n++;
  6824.     XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  6825.     strategy_browser = XmCreateToggleButtonGadget(strategy_rc,
  6826.                                                  "browser", args, n);
  6827.     XtManageChild(strategy_browser);
  6828.     
  6829.     XtAddCallback(strategy_browser, XmNvalueChangedCallback,
  6830.                   fe_document_appearance_use_custom_cb, (XtPointer)w_data);
  6831.  
  6832.     fe_DependentListAddDependent(&w_data->dependents,
  6833.                                  strategy_browser,
  6834.                                  DOCUMENT_USE_CUSTOM_MASK,
  6835.                                  fe_document_appearance_use_custom_update_cb,
  6836.                                  (XtPointer)w_data);
  6837.  
  6838. #ifdef DOCUMENT_COLOR_SCHEMES
  6839.     /*
  6840.      *    Color Schemes.
  6841.      */
  6842.     n = 0;
  6843.     schemes_frame = fe_CreateFrame(colors_rc, "schemes", args, n);
  6844.     XtManageChild(schemes_frame);
  6845.  
  6846.     n = 0;
  6847.     schemes_form = XmCreateForm(schemes_frame, "schemes", args, n);
  6848.     XtManageChild(schemes_form);
  6849.  
  6850.     n = 0;
  6851.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  6852.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  6853.     XtSetArg(args[n], XmNsensitive, FALSE); n++;
  6854.     schemes_remove = XmCreatePushButtonGadget(schemes_form, "remove", args, n);
  6855.     XtManageChild(schemes_remove);
  6856.  
  6857.     n = 0;
  6858.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  6859.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  6860.     XtSetArg(args[n], XmNrightWidget, schemes_remove); n++;
  6861.     XtSetArg(args[n], XmNsensitive, FALSE); n++;
  6862.     schemes_save = XmCreatePushButtonGadget(schemes_form, "save", args, n);
  6863.     XtManageChild(schemes_save);
  6864.  
  6865.     n = 0;
  6866.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  6867.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  6868.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  6869.     XtSetArg(args[n], XmNrightWidget, schemes_save); n++;
  6870.     XtSetArg(args[n], XmNsensitive, FALSE); n++;
  6871.     schemes_combo = fe_CreateCombo(schemes_form, "combo", args, n);
  6872.     XtManageChild(schemes_combo);
  6873. #else
  6874. #if 0
  6875.     /*
  6876.      *    make something to break up the top row from the colro buttons.
  6877.      */
  6878.     n = 0;
  6879.     custom_form = XmCreateSeparatorGadget(colors_rc, "separator", args, n);
  6880.     XtManageChild(custom_form);
  6881. #endif
  6882. #endif
  6883.  
  6884.     n = 0;
  6885.     custom_form = XmCreateForm(colors_rc, "custom", args, n);
  6886.     XtManageChild(custom_form);
  6887.  
  6888.     for (nchildren = DOCUMENT_NORMAL_TEXT_COLOR;
  6889.          nchildren <= DOCUMENT_BACKGROUND_COLOR;
  6890.          nchildren++) {
  6891.         Widget button;
  6892.         char*  name = fe_PreviewPanelCreate_names[nchildren];
  6893.         unsigned flags;
  6894.  
  6895.         n = 0;
  6896.         XtSetArg(args[n], XmNuserData, nchildren); n++;
  6897.         button = XmCreatePushButtonGadget(custom_form, name, args, n);
  6898.         XtAddCallback(button, XmNactivateCallback,
  6899.                       fe_document_appearance_color_cb, (XtPointer)w_data);
  6900.         flags = DOCUMENT_USE_CUSTOM_MASK;
  6901.         if (nchildren == DOCUMENT_BACKGROUND_COLOR)
  6902.             flags |= DOCUMENT_USE_IMAGE_MASK;
  6903.         fe_DependentListAddDependent(&w_data->dependents,
  6904.                                  button,
  6905.                                  flags,
  6906.                                  fe_document_appearance_sensitized_update_cb,
  6907.                                  (XtPointer)w_data);
  6908.         children[nchildren] = button;
  6909.     }
  6910.     XtManageChildren(children, nchildren);
  6911.  
  6912.     fat_guy = XfeBiggestWidget(TRUE, children, nchildren);
  6913.     XtVaGetValues(fat_guy, XmNwidth, &width, 0);
  6914.  
  6915.     /* swatches */
  6916.     for (nswatch = DOCUMENT_NORMAL_TEXT_COLOR;
  6917.          nswatch <= DOCUMENT_BACKGROUND_COLOR;
  6918.          nswatch++) {
  6919.         Widget foo;
  6920.         char   name[32];
  6921.         unsigned flags;
  6922.  
  6923.         sprintf(name, "%sSwatch", fe_PreviewPanelCreate_names[nswatch]);
  6924.         n = 0;
  6925.         XtSetArg(args[n], XmNuserData, nswatch); n++;
  6926.         XtSetArg(args[n], XmNwidth, SWATCH_SIZE); n++;
  6927.         foo = fe_CreateSwatch(custom_form, name, args, n);
  6928.         XtAddCallback(foo, XmNactivateCallback,
  6929.                       fe_document_appearance_color_cb, (XtPointer)w_data);
  6930.  
  6931.         flags = DOCUMENT_USE_CUSTOM_MASK|(1<<nswatch);
  6932.         if (nswatch == DOCUMENT_BACKGROUND_COLOR)
  6933.             flags |= DOCUMENT_USE_IMAGE_MASK;
  6934.         fe_DependentListAddDependent(&w_data->dependents,
  6935.                                      foo,
  6936.                                      flags,
  6937.                                      fe_document_appearance_swatch_update_cb,
  6938.                                      (XtPointer)w_data);
  6939.         swatches[nswatch] = foo;
  6940.     }
  6941.     XtManageChildren(swatches, nswatch);
  6942.  
  6943.     /*
  6944.      *    Do attachments.
  6945.      */
  6946.     for (top_guy = NULL, i = 0; i < nchildren; i++) {
  6947.  
  6948.         n = 0;
  6949.         if (top_guy) {
  6950.             XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  6951.             XtSetArg(args[n], XmNtopWidget, top_guy); n++;
  6952.         } else {
  6953.             XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  6954.         }
  6955.         XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  6956.  
  6957.         top_guy = children[i];
  6958.  
  6959.         if (top_guy != fat_guy) {
  6960.             /*
  6961.              *    Have to do this to avoid circular dependency in
  6962.              *    losing XmForm.
  6963.              */
  6964.             XtSetArg(args[n], XmNwidth, width); n++;
  6965. #if 0
  6966.             XtSetArg(args[n], XmNrightAttachment,
  6967.                    XmATTACH_OPPOSITE_WIDGET); n++;
  6968.             XtSetArg(args[n],XmNrightWidget, fat_guy); n++;
  6969. #endif
  6970.         }
  6971.         XtSetValues(top_guy, args, n);
  6972.  
  6973.         /* Do swatch. */
  6974.         n = 0;
  6975.         XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  6976.         XtSetArg(args[n], XmNleftWidget, top_guy); n++;
  6977.         XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  6978.         XtSetArg(args[n], XmNtopWidget, top_guy); n++;
  6979.         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  6980.         XtSetArg(args[n], XmNbottomWidget, top_guy); n++;
  6981.         XtSetValues(swatches[i], args, n);
  6982.     }
  6983.  
  6984.     top_guy = swatches[DOCUMENT_NORMAL_TEXT_COLOR];
  6985.     bottom_guy = swatches[DOCUMENT_FOLLOWED_TEXT_COLOR];
  6986.  
  6987.     n = 0;
  6988.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  6989.     XtSetArg(args[n], XmNleftWidget, top_guy); n++;
  6990.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  6991.     XtSetArg(args[n], XmNtopWidget, top_guy); n++;
  6992.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  6993.     XtSetArg(args[n], XmNbottomWidget, bottom_guy); n++;
  6994.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  6995. #if 1
  6996.     custom_frame = /*fe_*/XmCreateFrame(custom_form, "previewFrame", args, n);
  6997.     XtManageChild(custom_frame);
  6998.     n = 0; /* I'm tired of changing resources to get this right */
  6999.     XtSetArg(args[n], XmNmarginWidth, 0); n++;
  7000.     XtSetArg(args[n], XmNmarginHeight, 0); n++;
  7001.     XtSetValues(custom_frame, args, n);
  7002. #else
  7003.     n = 0;
  7004.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  7005.     XtSetArg(args[n], XmNborderWidth, 1); n++;
  7006.     XtSetArg(args[n], XmNborderColor,
  7007.              CONTEXT_DATA(w_data->context)->default_fg_pixel); n++;
  7008. #endif
  7009.     custom_preview_rc = fe_PreviewPanelCreate(custom_frame, "preview",
  7010.                                               args, n);
  7011.     XtManageChild(custom_preview_rc);
  7012.  
  7013.     XtAddCallback(custom_preview_rc, XmNinputCallback,
  7014.                   fe_preview_panel_click_cb, (XtPointer)w_data);
  7015.  
  7016.     fe_DependentListAddDependent(&w_data->dependents,
  7017.                          custom_preview_rc,
  7018.                          (DOCUMENT_USE_CUSTOM_MASK|DOCUMENT_ALL_APPEARANCE),
  7019.                          fe_document_appearance_preview_update_cb,
  7020.                          (XtPointer)w_data);
  7021. #if 1
  7022.     fe_DependentListAddDependent(&w_data->dependents,
  7023.                                  custom_preview_rc,
  7024.                                  DOCUMENT_USE_CUSTOM_MASK,
  7025.                                  fe_document_appearance_sensitized_update_cb,
  7026.                                  (XtPointer)w_data);
  7027. #endif
  7028.     top_guy = swatches[DOCUMENT_BACKGROUND_COLOR];
  7029.  
  7030.     n = 0;
  7031.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  7032.     XtSetArg(args[n], XmNleftWidget, top_guy); n++;
  7033.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  7034.     XtSetArg(args[n], XmNtopWidget, top_guy); n++;
  7035.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  7036.     XtSetArg(args[n], XmNbottomWidget, top_guy); n++;
  7037.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  7038.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  7039.     background_info = XmCreateLabelGadget(custom_form, "backgroundInfo", args, n);
  7040.     XtManageChild(background_info);
  7041.  
  7042.     /*
  7043.      *    Background.
  7044.      */
  7045.     n = 0;
  7046.     background_frame = fe_CreateFrame(main_rc, "backgroundImage", args, n);
  7047.     XtManageChild(background_frame);
  7048.  
  7049.     n = 0;
  7050.     background_form = XmCreateForm(background_frame, "backgroundImage", args, n);
  7051.     XtManageChild(background_form);
  7052.  
  7053.     nchildren = 0;
  7054.     n = 0;
  7055.     XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
  7056.     background_image_toggle = XmCreateToggleButtonGadget(background_form,
  7057.                                                         "useImage", args, n);
  7058.     children[nchildren++] = background_image_toggle;
  7059.  
  7060.     XtAddCallback(background_image_toggle, XmNvalueChangedCallback,
  7061.                   fe_document_appearance_use_image_cb, (XtPointer)w_data);
  7062.     fe_DependentListAddDependent(&w_data->dependents,
  7063.                          background_image_toggle,
  7064.                          (DOCUMENT_USE_IMAGE_MASK|DOCUMENT_USE_CUSTOM_MASK),
  7065.                          fe_document_appearance_use_image_update_cb,
  7066.                          (XtPointer)w_data);
  7067.  
  7068.     n = 0;
  7069.     background_image_text = fe_CreateTextField(background_form,
  7070.                                               "imageText", args, n);
  7071.     XtAddCallback(background_image_text, XmNvalueChangedCallback,
  7072.                   fe_document_appearance_image_text_cb,
  7073.                   (XtPointer)w_data);
  7074.     fe_DependentListAddDependent(&w_data->dependents,
  7075.                                  background_image_text,
  7076.                                  (DOCUMENT_BACKGROUND_IMAGE_MASK|
  7077.                                   DOCUMENT_USE_IMAGE_MASK|
  7078.                                   DOCUMENT_USE_CUSTOM_MASK),
  7079.                                  fe_document_appearance_image_text_update_cb,
  7080.                                  (XtPointer)w_data);
  7081.     w_data->image_text = background_image_text;
  7082.     children[nchildren++] = background_image_text;
  7083.  
  7084.     n = 0;
  7085.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  7086.     background_image_leave = XmCreateToggleButtonGadget(background_form,
  7087.                                                         "leaveImage",
  7088.                                                         args, n);
  7089.     children[nchildren++] = background_image_leave;
  7090.     XtAddCallback(background_image_leave, XmNvalueChangedCallback,
  7091.                   fe_document_appearance_leave_image_cb, (XtPointer)w_data);
  7092.     fe_DependentListAddDependent(&w_data->dependents,
  7093.                          background_image_leave,
  7094.                          (DOCUMENT_USE_IMAGE_MASK|DOCUMENT_USE_CUSTOM_MASK),
  7095.                          fe_document_appearance_leave_image_update_cb,
  7096.                          (XtPointer)w_data);
  7097.  
  7098.     n = 0;
  7099.     XtSetArg(args[n], XmNuserData, background_image_text); n++;
  7100.     background_image_button = XmCreatePushButtonGadget(background_form,
  7101.                                                        "browseImageFile",
  7102.                                                        args, n);
  7103.     XtAddCallback(background_image_button, XmNactivateCallback,
  7104.                   fe_document_appearance_image_text_browse_cb,
  7105.                   (XtPointer)w_data);
  7106.     fe_DependentListAddDependent(&w_data->dependents,
  7107.                          background_image_button,
  7108.                          (DOCUMENT_USE_IMAGE_MASK|DOCUMENT_USE_CUSTOM_MASK),
  7109.                          fe_document_appearance_use_image_button_update_cb,
  7110.                          (XtPointer)w_data);
  7111.     children[nchildren++] = background_image_button;
  7112.  
  7113.     /*
  7114.      *    Do background image group attachments.
  7115.      */
  7116.     n = 0;
  7117.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7118.     XtSetValues(background_image_toggle, args, n);
  7119.  
  7120.     n = 0;
  7121.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  7122.     XtSetArg(args[n], XmNleftWidget, background_image_toggle); n++;
  7123.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  7124.     XtSetValues(background_image_text, args, n);
  7125.  
  7126.     n = 0;
  7127.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7128.     XtSetArg(args[n], XmNtopWidget, background_image_text); n++;
  7129.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7130.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  7131.     XtSetArg(args[n], XmNrightWidget, background_image_button); n++;
  7132.     XtSetValues(background_image_leave, args, n);
  7133.  
  7134.     n = 0;
  7135.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7136.     XtSetArg(args[n], XmNtopWidget, background_image_text); n++;
  7137.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  7138.     XtSetValues(background_image_button, args, n);
  7139.  
  7140.     XtManageChildren(children, nchildren);
  7141.  
  7142.     /*
  7143.      *    Bottom line info text.
  7144.      */
  7145.     n = 0;
  7146.     info_label = XmCreateLabelGadget(main_rc, "infoLabel", args, n);
  7147.     XtManageChild(info_label);
  7148.  
  7149.     return main_rc;
  7150. }
  7151.  
  7152. #define DOCUMENT_GENERAL_TITLE           (0x1<<0)
  7153. #define DOCUMENT_GENERAL_AUTHOR          (0x1<<1)
  7154. #define DOCUMENT_GENERAL_DESCRIPTION     (0x1<<2)
  7155. #define DOCUMENT_GENERAL_KEYWORDS        (0x1<<3)
  7156. #define DOCUMENT_GENERAL_CLASSIFICATION  (0x1<<4)
  7157.  
  7158. static void
  7159. fe_document_general_changed_cb(Widget widget,
  7160.                                XtPointer closure, XtPointer call_data)
  7161. {
  7162.     fe_EditorDocumentGeneralPropertiesStruct* w_data
  7163.         = (fe_EditorDocumentGeneralPropertiesStruct*)closure;
  7164.     unsigned mask = (unsigned)fe_GetUserData(widget);
  7165.  
  7166.     w_data->changed |= mask;
  7167. }
  7168.  
  7169. /*
  7170.  *    Purpose:    Condense a URL to a given length.
  7171.  *              Lifted the algorithm from winfe/popup.cpp/WFE_CondenseURL()
  7172.  */
  7173. char*
  7174. FE_CondenseURL(char* target, char* source, unsigned target_len)
  7175. {
  7176.     unsigned source_len = strlen(source);
  7177.     unsigned first_half_len;
  7178.     unsigned second_half_len;
  7179.  
  7180.     if (source_len < target_len) {
  7181.         strcpy(target, source);
  7182.     } else {
  7183.         first_half_len = (target_len - 3)/2;
  7184.         second_half_len = target_len - first_half_len - 4; /* -1 for NUL */
  7185.  
  7186.         strncpy(target, source, first_half_len);
  7187.         strcpy(&target[first_half_len], "...");
  7188.         strcat(target, &source[source_len - second_half_len]);
  7189.     }
  7190.     return target;
  7191. }
  7192.  
  7193. static void
  7194. fe_document_general_init(MWContext* context,
  7195.                          fe_EditorDocumentGeneralPropertiesStruct* w_data)
  7196. {
  7197.     XmString xm_string;
  7198.     char buf[40]; /* will specifiy size of maximum location text length */
  7199.     char* value;
  7200.  
  7201.     /* set defaults */ /* <unknown> */
  7202.     xm_string = XmStringCreateLocalized(XP_GetString(XFE_UNKNOWN));
  7203. #ifdef EDITOR_SHOW_CREATE_DATE
  7204.     XtVaSetValues(w_data->created, XmNlabelString, xm_string, 0);
  7205.     XtVaSetValues(w_data->updated, XmNlabelString, xm_string, 0);
  7206. #endif /*EDITOR_SHOW_CREATE_DATE*/
  7207.     XtVaSetValues(w_data->location, XmNlabelString, xm_string, 0);
  7208.     XmStringFree(xm_string);
  7209.  
  7210.     /* get the location */
  7211.     fe_EditorMakeName(context, buf, sizeof(buf));
  7212.     xm_string = XmStringCreateLocalized(buf);
  7213.     XtVaSetValues(w_data->location, XmNlabelString, xm_string, 0);
  7214.     XmStringFree(xm_string);
  7215.  
  7216.     /* get the title */
  7217.     if ((value = fe_EditorDocumentGetTitle(context)) != NULL) {
  7218.         fe_SetTextFieldAndCallBack(w_data->title, value);
  7219.         XP_FREE(value);
  7220.     }
  7221.  
  7222.     /* get the author */
  7223.     if ((value = fe_EditorDocumentGetMetaData(context, "Author")) != NULL)
  7224.         fe_SetTextFieldAndCallBack(w_data->author, value);
  7225.  
  7226.     /* get the description */
  7227.     if ((value = fe_EditorDocumentGetMetaData(context, "Description")))
  7228.         fe_SetTextFieldAndCallBack(w_data->description, value);
  7229.  
  7230.     /* get the keywords */
  7231.     if ((value = fe_EditorDocumentGetMetaData(context, "Keywords")))
  7232.         fe_SetTextFieldAndCallBack(w_data->keywords, value);
  7233.  
  7234.     /* get the classification */
  7235.     if ((value = fe_EditorDocumentGetMetaData(context, "Classification")))
  7236.         fe_SetTextFieldAndCallBack(w_data->classification, value);
  7237.  
  7238. #ifdef EDITOR_SHOW_CREATE_DATE
  7239.     /* get the created */
  7240.     if ((value = fe_EditorDocumentGetMetaData(context, "Created"))) {
  7241.         xm_string = XmStringCreateLocalized(value);
  7242.         XtVaSetValues(w_data->created, XmNlabelString, xm_string, 0);
  7243.         XmStringFree(xm_string);
  7244.     }
  7245.  
  7246.     /* get the updated */
  7247.     if ((value = fe_EditorDocumentGetMetaData(context, "Last-Modified"))) {
  7248.         xm_string = XmStringCreateLocalized(value);
  7249.         XtVaSetValues(w_data->updated, XmNlabelString, xm_string, 0);
  7250.         XmStringFree(xm_string);
  7251.     }
  7252. #endif /*EDITOR_SHOW_CREATE_DATE*/
  7253.  
  7254.     w_data->changed = 0;
  7255. }
  7256.  
  7257. static void
  7258. fe_document_general_set(MWContext* context,
  7259.                         fe_EditorDocumentGeneralPropertiesStruct* w_data)
  7260. {
  7261.     char* value;
  7262.  
  7263.     /* set the title */
  7264.     if ((w_data->changed & DOCUMENT_GENERAL_TITLE) != 0) {
  7265.         value = fe_TextFieldGetString(w_data->title);
  7266.         fe_EditorDocumentSetTitle(context, value);
  7267.         XtFree(value);
  7268.     }
  7269.  
  7270.     /* author */
  7271.     if ((w_data->changed & DOCUMENT_GENERAL_AUTHOR) != 0) {
  7272.         value = fe_TextFieldGetString(w_data->author);
  7273.         fe_EditorDocumentSetMetaData(context, "Author", value);
  7274.         XtFree(value);
  7275.     }
  7276.     
  7277.     /* description */
  7278.     if ((w_data->changed & DOCUMENT_GENERAL_DESCRIPTION) != 0) {
  7279.         value = fe_TextFieldGetString(w_data->description);
  7280.         fe_EditorDocumentSetMetaData(context, "Description", value);
  7281.         XtFree(value);
  7282.     }
  7283.     
  7284.     /* keywords */
  7285.     if ((w_data->changed & DOCUMENT_GENERAL_KEYWORDS) != 0) {
  7286.         value = fe_TextFieldGetString(w_data->keywords);
  7287.         fe_EditorDocumentSetMetaData(context, "Keywords", value);
  7288.         XtFree(value);
  7289.     }
  7290.     
  7291.     /* classification */
  7292.     if ((w_data->changed & DOCUMENT_GENERAL_CLASSIFICATION) != 0) {
  7293.         value = fe_TextFieldGetString(w_data->classification);
  7294.         fe_EditorDocumentSetMetaData(context, "Classification", value);
  7295.         XtFree(value);
  7296.     }
  7297.     
  7298.     w_data->changed = 0;
  7299. }
  7300.  
  7301. static Widget
  7302. fe_document_general_create(
  7303.                           MWContext* context,
  7304.                           Widget parent,
  7305.                           fe_EditorDocumentGeneralPropertiesStruct* w_data)
  7306. {
  7307.     Widget form;
  7308.     Widget location_label;
  7309.     Widget location_text;
  7310.     Widget title_label;
  7311.     Widget title_text;
  7312.     Widget author_label;
  7313.     Widget author_text;
  7314.     Widget description_label;
  7315.     Widget description_text;
  7316. #ifdef EDITOR_SHOW_CREATE_DATE
  7317.     Widget created_label;
  7318.     Widget created_text;
  7319.     Widget updated_label;
  7320.     Widget updated_text;
  7321.     Widget fat_guy;
  7322. #endif /*EDITOR_SHOW_CREATE_DATE*/
  7323.     Widget other_frame;
  7324.     Widget other_form;
  7325.     Widget info_label;
  7326.     Widget keywords_label;
  7327.     Widget keywords_text;
  7328.     Widget classification_label;
  7329.     Widget classification_text;
  7330.     Widget children[16];
  7331.     Cardinal nchildren;
  7332.     Dimension left_offset;
  7333.     Arg    args[8];
  7334.     Cardinal n;
  7335.     Cardinal i;
  7336.  
  7337.     n = 0;
  7338.     form = XmCreateForm(parent, "general", args, n);
  7339.  
  7340.     nchildren = 0;
  7341.     n = 0;
  7342.     location_label = XmCreateLabelGadget(form, "locationLabel", args, n);
  7343.     children[nchildren++] = location_label;
  7344.     
  7345.     n = 0;
  7346.     title_label = XmCreateLabelGadget(form, "titleLabel", args, n);
  7347.     children[nchildren++] = title_label;
  7348.     
  7349.     n = 0;
  7350.     author_label = XmCreateLabelGadget(form, "authorLabel", args, n);
  7351.     children[nchildren++] = author_label;
  7352.     
  7353.     n = 0;
  7354.     description_label = XmCreateLabelGadget(form, "descriptionLabel", args, n);
  7355.     children[nchildren++] = description_label;
  7356.  
  7357.     left_offset = fe_get_offset_from_widest(children, nchildren);
  7358.  
  7359.     n = 0;
  7360.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  7361.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7362.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  7363.     location_text = XmCreateLabelGadget(form, "locationText", args, n);
  7364.     children[nchildren++] = location_text;
  7365.     
  7366.     n = 0;
  7367.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7368.     XtSetArg(args[n], XmNtopWidget, children[nchildren-1]); n++;
  7369.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  7370.     XtSetArg(args[n], XmNleftWidget, location_text); n++;
  7371.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  7372.     XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_TITLE); n++;
  7373.     title_text = fe_CreateTextField(form, "titleText", args, n);
  7374.     children[nchildren++] = title_text;
  7375.  
  7376.     XtAddCallback(title_text, XmNvalueChangedCallback,
  7377.                   fe_document_general_changed_cb, (XtPointer)w_data);
  7378.     
  7379.     n = 0;
  7380.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7381.     XtSetArg(args[n], XmNtopWidget, children[nchildren-1]); n++;
  7382.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  7383.     XtSetArg(args[n], XmNleftWidget, location_text); n++;
  7384.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  7385.     XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_AUTHOR); n++;
  7386.     author_text = fe_CreateTextField(form, "authorText", args, n);
  7387.     children[nchildren++] = author_text;
  7388.     
  7389.     XtAddCallback(author_text, XmNvalueChangedCallback,
  7390.                   fe_document_general_changed_cb, (XtPointer)w_data);
  7391.     
  7392.     n = 0;
  7393.     XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
  7394.     XtSetArg(args[n], XmNrows, 2); n++;
  7395.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7396.     XtSetArg(args[n], XmNtopWidget, children[nchildren-1]); n++;
  7397.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  7398.     XtSetArg(args[n], XmNleftWidget, location_text); n++;
  7399.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  7400.     XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_DESCRIPTION); n++;
  7401.     description_text = fe_CreateText(form, "descriptionText", args, n);
  7402.     children[nchildren++] = description_text;
  7403.  
  7404.     XtAddCallback(description_text, XmNvalueChangedCallback,
  7405.                   fe_document_general_changed_cb, (XtPointer)w_data);
  7406.     
  7407.     /* go back and do label attachments */
  7408.     for (i = 0; i < 4; i++) {
  7409.         n = 0;
  7410.         if (i == 0) {
  7411.             XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  7412.         } else {
  7413.             XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7414.             XtSetArg(args[n], XmNtopWidget, children[i+3]); n++;
  7415.         }
  7416.         XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7417.         XtSetValues(children[i], args, n);
  7418.     }
  7419.  
  7420.     XtManageChildren(children, nchildren);
  7421.  
  7422.     nchildren = 0;
  7423. #ifdef EDITOR_SHOW_CREATE_DATE
  7424.     n = 0;
  7425.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7426.     XtSetArg(args[n], XmNtopWidget, description_text); n++;
  7427.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7428.     created_label = XmCreateLabelGadget(form, "createdLabel", args, n);
  7429.     children[nchildren++] = created_label;
  7430.  
  7431.     n = 0;
  7432.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7433.     XtSetArg(args[n], XmNtopWidget, created_label); n++;
  7434.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7435.     updated_label = XmCreateLabelGadget(form, "updatedLabel", args, n);
  7436.     children[nchildren++] = updated_label;
  7437.  
  7438.     fat_guy = XfeBiggestWidget(TRUE, children, nchildren);
  7439.  
  7440.     n = 0;
  7441.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7442.     XtSetArg(args[n], XmNtopWidget, description_text); n++;
  7443.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  7444.     XtSetArg(args[n], XmNleftWidget, fat_guy); n++;
  7445.     created_text = XmCreateLabelGadget(form, "createdText", args, n);
  7446.     children[nchildren++] = created_text;
  7447.  
  7448.     n = 0;
  7449.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7450.     XtSetArg(args[n], XmNtopWidget, created_text); n++;
  7451.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  7452.     XtSetArg(args[n], XmNleftWidget, fat_guy); n++;
  7453.     updated_text = XmCreateLabelGadget(form, "updatedText", args, n);
  7454.     children[nchildren++] = updated_text;
  7455. #endif /*EDITOR_SHOW_CREATE_DATE*/
  7456.  
  7457.     n = 0;
  7458.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7459. #ifdef EDITOR_SHOW_CREATE_DATE
  7460.     XtSetArg(args[n], XmNtopWidget, updated_text); n++;
  7461. #else
  7462.     XtSetArg(args[n], XmNtopWidget, description_text); n++;
  7463. #endif /*EDITOR_SHOW_CREATE_DATE*/
  7464.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7465.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  7466.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  7467.     other_frame = fe_CreateFrame(form, "otherAttributes", args, n);
  7468.     children[nchildren++] = other_frame;
  7469.  
  7470.     XtManageChildren(children, nchildren);
  7471. #if 1
  7472.  
  7473.     n = 0;
  7474.     other_form = XmCreateForm(other_frame, "form", args, n);
  7475.     XtManageChild(other_form);
  7476.  
  7477.     nchildren = 0;
  7478.     n = 0;
  7479.     keywords_label = XmCreateLabelGadget(other_form, "keywordsLabel", args, n);
  7480.     children[nchildren++] = keywords_label;
  7481.  
  7482.     n = 0;
  7483.     classification_label = XmCreateLabelGadget(other_form,
  7484.                                                "classificationLabel",
  7485.                                                args, n);
  7486.     children[nchildren++] = classification_label;
  7487.  
  7488.     left_offset = fe_get_offset_from_widest(children, nchildren);
  7489.  
  7490.     n = 0;
  7491.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  7492.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7493.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  7494.     info_label = XmCreateLabelGadget(other_form, "infoLabel", args, n);
  7495.     children[nchildren++] = info_label;
  7496.  
  7497.     n = 0;
  7498.     XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
  7499.     XtSetArg(args[n], XmNrows, 2); n++;
  7500.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7501.     XtSetArg(args[n], XmNtopWidget, info_label); n++;
  7502.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  7503.     XtSetArg(args[n], XmNleftWidget, info_label); n++;
  7504.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  7505.     XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_KEYWORDS); n++;
  7506.     keywords_text = fe_CreateText(other_form, "keywordsText", args, n);
  7507.     children[nchildren++] = keywords_text;
  7508.  
  7509.     XtAddCallback(keywords_text, XmNvalueChangedCallback,
  7510.                   fe_document_general_changed_cb, (XtPointer)w_data);
  7511.     
  7512.     n = 0;
  7513.     XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
  7514.     XtSetArg(args[n], XmNrows, 2); n++;
  7515.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7516.     XtSetArg(args[n], XmNtopWidget, keywords_text); n++;
  7517.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  7518.     XtSetArg(args[n], XmNleftWidget, info_label); n++;
  7519.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  7520.     XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_CLASSIFICATION); n++;
  7521.     classification_text = fe_CreateText(other_form, "classificationText",
  7522.                                        args, n);
  7523.     children[nchildren++] = classification_text;
  7524.  
  7525.     XtAddCallback(classification_text, XmNvalueChangedCallback,
  7526.                   fe_document_general_changed_cb, (XtPointer)w_data);
  7527.     
  7528.     /* go back set attachments for labels */
  7529.     n = 0;
  7530.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7531.     XtSetArg(args[n], XmNtopWidget, info_label); n++;
  7532.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7533.     XtSetValues(keywords_label, args, n);
  7534.     
  7535.     n = 0;
  7536.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  7537.     XtSetArg(args[n], XmNtopWidget, keywords_text); n++;
  7538.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  7539.     XtSetValues(classification_label, args, n);
  7540.  
  7541.     XtManageChildren(children, nchildren);
  7542. #endif
  7543.     XtManageChild(form);
  7544.  
  7545.     w_data->location = location_text;
  7546.     w_data->title = title_text;
  7547.     w_data->author = author_text;
  7548.     w_data->description = description_text;
  7549. #ifdef EDITOR_SHOW_CREATE_DATE
  7550.     w_data->created = created_text;
  7551.     w_data->updated = updated_text;
  7552. #endif /*EDITOR_SHOW_CREATE_DATE*/
  7553.     w_data->keywords = keywords_text;
  7554.     w_data->classification = classification_text;
  7555.  
  7556.     return form;
  7557. }
  7558.  
  7559. typedef enum
  7560. {
  7561.   XFE_USERMETA_VIEW,
  7562.   XFE_USERMETA_MODIFY,
  7563.   XFE_USERMETA_NEW
  7564. } fe_AdvancedUserState;
  7565.  
  7566. typedef struct fe_NameValueItemList
  7567. {
  7568.     fe_NameValueItem* items;
  7569.     unsigned          nitems;    /* logical number of items */
  7570.     unsigned          size; /* size of vector */
  7571.     Widget            widget;
  7572.     Boolean           is_dirty;
  7573.     int               selected_item;
  7574.     unsigned          mask;
  7575. } fe_NameValueItemList;
  7576.  
  7577. #define NOTHING_SELECTED (-1)
  7578.  
  7579. typedef struct fe_EditorDocumentAdvancedPropertiesStruct
  7580. {
  7581.     MWContext* context;
  7582.     fe_NameValueItemList  system_list;
  7583.     fe_NameValueItemList  user_list;
  7584.     fe_NameValueItemList* active_list;
  7585.     Boolean  item_is_new;
  7586.     Boolean  item_is_dirty;
  7587.     Widget   name_text;
  7588.     Widget   value_text;
  7589.     unsigned changed;
  7590.     fe_DependentList* dependents;
  7591. } fe_EditorDocumentAdvancedPropertiesStruct;
  7592.  
  7593. #define DOCUMENT_ADVANCED_HTTP_LIST (0x1<<0)
  7594. #define DOCUMENT_ADVANCED_META_LIST (0x1<<1)
  7595. #define DOCUMENT_ADVANCED_ITEM      (0x1<<2)
  7596. #define DOCUMENT_ADVANCED_SELECTION (0x1<<3)
  7597.  
  7598. static void
  7599. fe_document_advanced_tell_me_eh(Widget widget, XtPointer closure,
  7600.                                 XEvent* event, Boolean* keep_going)
  7601. {
  7602.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7603.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7604.     fe_NameValueItemList* my_list;
  7605.  
  7606.     *keep_going = TRUE;
  7607.  
  7608.     XmProcessTraversal(widget, XmTRAVERSE_CURRENT);
  7609.  
  7610.     /*
  7611.      *    We may get called after the callback (next), so..
  7612.      */
  7613.     if (w_data->active_list != NULL && w_data->active_list->widget == widget)
  7614.         return;
  7615.  
  7616.     if (w_data->user_list.widget == widget)
  7617.         my_list = &w_data->user_list;
  7618.     else
  7619.         my_list = &w_data->system_list;
  7620.         
  7621.     w_data->active_list = my_list;
  7622.     my_list->selected_item = NOTHING_SELECTED;
  7623.     my_list->is_dirty = FALSE;
  7624.     if (my_list->nitems == 0)
  7625.         w_data->item_is_new = TRUE;
  7626.     else
  7627.         w_data->item_is_new = FALSE;
  7628.     w_data->item_is_dirty = FALSE;
  7629.  
  7630.     fe_DependentListCallDependents(widget,
  7631.                                    w_data->dependents,
  7632.                                    DOCUMENT_ADVANCED_SELECTION,
  7633.                                    closure);
  7634. }
  7635.  
  7636. static void
  7637. fe_document_advanced_list_cb(Widget widget, XtPointer closure,
  7638.                                     XtPointer foo)
  7639. {
  7640.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7641.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7642.     XmListCallbackStruct* cb_data = (XmListCallbackStruct*)foo;
  7643.     fe_NameValueItemList* my_list;
  7644.     
  7645.     if (cb_data->reason != XmCR_SINGLE_SELECT)
  7646.           return;
  7647.  
  7648.     if (w_data->user_list.widget == widget)
  7649.         my_list = &w_data->user_list;
  7650.     else
  7651.         my_list = &w_data->system_list;
  7652.  
  7653.     /*
  7654.      *    For some strange and unknown reason this callback
  7655.      *    adds one to the list position it provides.
  7656.      */
  7657.     if (cb_data->item_position > 0 && cb_data->selected_item_count > 0) {
  7658.         my_list->selected_item = cb_data->item_position - 1;
  7659.     } else {
  7660.         my_list->selected_item = NOTHING_SELECTED;
  7661.     }
  7662.  
  7663.     if (my_list->nitems == 0)
  7664.         w_data->item_is_new = TRUE;
  7665.     else
  7666.         w_data->item_is_new = FALSE;
  7667.  
  7668.     w_data->active_list = my_list;
  7669.     my_list->is_dirty = FALSE;
  7670.     w_data->item_is_dirty = FALSE;
  7671.  
  7672.     fe_DependentListCallDependents(widget,
  7673.                                    w_data->dependents,
  7674.                                    DOCUMENT_ADVANCED_SELECTION,
  7675.                                    closure);
  7676. }
  7677.  
  7678. static void
  7679. fe_copy_name_value_to_xm_list(Widget widget, fe_NameValueItem* list)
  7680. {
  7681.     unsigned i;
  7682.     char buf[512];
  7683.     XmString xm_string;
  7684.  
  7685.     XmListDeleteAllItems(widget);
  7686.  
  7687.     for (i = 0; list[i].name != NULL; i++) {
  7688.         strcpy(buf, list[i].name);
  7689.         strcat(buf, "=");
  7690.         strcat(buf, list[i].value);
  7691.  
  7692.         xm_string = XmStringCreateLocalized(buf);
  7693.         XmListAddItem(widget, xm_string, i + 1); /* MOTIFism */
  7694.         XmStringFree(xm_string);
  7695.     }
  7696. }
  7697.  
  7698. static void
  7699. fe_document_advanced_list_update_cb(Widget widget, XtPointer closure,
  7700.                                     XtPointer cb_data)
  7701. {
  7702.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7703.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7704.     fe_NameValueItemList* my_list;
  7705.     Pixel    parent_bg;
  7706.     Pixel    select_bg;
  7707.  
  7708.     XtVaGetValues(XtParent(widget), XmNbackground, &parent_bg, 0);
  7709.  
  7710.     XmGetColors(XtScreen(widget), fe_cmap(w_data->context),
  7711.                 parent_bg, NULL, NULL, NULL, &select_bg);
  7712.  
  7713.     if (w_data->user_list.widget == widget)
  7714.         my_list = &w_data->user_list;
  7715.     else
  7716.         my_list = &w_data->system_list;
  7717.  
  7718.     if (my_list->is_dirty) {
  7719.         fe_copy_name_value_to_xm_list(widget, my_list->items);
  7720.         my_list->is_dirty = FALSE;
  7721.     }
  7722.  
  7723.     if (w_data->active_list == my_list &&
  7724.         my_list->selected_item != NOTHING_SELECTED) {
  7725.         XmListSelectPos(widget, my_list->selected_item + 1, FALSE);
  7726.     } else {
  7727.         XmListDeselectAllItems(widget);
  7728.     }
  7729.  
  7730.     if (w_data->active_list == my_list)
  7731.         XtVaSetValues(widget, XmNbackground, select_bg, 0);
  7732.     else
  7733.         XtVaSetValues(widget, XmNbackground, parent_bg, 0);
  7734. }
  7735.  
  7736. static void
  7737. fe_document_advanced_value_cb(Widget widget, XtPointer closure,
  7738.                                     XtPointer cb_data)
  7739. {
  7740.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7741.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7742.  
  7743.     if (w_data->item_is_dirty == FALSE) {
  7744.         w_data->item_is_dirty = TRUE;
  7745.  
  7746.         fe_DependentListCallDependents(widget,
  7747.                                        w_data->dependents,
  7748.                                        DOCUMENT_ADVANCED_ITEM,
  7749.                                        closure);
  7750.     }
  7751. }
  7752.  
  7753. static void
  7754. fe_document_advanced_name_update_cb(Widget widget, XtPointer closure,
  7755.                                     XtPointer cb_data)
  7756. {
  7757.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7758.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7759.     fe_DependentListCallbackStruct* info = 
  7760.         (fe_DependentListCallbackStruct*)cb_data;
  7761.     char* name;
  7762.     
  7763.     if (info->caller == widget)
  7764.       return;
  7765.     
  7766.     if (w_data->item_is_new) {
  7767.         fe_TextFieldSetString(widget, "", FALSE);
  7768.         fe_TextFieldSetEditable(w_data->context, widget, TRUE);
  7769.         XtVaSetValues(XtParent(widget), XmNinitialFocus, widget, 0);
  7770.     } else {
  7771.         fe_NameValueItemList* active_list = w_data->active_list;
  7772.           if (active_list != NULL &&
  7773.             active_list->selected_item != NOTHING_SELECTED) {
  7774.             name = active_list->items[active_list->selected_item].name;
  7775.             
  7776.             fe_TextFieldSetString(widget, name, FALSE);
  7777.         } else {
  7778.             fe_TextFieldSetString(widget, "", FALSE);
  7779.         }
  7780.         fe_TextFieldSetEditable(w_data->context, widget, FALSE);
  7781.     }
  7782. }
  7783.  
  7784. static void
  7785. fe_document_advanced_value_update_cb(Widget widget, XtPointer closure,
  7786.                                     XtPointer cb_data)
  7787. {
  7788.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7789.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7790.     fe_DependentListCallbackStruct* info = 
  7791.         (fe_DependentListCallbackStruct*)cb_data;
  7792.     char* value;
  7793.     
  7794.     if (info->caller == widget)
  7795.       return;
  7796.     
  7797.     if (w_data->item_is_new) {
  7798.         fe_TextFieldSetString(widget, "", FALSE);
  7799.         fe_TextFieldSetEditable(w_data->context, widget, TRUE);
  7800.     } else {
  7801.         fe_NameValueItemList* active_list = w_data->active_list;
  7802.           if (active_list != NULL &&
  7803.             active_list->selected_item != NOTHING_SELECTED) {
  7804.             value = active_list->items[active_list->selected_item].value;
  7805.             
  7806.             if (value == NULL)
  7807.               value = "";
  7808.  
  7809.             fe_TextFieldSetString(widget, value, FALSE);
  7810.             fe_TextFieldSetEditable(w_data->context, widget, TRUE);
  7811. #if 0
  7812.             XmProcessTraversal(widget, XmTRAVERSE_CURRENT);
  7813. #endif
  7814.         }    else { /* nothing selected */
  7815.             fe_TextFieldSetString(widget, "", FALSE);
  7816.             fe_TextFieldSetEditable(w_data->context, widget, FALSE);
  7817.         }
  7818.     }
  7819. }
  7820.  
  7821. static void
  7822. fe_document_advanced_new_cb(Widget widget, XtPointer closure,
  7823.                                     XtPointer cb_data)
  7824. {
  7825.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7826.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7827.     w_data->item_is_new = TRUE;
  7828.     w_data->item_is_dirty = FALSE;
  7829.  
  7830.     fe_DependentListCallDependents(widget,
  7831.                                    w_data->dependents,
  7832.                                    DOCUMENT_ADVANCED_SELECTION,
  7833.                                    closure);
  7834. }
  7835.  
  7836. #if 0
  7837. static void
  7838. fe_document_advanced_new_update_cb(Widget widget, XtPointer closure,
  7839.                                     XtPointer cb_data)
  7840. {
  7841.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7842.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7843.     Boolean sensitive = (w_data->item_is_new == FALSE);
  7844.     
  7845.     XtVaSetValues(widget, XmNsensitive, sensitive, 0);
  7846. }
  7847. #endif
  7848.  
  7849. static void
  7850. list_set_item(fe_NameValueItemList* active_list, unsigned index,
  7851.                 char* name, char* value)
  7852. {
  7853.     unsigned size;
  7854.  
  7855.     if (active_list == NULL) /* this should be error */
  7856.         return;
  7857.  
  7858.     if (index == active_list->nitems)
  7859.         active_list->nitems++;
  7860.  
  7861.     if (active_list->nitems > active_list->size) {
  7862.  
  7863.         active_list->size = active_list->nitems;
  7864.         size = sizeof(fe_NameValueItem) * (active_list->size+1);
  7865.         if (active_list->size == 0)
  7866.             active_list->items = (fe_NameValueItem*)XtMalloc(size);
  7867.         else
  7868.             active_list->items = (fe_NameValueItem*)XtRealloc((void*)active_list->items,
  7869.                                                      size);
  7870.  
  7871.         active_list->items[active_list->nitems].name = NULL;
  7872.         active_list->items[active_list->nitems].value = NULL;
  7873.     }
  7874.  
  7875.     if (active_list->items[index].name != NULL)
  7876.         XtFree(active_list->items[index].name);
  7877.     if (active_list->items[index].value != NULL)
  7878.         XtFree(active_list->items[index].value);
  7879.  
  7880.     active_list->items[index].name = XtNewString(name);
  7881.     if (value)
  7882.         active_list->items[index].value = XtNewString(value);
  7883.     else
  7884.         active_list->items[index].value = NULL;
  7885.     active_list->is_dirty = TRUE;
  7886. }
  7887.  
  7888. static void
  7889. list_delete_item(fe_NameValueItemList* active_list, unsigned index)
  7890. {
  7891.  
  7892.     if (active_list == NULL) /* this should be error */
  7893.         return;
  7894.  
  7895.     if (active_list->items[index].name)
  7896.         XtFree(active_list->items[index].name);
  7897.     if (active_list->items[index].value)
  7898.         XtFree(active_list->items[index].value);
  7899.     
  7900.     active_list->nitems--;
  7901.     if (index < active_list->nitems) {
  7902.         memcpy(&active_list->items[index], &active_list->items[index+1],
  7903.                (sizeof(fe_NameValueItem) * (active_list->nitems - index)));
  7904.     }
  7905.     active_list->items[active_list->nitems].name = NULL;
  7906.     active_list->items[active_list->nitems].value = NULL;
  7907.     active_list->is_dirty = TRUE;
  7908. }
  7909.  
  7910. static void
  7911. fe_document_advanced_delete_cb(Widget widget, XtPointer closure,
  7912.                                     XtPointer cb_data)
  7913. {
  7914.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7915.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7916.     fe_NameValueItemList* active_list = w_data->active_list;
  7917.  
  7918.     if (active_list == NULL || active_list->selected_item == NOTHING_SELECTED)
  7919.         return;
  7920.  
  7921.     list_delete_item(active_list, active_list->selected_item);
  7922.     if (active_list->selected_item > 0)
  7923.         active_list->selected_item--;
  7924.     
  7925.     w_data->item_is_dirty = w_data->item_is_new = FALSE;
  7926.       
  7927.     fe_DependentListCallDependents(widget,
  7928.                                    w_data->dependents,
  7929.                                    w_data->active_list->mask,
  7930.                                    closure);
  7931.     w_data->changed |= w_data->active_list->mask;
  7932. }
  7933.  
  7934. static void
  7935. fe_document_advanced_delete_update_cb(Widget widget, XtPointer closure,
  7936.                                     XtPointer cb_data)
  7937. {
  7938.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7939.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7940.     Boolean sensitive =
  7941.         (w_data->item_is_new == FALSE) &&
  7942.         (w_data->active_list != NULL) &&
  7943.         (w_data->active_list->selected_item != NOTHING_SELECTED);
  7944.     
  7945.     XtVaSetValues(widget, XmNsensitive, sensitive, 0);
  7946. }
  7947.  
  7948. static void
  7949. fe_document_advanced_set_cb(Widget widget, XtPointer closure,
  7950.                                     XtPointer cb_data)
  7951. {
  7952.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7953.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7954.     char* name;
  7955.     char* value;
  7956.  
  7957.     if (w_data->active_list == NULL)
  7958.         return;
  7959.  
  7960.     name = fe_TextFieldGetString(w_data->name_text);
  7961.     value = fe_TextFieldGetString(w_data->value_text);
  7962.  
  7963.     if (w_data->item_is_new)
  7964.         w_data->active_list->selected_item = w_data->active_list->nitems;
  7965.  
  7966.     list_set_item(w_data->active_list, w_data->active_list->selected_item,
  7967.                   name, value);
  7968.  
  7969.     XtFree(name);
  7970.     XtFree(value);
  7971.  
  7972.     w_data->item_is_new = FALSE;
  7973.     w_data->item_is_dirty = FALSE;
  7974.  
  7975.     fe_DependentListCallDependents(widget,
  7976.                                    w_data->dependents,
  7977.                                    w_data->active_list->mask,
  7978.                                    closure);
  7979.     w_data->changed |= w_data->active_list->mask;
  7980. }
  7981.  
  7982. static void
  7983. fe_document_advanced_set_update_cb(Widget widget, XtPointer closure,
  7984.                                     XtPointer cb_data)
  7985. {
  7986.     fe_EditorDocumentAdvancedPropertiesStruct* w_data = 
  7987.       (fe_EditorDocumentAdvancedPropertiesStruct*)closure;
  7988.     Boolean sensitive = (w_data->item_is_dirty);
  7989.     
  7990.     XtVaSetValues(widget, XmNsensitive, sensitive, 0);
  7991. }
  7992.  
  7993. static void
  7994. fe_document_advanced_init(MWContext* context,
  7995.                           fe_EditorDocumentAdvancedPropertiesStruct* w_data)
  7996. {
  7997.     int i;
  7998.     fe_NameValueItem* list;
  7999.  
  8000.     list = fe_EditorDocumentGetHttpEquivMetaDataList(context);
  8001.     w_data->system_list.items = list;
  8002.     for (i = 0; list[i].name != NULL; i++)
  8003.         ;
  8004.     w_data->system_list.nitems = i;
  8005.     w_data->system_list.size = i;
  8006.     w_data->system_list.is_dirty = TRUE;
  8007.     w_data->system_list.selected_item = NOTHING_SELECTED;
  8008.     w_data->system_list.mask = DOCUMENT_ADVANCED_HTTP_LIST;
  8009.     
  8010.     list = fe_EditorDocumentGetAdvancedMetaDataList(context);
  8011.     w_data->user_list.items = list;
  8012.     for (i = 0; list[i].name != NULL; i++)
  8013.         ;
  8014.     w_data->user_list.nitems = i;
  8015.     w_data->user_list.size = i;
  8016.     w_data->user_list.is_dirty = TRUE;
  8017.     w_data->user_list.selected_item = NOTHING_SELECTED;
  8018.     w_data->user_list.mask = DOCUMENT_ADVANCED_META_LIST;
  8019.  
  8020.     fe_DependentListCallDependents(NULL,
  8021.                                    w_data->dependents,
  8022.                                    ~0,
  8023.                                    (XtPointer)w_data);
  8024. }
  8025.  
  8026. static void
  8027. fe_document_advanced_set(MWContext* context,
  8028.                           fe_EditorDocumentAdvancedPropertiesStruct* w_data)
  8029. {
  8030.     if ((w_data->changed & DOCUMENT_ADVANCED_HTTP_LIST) != 0) {
  8031.         fe_EditorDocumentSetHttpEquivMetaDataList(context,
  8032.                                                   w_data->system_list.items);
  8033.     }
  8034.  
  8035.     if ((w_data->changed & DOCUMENT_ADVANCED_META_LIST) != 0) {
  8036.         fe_EditorDocumentSetAdvancedMetaDataList(context,
  8037.                                                  w_data->user_list.items);
  8038.     }
  8039. }
  8040.  
  8041. static Widget
  8042. fe_document_advanced_create(
  8043.                           MWContext* context,
  8044.                           Widget parent,
  8045.                           fe_EditorDocumentAdvancedPropertiesStruct* w_data)
  8046. {
  8047.     Widget form;
  8048.     Widget system_label;
  8049.     Widget system_list;
  8050.     Widget user_label;
  8051.     Widget user_list;
  8052.     Widget name_label;
  8053.     Widget name_text;
  8054.     Widget name_new;
  8055.     Widget name_set;
  8056.     Widget value_label;
  8057.     Widget value_text;
  8058.     Widget name_delete;
  8059.     Widget list_parent;
  8060.     Widget fat_guy;
  8061.     Dimension left_offset;
  8062.     Arg args[16];
  8063.     Cardinal n;
  8064.     Widget children[12];
  8065.     Cardinal nchildren;
  8066.     Dimension width;
  8067.  
  8068. #if 1
  8069.     form = parent;
  8070. #else
  8071.     n = 0;
  8072.     form = XmCreateForm(parent, "advanced", args, n);
  8073.     XtManageChild(form);
  8074. #endif
  8075.  
  8076.     nchildren = 0;
  8077.     n = 0;
  8078.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  8079.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8080.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  8081.     system_label = XmCreateLabelGadget(form, "systemLabel", args, n);
  8082.     children[nchildren++] = system_label;
  8083.  
  8084. #define SCROLLED_LIST_SIZE 5
  8085.     n = 0;
  8086.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8087.     XtSetArg(args[n], XmNtopWidget, system_label); n++;
  8088.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8089.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  8090.     XtSetArg(args[n], XmNvisibleItemCount, SCROLLED_LIST_SIZE); n++;
  8091.     XtSetArg(args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
  8092.     XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); n++;
  8093.     system_list = XmCreateScrolledList(form, "systemList", args, n);
  8094.     XtManageChild(system_list);
  8095.     children[nchildren++] = list_parent = XtParent(system_list);
  8096.     
  8097.     n = 0;
  8098.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8099.     XtSetArg(args[n], XmNtopWidget, list_parent); n++;
  8100.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8101.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  8102.     user_label = XmCreateLabelGadget(form, "userLabel", args, n);
  8103.     children[nchildren++] = user_label;
  8104.  
  8105.     n = 0;
  8106.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8107.     XtSetArg(args[n], XmNtopWidget, user_label); n++;
  8108.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8109.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  8110.     XtSetArg(args[n], XmNvisibleItemCount, SCROLLED_LIST_SIZE); n++;
  8111.     XtSetArg(args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
  8112.     XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); n++;
  8113.     user_list = XmCreateScrolledList(form, "userList", args, n);
  8114.     XtManageChild(user_list);
  8115.     children[nchildren++] = list_parent = XtParent(user_list);
  8116.  
  8117.     n = 0;
  8118.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8119.     XtSetArg(args[n], XmNtopWidget, list_parent); n++;
  8120.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8121.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  8122.     name_label = XmCreateLabelGadget(form, "nameLabel", args, n);
  8123.     children[nchildren++] = name_label;
  8124.  
  8125.     n = 0;
  8126.     value_label = XmCreateLabelGadget(form, "valueLabel", args, n);
  8127.     children[nchildren++] = value_label;
  8128.  
  8129.     left_offset = fe_get_offset_from_widest(&children[nchildren-2], 2);
  8130.  
  8131.     n = 0;
  8132.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8133.     XtSetArg(args[n], XmNtopWidget, list_parent); n++;
  8134.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  8135.     name_new = XmCreatePushButtonGadget(form, "new", args, n);
  8136.     children[nchildren++] = name_new;
  8137.  
  8138.     n = 0;
  8139.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8140.     XtSetArg(args[n], XmNtopWidget, list_parent); n++;
  8141.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  8142.     XtSetArg(args[n], XmNrightWidget, name_new); n++;
  8143.     name_delete = XmCreatePushButtonGadget(form, "delete", args, n);
  8144.     children[nchildren++] = name_delete;
  8145.  
  8146.     n = 0;
  8147.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8148.     XtSetArg(args[n], XmNtopWidget, list_parent); n++;
  8149.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8150.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  8151.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  8152.     XtSetArg(args[n], XmNrightWidget, name_delete); n++;
  8153.     name_text = fe_CreateTextField(form, "nameText", args, n);
  8154.     children[nchildren++] = name_text;
  8155.  
  8156.     n = 0;
  8157.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8158.     XtSetArg(args[n], XmNtopWidget, name_text); n++;
  8159.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8160.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  8161.     XtSetValues(value_label, args, n);
  8162.  
  8163.     n = 0;
  8164.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8165.     XtSetArg(args[n], XmNtopWidget, name_text); n++;
  8166.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  8167.     name_set = XmCreatePushButtonGadget(form, "set", args, n);
  8168.     children[nchildren++] = name_set;
  8169.  
  8170.     n = 0;
  8171.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8172.     XtSetArg(args[n], XmNtopWidget, name_text); n++;
  8173.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8174.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  8175.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  8176.     XtSetArg(args[n], XmNrightWidget, name_set); n++;
  8177.     value_text = fe_CreateTextField(form, "valueText", args, n);
  8178.     children[nchildren++] = value_text;
  8179.  
  8180.     XtManageChildren(children, nchildren);
  8181.  
  8182.     nchildren = 0;
  8183.     children[nchildren++] = name_new;
  8184.     children[nchildren++] = name_delete;
  8185.     children[nchildren++] = name_set;
  8186.     fat_guy = XfeBiggestWidget(TRUE, children, nchildren);
  8187.  
  8188.     XtVaGetValues(fat_guy, XmNwidth, &width, 0);
  8189.     for (n = 0; n < nchildren; n++) {
  8190.         XtVaSetValues(children[n], XmNwidth, width, 0);
  8191.     }
  8192.  
  8193.     XtAddCallback(system_list, XmNsingleSelectionCallback,
  8194.                   fe_document_advanced_list_cb, (XtPointer)w_data);
  8195.     fe_DependentListAddDependent(&w_data->dependents,
  8196.                                  system_list,
  8197.                                  (DOCUMENT_ADVANCED_SELECTION|DOCUMENT_ADVANCED_HTTP_LIST),
  8198.                                  fe_document_advanced_list_update_cb,
  8199.                                  (XtPointer)w_data);
  8200.     XtInsertEventHandler(system_list, ButtonPressMask, False, 
  8201.                          fe_document_advanced_tell_me_eh, (XtPointer)w_data,
  8202.                          XtListTail);
  8203.  
  8204.     XtAddCallback(user_list, XmNsingleSelectionCallback,
  8205.                   fe_document_advanced_list_cb, (XtPointer)w_data);
  8206.     fe_DependentListAddDependent(&w_data->dependents,
  8207.                                  user_list,
  8208.                                  (DOCUMENT_ADVANCED_SELECTION|DOCUMENT_ADVANCED_META_LIST),
  8209.                                  fe_document_advanced_list_update_cb,
  8210.                                  (XtPointer)w_data);
  8211.     XtInsertEventHandler(user_list, ButtonPressMask, False, 
  8212.                          fe_document_advanced_tell_me_eh, (XtPointer)w_data,
  8213.                          XtListTail);
  8214.  
  8215.     XtAddCallback(name_text, XmNvalueChangedCallback,
  8216.                   fe_document_advanced_value_cb, (XtPointer)w_data);
  8217.     fe_DependentListAddDependent(&w_data->dependents,
  8218.                          name_text,
  8219.                          (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_SELECTION),
  8220.                          fe_document_advanced_name_update_cb,
  8221.                          (XtPointer)w_data);
  8222.  
  8223.     XtAddCallback(value_text, XmNvalueChangedCallback,
  8224.                   fe_document_advanced_value_cb, (XtPointer)w_data);
  8225.     fe_DependentListAddDependent(&w_data->dependents,
  8226.                          value_text,
  8227.                          (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_SELECTION),
  8228.                          fe_document_advanced_value_update_cb,
  8229.                          (XtPointer)w_data);
  8230.  
  8231.     XtAddCallback(name_new, XmNactivateCallback,
  8232.                   fe_document_advanced_new_cb,(XtPointer)w_data);
  8233. #if 0
  8234.     fe_DependentListAddDependent(&w_data->dependents,
  8235.                          name_new,
  8236.                          (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_SELECTION),
  8237.                          fe_document_advanced_new_update_cb,
  8238.                          (XtPointer)w_data);
  8239. #endif
  8240.  
  8241.     XtAddCallback(name_delete, XmNactivateCallback,
  8242.                   fe_document_advanced_delete_cb,(XtPointer)w_data);
  8243.     fe_DependentListAddDependent(&w_data->dependents,
  8244.                          name_delete,
  8245.                          (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_SELECTION),
  8246.                          fe_document_advanced_delete_update_cb,
  8247.                          (XtPointer)w_data);
  8248.  
  8249.     XtAddCallback(name_set, XmNactivateCallback,
  8250.                   fe_document_advanced_set_cb,(XtPointer)w_data);
  8251.     fe_DependentListAddDependent(&w_data->dependents,
  8252.                          name_set,
  8253.                          (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_ITEM
  8254.                           |DOCUMENT_ADVANCED_SELECTION),
  8255.                          fe_document_advanced_set_update_cb,
  8256.                          (XtPointer)w_data);
  8257.     w_data->name_text = name_text;
  8258.     w_data->value_text = value_text;
  8259.     w_data->system_list.widget = system_list;
  8260.     w_data->user_list.widget = user_list;
  8261.     w_data->context = context;
  8262.  
  8263.     return form;
  8264. }
  8265.  
  8266. typedef struct fe_EditorDocumentPropertiesStruct
  8267. {
  8268.   MWContext* context;
  8269.   fe_EditorDocumentAppearancePropertiesStruct* appearance;
  8270.   fe_EditorDocumentGeneralPropertiesStruct*    general;
  8271.   fe_EditorDocumentAdvancedPropertiesStruct*   advanced;
  8272. } fe_EditorDocumentPropertiesStruct;
  8273.  
  8274. static Widget
  8275. fe_EditorDocumentPropertiesCreate(MWContext* context,
  8276.                                   fe_EditorDocumentPropertiesStruct* p_data)
  8277. {
  8278.     Widget   dialog;
  8279.     Widget   form;
  8280.     Widget   tab_form;
  8281.     char*    name = "documentPropertiesDialog";
  8282.     Arg      args[8];
  8283.     Cardinal n;
  8284.     
  8285.     /*
  8286.      *    Make prompt with ok, apply, cancel, no separator.
  8287.      */
  8288.     dialog = fe_CreatePromptDialog(context, name,
  8289.                                    TRUE, TRUE, TRUE, FALSE, TRUE);
  8290.  
  8291.     form = XtVaCreateManagedWidget(
  8292.                                    "folder",
  8293.                                    xmlFolderWidgetClass, dialog,
  8294.                                    XmNshadowThickness, 2,
  8295.                                    XmNtopAttachment, XmATTACH_FORM,
  8296.                                    XmNleftAttachment, XmATTACH_FORM,
  8297.                                    XmNrightAttachment, XmATTACH_FORM,
  8298.                                    XmNbottomAttachment, XmATTACH_FORM,
  8299. #ifdef ALLOW_TAB_ROTATE
  8300.                                    XmNtabPlacement, XmFOLDER_LEFT,
  8301.                                    XmNrotateWhenLeftRight, FALSE,
  8302. #endif /* ALLOW_TAB_ROTATE */
  8303.                                    XmNbottomOffset, 3,
  8304.                                    XmNspacing, 1,
  8305.                                    NULL);
  8306.  
  8307.     n = 0;
  8308.     tab_form = fe_CreateTabForm(form, "appearanceProperties", args, n);
  8309.     fe_document_appearance_create(context, tab_form, p_data->appearance);
  8310.     
  8311.     tab_form = fe_CreateTabForm(form, "generalProperties", args, n);
  8312.     fe_document_general_create(context, tab_form, p_data->general);
  8313.  
  8314.     tab_form = fe_CreateTabForm(form, "advanced", args, n);
  8315.     fe_document_advanced_create(context, tab_form, p_data->advanced);
  8316.  
  8317.     XtManageChild(dialog);
  8318.  
  8319.     return form;
  8320. }
  8321.  
  8322. void
  8323. fe_EditorDocumentPropertiesDialogDo(MWContext* context, 
  8324.                               fe_EditorDocumentPropertiesDialogType tab_type)
  8325. {
  8326.     fe_EditorDocumentPropertiesStruct properties;
  8327.     fe_EditorDocumentAppearancePropertiesStruct appearance;
  8328.     fe_EditorDocumentGeneralPropertiesStruct general;
  8329.     fe_EditorDocumentAdvancedPropertiesStruct advanced;
  8330.     int done;
  8331.     Widget dialog;
  8332.     Widget form;
  8333.     Widget apply_button;
  8334.     Boolean apply_sensitized;
  8335.     unsigned tab_number;
  8336.     Boolean  three_tabs = (context->type == MWContextEditor); /* hack */
  8337.  
  8338.     /*
  8339.      *    Pick the tab.
  8340.      */
  8341.     tab_number = tab_type - 1;
  8342.  
  8343.     memset(&properties, 0, sizeof(fe_EditorDocumentPropertiesStruct));
  8344.     memset(&appearance, 0,
  8345.            sizeof(fe_EditorDocumentAppearancePropertiesStruct));
  8346.     memset(&general, 0, sizeof(fe_EditorDocumentGeneralPropertiesStruct));
  8347.     memset(&advanced, 0, sizeof(fe_EditorDocumentAdvancedPropertiesStruct));
  8348.  
  8349.     properties.appearance = &appearance;
  8350.     properties.general = &general;
  8351.     properties.advanced = &advanced;
  8352.  
  8353.     properties.context = context;
  8354.     if (three_tabs) {
  8355.         form = fe_EditorDocumentPropertiesCreate(context, &properties);
  8356.         fe_document_appearance_init(context, &appearance);
  8357.         fe_document_general_init(context, &general);
  8358.         fe_document_advanced_init(context, &advanced);
  8359.         XmLFolderSetActiveTab(form, tab_number, True);
  8360.         dialog = XtParent(form);
  8361.     } else {
  8362.         /*
  8363.          *    Make prompt with ok, apply, cancel, no separator.
  8364.          */
  8365.         dialog = fe_CreatePromptDialog(context, "documentPropertiesDialog",
  8366.                                        TRUE, TRUE, TRUE, TRUE, TRUE);
  8367.  
  8368.         form = XmCreateForm(dialog, "appearanceProperties", NULL, 0);
  8369.         XtManageChild(form);
  8370.         fe_document_appearance_create(context, form,  &appearance);
  8371.         XtManageChild(dialog);
  8372.         fe_document_appearance_init(context, &appearance);
  8373.         form = dialog;
  8374.     }
  8375.  
  8376.     /*
  8377.      *    Initialize.
  8378.      */
  8379. #if 0
  8380.     fe_DependentListCallDependents(NULL, properties.dependents,
  8381.                                    ~0, (XtPointer)&properties);
  8382. #endif
  8383.  
  8384.     /*
  8385.      *   Add a bunch of callbacks to the buttons.
  8386.      */
  8387.     XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done);
  8388.     XtAddCallback(dialog, XmNapplyCallback, fe_hrule_apply_cb, &done);
  8389.     XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  8390.     XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  8391.  
  8392.     /*
  8393.      *    We toggle the sensitivity of the apply button on/off
  8394.      *    depending if there are changes to apply. It would be
  8395.      *    nice to use the depdency meahcnism, but it might get
  8396.      *    very busy.
  8397.      */
  8398.     apply_button = XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON);
  8399.     XtVaSetValues(apply_button, XmNsensitive, FALSE, 0);
  8400.     apply_sensitized = FALSE;
  8401.  
  8402.     /*
  8403.      *    Popup.
  8404.      */
  8405.     XtManageChild(form);
  8406.  
  8407.     /*
  8408.      *    Wait.
  8409.      */
  8410.     fe_NukeBackingStore(dialog); /* what does this do? */
  8411.  
  8412.     done = XmDIALOG_NONE;
  8413.     while (done == XmDIALOG_NONE) {
  8414.  
  8415.         fe_EventLoop();
  8416.  
  8417.         if (done == XFE_DIALOG_DESTROY_BUTTON||done == XmDIALOG_CANCEL_BUTTON)
  8418.             break;
  8419.  
  8420. #define SOMETHING_CHANGED() \
  8421. (appearance.changed != 0 || general.changed != 0 || advanced.changed != 0)
  8422.  
  8423.         if (SOMETHING_CHANGED() && apply_sensitized == FALSE) {
  8424.             XtVaSetValues(apply_button, XmNsensitive, TRUE, 0);
  8425.             apply_sensitized = TRUE;
  8426.         }
  8427.  
  8428.         if (done == XmDIALOG_APPLY_BUTTON || done == XmDIALOG_OK_BUTTON) {
  8429.             /* apply */
  8430.  
  8431.             if (SOMETHING_CHANGED()) {
  8432.  
  8433.                 EDT_BeginBatchChanges(context);
  8434.  
  8435.                 if (appearance.changed != 0) {
  8436.                     fe_document_appearance_set(context, &appearance);
  8437.                     appearance.changed = 0;
  8438.                 }
  8439.                 if (general.changed != 0) {
  8440.                     fe_document_general_set(context, &general);
  8441.                     general.changed = 0;
  8442.                 }
  8443.                 if (advanced.changed != 0) {
  8444.                     fe_document_advanced_set(context, &advanced);
  8445.                     advanced.changed = 0;
  8446.                 }
  8447.  
  8448.                 EDT_EndBatchChanges(context);
  8449.             }
  8450.  
  8451.             if (done == XmDIALOG_APPLY_BUTTON) {
  8452.                 done = XmDIALOG_NONE; /* keep looping */
  8453.  
  8454.                 XtVaSetValues(apply_button, XmNsensitive, FALSE, 0);
  8455.                 apply_sensitized = FALSE;
  8456.             }
  8457.         }
  8458.     }
  8459. #undef SOMETHING_CHANGED
  8460.  
  8461.     /*
  8462.      *    Unload data.
  8463.      */
  8464.     fe_DependentListDestroy(appearance.dependents);
  8465.  
  8466.     if (done != XFE_DIALOG_DESTROY_BUTTON)
  8467.         XtDestroyWidget(dialog);
  8468. }
  8469.  
  8470. typedef struct fe_EditorGeneralPreferencesStruct
  8471. {
  8472.     MWContext* context;
  8473.  
  8474.     Widget author;
  8475.     Widget html_editor;
  8476.     Widget image_editor;
  8477.     Widget template;
  8478.     Widget autosave_toggle;
  8479.     Widget autosave_text;
  8480.  
  8481.     unsigned changed;
  8482.     
  8483. } fe_EditorGeneralPreferencesStruct;
  8484.  
  8485. #define EDITOR_GENERAL_AUTHOR          (0x1<<0)
  8486. #define EDITOR_GENERAL_HTML_EDITOR     (0x1<<1)
  8487. #define EDITOR_GENERAL_IMAGE_EDITOR    (0x1<<2)
  8488. #define EDITOR_GENERAL_TEMPLATE        (0x1<<3)
  8489. #define EDITOR_GENERAL_AUTOSAVE        (0x1<<4)
  8490.  
  8491. static void
  8492. fe_general_preferences_restore_template_cb(Widget widget,
  8493.                                XtPointer closure, XtPointer call_data)
  8494. {
  8495.     char* value;
  8496.     fe_EditorGeneralPreferencesStruct* w_data
  8497.         = (fe_EditorGeneralPreferencesStruct*)closure;
  8498.  
  8499.     /* get the template */
  8500.     if ((value = fe_EditorDefaultGetTemplate()) == NULL)
  8501.         value = "";
  8502.  
  8503.     fe_SetTextFieldAndCallBack(w_data->template, value);
  8504.  
  8505.     w_data->changed |= EDITOR_GENERAL_TEMPLATE;
  8506. }
  8507.  
  8508. static void
  8509. fe_general_preferences_changed_cb(Widget widget,
  8510.                                XtPointer closure, XtPointer call_data)
  8511. {
  8512.     fe_EditorGeneralPreferencesStruct* w_data
  8513.         = (fe_EditorGeneralPreferencesStruct*)closure;
  8514.     unsigned mask = (unsigned)fe_GetUserData(widget);
  8515.  
  8516.     w_data->changed |= mask;
  8517. }
  8518.  
  8519. static void
  8520. fe_general_preferences_autosave_toggle_cb(Widget widget,
  8521.                                XtPointer closure, XtPointer call_data)
  8522. {
  8523.     fe_EditorGeneralPreferencesStruct* w_data
  8524.         = (fe_EditorGeneralPreferencesStruct*)closure;
  8525.     XmToggleButtonCallbackStruct* cb
  8526.         = (XmToggleButtonCallbackStruct*)call_data;
  8527.  
  8528.     fe_TextFieldSetEditable(w_data->context, w_data->autosave_text, cb->set);
  8529.     w_data->changed |= EDITOR_GENERAL_AUTOSAVE;
  8530. }
  8531.  
  8532. static void
  8533. fe_general_preferences_init(MWContext* context,
  8534.                          fe_EditorGeneralPreferencesStruct* w_data)
  8535. {
  8536.     char* value;
  8537.     char* value2;
  8538.     Boolean as_enable;
  8539.     unsigned as_time;
  8540.  
  8541.     /* get the author */
  8542.     if ((value = fe_EditorPreferencesGetAuthor(context)) != NULL)
  8543.         fe_SetTextFieldAndCallBack(w_data->author, value);
  8544.  
  8545.     /* get the editors */
  8546.     fe_EditorPreferencesGetEditors(context, &value, &value2);
  8547.     if (value != NULL)
  8548.         fe_SetTextFieldAndCallBack(w_data->html_editor, value);
  8549.  
  8550.     if (value2 != NULL)
  8551.         fe_SetTextFieldAndCallBack(w_data->image_editor, value2);
  8552.  
  8553.     /* get the template */
  8554.     if ((value = fe_EditorPreferencesGetTemplate(context)))
  8555.         fe_SetTextFieldAndCallBack(w_data->template, value);
  8556.  
  8557.     /* get the autosave state */
  8558.     fe_EditorPreferencesGetAutoSave(context, &as_enable, &as_time);
  8559.     if (!as_enable)
  8560.         as_time = 10;
  8561.     
  8562.     fe_set_numeric_text_field(w_data->autosave_text, as_time);
  8563.     fe_TextFieldSetEditable(context, w_data->autosave_text, as_enable);
  8564.     XmToggleButtonGadgetSetState(w_data->autosave_toggle, as_enable, FALSE);
  8565.  
  8566.     w_data->context = context;
  8567.     w_data->changed = 0;
  8568. }
  8569.  
  8570. static Boolean
  8571. fe_general_preferences_validate(MWContext* context,
  8572.                         fe_EditorGeneralPreferencesStruct* w_data)
  8573. {
  8574.     Boolean as_enable;
  8575.     int as_time;
  8576.  
  8577.     /* autosave */
  8578.     if ((w_data->changed & EDITOR_GENERAL_AUTOSAVE) != 0) {
  8579.         as_time = fe_get_numeric_text_field(w_data->autosave_text);
  8580.         as_enable = XmToggleButtonGadgetGetState(w_data->autosave_toggle);
  8581.         
  8582.         if (as_time == 0)
  8583.             as_enable = FALSE;
  8584.         
  8585.         if (as_enable) {
  8586.             if (RANGE_CHECK(as_time,AUTOSAVE_MIN_PERIOD,AUTOSAVE_MAX_PERIOD)) {
  8587.                 char* msg = XP_GetString(XFE_EDITOR_AUTOSAVE_PERIOD_RANGE);
  8588.                 fe_error_dialog(context, w_data->autosave_text, msg);
  8589.                 return FALSE;
  8590.             }
  8591.         }
  8592.     }
  8593.     return TRUE;
  8594. }
  8595.  
  8596. static void
  8597. fe_general_preferences_set(MWContext* context,
  8598.                         fe_EditorGeneralPreferencesStruct* w_data)
  8599. {
  8600.     char* value;
  8601.     Boolean as_enable;
  8602.     unsigned as_time;
  8603.  
  8604.     /* author */
  8605.     if ((w_data->changed & EDITOR_GENERAL_AUTHOR) != 0) {
  8606.         value = fe_TextFieldGetString(w_data->author);
  8607.         fe_EditorPreferencesSetAuthor(context, value);
  8608.         XtFree(value);
  8609.     }
  8610.     
  8611.     /* editors */
  8612.     value = NULL;
  8613.     if ((w_data->changed & EDITOR_GENERAL_HTML_EDITOR) != 0) {
  8614.         value = fe_TextFieldGetString(w_data->html_editor);
  8615.         fe_EditorPreferencesSetEditors(context, value, NULL);
  8616.         XtFree(value);
  8617.     }
  8618.  
  8619.     if ((w_data->changed & EDITOR_GENERAL_IMAGE_EDITOR) != 0) {
  8620.         value = fe_TextFieldGetString(w_data->image_editor);
  8621.         fe_EditorPreferencesSetEditors(context, NULL, value);
  8622.         XtFree(value);
  8623.     }
  8624.  
  8625.     /* template */
  8626.     if ((w_data->changed & EDITOR_GENERAL_TEMPLATE) != 0) {
  8627.         value = fe_TextFieldGetString(w_data->template);
  8628.         fe_EditorPreferencesSetTemplate(context, value);
  8629.         XtFree(value);
  8630.     }
  8631.  
  8632.     /* autosave */
  8633.     if ((w_data->changed & EDITOR_GENERAL_AUTOSAVE) != 0) {
  8634.         as_time = fe_get_numeric_text_field(w_data->autosave_text);
  8635.         as_enable = XmToggleButtonGadgetGetState(w_data->autosave_toggle);
  8636.         fe_EditorPreferencesSetAutoSave(context, as_enable, as_time);
  8637.     }
  8638.  
  8639.     w_data->changed = 0;
  8640. }
  8641.  
  8642. static Widget
  8643. fe_general_preferences_create(MWContext* context, Widget parent,
  8644.                              fe_EditorGeneralPreferencesStruct* w_data)
  8645. {
  8646.     Widget main_rc;
  8647.     Widget author_frame;
  8648.     Widget author_text;
  8649.     Widget external_frame;
  8650.     Widget external_form;
  8651.     Widget html_label;
  8652.     Widget html_text;
  8653.     Widget html_browse;
  8654.     Widget image_label;
  8655.     Widget image_text;
  8656.     Widget image_browse;
  8657.     Widget template_frame;
  8658.     Widget template_form;
  8659.     Widget template_label;
  8660.     Widget template_text;
  8661.     Widget template_info_label;
  8662.     Widget template_restore;
  8663.     Widget autosave_frame;
  8664.     Widget autosave_form;
  8665.     Widget autosave_toggle;
  8666.     Widget autosave_text;
  8667.     Widget autosave_label;
  8668.     Widget children[8];
  8669.     Cardinal nchildren;
  8670.     Dimension left_offset;
  8671.     Dimension right_offset;
  8672.     Arg    args[8];
  8673.     Cardinal n;
  8674.     Cardinal i;
  8675.  
  8676.     n = 0;
  8677.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  8678.     main_rc = XmCreateRowColumn(parent, "general", args, n);
  8679.     XtManageChild(main_rc);
  8680.  
  8681.     n = 0;
  8682.     author_frame = fe_CreateFrame(main_rc, "author", args, n);
  8683.     XtManageChild(author_frame);
  8684.  
  8685.     n = 0;
  8686.     XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_AUTHOR); n++;
  8687.     author_text = fe_CreateTextField(author_frame, "authorText", args, n);
  8688.     XtManageChild(author_text);
  8689.     w_data->author = author_text;
  8690.  
  8691.     XtAddCallback(author_text, XmNvalueChangedCallback,
  8692.                   fe_general_preferences_changed_cb, (XtPointer)w_data);
  8693.  
  8694.     n = 0;
  8695.     external_frame = fe_CreateFrame(main_rc, "external", args, n);
  8696.     XtManageChild(external_frame);
  8697.  
  8698.     n = 0;
  8699.     external_form = XmCreateForm(external_frame, "external", args, n);
  8700.     XtManageChild(external_form);
  8701.  
  8702.     nchildren = 0;
  8703.     n = 0;
  8704.     html_label = XmCreateLabelGadget(external_form, "htmlLabel", args, n);
  8705.     children[nchildren++] = html_label;
  8706.  
  8707.     n = 0;
  8708.     image_label = XmCreateLabelGadget(external_form, "imageLabel", args, n);
  8709.     children[nchildren++] = image_label;
  8710.  
  8711.     left_offset = fe_get_offset_from_widest(children, nchildren);
  8712.  
  8713.     n = 0;
  8714.     html_browse = XmCreatePushButtonGadget(external_form, "browse", args, n);
  8715.     children[nchildren++] = html_browse;
  8716.  
  8717.     n = 0;
  8718.     image_browse = XmCreatePushButtonGadget(external_form, "browse", args, n);
  8719.     children[nchildren++] = image_browse;
  8720.  
  8721.     right_offset = fe_get_offset_from_widest(&children[2], 2);
  8722.  
  8723.     n = 0;
  8724.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  8725.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8726.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  8727.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  8728.     XtSetArg(args[n], XmNrightOffset, right_offset); n++;
  8729.     XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_HTML_EDITOR); n++;
  8730.     html_text = fe_CreateTextField(external_form, "htmlText", args, n);
  8731.     children[nchildren++] = html_text;
  8732.     w_data->html_editor = html_text;
  8733.  
  8734.     XtAddCallback(html_text, XmNvalueChangedCallback,
  8735.                   fe_general_preferences_changed_cb, (XtPointer)w_data);
  8736.  
  8737.     n = 0;
  8738.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8739.     XtSetArg(args[n], XmNtopWidget, html_text); n++;
  8740.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8741.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  8742.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  8743.     XtSetArg(args[n], XmNrightOffset, right_offset); n++;
  8744.     XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_IMAGE_EDITOR); n++;
  8745.     image_text = fe_CreateTextField(external_form, "imageText", args, n);
  8746.     children[nchildren++] = image_text;
  8747.     w_data->image_editor = image_text;
  8748.  
  8749.     XtAddCallback(image_text, XmNvalueChangedCallback,
  8750.                   fe_general_preferences_changed_cb, (XtPointer)w_data);
  8751.  
  8752.     /*
  8753.      *    Go back for browse callbacks
  8754.      */
  8755.     XtVaSetValues(image_browse, XmNuserData, image_text, 0);
  8756.     XtAddCallback(image_browse, XmNactivateCallback,
  8757.                   fe_browse_to_text_field_cb, (XtPointer)context);
  8758.  
  8759.     XtVaSetValues(html_browse, XmNuserData, html_text, 0);
  8760.     XtAddCallback(html_browse, XmNactivateCallback,
  8761.                   fe_browse_to_text_field_cb, (XtPointer)context);
  8762.  
  8763.  
  8764.     /*
  8765.      *    Go back and attach the labels and browse buttons.
  8766.      */
  8767.     for (i = 0; i < 4; i++) {
  8768.       n = 0;
  8769.       if ((i & 0x1) == 0) { /* even, therefore topmost of pair */
  8770.         XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  8771.       } else {
  8772.         XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8773.         XtSetArg(args[n], XmNtopWidget, html_text); n++;
  8774.       }
  8775.  
  8776.       if (i < 2) { /* label, attach to left */
  8777.         XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8778.       } else { /* button, attach to right */
  8779.         XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  8780.       }
  8781.       XtSetValues(children[i], args, n);
  8782.     }
  8783.  
  8784.     XtManageChildren(children, nchildren);
  8785.  
  8786.     n = 0;
  8787.     template_frame = fe_CreateFrame(main_rc, "template", args, n);
  8788.     XtManageChild(template_frame);
  8789.  
  8790.     n = 0;
  8791.     template_form = XmCreateForm(template_frame, "template", args, n);
  8792.     XtManageChild(template_form);
  8793.  
  8794.     nchildren = 0;
  8795.     n = 0;
  8796.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  8797.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8798.     template_label = XmCreateLabelGadget(template_form, "locationLabel",
  8799.                                          args, n);
  8800.     children[nchildren++] = template_label;
  8801.  
  8802.     n = 0;
  8803.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  8804.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  8805.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  8806.     XtSetArg(args[n], XmNleftWidget, template_label); n++;
  8807.     XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_TEMPLATE); n++;
  8808.     template_text = fe_CreateTextField(template_form, "templateText", args, n);
  8809.     children[nchildren++] = template_text;
  8810.     w_data->template = template_text;
  8811.  
  8812.     XtAddCallback(template_text, XmNvalueChangedCallback,
  8813.                   fe_general_preferences_changed_cb, (XtPointer)w_data);
  8814.  
  8815.     n = 0;
  8816.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8817.     XtSetArg(args[n], XmNtopWidget, template_text); n++;
  8818.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  8819.     template_restore = XmCreatePushButtonGadget(template_form,
  8820.                                                 "restoreDefault", args, n);
  8821.     children[nchildren++] = template_restore;
  8822.  
  8823.     n = 0;
  8824.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  8825.     XtSetArg(args[n], XmNtopWidget, template_text); n++;
  8826.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8827.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  8828.     XtSetArg(args[n], XmNrightWidget, template_restore); n++;
  8829.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  8830.     template_info_label = XmCreateLabelGadget(template_form, "templateInfo",
  8831.                                          args, n);
  8832.     children[nchildren++] = template_info_label;
  8833.  
  8834.     XtAddCallback(template_restore, XmNactivateCallback,
  8835.                   fe_general_preferences_restore_template_cb,
  8836.                   (XtPointer)w_data);
  8837.  
  8838.     XtManageChildren(children, nchildren);
  8839.  
  8840.     /*
  8841.      *    Auto Save.
  8842.      */
  8843.     n = 0;
  8844.     autosave_frame = fe_CreateFrame(main_rc, "autosave", args, n);
  8845.     XtManageChild(autosave_frame);
  8846.  
  8847.     n = 0;
  8848.     autosave_form = XmCreateForm(autosave_frame, "autosave", args, n);
  8849.     XtManageChild(autosave_form);
  8850.  
  8851.     nchildren = 0;
  8852.     n = 0;
  8853.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  8854.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  8855.     XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
  8856.     autosave_toggle = XmCreateToggleButtonGadget(autosave_form, 
  8857.                                                  "autosaveEnable", args, n);
  8858.     children[nchildren++] = autosave_toggle;
  8859.  
  8860.     XtAddCallback(autosave_toggle, XmNvalueChangedCallback,
  8861.                   fe_general_preferences_autosave_toggle_cb,
  8862.                   (XtPointer)w_data);
  8863.     w_data->autosave_toggle = autosave_toggle;
  8864.  
  8865.     n = 0;
  8866.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  8867.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  8868.     XtSetArg(args[n], XmNleftWidget, autosave_toggle); n++;
  8869.     XtSetArg(args[n], XmNcolumns, 4); n++;
  8870.     XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_AUTOSAVE); n++;
  8871.     autosave_text = fe_CreateTextField(autosave_form, "autosaveText", args, n);
  8872.     children[nchildren++] = autosave_text;
  8873.  
  8874.     XtAddCallback(autosave_text, XmNvalueChangedCallback,
  8875.                   fe_general_preferences_changed_cb,
  8876.                   (XtPointer)w_data);
  8877.     w_data->autosave_text = autosave_text;
  8878.  
  8879.     n = 0;
  8880.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  8881.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  8882.     XtSetArg(args[n], XmNleftWidget, autosave_text); n++;
  8883.     autosave_label = XmCreateLabelGadget(autosave_form,    "minutes", args, n);
  8884.     children[nchildren++] = autosave_label;
  8885.  
  8886.     XtManageChildren(children, nchildren);
  8887.     
  8888.     return main_rc;
  8889. }
  8890.  
  8891. typedef struct fe_EditorPublishPreferencesStruct
  8892. {
  8893.     Widget maintain_links;
  8894.     Widget keep_images;
  8895.     Widget publish_text;
  8896.     Widget browse_text;
  8897.     Widget username_text;
  8898.     Widget password_text;
  8899.     Widget save_password;
  8900.     unsigned changed;
  8901. } fe_EditorPublishPreferencesStruct;
  8902.  
  8903. #define EDITOR_PUBLISH_LINKS           (0x1<<0)
  8904. #define EDITOR_PUBLISH_IMAGES          (0x1<<1)
  8905. #define EDITOR_PUBLISH_PUBLISH         (0x1<<2)
  8906. #define EDITOR_PUBLISH_BROWSE          (0x1<<3)
  8907. #define EDITOR_PUBLISH_USERNAME        (0x1<<4)
  8908. #define EDITOR_PUBLISH_PASSWORD        (0x1<<5)
  8909. #define EDITOR_PUBLISH_PASSWORD_SAVE   (0x1<<6)
  8910.  
  8911. static void
  8912. fe_publish_page_changed(Widget widget, XtPointer closure, XtPointer cb)
  8913. {
  8914.     fe_EditorPublishPreferencesStruct* w_data = 
  8915.         (fe_EditorPublishPreferencesStruct*)closure;
  8916.  
  8917.     w_data->changed |= (unsigned)fe_GetUserData(widget);
  8918. }
  8919.  
  8920. static void
  8921. fe_publish_password_changed(Widget widget, XtPointer closure, XtPointer cb)
  8922. {
  8923.     fe_EditorPublishPreferencesStruct* w_data = 
  8924.         (fe_EditorPublishPreferencesStruct*)closure;
  8925.  
  8926.     w_data->changed |= EDITOR_PUBLISH_PASSWORD;
  8927. }
  8928.  
  8929. static void
  8930. fe_publish_preferences_set(MWContext* context,
  8931.                            fe_EditorPublishPreferencesStruct* w_data)
  8932. {
  8933.     char* location = NULL;
  8934.     char* browse_location = NULL;
  8935.     char* username = NULL;
  8936.     char* password = NULL;
  8937.     Boolean new_links;
  8938.     Boolean new_images;
  8939.     Boolean old_links;
  8940.     Boolean old_images;
  8941.  
  8942.     new_links = XmToggleButtonGetState(w_data->maintain_links);
  8943.     new_images = XmToggleButtonGetState(w_data->keep_images);
  8944.  
  8945.     fe_EditorPreferencesGetLinksAndImages(context, &old_links, &old_images);
  8946.  
  8947.     if (new_links != old_links || new_images != old_images) {
  8948.         fe_EditorPreferencesSetLinksAndImages(context, new_links, new_images);
  8949.     }
  8950.  
  8951. #ifdef _SECURITY_BTN_ON_PREFS
  8952.  
  8953.     /* don't need save password in prefs anymore - benjie */
  8954.     new_save_password = XmToggleButtonGetState(w_data->save_password); 
  8955.  
  8956.     old_save_password = fe_EditorPreferencesGetPublishLocation(context, 
  8957.                                                                NULL, NULL, 
  8958.                                                                NULL);
  8959. #endif
  8960.  
  8961. #define PUBLISH_MASK (EDITOR_PUBLISH_PUBLISH|  \
  8962.                       EDITOR_PUBLISH_BROWSE| \
  8963.                       EDITOR_PUBLISH_USERNAME| \
  8964.                       EDITOR_PUBLISH_PASSWORD|EDITOR_PUBLISH_PASSWORD_SAVE)
  8965.  
  8966. #ifdef _SECURITY_BTN_ON_PREFS        
  8967.     if (new_save_password != old_save_password || 
  8968.         (w_data->changed & PUBLISH_MASK) != 0) { 
  8969. #else
  8970.     if ((w_data->changed & PUBLISH_MASK) != 0) { 
  8971. #endif
  8972.         location = fe_TextFieldGetString(w_data->publish_text);
  8973.         browse_location = fe_TextFieldGetString(w_data->browse_text);
  8974.         username = fe_TextFieldGetString(w_data->username_text);
  8975.         password = fe_GetPasswdText(w_data->password_text);
  8976.         
  8977.         fe_EditorPreferencesSetPublishLocation(context,
  8978.                                                location,
  8979.                                                username,
  8980.                                                password);
  8981. /*
  8982.                                                new_save_password? password: 0);
  8983. */
  8984.         fe_EditorPreferencesSetBrowseLocation(context, browse_location);
  8985.     }
  8986. #undef PUBLISH_MASK
  8987.     if (browse_location) {
  8988.         XtFree(browse_location);
  8989.     }
  8990.     if (location) {
  8991.         XtFree(location);
  8992.     }
  8993.     if (username) {
  8994.         XtFree(username);
  8995.     }
  8996.     if (password) {
  8997.         memset(password, 0, strlen(password));
  8998.         XtFree(password);
  8999.     }
  9000. }
  9001.  
  9002.  
  9003. static void
  9004. fe_publish_preferences_init(MWContext* context,
  9005.                             fe_EditorPublishPreferencesStruct* w_data)
  9006. {
  9007.     char* location;
  9008.     char* browse_location;
  9009.     char* username;
  9010.     char* password;
  9011.     Boolean links;
  9012.     Boolean images;
  9013.     Boolean save_password;
  9014.  
  9015.     fe_EditorPreferencesGetLinksAndImages(context, &links, &images);
  9016.  
  9017.     save_password = fe_EditorPreferencesGetPublishLocation(context,
  9018.                                                            &location,
  9019.                                                            &username,
  9020.                                                            &password);
  9021.  
  9022.     browse_location = fe_EditorPreferencesGetBrowseLocation(context);
  9023.  
  9024.     XmToggleButtonSetState(w_data->maintain_links, links, FALSE);
  9025.     XmToggleButtonSetState(w_data->keep_images, images, FALSE);
  9026.     /*XmToggleButtonSetState(w_data->save_password, save_password, FALSE);*/
  9027.  
  9028.     if (location) {
  9029.         fe_TextFieldSetString(w_data->publish_text, location, FALSE);
  9030.  
  9031.         if (username)
  9032.             fe_TextFieldSetString(w_data->username_text, username, FALSE);
  9033.         else
  9034.             fe_TextFieldSetString(w_data->username_text, "", FALSE);
  9035.  
  9036.         if (password)
  9037.             fe_TextFieldSetString(w_data->password_text, password, FALSE);
  9038.         else
  9039.             fe_TextFieldSetString(w_data->password_text, "", FALSE);
  9040.  
  9041.     }
  9042.  
  9043.     if (browse_location)
  9044.         fe_TextFieldSetString(w_data->browse_text, browse_location, FALSE);
  9045.     else
  9046.         fe_TextFieldSetString(w_data->browse_text, "", FALSE);
  9047.  
  9048.     if (browse_location) {
  9049.         XtFree(browse_location);
  9050.     }
  9051.     if (location) {
  9052.         XtFree(location);
  9053.     }
  9054.     if (username) {
  9055.         XtFree(username);
  9056.     }
  9057.     if (password) {
  9058.         memset(password, 0, strlen(password));
  9059.         XtFree(password);
  9060.     }
  9061. }
  9062.  
  9063. static Widget
  9064. fe_publish_preferences_create(MWContext* context, Widget parent,
  9065.                               fe_EditorPublishPreferencesStruct* w_data)
  9066. {
  9067.     Widget main_rc;
  9068.  
  9069.     Widget links_frame;
  9070.     Widget links_main_rc;
  9071.     Widget links_main_info;
  9072.     Widget links_sub_rc;
  9073.     Widget links_toggle;
  9074.     Widget links_info;
  9075.     Widget images_toggle;
  9076.     Widget images_info;
  9077.     Widget links_main_tip;
  9078.  
  9079.     Widget publish_frame;
  9080.     Widget publish_form;
  9081.     Widget publish_label;
  9082.     Widget publish_text;
  9083.     Widget browse_label;
  9084.     Widget browse_text;
  9085.     Widget username_label;
  9086.     Widget username_text;
  9087.     Widget password_label;
  9088.     Widget password_text;
  9089.     Widget children[16];
  9090.     Cardinal nchildren;
  9091.     Dimension left_offset;
  9092.     Arg    args[16];
  9093.     Cardinal n;
  9094.  
  9095.     n = 0;
  9096.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  9097.     main_rc = XmCreateRowColumn(parent, "publish", args, n);
  9098.     XtManageChild(main_rc);
  9099.  
  9100.     n = 0;
  9101.     links_frame = fe_CreateFrame(main_rc, "linksAndImages", args, n);
  9102.     XtManageChild(links_frame);
  9103.  
  9104.     n = 0;
  9105.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  9106.     links_main_rc = XmCreateRowColumn(links_frame, "linksAndImages", args, n);
  9107.     XtManageChild(links_main_rc);
  9108.  
  9109.     nchildren = 0;
  9110.     n = 0;
  9111.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  9112.     links_main_info = XmCreateLabelGadget(links_main_rc, "linksAndImagesLabel",
  9113.                                           args, n);
  9114.     children[nchildren++] = links_main_info;
  9115.  
  9116.     n = 0;
  9117.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  9118.     XtSetArg(args[n], XmNisAligned, TRUE); n++;
  9119.     XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_BEGINNING); n++;
  9120.     links_sub_rc = XmCreateRowColumn(links_main_rc, "linksAndImagesToggles",
  9121.                                      args, n);
  9122.     children[nchildren++] = links_sub_rc;
  9123.  
  9124.     n = 0;
  9125.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  9126.     links_main_tip = XmCreateLabelGadget(links_main_rc, "linksAndImagesTip",
  9127.                                           args, n);
  9128.     children[nchildren++] = links_main_tip;
  9129.  
  9130.     XtManageChildren(children, nchildren);
  9131.  
  9132.     nchildren = 0;
  9133.     n = 0;
  9134.     links_toggle = XmCreateToggleButtonGadget(links_sub_rc, "linksToggle",
  9135.                                           args, n);
  9136.     children[nchildren++] = links_toggle;
  9137.  
  9138.     n = 0;
  9139.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  9140.     links_info = XmCreateLabelGadget(links_sub_rc, "linksInfo", args, n);
  9141.     children[nchildren++] = links_info;
  9142.  
  9143.     n = 0;
  9144.     images_toggle = XmCreateToggleButtonGadget(links_sub_rc, "imagesToggle",
  9145.                                           args, n);
  9146.     children[nchildren++] = images_toggle;
  9147.  
  9148.     n = 0;
  9149.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  9150.     images_info = XmCreateLabelGadget(links_sub_rc, "imagesInfo", args, n);
  9151.     children[nchildren++] = images_info;
  9152.  
  9153.     XtManageChildren(children, nchildren);
  9154.  
  9155.     n = 0;
  9156.     publish_frame = fe_CreateFrame(main_rc, "publish", args, n);
  9157.     XtManageChild(publish_frame);
  9158.  
  9159.     n = 0;
  9160.     publish_form = XmCreateForm(publish_frame, "publish", args, n);
  9161.     XtManageChild(publish_form);
  9162.  
  9163.     nchildren = 0;
  9164.     n = 0;
  9165.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  9166.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  9167.     publish_label = XmCreateLabelGadget(publish_form, "publishLabel", args, n);
  9168.     children[nchildren++] = publish_label;
  9169.  
  9170.     n = 0;
  9171.     browse_label = XmCreateLabelGadget(publish_form, "browseLabel", args, n);
  9172.     children[nchildren++] = browse_label;
  9173.  
  9174.     left_offset = fe_get_offset_from_widest(children, 2);
  9175.  
  9176.     n = 0;
  9177.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  9178.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  9179.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  9180.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  9181.     XtSetArg(args[n], XmNuserData, EDITOR_PUBLISH_PUBLISH); n++;
  9182.     publish_text = fe_CreateTextField(publish_form, "publishText", args, n);
  9183.     children[nchildren++] = publish_text;
  9184.     
  9185.     n = 0;
  9186.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  9187.     XtSetArg(args[n], XmNtopWidget, publish_text); n++;
  9188.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  9189.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  9190.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  9191.     XtSetArg(args[n], XmNuserData, EDITOR_PUBLISH_BROWSE); n++;
  9192.     browse_text = fe_CreateTextField(publish_form, "browseText", args, n);
  9193.     children[nchildren++] = browse_text;
  9194.  
  9195.     /*
  9196.      *    Go back for browse label attachments.
  9197.      */
  9198.     n = 0;
  9199.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  9200.     XtSetArg(args[n], XmNtopWidget, publish_text); n++;
  9201.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  9202.     XtSetValues(browse_label, args, n);
  9203.  
  9204.     n = 0;
  9205.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  9206.     XtSetArg(args[n], XmNtopWidget, browse_text); n++;
  9207.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  9208.     username_label = XmCreateLabelGadget(publish_form, "usernameLabel",
  9209.                                          args, n);
  9210.     children[nchildren++] = username_label;
  9211.  
  9212.     n = 0;
  9213.     password_label = XmCreateLabelGadget(publish_form, "passwordLabel",
  9214.                                          args, n);
  9215.     children[nchildren++] = password_label;
  9216.  
  9217.     left_offset = fe_get_offset_from_widest(&children[4], 2);
  9218.  
  9219.     n = 0;
  9220.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  9221.     XtSetArg(args[n], XmNtopWidget, browse_text); n++;
  9222.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  9223.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  9224.     XtSetArg(args[n], XmNuserData, EDITOR_PUBLISH_USERNAME); n++;
  9225.     username_text = fe_CreateTextField(publish_form, "usernameText", args, n);
  9226.     children[nchildren++] = username_text;
  9227.     
  9228.     n = 0;
  9229.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  9230.     XtSetArg(args[n], XmNtopWidget, username_text); n++;
  9231.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  9232.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  9233.     XtSetArg(args[n], XmNmaxLength, 1024); n++;
  9234.     password_text = fe_CreatePasswordField(publish_form, "passwordText",
  9235.                                            args, n);
  9236.     children[nchildren++] = password_text;
  9237.  
  9238.     n = 0;
  9239.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  9240.     XtSetArg(args[n], XmNtopWidget, username_text); n++;
  9241.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  9242.     XtSetValues(password_label, args, n);
  9243.  
  9244.     /* we don't need this anymore - benjie */
  9245.     /* according to the bugsplat */
  9246. #ifdef _SECURITY_BTN_ON_PREFS
  9247.     n = 0;
  9248.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  9249.     XtSetArg(args[n], XmNtopWidget, username_text); n++;
  9250.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  9251.     XtSetArg(args[n], XmNleftWidget, password_text); n++;
  9252.     password_save = XmCreateToggleButtonGadget(publish_form, "savePassword",
  9253.                                           args, n);
  9254.     children[nchildren++] = password_save;
  9255. #endif
  9256.  
  9257.     XtManageChildren(children, nchildren);
  9258.  
  9259.     w_data->maintain_links = links_toggle;
  9260.     w_data->keep_images = images_toggle;
  9261.     w_data->publish_text = publish_text;
  9262.     w_data->browse_text = browse_text;
  9263.     w_data->username_text = username_text;
  9264.     w_data->password_text = password_text;
  9265. #ifdef _SECURITY_BTN_ON_PREFS
  9266.     w_data->save_password = password_save; 
  9267. #endif
  9268.  
  9269.     XtVaSetValues(links_toggle, XmNuserData, EDITOR_PUBLISH_LINKS, 0);
  9270.     XtAddCallback(links_toggle, XmNvalueChangedCallback,
  9271.                   fe_publish_page_changed, (XtPointer)w_data);
  9272.     XtVaSetValues(images_toggle, XmNuserData, EDITOR_PUBLISH_IMAGES, 0);
  9273.     XtAddCallback(images_toggle, XmNvalueChangedCallback,
  9274.                   fe_publish_page_changed, (XtPointer)w_data);
  9275.     XtVaSetValues(publish_text, XmNuserData, EDITOR_PUBLISH_PUBLISH, 0);
  9276.     XtAddCallback(publish_text, XmNvalueChangedCallback,
  9277.                   fe_publish_page_changed, (XtPointer)w_data);
  9278.     XtVaSetValues(browse_text, XmNuserData, EDITOR_PUBLISH_BROWSE, 0);
  9279.     XtAddCallback(browse_text, XmNvalueChangedCallback,
  9280.                   fe_publish_page_changed, (XtPointer)w_data);
  9281.     XtVaSetValues(username_text, XmNuserData, EDITOR_PUBLISH_USERNAME, 0);
  9282.     XtAddCallback(username_text, XmNvalueChangedCallback,
  9283.                   fe_publish_page_changed, (XtPointer)w_data);
  9284.  
  9285.     XtAddCallback(password_text, XmNvalueChangedCallback,
  9286.                   fe_publish_password_changed, (XtPointer)w_data);
  9287. #ifdef _SECURITY_BTN_ON_PREFS
  9288.     XtVaSetValues(password_save, XmNuserData, EDITOR_PUBLISH_PASSWORD_SAVE, 0);
  9289.     XtAddCallback(password_save, XmNvalueChangedCallback,
  9290.                   fe_publish_page_changed, (XtPointer)w_data);
  9291. #endif
  9292.  
  9293.     return main_rc;
  9294. }
  9295.  
  9296. typedef struct fe_EditorPreferencesStruct
  9297. {
  9298.   fe_EditorGeneralPreferencesStruct*           general;
  9299.   fe_EditorDocumentAppearancePropertiesStruct* appearance;
  9300.   fe_EditorPublishPreferencesStruct*           publish;
  9301. } fe_EditorPreferencesStruct;
  9302.  
  9303.  
  9304. static Widget
  9305. fe_editor_preferences_dialog_create(MWContext* context,
  9306.                                   fe_EditorPreferencesStruct* p_data)
  9307. {
  9308.     Widget   dialog;
  9309.     Widget   form;
  9310.     Widget   tab_form;
  9311.     char*    name = "editorPreferencesDialog";
  9312.     
  9313.     /*
  9314.      *    Make prompt with ok, apply, cancel, no separator.
  9315.      */
  9316.     dialog = fe_CreatePromptDialog(context, name,
  9317.                                    TRUE, TRUE, TRUE, FALSE, TRUE);
  9318.  
  9319.     form = XtVaCreateManagedWidget(
  9320.                                    "folder",
  9321.                                    xmlFolderWidgetClass, dialog,
  9322.                                    XmNshadowThickness, 2,
  9323.                                    XmNtopAttachment, XmATTACH_FORM,
  9324.                                    XmNleftAttachment, XmATTACH_FORM,
  9325.                                    XmNrightAttachment, XmATTACH_FORM,
  9326.                                    XmNbottomAttachment, XmATTACH_FORM,
  9327. #ifdef ALLOW_TAB_ROTATE
  9328.                                    XmNtabPlacement, XmFOLDER_LEFT,
  9329.                                    XmNrotateWhenLeftRight, FALSE,
  9330. #endif /* ALLOW_TAB_ROTATE */
  9331.                                    XmNbottomOffset, 3,
  9332.                                    XmNspacing, 1,
  9333.                                    NULL);
  9334.  
  9335.     tab_form = fe_CreateTabForm(form, "appearanceProperties", NULL, 0);
  9336.     fe_document_appearance_create(context, tab_form, p_data->appearance);
  9337.     
  9338.     tab_form = fe_CreateTabForm(form, "generalPreferences", NULL, 0);
  9339.     fe_general_preferences_create(context, tab_form, p_data->general);
  9340.  
  9341.     tab_form = fe_CreateTabForm(form, "publishPreferences", NULL, 0);
  9342.     fe_publish_preferences_create(context, tab_form, p_data->publish);
  9343.  
  9344.     XtManageChild(dialog);
  9345.  
  9346.     return form;
  9347. }
  9348.  
  9349. void
  9350. fe_EditorPreferencesDialogDo(MWContext* context, unsigned tab_type)
  9351. {
  9352.     fe_EditorPreferencesStruct properties;
  9353.     fe_EditorDocumentAppearancePropertiesStruct appearance;
  9354.     fe_EditorGeneralPreferencesStruct general;
  9355.     fe_EditorPublishPreferencesStruct publish;
  9356.     int done;
  9357.     Widget dialog;
  9358.     Widget form;
  9359.     Widget apply_button;
  9360.     Boolean apply_sensitized;
  9361.     unsigned tab_number;
  9362.  
  9363.     /*
  9364.      *    Pick the tab.
  9365.      */
  9366.     tab_number = tab_type - 1;
  9367.  
  9368.     memset(&properties, 0, sizeof(fe_EditorPreferencesStruct));
  9369.     memset(&appearance, 0,
  9370.            sizeof(fe_EditorDocumentAppearancePropertiesStruct));
  9371.     memset(&general, 0, sizeof(fe_EditorGeneralPreferencesStruct));
  9372.     memset(&publish, 0, sizeof(fe_EditorPublishPreferencesStruct));
  9373.  
  9374.     properties.appearance = &appearance;
  9375.     properties.general = &general;
  9376.     properties.publish = &publish;
  9377.  
  9378.     form = fe_editor_preferences_dialog_create(context, &properties);
  9379.     dialog = XtParent(form);
  9380.  
  9381.     appearance.is_editor_preferences = TRUE;
  9382.     fe_document_appearance_init(context, &appearance);
  9383.     fe_general_preferences_init(context, &general);
  9384.     fe_publish_preferences_init(context, &publish);
  9385.  
  9386.     /*
  9387.      *   Add a bunch of callbacks to the buttons.
  9388.      */
  9389.     XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done);
  9390.     XtAddCallback(dialog, XmNapplyCallback, fe_hrule_apply_cb, &done);
  9391.     XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  9392.     XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  9393.  
  9394.     /*
  9395.      *    We toggle the sensitivity of the apply button on/off
  9396.      *    depending if there are changes to apply. It would be
  9397.      *    nice to use the depdency meahcnism, but it might get
  9398.      *    very busy.
  9399.      */
  9400.     apply_button = XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON);
  9401.     XtVaSetValues(apply_button, XmNsensitive, FALSE, 0);
  9402.     apply_sensitized = FALSE;
  9403.  
  9404.     /*
  9405.      *    Popup.
  9406.      */
  9407.     XtManageChild(form);
  9408.  
  9409.     XmLFolderSetActiveTab(form, tab_number, True);
  9410.  
  9411.     /*
  9412.      *    Wait.
  9413.      */
  9414.     fe_NukeBackingStore(dialog); /* what does this do? */
  9415.  
  9416.     done = XmDIALOG_NONE;
  9417.     while (done == XmDIALOG_NONE) {
  9418.  
  9419.         fe_EventLoop();
  9420.  
  9421.         if (done == XFE_DIALOG_DESTROY_BUTTON||done == XmDIALOG_CANCEL_BUTTON)
  9422.             break;
  9423.  
  9424. #define SOMETHING_CHANGED() \
  9425. (appearance.changed != 0 || general.changed != 0 || publish.changed != 0)
  9426.  
  9427.         if (SOMETHING_CHANGED() && apply_sensitized == FALSE) {
  9428.             XtVaSetValues(apply_button, XmNsensitive, TRUE, 0);
  9429.             apply_sensitized = TRUE;
  9430.         }
  9431.  
  9432.         if (done == XmDIALOG_APPLY_BUTTON || done == XmDIALOG_OK_BUTTON) {
  9433.             /* apply */
  9434.  
  9435.             if (SOMETHING_CHANGED()) {
  9436.  
  9437.                 if (!fe_general_preferences_validate(context, &general)) {
  9438.                     done = XmDIALOG_NONE;
  9439.                     continue; /* you are not going anywhere buddy */
  9440.                 }
  9441.                 
  9442.                 EDT_BeginBatchChanges(context);
  9443.  
  9444.                 if (appearance.changed != 0) {
  9445.                     fe_document_appearance_set(context, &appearance);
  9446.                     appearance.changed = 0;
  9447.                 }
  9448.                 if (general.changed != 0) {
  9449.                     fe_general_preferences_set(context, &general);
  9450.                     general.changed = 0;
  9451.                 }
  9452.                 if (publish.changed != 0) {
  9453.                     fe_publish_preferences_set(context, &publish);
  9454.                     publish.changed = 0;
  9455.                 }
  9456.  
  9457.                 EDT_EndBatchChanges(context);
  9458.  
  9459.                 /*
  9460.                  *    Save options.
  9461.                  */
  9462.                 if (!XFE_SavePrefs((char *)fe_globalData.user_prefs_file,
  9463.                                    &fe_globalPrefs)) {
  9464.                     fe_perror(context, XP_GetString(XFE_ERROR_SAVING_OPTIONS));
  9465.                 } else {
  9466.                     appearance.changed = 0;
  9467.                     general.changed = 0;
  9468.                     publish.changed = 0;
  9469.                 }
  9470.             }
  9471.  
  9472.             if (done == XmDIALOG_APPLY_BUTTON) {
  9473.                 done = XmDIALOG_NONE; /* keep looping */
  9474.  
  9475.                 XtVaSetValues(apply_button, XmNsensitive, FALSE, 0);
  9476.                 apply_sensitized = FALSE;
  9477.             }
  9478.         }
  9479.     }
  9480. #undef SOMETHING_CHANGED
  9481.  
  9482.     /*
  9483.      *    Unload data.
  9484.      */
  9485.     fe_DependentListDestroy(appearance.dependents);
  9486.  
  9487.     if (done != XFE_DIALOG_DESTROY_BUTTON)
  9488.         XtDestroyWidget(dialog);
  9489. }
  9490.  
  9491. typedef struct fe_EditorTargetPropertiesStruct
  9492. {
  9493.     Widget   text;
  9494.     Boolean  inserting;
  9495. } fe_EditorTargetPropertiesStruct;
  9496.  
  9497. static char*
  9498. cleanup_selection(char* target, char* source, unsigned max_size)
  9499. {
  9500.     char* p;
  9501.     char* q;
  9502.     char* end;
  9503.  
  9504.     for (p = source; isspace(*p); p++) /* skip beginning whitespace */
  9505.         ;
  9506.  
  9507.     end = &p[max_size-1];
  9508.     q = target;
  9509.  
  9510.     while (p < end) {
  9511.         /*
  9512.          *    Stop if we detect an unprintable, or newline.
  9513.          */
  9514.         if (!isprint(*p) || *p == '\n' || *p == '\r')
  9515.             break;
  9516.  
  9517.         if (isspace(*p))
  9518.             *q++ = ' ', p++;
  9519.         else
  9520.             *q++ = *p++;
  9521.     }
  9522.     /* strip trailing whitespace */
  9523.     while (q > target && isspace(q[-1]))
  9524.         q--;
  9525.      
  9526.     *q = '\0';
  9527.  
  9528.     return target;
  9529. }
  9530.  
  9531. static void
  9532. fe_target_properties_init(MWContext* context,
  9533.                           fe_EditorTargetPropertiesStruct* w_data)
  9534. {
  9535.     char* value;
  9536.     char buf[64];
  9537.  
  9538.     w_data->inserting = FALSE;
  9539.     
  9540.     if (EDT_GetCurrentElementType(context) == ED_ELEMENT_TARGET) {
  9541.         value = EDT_GetTargetData(context);
  9542.     } else {
  9543.         w_data->inserting = TRUE;
  9544.  
  9545.         /*
  9546.          *    Use current selected text as suggested target name...
  9547.          */
  9548.         if ((value = (char*)LO_GetSelectionText(context))) {
  9549.             cleanup_selection(buf, value, sizeof(buf));
  9550.             XP_FREE(value);
  9551.             value = buf;
  9552.         } else {
  9553.             value = "";
  9554.         }
  9555.     }
  9556.  
  9557.     /*
  9558.      *    Zap text field.
  9559.      */
  9560.     fe_TextFieldSetString(w_data->text, value, FALSE);
  9561. }
  9562.  
  9563. static char*
  9564. cleanup_string(char* target, char* source, unsigned max_size)
  9565. {
  9566.     char* p;
  9567.     char* q;
  9568.     char* end;
  9569.  
  9570.     if (max_size == 0)
  9571.         return NULL;
  9572.  
  9573.     for (p = source; isspace(*p); p++) /* skip beginning whitespace */
  9574.         ;
  9575.  
  9576.     end = &p[max_size-1];
  9577.     q = target;
  9578.  
  9579.     if (strcmp(p,"")==0) return NULL;
  9580.  
  9581.     while (p < end) {
  9582.         /*
  9583.          *    Stop if we detect an unprintable, or newline.
  9584.          */
  9585.         if (*p == '\"')
  9586.             p++;
  9587.         else
  9588.             *q++ = *p++;
  9589.     }
  9590.  
  9591.     /* strip trailing whitespace */
  9592.     while (q > target && isspace(q[-1]))
  9593.         q--;
  9594.      
  9595.     *q = '\0';
  9596.  
  9597.     return target;
  9598. }
  9599.  
  9600. static void
  9601. fe_target_properties_set(MWContext* context,
  9602.                          fe_EditorTargetPropertiesStruct* w_data)
  9603. {
  9604.  
  9605.     char* xm_value;
  9606.     char* value;
  9607.     char* target_list;
  9608.     char buf[512];
  9609.     
  9610.     xm_value = fe_TextFieldGetString(w_data->text);
  9611.  
  9612.     target_list = EDT_GetAllDocumentTargets(context);
  9613.     /*FIXME*/ /* look at this thing */
  9614.  
  9615.     value = cleanup_string(buf, xm_value, sizeof(buf));
  9616.     if (value == NULL) {
  9617.         XtFree(xm_value);
  9618.         return;
  9619.     }
  9620.         
  9621.     EDT_BeginBatchChanges(context);
  9622.     if (value[0] == '#')
  9623.         value++;
  9624.     if (w_data->inserting)
  9625.         EDT_InsertTarget(context, value);
  9626.     else
  9627.         EDT_SetTargetData(context, value);
  9628.     EDT_EndBatchChanges(context);
  9629.     
  9630.     XtFree(xm_value);
  9631. }
  9632.  
  9633. static Widget
  9634. fe_target_properties_create(MWContext* context, Widget form,
  9635.                                    fe_EditorTargetPropertiesStruct* w_data)
  9636. {
  9637.     Widget main_rc;
  9638.     Widget label;
  9639.     Widget text;
  9640.     Arg args[8];
  9641.     Cardinal n;
  9642.  
  9643.     n = 0;
  9644.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  9645.     main_rc = XmCreateRowColumn(form, "targetRC", args, n);
  9646.     XtManageChild(main_rc);
  9647.  
  9648.     n = 0;
  9649.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  9650.     label = XmCreateLabelGadget(main_rc, "targetLabel", args, n);
  9651.     XtManageChild(label);
  9652.  
  9653.     n = 0;
  9654.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  9655.     XtSetArg(args[n], XmNcolumns, 40); n++; /* room to move dude! */
  9656.     text = fe_CreateTextField(main_rc, "targetText", args, n);
  9657.     XtManageChild(text);
  9658.  
  9659.     w_data->text = text;
  9660.  
  9661.     return main_rc;
  9662. }
  9663.  
  9664. void
  9665. fe_EditorTargetPropertiesDialogDo(MWContext* context)
  9666. {
  9667.     Widget dialog;
  9668.     Widget form;
  9669.     fe_EditorTargetPropertiesStruct data;
  9670.     int done;
  9671.  
  9672.     /*
  9673.      *    Make prompt with ok, no apply, cancel, separator.
  9674.      */
  9675.     form = fe_CreatePromptDialog(context, "targetPropertiesDialog",
  9676.                                  TRUE, TRUE, FALSE, TRUE, TRUE);
  9677.     dialog = XtParent(form);
  9678.  
  9679.     fe_target_properties_create(context, form, &data);
  9680.     fe_target_properties_init(context, &data);
  9681.  
  9682.     /*
  9683.      *   Add a bunch of callbacks to the buttons.
  9684.      */
  9685.     XtAddCallback(form, XmNokCallback, fe_hrule_ok_cb, &done);
  9686.     XtAddCallback(form, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  9687.     XtAddCallback(form, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  9688.  
  9689.     /*
  9690.      *    Popup.
  9691.      */
  9692.     XtManageChild(form);
  9693.  
  9694.     /*
  9695.      *    Wait.
  9696.      */
  9697.     fe_NukeBackingStore(dialog); /* what does this do? */
  9698.  
  9699.     done = XmDIALOG_NONE;
  9700.     while (done == XmDIALOG_NONE)
  9701.         fe_EventLoop();
  9702.     
  9703.     if (done == XmDIALOG_OK_BUTTON)
  9704.         fe_target_properties_set(context, &data);
  9705.  
  9706.     if (done != XFE_DIALOG_DESTROY_BUTTON)
  9707.         XtDestroyWidget(dialog);
  9708. }
  9709.  
  9710. typedef struct fe_EditorHtmlPropertiesStruct
  9711. {
  9712.     Widget   text;
  9713.     unsigned changed;
  9714.     Boolean inserting;
  9715. } fe_EditorHtmlPropertiesStruct;
  9716.  
  9717. static void
  9718. fe_html_properties_init(MWContext* context,
  9719.                           fe_EditorHtmlPropertiesStruct* w_data)
  9720. {
  9721.     char* value;
  9722.     char buf[64];
  9723.  
  9724.     w_data->inserting = FALSE;
  9725.     
  9726.     if (EDT_GetCurrentElementType(context) == ED_ELEMENT_UNKNOWN_TAG) {
  9727.         value = EDT_GetUnknownTagData(context);
  9728.     } else {
  9729.         w_data->inserting = TRUE;
  9730.  
  9731.         /*
  9732.          *    Use current selected text as suggested target name...
  9733.          */
  9734.         if ((value = (char*)LO_GetSelectionText(context))) {
  9735.             cleanup_selection(buf, value, sizeof(buf));
  9736.             XP_FREE(value);
  9737.             value = buf;
  9738.         } else {
  9739.             value = "";
  9740.         }
  9741.     }
  9742.  
  9743.     /*
  9744.      *    Zap text field.
  9745.      */
  9746.     fe_SetTextFieldAndCallBack(w_data->text, value);
  9747.     w_data->changed = 0;
  9748. }
  9749.  
  9750. static void
  9751. fe_html_properties_set(MWContext* context,
  9752.                        fe_EditorHtmlPropertiesStruct* w_data)
  9753. {
  9754.     char* xm_value;
  9755.     
  9756.     xm_value = fe_TextFieldGetString(w_data->text);
  9757.  
  9758.     EDT_BeginBatchChanges(context);
  9759.     if (EDT_GetCurrentElementType(context) == ED_ELEMENT_UNKNOWN_TAG)
  9760.         EDT_SetUnknownTagData(context, xm_value);
  9761.     else
  9762.         EDT_InsertUnknownTag(context, xm_value);
  9763.     EDT_EndBatchChanges(context);
  9764.  
  9765.     XtFree(xm_value);
  9766. }
  9767.  
  9768. Boolean
  9769. fe_html_properties_verify(MWContext* context,
  9770.                          fe_EditorHtmlPropertiesStruct* w_data)
  9771. {
  9772.     char* xm_value;
  9773.     int id = XFE_EDITOR_TAG_UNKNOWN; /* keep -O happy */
  9774.     ED_TagValidateResult e;
  9775.     Widget parent;
  9776.     
  9777.     xm_value = fe_TextFieldGetString(w_data->text);
  9778.     
  9779.     e = EDT_ValidateTag(xm_value, FALSE );
  9780.  
  9781.     switch (e) {
  9782.     case ED_TAG_OK:
  9783.         break;
  9784.     case ED_TAG_UNOPENED:
  9785.         id = XFE_EDITOR_TAG_UNOPENED;
  9786.         /* Unopened Tag: '<' was expected */
  9787.         break;
  9788.     case ED_TAG_UNCLOSED:
  9789.         id = XFE_EDITOR_TAG_UNCLOSED;
  9790.         /* Unopened Tag:  '>' was expected */
  9791.         break;
  9792.     case ED_TAG_UNTERMINATED_STRING:
  9793.         id = XFE_EDITOR_TAG_UNTERMINATED_STRING;
  9794.         /* Unterminated String in tag: closing quote expected */
  9795.         break;
  9796.     case ED_TAG_PREMATURE_CLOSE:
  9797.         id = XFE_EDITOR_TAG_PREMATURE_CLOSE;
  9798.         /* Premature close of tag */
  9799.         break;
  9800.     case ED_TAG_TAGNAME_EXPECTED:
  9801.         id = XFE_EDITOR_TAG_TAGNAME_EXPECTED;
  9802.         /* Tagname was expected */
  9803.         break;
  9804.     default:
  9805.         id = XFE_EDITOR_TAG_UNKNOWN;
  9806.         /* Unknown tag error */
  9807.         break;
  9808.     }
  9809.  
  9810.     XtFree(xm_value);
  9811.  
  9812.     parent = w_data->text;
  9813.         
  9814.     if (e == ED_TAG_OK) {
  9815.         return TRUE;
  9816.     } else {
  9817.         fe_error_dialog(context, w_data->text, XP_GetString(id));
  9818.         return FALSE;
  9819.     }
  9820. }
  9821.  
  9822. static void
  9823. fe_html_text_changed_cb(Widget widget, XtPointer closure, XtPointer cb)
  9824. {
  9825.      fe_EditorHtmlPropertiesStruct* w_data =
  9826.          (fe_EditorHtmlPropertiesStruct*)closure;
  9827.      w_data->changed = 0x1;
  9828. }
  9829.  
  9830. static Widget
  9831. fe_html_properties_create(MWContext* context, Widget form,
  9832.                                    fe_EditorHtmlPropertiesStruct* w_data)
  9833. {
  9834.     Widget main_rc;
  9835.     Widget label;
  9836.     Widget text;
  9837.     Arg args[8];
  9838.     Cardinal n;
  9839.  
  9840.     n = 0;
  9841.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  9842.     main_rc = XmCreateRowColumn(form, "htmlRC", args, n);
  9843.     XtManageChild(main_rc);
  9844.  
  9845.     n = 0;
  9846.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  9847.     label = XmCreateLabelGadget(main_rc, "htmlPropertiesInfo", args, n);
  9848.     XtManageChild(label);
  9849.  
  9850.     n = 0;
  9851.     XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
  9852.     XtSetArg(args[n], XmNcolumns, 70); n++;
  9853.     XtSetArg(args[n], XmNrows, 8); n++;
  9854.     text = XmCreateScrolledText(main_rc, "htmlText", args, n);
  9855.     fe_HackTextTranslations(text);
  9856.     XtAddCallback(text, XmNvalueChangedCallback, fe_html_text_changed_cb,
  9857.                   (XtPointer)w_data);
  9858.     XtManageChild(text);
  9859.  
  9860.     w_data->text = text;
  9861.  
  9862.     return main_rc;
  9863. }
  9864.  
  9865. void
  9866. fe_EditorHtmlPropertiesDialogDo(MWContext* context)
  9867. {
  9868.     Widget dialog;
  9869.     Widget form;
  9870.     Widget ok_button;
  9871.     fe_EditorHtmlPropertiesStruct data;
  9872.     int    done;
  9873.  
  9874.     /*
  9875.      *    Make prompt with ok, no apply, cancel, separator.
  9876.      */
  9877.     form = fe_CreatePromptDialog(context, "htmlPropertiesDialog",
  9878.                                  TRUE, TRUE, TRUE, TRUE, TRUE);
  9879.     dialog = XtParent(form);
  9880.  
  9881.     fe_html_properties_create(context, form, &data);
  9882.     fe_html_properties_init(context, &data);
  9883.  
  9884.     /*
  9885.      *   Add a bunch of callbacks to the buttons.
  9886.      */
  9887.     XtAddCallback(form, XmNokCallback, fe_hrule_ok_cb, &done);
  9888.     XtAddCallback(form, XmNapplyCallback, fe_hrule_apply_cb, &done);
  9889.     XtAddCallback(form, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  9890.     XtAddCallback(form, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  9891.  
  9892.     ok_button = XmSelectionBoxGetChild(form, XmDIALOG_OK_BUTTON);
  9893.  
  9894.     /*
  9895.      *    Popup.
  9896.      */
  9897.     XtManageChild(form);
  9898.  
  9899.     /*
  9900.      *    Wait.
  9901.      */
  9902.     fe_NukeBackingStore(dialog); /* what does this do? */
  9903.  
  9904.     done = XmDIALOG_NONE;
  9905.     while (done == XmDIALOG_NONE) {
  9906.         fe_EventLoop();
  9907.  
  9908.         if (done == XmDIALOG_APPLY_BUTTON || done == XmDIALOG_OK_BUTTON) {
  9909.             if (fe_html_properties_verify(context, &data) == FALSE) {
  9910.                 done = XmDIALOG_NONE;
  9911.             } else if (done == XmDIALOG_APPLY_BUTTON) { /* but verified */
  9912.                 /* Tag seems ok */
  9913.                 fe_message_dialog(context,
  9914.                                   dialog,
  9915.                                   XP_GetString(XFE_EDITOR_TAG_OK));
  9916.                 done = XmDIALOG_NONE;
  9917.             }
  9918.         }
  9919.     }
  9920.     
  9921.     if (done == XmDIALOG_OK_BUTTON && data.changed != 0)
  9922.         fe_html_properties_set(context, &data);
  9923.  
  9924.     if (done != XFE_DIALOG_DESTROY_BUTTON)
  9925.         XtDestroyWidget(dialog);
  9926. }
  9927.  
  9928. char* fe_SimpleTableAlignment[3] = {
  9929.     "left",
  9930.     "center",
  9931.     "right"
  9932. };
  9933.  
  9934. char* fe_SimpleOptionAboveBelow[2] = {
  9935.     "above",
  9936.     "below"
  9937. };
  9938.  
  9939. char* fe_SimpleOptionPixelPercent[2] = {
  9940.     "pixels",
  9941.     "percent"
  9942. };
  9943.  
  9944. char* fe_SimpleOptionHorizontalAlignment[4] = {
  9945.     "default",
  9946.     "left",
  9947.     "center",
  9948.     "right"
  9949. };
  9950.  
  9951. char* fe_SimpleOptionVerticalAlignment[5] = {
  9952.     "default",
  9953.     "top",
  9954.     "center",
  9955.     "bottom",
  9956.     "baselines"
  9957. };
  9958.  
  9959. Widget
  9960. fe_CreateSimpleOptionMenu(Widget parent, char* name, Arg* p_args, Cardinal p_n)
  9961. {
  9962.     Widget pulldown;
  9963.     Widget button;
  9964.     Widget option_menu;
  9965.     Widget history_widget = NULL;
  9966.     char namebuf[64];
  9967.     Arg args[32];
  9968.     Cardinal n;
  9969.     Cardinal i;
  9970.     char** button_names = NULL;
  9971.     unsigned button_count = 0;
  9972.     unsigned button_set = 0;
  9973.     char* button_name;
  9974.     XtCallbackRec* callback = NULL;
  9975.  
  9976.     strcpy(namebuf, name);
  9977.     strcat(namebuf, "Menu");
  9978.  
  9979.     n = 0;
  9980.     pulldown = fe_CreatePulldownMenu(parent, namebuf, args, n);
  9981.  
  9982.     n = 0;
  9983.     for (i = 0; i < p_n; i++) {
  9984.         if (p_args[i].name == XmNsimpleCallback)
  9985.             callback = (XtCallbackRec*)p_args[i].value;
  9986.         else if (p_args[i].name == XmNbuttons)
  9987.             button_names = (char**)p_args[i].value;
  9988.         else if (p_args[i].name == XmNbuttonCount)
  9989.             button_count = (unsigned)p_args[i].value;
  9990.         else if (p_args[i].name == XmNbuttonSet)
  9991.             button_set = (unsigned)p_args[i].value;
  9992.         else
  9993.             args[n++] = p_args[i];
  9994.     }
  9995.  
  9996.     if (button_names == fe_SimpleOptionAboveBelow)
  9997.         button_count = XtNumber(fe_SimpleOptionAboveBelow);
  9998.     else if (button_names == fe_SimpleOptionPixelPercent)
  9999.         button_count = XtNumber(fe_SimpleOptionPixelPercent);
  10000.     else if (button_names == fe_SimpleOptionHorizontalAlignment)
  10001.         button_count = XtNumber(fe_SimpleOptionHorizontalAlignment);
  10002.     else if (button_names == fe_SimpleOptionVerticalAlignment)
  10003.         button_count = XtNumber(fe_SimpleOptionVerticalAlignment);
  10004.  
  10005.     for (i = 0; i < button_count; i++) {
  10006.         if (button_names) {
  10007.             button_name = button_names[i];
  10008.         } else {
  10009.             sprintf(namebuf, "button%d", i);
  10010.             button_name = namebuf;
  10011.         }
  10012.         button = XmCreatePushButtonGadget(pulldown, button_name, NULL, 0);
  10013.         XtManageChild(button);
  10014.         if (i == button_set)
  10015.             history_widget = button;
  10016.  
  10017.         if (callback != NULL) {
  10018.             XtAddCallback(button, XmNactivateCallback,
  10019.                           callback->callback, callback->closure);
  10020.         }
  10021.     }
  10022.  
  10023.     XtSetArg(args[n], XmNsubMenuId, pulldown); n++;
  10024.     option_menu = fe_CreateOptionMenu(parent, name, args, n);
  10025.     fe_UnmanageChild_safe(XmOptionLabelGadget(option_menu));
  10026.  
  10027.     if (history_widget)
  10028.         XtVaSetValues(option_menu, XmNmenuHistory, history_widget, 0);
  10029.  
  10030.     return option_menu;
  10031. }
  10032.  
  10033. #endif  /* EDITOR */
  10034.  
  10035.  
  10036. #ifdef EDITOR
  10037.  
  10038. static Widget
  10039. fe_CreateSimpleRadioGroup(Widget parent, char* name, Arg* p_args, Cardinal p_n)
  10040. {
  10041.     Widget button;
  10042.     Widget option_menu;
  10043.     char namebuf[64];
  10044.     Arg args[32];
  10045.     Cardinal n;
  10046.     Cardinal i;
  10047.     char** button_names = NULL;
  10048.     unsigned button_count = 0;
  10049.     unsigned button_set = 0;
  10050.     char* button_name;
  10051.  
  10052.     strcpy(namebuf, name);
  10053.     strcat(namebuf, "Radio");
  10054.  
  10055.     n = 0;
  10056.     for (i = 0; i < p_n; i++) {
  10057.         if (p_args[i].name == XmNbuttons)
  10058.             button_names = (char**)p_args[i].value;
  10059.         else if (p_args[i].name == XmNbuttonCount)
  10060.             button_count = (unsigned)p_args[i].value;
  10061.         else if (p_args[i].name == XmNbuttonSet)
  10062.             button_set = (unsigned)p_args[i].value;
  10063.         else
  10064.             args[n++] = p_args[i];
  10065.     }
  10066.  
  10067.     XtSetArg(args[n], XmNradioBehavior, TRUE); n++;
  10068.     option_menu = XmCreateRowColumn(parent, name, args, n);
  10069.  
  10070.     if (button_names == fe_SimpleOptionAboveBelow)
  10071.         button_count = XtNumber(fe_SimpleOptionAboveBelow);
  10072.     else if (button_names == fe_SimpleOptionPixelPercent)
  10073.         button_count = XtNumber(fe_SimpleOptionPixelPercent);
  10074.     else if (button_names == fe_SimpleOptionHorizontalAlignment)
  10075.         button_count = XtNumber(fe_SimpleOptionHorizontalAlignment);
  10076.     else if (button_names == fe_SimpleOptionVerticalAlignment)
  10077.         button_count = XtNumber(fe_SimpleOptionVerticalAlignment);
  10078.     else if (button_names == fe_SimpleTableAlignment)
  10079.         button_count = XtNumber(fe_SimpleTableAlignment);
  10080.  
  10081.     for (i = 0; i < button_count; i++) {
  10082.         if (button_names) {
  10083.             button_name = button_names[i];
  10084.         } else {
  10085.             sprintf(namebuf, "button%d", i);
  10086.             button_name = namebuf;
  10087.         }
  10088.         n = 0;
  10089.         XtSetArg(args[n], XmNset, (i == button_set)); n++;
  10090.         XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  10091.         button = XmCreateToggleButtonGadget(option_menu, button_name, args, n);
  10092.         XtManageChild(button);
  10093.     }
  10094.  
  10095.     return option_menu;
  10096. }
  10097.  
  10098. void
  10099. fe_SimpleRadioGroupSetWhich(Widget widget, unsigned which)
  10100. {
  10101.     Widget* children;
  10102.     Cardinal num_children;
  10103.     Cardinal i;
  10104.  
  10105.     XtVaGetValues(widget,
  10106.                   XmNchildren, &children,
  10107.                   XmNnumChildren, &num_children, 0);
  10108.  
  10109.     if (which < num_children) {
  10110.  
  10111.         for (i = 0; i < num_children; i++) {
  10112.             XmToggleButtonGadgetSetState(children[i], (i == which), FALSE);
  10113.         }
  10114.     }
  10115. }
  10116.  
  10117. void
  10118. fe_SimpleRadioGroupSetSensitive(Widget widget, Boolean sensitive)
  10119. {
  10120.     Widget* children;
  10121.     Cardinal num_children;
  10122.     Cardinal i;
  10123.  
  10124.     XtVaGetValues(widget,
  10125.                   XmNchildren, &children,
  10126.                   XmNnumChildren, &num_children, 0);
  10127.  
  10128.     for (i = 0; i < num_children; i++) {
  10129.         XtVaSetValues(children[i], XmNsensitive, sensitive, 0);
  10130.     }
  10131. }
  10132.  
  10133. int
  10134. fe_SimpleRadioGroupGetWhich(Widget widget)
  10135. {
  10136.     Widget* children;
  10137.     Cardinal num_children;
  10138.     Cardinal i;
  10139.  
  10140.     XtVaGetValues(widget,
  10141.                   XmNchildren, &children,
  10142.                   XmNnumChildren, &num_children, 0);
  10143.  
  10144.     for (i = 0; i < num_children; i++) {
  10145.         if (XmToggleButtonGadgetGetState(children[i]) == TRUE)
  10146.             return i;
  10147.     }
  10148.     return -1; /* ?? */
  10149. }
  10150.  
  10151. Widget
  10152. fe_SimpleRadioGroupGetChild(Widget widget, unsigned n)
  10153. {
  10154.     Widget*  children;
  10155.     Cardinal num_children;
  10156.  
  10157.     XtVaGetValues(widget,
  10158.                   XmNchildren, &children,
  10159.                   XmNnumChildren, &num_children, 0);
  10160.  
  10161.     if (n < num_children)
  10162.         return children[n];
  10163.     else
  10164.         return NULL;
  10165. }
  10166.  
  10167.  
  10168. static unsigned
  10169. fe_ED_Alignment_to_index(ED_Alignment type)
  10170. {
  10171.     switch (type) {
  10172.     case ED_ALIGN_LEFT:
  10173.     case ED_ALIGN_ABSTOP:
  10174.     case ED_ALIGN_TOP:       return 1;
  10175.     case ED_ALIGN_CENTER:
  10176.     case ED_ALIGN_ABSCENTER: return 2;
  10177.     case ED_ALIGN_RIGHT:
  10178.     case ED_ALIGN_BOTTOM:
  10179.     case ED_ALIGN_ABSBOTTOM: return 3;
  10180.     case ED_ALIGN_BASELINE:  return 4;
  10181.     case ED_ALIGN_DEFAULT:
  10182.     default:                 return 0;
  10183.   }
  10184. }
  10185.  
  10186. typedef struct fe_EditorTablesTableStruct
  10187. {
  10188.     Widget number_rows_text;
  10189.     Widget number_columns_text;
  10190.     Widget line_width_toggle;
  10191.     Widget line_width_text;
  10192.     Widget spacing_text;
  10193.     Widget padding_text;
  10194.     Widget width_toggle;
  10195.     Widget width_text;
  10196.     Widget width_units;
  10197.     Widget height_toggle;
  10198.     Widget height_text;
  10199.     Widget height_units;
  10200.     Widget bg_group;
  10201.     Widget choose_color;
  10202.     LO_Color color_value;
  10203.     Widget caption_toggle;
  10204.     Widget caption_type;
  10205.     Widget equal_column_toggle;
  10206.     Widget alignBox;
  10207.     Boolean inserting;
  10208. } fe_EditorTablesTableStruct; 
  10209.  
  10210. #if 0
  10211. static void
  10212. check_children(Widget* children, Cardinal nchildren)
  10213. {
  10214.     Widget widget;
  10215.     Widget parent;
  10216.     int i;
  10217.  
  10218.     for (i = 0; i < nchildren; i++) {
  10219.         widget = children[i];
  10220.         parent = XtParent(widget);
  10221.         fprintf(real_stderr, "parent(%s) = %s, ", XtName(widget), 
  10222.                 XtName(parent));
  10223.     }
  10224.     fprintf(real_stderr, "\n");
  10225.     
  10226. }
  10227. #endif
  10228.  
  10229. static void
  10230. fe_table_tbr_set(MWContext* context, Widget toggle, Widget text, Widget radio,
  10231.                  Boolean enabled, unsigned numeric, Boolean second_one)
  10232. {
  10233.     XmToggleButtonGadgetSetState(toggle, enabled, FALSE);
  10234.     if (text != NULL) {
  10235.         char buf[32];
  10236.  
  10237.         sprintf(buf, "%d", numeric);
  10238.  
  10239.         fe_TextFieldSetString(text, buf, FALSE);
  10240.         fe_TextFieldSetEditable(context, text, enabled);
  10241.     }
  10242.     if (radio != NULL) {
  10243.         fe_SimpleRadioGroupSetWhich(radio, second_one);
  10244.         fe_SimpleRadioGroupSetSensitive(radio, enabled);
  10245.     }
  10246. }
  10247.  
  10248. static void
  10249. fe_table_percent_label_set(Widget widget, Boolean nested)
  10250. {
  10251.     char * name = (nested ? "percentOfCell" : "percentOfWindow");
  10252.  
  10253.     XmString xm_string = XfeSubResourceGetXmStringValue(widget,
  10254.                                                         name,
  10255.                                                         XfeClassNameForWidget(widget),
  10256.                                                         XmNlabelString,
  10257.                                                         XmCXmString,
  10258.                                                         NULL);
  10259.  
  10260.     if (!xm_string)
  10261.     {
  10262.         xm_string = XmStringCreateLocalized(name);
  10263.  
  10264.         XtVaSetValues(widget, XmNlabelString, xm_string, 0);
  10265.  
  10266.         XmStringFree(xm_string);
  10267.     }
  10268.     /* No need to free xm_string.  The resource converter dtor will */
  10269.     else
  10270.     {
  10271.         XtVaSetValues(widget, XmNlabelString, xm_string, 0);
  10272.     }
  10273. }
  10274.  
  10275. static void
  10276. fe_table_toggle_cb(Widget widget, XtPointer closure, XtPointer cb_data)
  10277. {
  10278.     fe_EditorTablesTableStruct* w_data = (fe_EditorTablesTableStruct*)closure;
  10279.     Boolean enabled = XmToggleButtonGetState(widget);
  10280.     MWContext* context = fe_WidgetToMWContext(widget);
  10281.     Widget  text = NULL; /* keep -O happy */
  10282.     Widget  radio = NULL; /* keep -O happy */
  10283.  
  10284.     if (widget == w_data->line_width_toggle) {
  10285.         text = w_data->line_width_text;
  10286.         radio = NULL;
  10287.     } else if (widget == w_data->width_toggle) {
  10288.         text = w_data->width_text;
  10289.         radio = w_data->width_units;
  10290.     } else if (widget == w_data->height_toggle) {
  10291.         text = w_data->height_text;
  10292.         radio = w_data->height_units;
  10293.     } else if (widget == w_data->caption_toggle) {
  10294.         fe_SimpleRadioGroupSetSensitive(w_data->caption_type, enabled);
  10295.         return;
  10296.     }
  10297.  
  10298.     if (text != NULL)
  10299.         fe_TextFieldSetEditable(context, text, enabled);
  10300.     if (radio != NULL)
  10301.         fe_SimpleRadioGroupSetSensitive(radio, enabled);
  10302. }
  10303.  
  10304. #define RGB_TO(r,g,b) (((r)<<16)+((g)<<8)+(b))
  10305. #define R_FROM(l)     (((l)>>16)&0xff)
  10306. #define G_FROM(l)     (((l)>>8)&0xff)
  10307. #define B_FROM(l)     ((l)&0xff)
  10308.  
  10309. static void
  10310. fe_NewSwatchSetColor(Widget widget, LO_Color* color)
  10311. {
  10312.     unsigned long pack_color = 0;
  10313.  
  10314.     if (color)
  10315.         pack_color = RGB_TO(color->red, color->green, color->blue);
  10316.  
  10317.     XtVaSetValues(widget,
  10318.                   XmNuserData, pack_color,
  10319.                   0);
  10320.     fe_SwatchSetColor(widget, color);
  10321. }
  10322.  
  10323. static LO_Color*
  10324. fe_NewSwatchGetColor(Widget widget, LO_Color* color)
  10325. {
  10326.     unsigned long pack_color;
  10327.  
  10328.     XtVaGetValues(widget, XmNuserData, &pack_color, 0);
  10329.  
  10330.     color->red = R_FROM(pack_color);
  10331.     color->green = G_FROM(pack_color);
  10332.     color->blue = B_FROM(pack_color);
  10333.  
  10334.     return color;
  10335. }
  10336.  
  10337. static void
  10338. fe_bg_group_use_color_cb(Widget widget, XtPointer closure, XtPointer cbd)
  10339. {
  10340.     XmToggleButtonCallbackStruct* cbs = (XmToggleButtonCallbackStruct*)cbd;
  10341.     Widget swatch = (Widget)closure;
  10342.     
  10343.     fe_WidgetSetSensitive(swatch, cbs->set);
  10344. }
  10345.  
  10346. static void
  10347. fe_bg_group_swatch_cb(Widget widget, XtPointer closure, XtPointer cbd)
  10348. {
  10349.     MWContext* context = fe_WidgetToMWContext(widget);
  10350.     LO_Color   color;
  10351.     Widget     toggle = (Widget)closure;
  10352.  
  10353.     fe_NewSwatchGetColor(widget, &color);
  10354.  
  10355.     if (fe_ColorPicker(context, &color)) {
  10356.         fe_NewSwatchSetColor(widget, &color);
  10357.         XmToggleButtonSetState(toggle, TRUE, FALSE);
  10358.     }
  10359. }
  10360.  
  10361. static void
  10362. fe_bg_use_image_cb(Widget widget, XtPointer closure, XtPointer cbd)
  10363. {
  10364.     XmToggleButtonCallbackStruct* cbs = (XmToggleButtonCallbackStruct*)cbd;
  10365.     MWContext* context = fe_WidgetToMWContext(widget);
  10366.     Widget     text_widget = (Widget)closure;
  10367.  
  10368.     fe_TextFieldSetEditable(context, text_widget, cbs->set);
  10369. }
  10370.  
  10371. static void
  10372. fe_bg_image_browse_cb(Widget widget, XtPointer closure, XtPointer cbd)
  10373. {
  10374.     MWContext* context = fe_WidgetToMWContext(widget);
  10375.     Widget     text_widget = (Widget)closure;
  10376.  
  10377.     fe_url_browse_file_of_text(context, text_widget);
  10378. }
  10379.  
  10380. #define BG_GROUP_USECOLOR_TOGGLE   "useColor"
  10381. #define BG_GROUP_USECOLOR_SWATCH   "useColorSwatch"
  10382. #define BG_GROUP_USEIMAGE_TOGGLE   "useImage"
  10383. #define BG_GROUP_USEIMAGE_TEXT     "useImageText"
  10384. #define BG_GROUP_LEAVEIMAGE_TOGGLE "leaveImage"
  10385.  
  10386. static Widget
  10387. fe_create_background_group(Widget parent, char* name,
  10388.                            Arg* p_args, Cardinal p_n)
  10389. {
  10390.     Widget frame;
  10391.     Widget form;
  10392.     Widget use_color_toggle;
  10393.     Widget use_color_swatch;
  10394.     Widget use_image_toggle;
  10395.     Widget use_image_text;
  10396.     Widget use_image_chooser;
  10397.     Widget leave_image_toggle;
  10398.     Widget children[8];
  10399.     Cardinal nchildren;
  10400.     Arg args[16];
  10401.     Cardinal n;
  10402.     Cardinal offset;
  10403.     Dimension height;
  10404.     
  10405.     frame = fe_CreateFrame(parent, name, p_args, p_n);
  10406.  
  10407.     n = 0;
  10408.     form = XmCreateForm(frame, "backgroundAttributes", args, n);
  10409.     XtManageChild(form);
  10410.  
  10411.     nchildren = 0;
  10412.  
  10413.     n = 0;
  10414.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  10415.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10416.     use_color_toggle = XmCreateToggleButtonGadget(form,
  10417.                                                   BG_GROUP_USECOLOR_TOGGLE,
  10418.                                                   args, n);
  10419.     children[nchildren++] = use_color_toggle;
  10420.  
  10421.     n = 0;
  10422.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10423.     XtSetArg(args[n], XmNtopWidget, use_color_toggle); n++;
  10424.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10425.     use_image_toggle = XmCreateToggleButtonGadget(form,
  10426.                                                   BG_GROUP_USEIMAGE_TOGGLE,
  10427.                                                   args, n);
  10428.     children[nchildren++] = use_image_toggle;
  10429.  
  10430.     offset = fe_get_offset_from_widest(children, nchildren);
  10431.  
  10432.     XtVaGetValues(use_color_toggle, XmNheight, &height, 0);
  10433.  
  10434.     n = 0;
  10435.     XtSetArg(args[n], XmNheight, height); n++;
  10436.     XtSetArg(args[n], XmNwidth, SWATCH_SIZE); n++;
  10437.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  10438.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10439.     XtSetArg(args[n], XmNleftOffset, offset); n++;
  10440.     use_color_swatch = fe_CreateSwatch(form,
  10441.                                        BG_GROUP_USECOLOR_SWATCH, args, n);
  10442.     children[nchildren++] = use_color_swatch;
  10443.  
  10444.     XtAddCallback(use_color_toggle, XmNvalueChangedCallback,
  10445.                   fe_bg_group_use_color_cb, use_color_swatch);
  10446.     XtAddCallback(use_color_swatch, XmNactivateCallback,
  10447.                   fe_bg_group_swatch_cb, use_color_toggle);
  10448.  
  10449.     n = 0;
  10450.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10451.     XtSetArg(args[n], XmNtopWidget, use_color_toggle); n++;
  10452.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10453.     XtSetArg(args[n], XmNleftOffset, offset); n++;
  10454.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  10455.     use_image_text = fe_CreateTextField(form,
  10456.                                         BG_GROUP_USEIMAGE_TEXT, args, n);
  10457.     children[nchildren++] = use_image_text;
  10458.  
  10459.     n = 0;
  10460.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10461.     XtSetArg(args[n], XmNtopWidget, use_image_text); n++;
  10462.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10463.     leave_image_toggle = XmCreateToggleButtonGadget(form,
  10464.                                                     BG_GROUP_LEAVEIMAGE_TOGGLE,
  10465.                                                     args, n);
  10466.     children[nchildren++] = leave_image_toggle;
  10467.  
  10468.     n = 0;
  10469.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10470.     XtSetArg(args[n], XmNtopWidget, use_image_text); n++;
  10471.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  10472.     use_image_chooser = XmCreatePushButtonGadget(form, "chooseImage",
  10473.                                                   args, n);
  10474.     children[nchildren++] = use_image_chooser;
  10475.  
  10476.     XtAddCallback(use_image_toggle, XmNvalueChangedCallback,
  10477.                   fe_bg_use_image_cb, use_image_text);
  10478.     XtAddCallback(use_image_chooser, XmNactivateCallback,
  10479.                   fe_bg_image_browse_cb, use_image_text);
  10480.     
  10481.     XtManageChildren(children, nchildren);
  10482.     
  10483.     return frame;
  10484. }
  10485.  
  10486. static void
  10487. fe_bg_group_set(Widget parent,
  10488.                 LO_Color* color, char* bg_image, XP_Bool leave_image)
  10489. {
  10490.     Widget  use_color_toggle;
  10491.     Widget  use_color_swatch;
  10492.     Widget  use_image_toggle;
  10493.     Widget  use_image_text;
  10494.     Widget  leave_image_toggle;
  10495.     
  10496.     use_color_toggle = XtNameToWidget(parent, "*" BG_GROUP_USECOLOR_TOGGLE);
  10497.     use_color_swatch = XtNameToWidget(parent, "*" BG_GROUP_USECOLOR_SWATCH);
  10498.     use_image_toggle = XtNameToWidget(parent, "*" BG_GROUP_USEIMAGE_TOGGLE);
  10499.     use_image_text = XtNameToWidget(parent, "*" BG_GROUP_USEIMAGE_TEXT);
  10500.     leave_image_toggle = XtNameToWidget(parent,"*" BG_GROUP_LEAVEIMAGE_TOGGLE);
  10501.  
  10502.     if (use_color_toggle != NULL)
  10503.         XmToggleButtonGadgetSetState(use_color_toggle, (color != NULL), FALSE);
  10504.  
  10505.     if (use_color_swatch != NULL)
  10506.         fe_NewSwatchSetColor(use_color_swatch, color);
  10507.  
  10508.     if (use_image_toggle != NULL) {
  10509.         XmToggleButtonGadgetSetState(use_image_toggle, (bg_image != NULL),
  10510.                                      FALSE);
  10511.     }
  10512.  
  10513.     if (bg_image == NULL)
  10514.         bg_image = "";
  10515.  
  10516.     if (use_image_text != NULL)
  10517.         fe_TextFieldSetString(use_image_text, bg_image, FALSE);
  10518.  
  10519.     if (leave_image_toggle != NULL)
  10520.         XmToggleButtonGadgetSetState(leave_image_toggle, (leave_image_toggle != NULL),
  10521.                                      FALSE);
  10522. }
  10523.  
  10524. static void
  10525. fe_bg_group_get(Widget   parent,
  10526.                 LO_Color** color_r, char** bg_image_r, XP_Bool* leave_image_r)
  10527. {
  10528.     XP_Bool use_color = FALSE;
  10529.     XP_Bool use_image = FALSE;
  10530.     XP_Bool leave_image = FALSE;
  10531.     Widget  use_color_toggle;
  10532.     Widget  use_color_swatch;
  10533.     Widget  use_image_toggle;
  10534.     Widget  use_image_text;
  10535.     Widget  leave_image_toggle;
  10536.     
  10537.     use_color_toggle = XtNameToWidget(parent, "*" BG_GROUP_USECOLOR_TOGGLE);
  10538.     use_color_swatch = XtNameToWidget(parent, "*" BG_GROUP_USECOLOR_SWATCH);
  10539.     use_image_toggle = XtNameToWidget(parent, "*" BG_GROUP_USEIMAGE_TOGGLE);
  10540.     use_image_text = XtNameToWidget(parent, "*" BG_GROUP_USEIMAGE_TEXT);
  10541.     leave_image_toggle = XtNameToWidget(parent,"*" BG_GROUP_LEAVEIMAGE_TOGGLE);
  10542.     
  10543.     if (use_color_toggle != NULL)
  10544.         use_color = (XP_Bool)XmToggleButtonGadgetGetState(use_color_toggle);
  10545.  
  10546.     if (use_image_toggle != NULL)
  10547.         use_image = (XP_Bool)XmToggleButtonGadgetGetState(use_image_toggle);
  10548.  
  10549.     if (leave_image_toggle != NULL)
  10550.         leave_image=(XP_Bool)XmToggleButtonGadgetGetState(leave_image_toggle);
  10551.  
  10552.     if (color_r != NULL) {
  10553.         LO_Color* foo = NULL;
  10554.         if (use_color && use_color_swatch != NULL) {
  10555.             foo = XP_NEW(LO_Color);
  10556.             fe_NewSwatchGetColor(use_color_swatch, foo);
  10557.         }
  10558.         *color_r = foo;
  10559.     }
  10560.  
  10561.     if (bg_image_r != NULL) {
  10562.         char* tmp = NULL;
  10563.         if (use_image && use_image_text != NULL) {
  10564.             tmp = fe_TextFieldGetString(use_image_text);
  10565.             if (tmp != NULL) {
  10566.                 fe_StringTrim(tmp);
  10567.                 if (tmp[0] == '\0') {
  10568.                     XP_FREE(tmp);
  10569.                     tmp = NULL;
  10570.                 }
  10571.             }
  10572.         }
  10573.             
  10574.         *bg_image_r = tmp;
  10575.     }
  10576.  
  10577.     if (leave_image_r != NULL)
  10578.         *leave_image_r = leave_image;
  10579. }
  10580.  
  10581.  
  10582. static Widget
  10583. fe_tables_table_properties_create(MWContext* context, Widget parent,
  10584.                                   fe_EditorTablesTableStruct* w_data)
  10585. {
  10586.     Widget frame;
  10587.     Widget form;
  10588.     Widget line_width_toggle;
  10589.     Widget line_width_text;
  10590.     Widget line_width_units;
  10591.     Widget spacing_label;
  10592.     Widget spacing_text;
  10593.     Widget spacing_units;
  10594.     Widget padding_label;
  10595.     Widget padding_text;
  10596.     Widget padding_units;
  10597.     Widget width_toggle;
  10598.     Widget width_text;
  10599.     Widget width_units;
  10600.     Widget height_toggle;
  10601.     Widget height_text;
  10602.     Widget height_units;
  10603.     Widget caption_toggle;
  10604.     Widget caption_type;
  10605.     Widget alignframe;
  10606.     Widget alignBox;
  10607.     Widget equal_column_toggle;
  10608.     Widget bg_group;
  10609.     Arg args[16];
  10610.     Cardinal n;
  10611.     Cardinal nchildren;
  10612.     Widget children[32];
  10613.     Cardinal i;
  10614.     Dimension left_offset;
  10615.     Dimension height;
  10616.     Cardinal ncolumn_one;
  10617.     Cardinal ncolumn_two;
  10618.     Cardinal ncolumn_three;
  10619.     Widget top_guy;
  10620.  
  10621.     /*
  10622.      *    Alignment frame.
  10623.      */
  10624.     n = 0;
  10625.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  10626.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10627.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  10628.     alignframe = fe_CreateFrame(parent, "tableAlignment", args, n);
  10629.     XtManageChild(alignframe);
  10630.  
  10631.     n = 0;
  10632.     XtSetArg(args[n], XmNbuttons, fe_SimpleTableAlignment); n++;
  10633.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  10634.     alignBox = fe_CreateSimpleRadioGroup(alignframe, "tableAlignmentBox", 
  10635.                                          args, n);
  10636.     XtManageChild(alignBox);
  10637.     fe_SimpleRadioGroupSetWhich(alignBox, 0);
  10638.  
  10639.     n = 0;
  10640.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10641.     XtSetArg(args[n], XmNtopWidget, alignframe); n++;
  10642.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10643.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  10644.     frame = fe_CreateFrame(parent, "attributes", args, n);
  10645.     XtManageChild(frame);
  10646.  
  10647.     n = 0;
  10648.     form = XmCreateForm(frame, "attributes", args, n);
  10649.     XtManageChild(form);
  10650.  
  10651.     nchildren = 0;
  10652.     n = 0;
  10653.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;    
  10654.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10655.     caption_toggle = XmCreateToggleButtonGadget(form, "captionToggle",
  10656.                                                 args, n);
  10657.     children[nchildren++] = caption_toggle;
  10658.     XtAddCallback(caption_toggle, XmNvalueChangedCallback, 
  10659.                   fe_table_toggle_cb, (XtPointer)w_data);
  10660.  
  10661.     n = 0;
  10662.     XtSetArg(args[n], XmNmarginWidth, 0); n++;
  10663.     XtSetArg(args[n], XmNmarginHeight, 0); n++;
  10664.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  10665.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  10666.     XtSetArg(args[n], XmNleftWidget, caption_toggle); n++;
  10667.     XtSetArg(args[n], XmNbuttons, fe_SimpleOptionAboveBelow); n++;
  10668. #ifdef TABLES_USE_OPTION_MENU    
  10669.     caption_type = fe_CreateSimpleOptionMenu(form, "captionType", args, n);
  10670. #else
  10671.     XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); n++;
  10672.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  10673.     caption_type = fe_CreateSimpleRadioGroup(form, "captionType", args, n);
  10674. #endif
  10675.     children[nchildren++] = caption_type;
  10676.  
  10677.     XtManageChildren(children, nchildren);
  10678.     
  10679.     nchildren = 0;
  10680.     n = 0;
  10681.     line_width_toggle = XmCreateToggleButtonGadget(form,
  10682.                                                    "borderLineWidth",
  10683.                                                    args, n);
  10684.     children[nchildren++] = line_width_toggle;
  10685.     XtAddCallback(line_width_toggle, XmNvalueChangedCallback, 
  10686.                   fe_table_toggle_cb, (XtPointer)w_data);
  10687.  
  10688.     n = 0;
  10689.     spacing_label = XmCreateLabelGadget(form, "cellSpacingLabel", args, n);
  10690.     children[nchildren++] = spacing_label;
  10691.  
  10692.     n = 0;
  10693.     padding_label = XmCreateLabelGadget(form, "cellPaddingLabel", args, n);
  10694.     children[nchildren++] = padding_label;
  10695.  
  10696.     n = 0;
  10697.     width_toggle = XmCreateToggleButtonGadget(form, "tableWidthToggle",
  10698.                                               args, n);
  10699.     children[nchildren++] = width_toggle;
  10700.     XtAddCallback(width_toggle, XmNvalueChangedCallback, 
  10701.                   fe_table_toggle_cb, (XtPointer)w_data);
  10702.  
  10703.     n = 0;
  10704.     height_toggle = XmCreateToggleButtonGadget(form, "tableHeightToggle",
  10705.                                                args, n);
  10706.     children[nchildren++] = height_toggle;
  10707.     XtAddCallback(height_toggle, XmNvalueChangedCallback, 
  10708.                   fe_table_toggle_cb, (XtPointer)w_data);
  10709.  
  10710.     n = 0;
  10711.     equal_column_toggle = XmCreateToggleButtonGadget(form, "equalColumnWidth",
  10712.                                                      args, n);
  10713.     children[nchildren++] = equal_column_toggle;
  10714.  
  10715.     ncolumn_one = nchildren;
  10716.  
  10717.     left_offset = fe_get_offset_from_widest(children, nchildren);
  10718.  
  10719.     /*
  10720.      *    Make all the text dudes + swatch
  10721.      */
  10722.     n = 0;
  10723.     XtSetArg(args[n], XmNcolumns, 4); n++;
  10724.     line_width_text = fe_CreateTextField(form, "borderLineWidthText",
  10725.                                           args, n);
  10726.     children[nchildren++] = line_width_text;
  10727.     
  10728.     n = 0;
  10729.     spacing_text = fe_CreateTextField(form, "cellSpacingText", args, n);
  10730.     children[nchildren++] = spacing_text;
  10731.     
  10732.     n = 0;
  10733.     padding_text = fe_CreateTextField(form, "cellPaddingText", args, n);
  10734.     children[nchildren++] = padding_text;
  10735.     
  10736.     n = 0;
  10737.     width_text = fe_CreateTextField(form, "tableWidthText", args, n);
  10738.     children[nchildren++] = width_text;
  10739.     
  10740.     n = 0;
  10741.     height_text = fe_CreateTextField(form, "tableHeightText", args, n);
  10742.     children[nchildren++] = height_text;
  10743.  
  10744.     XtVaGetValues(line_width_text, XmNheight, &height, 0);
  10745.     
  10746.     ncolumn_two = nchildren - ncolumn_one;
  10747.  
  10748.     n = 0;
  10749.     line_width_units = XmCreateLabelGadget(form, "borderLineWidthUnits",
  10750.                                            args, n);
  10751.     children[nchildren++] = line_width_units;
  10752.  
  10753.     n = 0;
  10754.     spacing_units = XmCreateLabelGadget(form, "cellSpacingUnits", args, n);
  10755.     children[nchildren++] = spacing_units;
  10756.  
  10757.     n = 0;
  10758.     padding_units = XmCreateLabelGadget(form, "cellPaddingUnits", args, n);
  10759.     children[nchildren++] = padding_units;
  10760.  
  10761.     n = 0;
  10762.     XtSetArg(args[n], XmNbuttons, fe_SimpleOptionPixelPercent); n++;
  10763. #ifdef TABLES_USE_OPTION_MENU    
  10764.     width_units = fe_CreateSimpleOptionMenu(form, "tableWidthUnits", args, n);
  10765. #else
  10766.     XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); n++;
  10767.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  10768.     width_units = fe_CreateSimpleRadioGroup(form, "tableWidthUnits", args, n);
  10769. #endif
  10770.     children[nchildren++] = width_units;
  10771.  
  10772.     n = 0;
  10773.     XtSetArg(args[n], XmNbuttons, fe_SimpleOptionPixelPercent); n++;
  10774. #ifdef TABLES_USE_OPTION_MENU    
  10775.     height_units = fe_CreateSimpleOptionMenu(form, "tableHeightUnits",args, n);
  10776. #else
  10777.     XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); n++;
  10778.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  10779.     height_units = fe_CreateSimpleRadioGroup(form, "tableHeightUnits",args, n);
  10780. #endif
  10781.     children[nchildren++] = height_units;
  10782.  
  10783.     ncolumn_three = nchildren - (ncolumn_two + ncolumn_one);
  10784.  
  10785.     /*
  10786.      *    Go back and do attachments.
  10787.      */
  10788.     n = 0;
  10789.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10790.     XtSetArg(args[n], XmNtopWidget, caption_type); n++;
  10791.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10792.     XtSetValues(line_width_toggle, args, n);
  10793.     
  10794.     n = 0;
  10795.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10796.     XtSetArg(args[n], XmNtopWidget, caption_type); n++;
  10797.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10798.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  10799.     XtSetValues(line_width_text, args, n);
  10800.     
  10801.     n = 0;
  10802.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10803.     XtSetArg(args[n], XmNtopWidget, caption_type); n++;
  10804.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  10805.     XtSetArg(args[n], XmNleftWidget, line_width_text); n++;
  10806.     XtSetValues(line_width_units, args, n);
  10807.  
  10808.     top_guy = line_width_text;
  10809.     /* column 1 */
  10810.     for (i = 1; i < ncolumn_one; i++) {
  10811.         Widget label_guy = children[i];
  10812.         Widget text_guy = NULL;
  10813.         Widget unit_guy = NULL;
  10814.  
  10815.         n = 0;
  10816.         XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10817.         XtSetArg(args[n], XmNtopWidget, top_guy); n++;
  10818.         XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10819.         XtSetValues(label_guy, args, n);
  10820.  
  10821.         /* column 2 */
  10822.         if (i < ncolumn_two) {
  10823.             text_guy = children[i+ncolumn_one];
  10824.             n = 0;
  10825.             XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10826.             XtSetArg(args[n], XmNtopWidget, top_guy); n++;
  10827.             XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET);n++;
  10828.             XtSetArg(args[n], XmNleftWidget, line_width_text); n++;
  10829.             XtSetArg(args[n], XmNrightAttachment,XmATTACH_OPPOSITE_WIDGET);n++;
  10830.             XtSetArg(args[n], XmNrightWidget, line_width_text); n++;
  10831.             XtSetValues(text_guy, args, n);
  10832.         }
  10833.  
  10834.         /* column 3 */
  10835.         if (i < ncolumn_three) {
  10836.             unit_guy = children[i+ncolumn_one+ncolumn_two];
  10837.             n = 0;
  10838.             XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10839.             XtSetArg(args[n], XmNtopWidget, top_guy); n++;
  10840.             XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  10841.             XtSetArg(args[n], XmNleftWidget, line_width_text); n++;
  10842.             XtSetValues(unit_guy, args, n);
  10843.         }
  10844.  
  10845.         top_guy = text_guy;
  10846.     }
  10847. #if 0
  10848.     check_children(children, nchildren);
  10849. #endif
  10850.     XtManageChildren(children, nchildren);
  10851.  
  10852.     /*
  10853.      *    Background..
  10854.      */
  10855.     n = 0;
  10856.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10857.     XtSetArg(args[n], XmNtopWidget, frame); n++;
  10858.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10859.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  10860.     bg_group = fe_create_background_group(parent, "background", args, n);
  10861.     XtManageChild(bg_group);
  10862.  
  10863.     w_data->line_width_toggle = line_width_toggle;
  10864.     w_data->line_width_text = line_width_text;
  10865.     w_data->spacing_text = spacing_text;
  10866.     w_data->padding_text = padding_text;
  10867.     w_data->width_toggle = width_toggle;
  10868.     w_data->width_text = width_text;
  10869.     w_data->width_units = width_units;
  10870.     w_data->height_toggle = height_toggle;
  10871.     w_data->height_text = height_text;
  10872.     w_data->height_units = height_units;
  10873.     w_data->caption_toggle = caption_toggle;
  10874.     w_data->caption_type = caption_type;
  10875.     w_data->alignBox = alignBox;
  10876.     w_data->equal_column_toggle = equal_column_toggle;
  10877.     w_data->bg_group = bg_group;
  10878.  
  10879.     return alignframe;
  10880. }
  10881.  
  10882. static Widget
  10883. fe_tables_table_create_create(MWContext* context, Widget parent,
  10884.                               fe_EditorTablesTableStruct* w_data)
  10885. {
  10886.     Widget form;
  10887.     Widget rows_label;
  10888.     Widget rows_text;
  10889.     Widget columns_label;
  10890.     Widget columns_text;
  10891.     Widget attributes;
  10892.     Arg args[8];
  10893.     Cardinal n;
  10894.     Cardinal nchildren = 0;
  10895.     Widget children[6];
  10896.  
  10897.     n = 0;
  10898.     form = XmCreateForm(parent, "tablesCreate", args, n);
  10899.     XtManageChild(form);
  10900.  
  10901.     n = 0;
  10902.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  10903.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10904.     rows_label = XmCreateLabelGadget(form, "tableRowsLabel", args, n);
  10905.     children[nchildren++] = rows_label;
  10906.  
  10907.     n = 0;
  10908.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  10909.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  10910.     XtSetArg(args[n], XmNleftWidget, children[nchildren-1]); n++;
  10911.     XtSetArg(args[n], XmNcolumns, 4); n++;
  10912.     rows_text = fe_CreateTextField(form, "tableRowsText", args, n);
  10913.     children[nchildren++] = rows_text;
  10914.  
  10915.     n = 0;
  10916.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  10917.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  10918.     XtSetArg(args[n], XmNleftWidget, children[nchildren-1]); n++;
  10919.     columns_label = XmCreateLabelGadget(form, "tableColumnsLabel", args, n);
  10920.     children[nchildren++] = columns_label;
  10921.  
  10922.     n = 0;
  10923.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  10924.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  10925.     XtSetArg(args[n], XmNleftWidget, children[nchildren-1]); n++;
  10926.     XtSetArg(args[n], XmNcolumns, 4); n++;
  10927.     columns_text = fe_CreateTextField(form, "tableColumnsText", args, n);
  10928.     children[nchildren++] = columns_text;
  10929.  
  10930.     attributes = fe_tables_table_properties_create(context, form, w_data);
  10931.     children[nchildren++] = attributes;
  10932.  
  10933.     /*
  10934.      *    Override attachments on top guy in properties section.
  10935.      */
  10936.     n = 0;
  10937.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  10938.     XtSetArg(args[n], XmNtopWidget, rows_text); n++;
  10939.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  10940.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  10941.     XtSetValues(attributes, args, n);
  10942.  
  10943. #if 0
  10944.     check_children(children, nchildren);
  10945. #endif
  10946.     XtManageChildren(children, nchildren);
  10947.  
  10948.     w_data->number_rows_text = rows_text;
  10949.     w_data->number_columns_text = columns_text;
  10950.  
  10951.     return form;
  10952. }
  10953.  
  10954. static void
  10955. fe_table_properties_common_init(MWContext* context,
  10956.                                 EDT_AllTableData* table_data,
  10957.                                 fe_EditorTablesTableStruct* w_data)
  10958. {
  10959.     Boolean is_nested;
  10960.     Widget  widget;
  10961.  
  10962.     if (w_data->number_rows_text != NULL) /* inserting */
  10963.         is_nested = EDT_IsInsertPointInTable(context);
  10964.     else
  10965.         is_nested = EDT_IsInsertPointInNestedTable(context);
  10966.  
  10967.     /* set the border width parts */
  10968.     fe_table_tbr_set(context, w_data->line_width_toggle,
  10969.                      w_data->line_width_text, NULL,
  10970.                      table_data->td.bBorderWidthDefined,
  10971.                      table_data->td.iBorderWidth,
  10972.                      0);
  10973.     fe_set_numeric_text_field(w_data->spacing_text,
  10974.                               table_data->td.iCellSpacing);
  10975.     fe_set_numeric_text_field(w_data->padding_text,
  10976.                               table_data->td.iCellPadding);
  10977.  
  10978.     fe_table_tbr_set(context, w_data->width_toggle,
  10979.                      w_data->width_text, w_data->width_units,
  10980.                      table_data->td.bWidthDefined,
  10981.                      table_data->td.iWidth,
  10982.                      (table_data->td.bWidthPercent));
  10983.  
  10984.     widget = fe_SimpleRadioGroupGetChild(w_data->width_units, 1);
  10985.     fe_table_percent_label_set(widget, is_nested);
  10986.     
  10987.     fe_table_tbr_set(context, w_data->height_toggle,
  10988.                      w_data->height_text, w_data->height_units,
  10989.                      table_data->td.bHeightDefined,
  10990.                      table_data->td.iHeight,
  10991.                      (table_data->td.bHeightPercent));
  10992.     widget = fe_SimpleRadioGroupGetChild(w_data->height_units, 1);
  10993.     fe_table_percent_label_set(widget, is_nested);
  10994.  
  10995.     /*
  10996.      *    Background stuff
  10997.      */
  10998.     fe_bg_group_set(w_data->bg_group,
  10999.                     table_data->td.pColorBackground,
  11000.                     table_data->td.pBackgroundImage,
  11001.                     table_data->td.bBackgroundNoSave);
  11002.  
  11003.     fe_table_tbr_set(context, w_data->caption_toggle,
  11004.                      NULL, w_data->caption_type,
  11005.                      table_data->has_caption,
  11006.                      0,
  11007.                      (table_data->cd.align != ED_ALIGN_ABSTOP));
  11008.  
  11009.     XmToggleButtonGadgetSetState(w_data->equal_column_toggle,
  11010.                                  table_data->td.bUseCols,
  11011.                                  FALSE);
  11012.  
  11013.     /* we don't have default for alignment yet, so we need to subtract one
  11014.      * from index 
  11015.        */
  11016.     fe_SimpleRadioGroupSetWhich(w_data->alignBox,
  11017.                                 fe_ED_Alignment_to_index(table_data->td.align)-1);
  11018. }
  11019.  
  11020. static void
  11021. fe_tables_table_properties_init(MWContext* context,
  11022.                                 fe_EditorTablesTableStruct* w_data)
  11023. {
  11024.     EDT_AllTableData table_data;
  11025.  
  11026.     memset(&table_data, 0, sizeof(EDT_AllTableData));
  11027.  
  11028.     if (!fe_EditorTableGetData(context, &table_data))
  11029.         return;
  11030.  
  11031.     w_data->number_rows_text = NULL;
  11032.     w_data->number_columns_text = NULL;
  11033.     fe_table_properties_common_init(context, &table_data, w_data);
  11034. }
  11035.  
  11036. static void
  11037. fe_table_properties_common_set(MWContext* context,
  11038.                                EDT_AllTableData* table_data,
  11039.                                fe_EditorTablesTableStruct* w_data)
  11040. {
  11041.     int alignment;
  11042.  
  11043.     /*FIXME*/
  11044.     /*
  11045.      *    Don't know what this slot is, WinFE doesn't use it??
  11046.      */
  11047.     table_data->td.malign = ED_ALIGN_DEFAULT;
  11048.  
  11049.     table_data->td.bBorderWidthDefined =
  11050.         XmToggleButtonGetState(w_data->line_width_toggle);
  11051.     table_data->td.iBorderWidth = 
  11052.         fe_get_numeric_text_field(w_data->line_width_text);
  11053.  
  11054.     table_data->td.iCellSpacing = 
  11055.         fe_get_numeric_text_field(w_data->spacing_text);
  11056.     table_data->td.iCellPadding = 
  11057.         fe_get_numeric_text_field(w_data->padding_text);
  11058.  
  11059.     table_data->td.bWidthDefined =
  11060.         XmToggleButtonGetState(w_data->width_toggle);
  11061.     table_data->td.iWidth =
  11062.         fe_get_numeric_text_field(w_data->width_text);
  11063.     table_data->td.bWidthPercent =
  11064.         (fe_SimpleRadioGroupGetWhich(w_data->width_units) == 1);
  11065.  
  11066.     table_data->td.bHeightDefined =
  11067.         XmToggleButtonGetState(w_data->height_toggle);
  11068.     table_data->td.iHeight =
  11069.         fe_get_numeric_text_field(w_data->height_text);
  11070.     table_data->td.bHeightPercent =
  11071.         (fe_SimpleRadioGroupGetWhich(w_data->height_units) == 1);
  11072.  
  11073.     alignment = fe_SimpleRadioGroupGetWhich(w_data->alignBox);
  11074.  
  11075.     switch(alignment) {
  11076.         case 0:
  11077.             table_data->td.align = ED_ALIGN_LEFT;
  11078.             break;
  11079.         case 1:
  11080.             table_data->td.align = ED_ALIGN_ABSCENTER;
  11081.             break;
  11082.         case 2:
  11083.             table_data->td.align = ED_ALIGN_RIGHT;
  11084.             break;
  11085.         default:
  11086.             XP_ASSERT(0);
  11087.             break;
  11088.     }
  11089.  
  11090.     /*
  11091.      *    Don't get the background stuff here, because none of it gets
  11092.      *    validated, and we don't want to bother when we validate.
  11093.      */
  11094.  
  11095.     table_data->has_caption = XmToggleButtonGetState(w_data->caption_toggle);
  11096.     table_data->td.bUseCols =
  11097.         XmToggleButtonGetState(w_data->equal_column_toggle);
  11098.  
  11099.     if (fe_SimpleRadioGroupGetWhich(w_data->caption_type) == 1)
  11100.         table_data->cd.align = ED_ALIGN_ABSBOTTOM;
  11101.     else
  11102.         table_data->cd.align = ED_ALIGN_ABSTOP;
  11103. }
  11104.  
  11105. static Boolean
  11106. fe_tables_table_properties_validate(MWContext* context,
  11107.                                     fe_EditorTablesTableStruct* w_data)
  11108. {
  11109.     EDT_AllTableData table_data;
  11110.     EDT_TableData*   t = &table_data.td;
  11111.     unsigned         errors[16];
  11112.     unsigned         nerrors = 0;
  11113.     EDT_TableData*   tmp = EDT_NewTableData();
  11114.  
  11115.     memset(&table_data, 0, sizeof(EDT_AllTableData));
  11116.     memcpy(&table_data.td, tmp, sizeof(EDT_TableData));
  11117.  
  11118.     fe_table_properties_common_set(context, &table_data, w_data);
  11119.  
  11120.     if (w_data->number_rows_text != NULL) {
  11121.         t->iRows = fe_get_numeric_text_field(w_data->number_rows_text);
  11122.         t->iColumns = 
  11123.             fe_get_numeric_text_field(w_data->number_columns_text);
  11124.      
  11125.         if (RANGE_CHECK(t->iRows, TABLE_MIN_ROWS, TABLE_MAX_ROWS))
  11126.             errors[nerrors++] = XFE_INVALID_TABLE_NROWS;
  11127.         if (RANGE_CHECK(t->iColumns, TABLE_MIN_COLUMNS, TABLE_MAX_COLUMNS))
  11128.             errors[nerrors++] = XFE_INVALID_TABLE_NCOLUMNS;
  11129.     }
  11130.  
  11131.     if (RANGE_CHECK(t->iBorderWidth, TABLE_MIN_BORDER, TABLE_MAX_BORDER))
  11132.         errors[nerrors++] = XFE_INVALID_TABLE_BORDER;
  11133.         
  11134.     if (RANGE_CHECK(t->iCellSpacing, TABLE_MIN_SPACING, TABLE_MAX_SPACING))
  11135.         errors[nerrors++] = XFE_INVALID_TABLE_SPACING;
  11136.         
  11137.     if (RANGE_CHECK(t->iCellPadding, TABLE_MIN_PADDING, TABLE_MAX_PADDING))
  11138.         errors[nerrors++] = XFE_INVALID_TABLE_PADDING;
  11139.  
  11140.     if (t->bWidthDefined) {
  11141.         if (t->bWidthPercent) {
  11142.             if (RANGE_CHECK(t->iWidth,
  11143.                         TABLE_MIN_PERCENT_WIDTH, TABLE_MAX_PERCENT_WIDTH))
  11144.                 errors[nerrors++] = XFE_INVALID_TABLE_WIDTH;
  11145.         } else {
  11146.             if (RANGE_CHECK(t->iWidth,
  11147.                             TABLE_MIN_PIXEL_WIDTH, TABLE_MAX_PIXEL_WIDTH))
  11148.                 errors[nerrors++] = XFE_INVALID_TABLE_WIDTH;
  11149.         }
  11150.     }
  11151.         
  11152.     if (t->bHeightDefined) {
  11153.         if (t->bHeightPercent) {
  11154.             if (RANGE_CHECK(t->iHeight,
  11155.                         TABLE_MIN_PERCENT_HEIGHT, TABLE_MAX_PERCENT_HEIGHT))
  11156.                 errors[nerrors++] = XFE_INVALID_TABLE_HEIGHT;
  11157.         } else {
  11158.             if (RANGE_CHECK(t->iHeight,
  11159.                             TABLE_MIN_PIXEL_HEIGHT, TABLE_MAX_PIXEL_HEIGHT))
  11160.                 errors[nerrors++] = XFE_INVALID_TABLE_HEIGHT;
  11161.         }
  11162.     }
  11163.  
  11164.     EDT_FreeTableData(tmp);
  11165.  
  11166.     if (nerrors > 0) {
  11167.         fe_editor_range_error_dialog(context, w_data->spacing_text,
  11168.                                      errors, nerrors);
  11169.         return FALSE;
  11170.     }
  11171.  
  11172.     return TRUE;
  11173. }
  11174.  
  11175. static void
  11176. fe_tables_table_properties_set(MWContext* context,
  11177.                                fe_EditorTablesTableStruct* w_data)
  11178. {
  11179.     EDT_AllTableData table_data;
  11180.     EDT_TableData*   tmp = EDT_NewTableData();
  11181.  
  11182.     memset(&table_data, 0, sizeof(EDT_AllTableData));
  11183.     memcpy(&table_data.td, tmp, sizeof(EDT_TableData));
  11184.  
  11185.     if (!fe_EditorTableGetData(context, &table_data))
  11186.         return;
  11187.  
  11188.     fe_table_properties_common_set(context, &table_data, w_data);
  11189.  
  11190.     /* Get the background stuff, because ..common_set() did not. */
  11191.     fe_bg_group_get(w_data->bg_group,
  11192.                     &table_data.td.pColorBackground,
  11193.                     &table_data.td.pBackgroundImage,
  11194.                     &table_data.td.bBackgroundNoSave);
  11195.  
  11196.     fe_EditorTableSetData(context, &table_data);
  11197.  
  11198.     if (table_data.td.pColorBackground)
  11199.         XP_FREE(table_data.td.pColorBackground);
  11200.     if (table_data.td.pBackgroundImage)
  11201.         XP_FREE(table_data.td.pBackgroundImage);
  11202.  
  11203.     EDT_FreeTableData(tmp);
  11204. }
  11205.  
  11206. static void
  11207. fe_tables_table_create_init(MWContext* context,
  11208.                             fe_EditorTablesTableStruct* w_data)
  11209. {
  11210.     EDT_AllTableData table_data;
  11211.     EDT_TableData*   tmp;
  11212.  
  11213.     memset(&table_data, 0, sizeof(EDT_AllTableData));
  11214.  
  11215.     tmp = EDT_NewTableData();
  11216.     memcpy(&table_data.td, tmp, sizeof(EDT_TableData));
  11217.  
  11218.     fe_set_numeric_text_field(w_data->number_rows_text,
  11219.                               table_data.td.iRows);
  11220.     fe_set_numeric_text_field(w_data->number_columns_text,
  11221.                               table_data.td.iColumns);
  11222.  
  11223.     w_data->inserting = TRUE; /* reset after first insert */
  11224.     fe_table_properties_common_init(context, &table_data, w_data);
  11225.  
  11226.     EDT_FreeTableData(tmp);
  11227. }
  11228.  
  11229. static void
  11230. fe_tables_table_create_set(MWContext* context,
  11231.                               fe_EditorTablesTableStruct* w_data)
  11232. {
  11233.     EDT_AllTableData table_data;
  11234.     EDT_TableData*   tmp = EDT_NewTableData();
  11235.  
  11236.     memset(&table_data, 0, sizeof(EDT_AllTableData));
  11237.     memcpy(&table_data.td, tmp, sizeof(EDT_TableData));
  11238.  
  11239.     table_data.td.iRows = 
  11240.         fe_get_numeric_text_field(w_data->number_rows_text);
  11241.     table_data.td.iColumns = 
  11242.         fe_get_numeric_text_field(w_data->number_columns_text);
  11243.      
  11244.     fe_table_properties_common_set(context, &table_data, w_data);
  11245.  
  11246.     /* Get the background stuff, because ..common_set() did not. */
  11247.     fe_bg_group_get(w_data->bg_group,
  11248.                     &table_data.td.pColorBackground,
  11249.                     &table_data.td.pBackgroundImage,
  11250.                     &table_data.td.bBackgroundNoSave);
  11251.  
  11252.     if (w_data->inserting) {
  11253.         fe_EditorTableInsert(context, &table_data);
  11254.         w_data->inserting = FALSE; /* can only insert once */
  11255.     } else {
  11256.         fe_EditorTableSetData(context, &table_data);
  11257.     }
  11258.  
  11259.     if (table_data.td.pColorBackground)
  11260.         XP_FREE(table_data.td.pColorBackground);
  11261.     if (table_data.td.pBackgroundImage)
  11262.         XP_FREE(table_data.td.pBackgroundImage);
  11263.  
  11264.     EDT_FreeTableData(tmp);
  11265. }
  11266.  
  11267. static void
  11268. fe_cancel_button_set_cancel(Widget widget, Boolean can_cancel)
  11269. {
  11270.     char* name;
  11271.     char* string;
  11272.     XmString xm_string;
  11273.  
  11274.     if (can_cancel)
  11275.         name = "cancelLabelString";
  11276.     else
  11277.         name = "closeLabelString";
  11278.  
  11279.     string = XfeSubResourceGetWidgetStringValue(widget, name, XmCXmString);
  11280.     if (!string)
  11281.       string = name;
  11282.     xm_string = XmStringCreateLocalized(string);
  11283.  
  11284.     XtVaSetValues(widget, XmNlabelString, xm_string, 0);
  11285.  
  11286.     XmStringFree(xm_string);
  11287. }
  11288.  
  11289. void
  11290. fe_EditorTableCreateDialogDo(MWContext* context)
  11291. {
  11292.     Widget dialog;
  11293.     Widget form;
  11294.     Widget apply_button;
  11295.     Widget cancel_button;
  11296.     fe_EditorTablesTableStruct data;
  11297.     int done;
  11298.  
  11299.     /*
  11300.      *    Make prompt with ok, cancel, apply, separator.
  11301.      */
  11302.     form = fe_CreatePromptDialog(context, "tableCreateDialog",
  11303.                                  TRUE, TRUE, TRUE, TRUE, TRUE);
  11304.     dialog = XtParent(form);
  11305.  
  11306.     fe_tables_table_create_create(context, form, &data);
  11307.     fe_tables_table_create_init(context, &data);
  11308.  
  11309.     /*
  11310.      *   Add a bunch of callbacks to the buttons.
  11311.      */
  11312.     XtAddCallback(form, XmNokCallback, fe_hrule_ok_cb, &done);
  11313.     XtAddCallback(form, XmNapplyCallback, fe_hrule_apply_cb, &done);
  11314.     XtAddCallback(form, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  11315.     XtAddCallback(form, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  11316.  
  11317.     apply_button = XmSelectionBoxGetChild(form, XmDIALOG_APPLY_BUTTON);
  11318.     XtVaSetValues(apply_button, XmNsensitive, FALSE, 0);
  11319.     cancel_button = XmSelectionBoxGetChild(form, XmDIALOG_CANCEL_BUTTON);
  11320.     fe_cancel_button_set_cancel(cancel_button, TRUE);
  11321.  
  11322.     /*
  11323.      *    Popup.
  11324.      */
  11325.     XtManageChild(form);
  11326.  
  11327.     /*
  11328.      *    Wait.
  11329.      */
  11330.     fe_NukeBackingStore(dialog); /* what does this do? */
  11331.  
  11332.     done = XmDIALOG_NONE;
  11333.     while (done == XmDIALOG_NONE) {
  11334.         fe_EventLoop();
  11335.  
  11336.         if (done == XmDIALOG_OK_BUTTON || done == XmDIALOG_APPLY_BUTTON) {
  11337.             if (fe_tables_table_properties_validate(context, &data)) {
  11338.                 fe_tables_table_create_set(context, &data);
  11339.                 
  11340.                 if (done == XmDIALOG_APPLY_BUTTON) {
  11341.                     fe_cancel_button_set_cancel(cancel_button, FALSE);
  11342.                     done = XmDIALOG_NONE;
  11343.                 }
  11344.             } else {
  11345.                 done = XmDIALOG_NONE;
  11346.             }
  11347.         }
  11348.     }
  11349.  
  11350.     if (done != XFE_DIALOG_DESTROY_BUTTON)
  11351.         XtDestroyWidget(dialog);
  11352. }
  11353.  
  11354. typedef struct fe_EditorTablesRowStruct
  11355. {
  11356.     Widget horizontal_alignment;
  11357.     Widget vertical_alignment;
  11358.     Widget bg_group;
  11359.     LO_Color color_value;
  11360. } fe_EditorTablesRowStruct;
  11361.  
  11362. static ED_Alignment
  11363. fe_index_to_ED_Alignment(unsigned index, Boolean horizontal)
  11364. {
  11365.   switch (index) {
  11366.   case 1: return (horizontal)? ED_ALIGN_LEFT: ED_ALIGN_ABSTOP;
  11367.   case 2: return ED_ALIGN_ABSCENTER;
  11368.   case 3: return (horizontal)? ED_ALIGN_RIGHT: ED_ALIGN_ABSBOTTOM;
  11369.   case 4: if (!horizontal) return ED_ALIGN_BASELINE; /*FALLTHRU*/
  11370.   case 0:
  11371.   default: return ED_ALIGN_DEFAULT;
  11372.   }
  11373. }
  11374.  
  11375. static void
  11376. fe_tables_row_properties_init(MWContext* context,
  11377.                      fe_EditorTablesRowStruct* w_data)
  11378. {
  11379. #if 0
  11380.     EDT_TableRowData row_data;
  11381.     Boolean enabled = TRUE;
  11382.  
  11383.     memset(&row_data, 0, sizeof(EDT_TableRowData));
  11384.  
  11385.     if (!fe_EditorTableRowGetData(context, &row_data)) {
  11386.         row_data.align = ED_ALIGN_DEFAULT;
  11387.         row_data.valign = ED_ALIGN_DEFAULT;
  11388.         row_data.pColorBackground = NULL;
  11389.         enabled = FALSE;
  11390.     }
  11391.  
  11392.     fe_SimpleRadioGroupSetWhich(w_data->horizontal_alignment,
  11393.                                 fe_ED_Alignment_to_index(row_data.align));
  11394.     fe_SimpleRadioGroupSetSensitive(w_data->horizontal_alignment, enabled);
  11395.  
  11396.     fe_SimpleRadioGroupSetWhich(w_data->vertical_alignment,
  11397.                                 fe_ED_Alignment_to_index(row_data.valign));
  11398.     fe_SimpleRadioGroupSetSensitive(w_data->vertical_alignment, enabled);
  11399.  
  11400.     /*
  11401.      *    Background stuff
  11402.      */
  11403.     fe_bg_group_set(w_data->bg_group,
  11404.                     row_data.pColorBackground,
  11405.                     row_data.pBackgroundImage,
  11406.                     row_data.bBackgroundNoSave);
  11407. #else
  11408.     EDT_TableRowData* row_data = EDT_GetTableRowData(context);
  11409.     Boolean enabled = TRUE;
  11410.  
  11411.     if (!row_data) {
  11412.         row_data = EDT_NewTableRowData();
  11413.         enabled = FALSE;
  11414.     }
  11415.  
  11416.     if (!row_data)
  11417.         return; /* oops */
  11418.  
  11419.     fe_SimpleRadioGroupSetWhich(w_data->horizontal_alignment,
  11420.                                 fe_ED_Alignment_to_index(row_data->align));
  11421.     fe_SimpleRadioGroupSetSensitive(w_data->horizontal_alignment, enabled);
  11422.  
  11423.     fe_SimpleRadioGroupSetWhich(w_data->vertical_alignment,
  11424.                                 fe_ED_Alignment_to_index(row_data->valign));
  11425.     fe_SimpleRadioGroupSetSensitive(w_data->vertical_alignment, enabled);
  11426.  
  11427.     /*
  11428.      *    Background stuff
  11429.      */
  11430.     fe_bg_group_set(w_data->bg_group,
  11431.                     row_data->pColorBackground,
  11432.                     row_data->pBackgroundImage,
  11433.                     row_data->bBackgroundNoSave);
  11434.  
  11435.     EDT_FreeTableRowData(row_data);
  11436. #endif
  11437. }
  11438.  
  11439. static void
  11440. fe_tables_row_properties_set(MWContext* context,
  11441.                      fe_EditorTablesRowStruct* w_data)
  11442. {
  11443.     EDT_TableRowData row_data;
  11444.     unsigned index;
  11445.  
  11446.     memset(&row_data, 0, sizeof(EDT_TableRowData));
  11447.  
  11448.     index = fe_SimpleRadioGroupGetWhich(w_data->horizontal_alignment);
  11449.     row_data.align = fe_index_to_ED_Alignment(index, TRUE);
  11450.  
  11451.     index = fe_SimpleRadioGroupGetWhich(w_data->vertical_alignment);
  11452.     row_data.valign = fe_index_to_ED_Alignment(index, FALSE);
  11453.  
  11454.     /*
  11455.      *    Background stuff
  11456.      */
  11457.     fe_bg_group_get(w_data->bg_group,
  11458.                     &row_data.pColorBackground,
  11459.                     &row_data.pBackgroundImage,
  11460.                     &row_data.bBackgroundNoSave);
  11461.  
  11462.     fe_EditorTableRowSetData(context, &row_data);
  11463.  
  11464.     if (row_data.pColorBackground)
  11465.         XP_FREE(row_data.pColorBackground);
  11466.     if (row_data.pBackgroundImage)
  11467.         XP_FREE(row_data.pBackgroundImage);
  11468. }
  11469.  
  11470. static Widget
  11471. fe_create_table_text_alignment_group(Widget parent, char* name,
  11472.                                      Arg* p_args, Cardinal p_n,
  11473.                                      Widget* h, Widget* v)
  11474. {
  11475.     Widget frame;
  11476.     Widget rc;
  11477.     Widget sub_rc;
  11478.     Widget horizontal_label;
  11479.     Widget horizontal_alignment;
  11480.     Widget vertical_label;
  11481.     Widget vertical_alignment;
  11482.     Arg args[16];
  11483.     Cardinal n;
  11484.     Widget children[8];
  11485.     Cardinal nchildren;
  11486.  
  11487.     frame = fe_CreateFrame(parent, name, p_args, p_n);
  11488.     XtManageChild(frame);
  11489.  
  11490.     n = 0;
  11491.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  11492.     rc = XmCreateRowColumn(frame, "textAlignment", args, n);
  11493.     XtManageChild(rc);
  11494.  
  11495.     n = 0;
  11496.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  11497.     sub_rc = XmCreateRowColumn(rc, "horizontal", args, n);
  11498.     XtManageChild(sub_rc);
  11499.  
  11500.     nchildren = 0;
  11501.     n = 0;
  11502.     horizontal_label = XmCreateLabelGadget(sub_rc, "horizontalLabel", args, n);
  11503.     children[nchildren++] = horizontal_label;
  11504.  
  11505.     n = 0;
  11506.     XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_BEGINNING); n++;
  11507.     XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++;
  11508.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  11509.     XtSetArg(args[n], XmNbuttons, fe_SimpleOptionHorizontalAlignment); n++;
  11510.     horizontal_alignment = fe_CreateSimpleRadioGroup(sub_rc,
  11511.                                              "horizontalAlignment", args, n);
  11512.     children[nchildren++] = horizontal_alignment;
  11513.  
  11514.     XtManageChildren(children, nchildren);
  11515.  
  11516.     n = 0;
  11517.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  11518.     sub_rc = XmCreateRowColumn(rc, "vertical", args, n);
  11519.     XtManageChild(sub_rc);
  11520.  
  11521.     nchildren = 0;
  11522.     n = 0;
  11523.     vertical_label = XmCreateLabelGadget(sub_rc, "verticalLabel", args, n);
  11524.     children[nchildren++] = vertical_label;
  11525.  
  11526.     n = 0;
  11527.     XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_BEGINNING); n++;
  11528.     XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++;
  11529.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  11530.     XtSetArg(args[n], XmNbuttons, fe_SimpleOptionVerticalAlignment); n++;
  11531.     vertical_alignment = fe_CreateSimpleRadioGroup(sub_rc,
  11532.                                              "verticalAlignment", args, n);
  11533.     children[nchildren++] = vertical_alignment;
  11534.  
  11535.     XtManageChildren(children, nchildren);
  11536.  
  11537.     *v = vertical_alignment;
  11538.     *h = horizontal_alignment;
  11539.  
  11540.     return frame;
  11541. }
  11542.  
  11543. static Widget
  11544. fe_tables_row_properties_create(MWContext* context, Widget parent,
  11545.                      fe_EditorTablesRowStruct* w_data)
  11546. {
  11547.     Widget outside_form;
  11548.     Widget frame;
  11549.     Widget horizontal_alignment;
  11550.     Widget vertical_alignment;
  11551.     Widget bg_group;
  11552.     Arg args[16];
  11553.     Cardinal n;
  11554.     Widget children[8];
  11555.     Cardinal nchildren;
  11556.  
  11557.     outside_form = parent;
  11558.  
  11559.     nchildren = 0;
  11560.     n = 0;
  11561.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  11562.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  11563.     frame = fe_create_table_text_alignment_group(outside_form,
  11564.                                                  "textAlignment", args, n,
  11565.                                                  &horizontal_alignment,
  11566.                                                  &vertical_alignment);
  11567.     children[nchildren++] = frame;
  11568.  
  11569.     /*
  11570.      *    Background..
  11571.      */
  11572.     n = 0;
  11573.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  11574.     XtSetArg(args[n], XmNtopWidget, frame); n++;
  11575.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  11576.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  11577.     bg_group = fe_create_background_group(outside_form, "background", args, n);
  11578.     children[nchildren++] = bg_group;
  11579.  
  11580.     XtManageChildren(children, nchildren);
  11581.  
  11582.     w_data->horizontal_alignment = horizontal_alignment;
  11583.     w_data->vertical_alignment = vertical_alignment;
  11584.     w_data->bg_group = bg_group;
  11585.  
  11586.     return outside_form;
  11587. }
  11588.  
  11589. typedef struct fe_EditorTablesCellStruct
  11590. {
  11591.     Widget number_rows_text;
  11592.     Widget number_columns_text;
  11593.     Widget line_width_text;
  11594.     Widget horizontal_alignment;
  11595.     Widget vertical_alignment;
  11596.     Widget header_style;
  11597.     Widget wrap_text;
  11598.     Widget width_toggle;
  11599.     Widget width_text;
  11600.     Widget width_units;
  11601.     Widget height_toggle;
  11602.     Widget height_text;
  11603.     Widget height_units;
  11604.     Widget bg_group;
  11605.     LO_Color color_value;
  11606. } fe_EditorTablesCellStruct;
  11607.  
  11608. #if 1
  11609. static void
  11610. fe_cell_toggle_cb(Widget widget, XtPointer closure, XtPointer cb_data)
  11611. {
  11612.     fe_EditorTablesCellStruct* w_data = (fe_EditorTablesCellStruct*)closure;
  11613.     Boolean enabled = XmToggleButtonGetState(widget);
  11614.     MWContext* context = fe_WidgetToMWContext(widget);
  11615.     Widget  text = NULL;
  11616.     Widget  radio = NULL;
  11617.  
  11618.     if (widget == w_data->width_toggle) {
  11619.         text = w_data->width_text;
  11620.         radio = w_data->width_units;
  11621.     } else if (widget == w_data->height_toggle) {
  11622.         text = w_data->height_text;
  11623.         radio = w_data->height_units;
  11624.     }
  11625.  
  11626.     if (text != NULL)
  11627.         fe_TextFieldSetEditable(context, text, enabled);
  11628.     if (radio != NULL)
  11629.         fe_SimpleRadioGroupSetSensitive(radio, enabled);
  11630. }
  11631. #else
  11632. static void
  11633. fe_cell_toggle_cb(Widget widget, XtPointer closure, XtPointer cb_data)
  11634. {
  11635.     Widget  first = (Widget)closure;
  11636.     Boolean enabled = XmToggleButtonGetState(widget);
  11637.     MWContext* context = fe_WidgetToMWContext(widget);
  11638.     Widget*  children;
  11639.     Cardinal num_children;
  11640.     Cardinal i;
  11641.     Widget*  group = NULL;
  11642.  
  11643.     XtVaGetValues(XtParent(widget),
  11644.                   XmNchildren, &children,
  11645.                   XmNnumChildren, &num_children, 0);
  11646.  
  11647.     for (i = 0; i < num_children; i++) {
  11648.         if (children[i] == first) {
  11649.             group = &children[i];
  11650.             break;
  11651.         }
  11652.     }
  11653.  
  11654.     if (!group)
  11655.           return;
  11656.  
  11657.     for (i = 0; i < 3; i++) {
  11658.         if (group[i] == widget)
  11659.             break;
  11660.     }
  11661.  
  11662.     if (i == 0 || i == 1) { /* width & height */
  11663.         fe_TextFieldSetEditable(context, group[i+3], enabled);
  11664.         fe_SimpleRadioGroupSetSensitive(group[i+6], enabled);
  11665.     } else if (i == 2) { /* color */
  11666.         XtVaSetValues(group[i+3], XmNsensitive, enabled, 0);
  11667.     }
  11668. }
  11669.  
  11670. #endif
  11671.  
  11672. static Widget
  11673. fe_tables_cell_properties_create(MWContext* context, Widget parent,
  11674.                      fe_EditorTablesCellStruct* w_data)
  11675. {
  11676.     Widget form;
  11677.     Widget rows_label;
  11678.     Widget rows_text;
  11679.     Widget columns_label;
  11680.     Widget columns_text;
  11681.     Widget columns_units;
  11682.     Widget horizontal_alignment;
  11683.     Widget vertical_alignment;
  11684.     Widget align_frame;
  11685.     Widget other_frame;
  11686.     Widget rc;
  11687.     Widget header_style;
  11688.     Widget wrap_text;
  11689.     Widget width_toggle;
  11690.     Widget width_text;
  11691.     Widget width_units;
  11692.     Widget height_toggle;
  11693.     Widget height_text;
  11694.     Widget height_units;
  11695.     Widget bg_group;
  11696.     Arg args[16];
  11697.     Cardinal n;
  11698.     Cardinal nchildren = 0;
  11699.     Widget children[20];
  11700.     Dimension left_offset;
  11701.  
  11702.     form = parent;
  11703.  
  11704.     n = 0;
  11705.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  11706.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  11707.     rows_label = XmCreateLabelGadget(form, "cellRowsLabel", args, n);
  11708.     children[nchildren++] = rows_label;
  11709.  
  11710.     n = 0;
  11711.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  11712.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  11713.     XtSetArg(args[n], XmNleftWidget, children[nchildren-1]); n++;
  11714.     XtSetArg(args[n], XmNcolumns, 4); n++;
  11715.     rows_text = fe_CreateTextField(form, "cellRowsText", args, n);
  11716.     children[nchildren++] = rows_text;
  11717.  
  11718.     n = 0;
  11719.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  11720.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  11721.     XtSetArg(args[n], XmNleftWidget, children[nchildren-1]); n++;
  11722.     columns_label = XmCreateLabelGadget(form, "cellColumnsLabel", args, n);
  11723.     children[nchildren++] = columns_label;
  11724.  
  11725.     n = 0;
  11726.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  11727.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  11728.     XtSetArg(args[n], XmNleftWidget, children[nchildren-1]); n++;
  11729.     XtSetArg(args[n], XmNcolumns, 4); n++;
  11730.     columns_text = fe_CreateTextField(form, "cellColumnsText", args, n);
  11731.     children[nchildren++] = columns_text;
  11732.  
  11733.     n = 0;
  11734.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  11735.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  11736.     XtSetArg(args[n], XmNleftWidget, children[nchildren-1]); n++;
  11737.     columns_units = XmCreateLabelGadget(form, "cellColumnsUnits", args, n);
  11738.     children[nchildren++] = columns_units;
  11739.  
  11740.     n = 0;
  11741.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  11742.     XtSetArg(args[n], XmNtopWidget, rows_text); n++;
  11743.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  11744.     align_frame = fe_create_table_text_alignment_group(form, "textAlignment",
  11745.                                                       args, n,
  11746.                                                       &horizontal_alignment,
  11747.                                                       &vertical_alignment);
  11748.     children[nchildren++] = align_frame;
  11749.  
  11750.     n = 0;
  11751.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  11752.     XtSetArg(args[n], XmNtopWidget, rows_text); n++;
  11753.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  11754.     XtSetArg(args[n], XmNleftWidget, align_frame); n++;
  11755.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  11756.     XtSetArg(args[n], XmNbottomWidget, align_frame); n++;
  11757.     other_frame = fe_CreateFrame(form, "textOther", args, n);
  11758.     children[nchildren++] = other_frame;
  11759.  
  11760.     n = 0;
  11761.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  11762.     rc = XmCreateRowColumn(other_frame, "textOther", args, n);
  11763.     XtManageChild(rc);
  11764.  
  11765.     n = 0;
  11766.     header_style = XmCreateToggleButtonGadget(rc, "headerStyle", args, n);
  11767.     XtManageChild(header_style);
  11768.  
  11769.     n = 0;
  11770.     wrap_text = XmCreateToggleButtonGadget(rc, "nonBreaking", args, n);
  11771.     XtManageChild(wrap_text);
  11772.  
  11773.     XtManageChildren(children, nchildren); nchildren = 0;
  11774.  
  11775.     n = 0;
  11776.     width_toggle = XmCreateToggleButtonGadget(form, "cellWidthToggle",
  11777.                                               args, n);
  11778.     children[nchildren++] = width_toggle;
  11779.  
  11780.     n = 0;
  11781.     height_toggle = XmCreateToggleButtonGadget(form, "cellHeightToggle",
  11782.                                               args, n);
  11783.     children[nchildren++] = height_toggle;
  11784.  
  11785.     left_offset = fe_get_offset_from_widest(children, nchildren);
  11786.  
  11787.     n = 0;
  11788.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  11789.     XtSetArg(args[n], XmNtopWidget, align_frame); n++;
  11790.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  11791.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  11792.     XtSetArg(args[n], XmNcolumns, 4); n++;
  11793.     width_text = fe_CreateTextField(form, "cellWidthText", args, n);
  11794.     children[nchildren++] = width_text;
  11795.  
  11796.     n = 0;
  11797.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  11798.     XtSetArg(args[n], XmNtopWidget, width_text); n++;
  11799.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  11800.     XtSetArg(args[n], XmNleftWidget, width_text); n++;
  11801.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  11802.     XtSetArg(args[n], XmNrightWidget, width_text); n++;
  11803.     height_text = fe_CreateTextField(form, "cellHeightText", args, n);
  11804.     children[nchildren++] = height_text;
  11805.  
  11806.     XtVaSetValues(width_toggle,
  11807.                   XmNleftAttachment, XmATTACH_FORM,
  11808.                   XmNtopAttachment, XmATTACH_WIDGET,
  11809.                   XmNtopWidget, align_frame,
  11810.                   0);
  11811.     XtAddCallback(width_toggle, XmNvalueChangedCallback, 
  11812.                   fe_cell_toggle_cb, (XtPointer)w_data);
  11813.  
  11814.     XtVaSetValues(height_toggle,
  11815.                   XmNleftAttachment, XmATTACH_FORM,
  11816.                   XmNtopAttachment, XmATTACH_WIDGET,
  11817.                   XmNtopWidget, width_text,
  11818.                   0);
  11819.     XtAddCallback(height_toggle, XmNvalueChangedCallback, 
  11820.                   fe_cell_toggle_cb, (XtPointer)w_data);
  11821.  
  11822.     n = 0;
  11823.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  11824.     XtSetArg(args[n], XmNtopWidget, align_frame); n++;
  11825.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  11826.     XtSetArg(args[n], XmNleftWidget, width_text); n++;
  11827.     XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_BEGINNING); n++;
  11828.     XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); n++;
  11829.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  11830.     XtSetArg(args[n], XmNbuttons, fe_SimpleOptionPixelPercent); n++;
  11831.     width_units = fe_CreateSimpleRadioGroup(form, "widthUnits", args, n);
  11832.     children[nchildren++] = width_units;
  11833.  
  11834.     n = 0;
  11835.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  11836.     XtSetArg(args[n], XmNtopWidget, height_text); n++;
  11837.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  11838.     XtSetArg(args[n], XmNbottomWidget, height_text); n++;
  11839.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  11840.     XtSetArg(args[n], XmNleftWidget, width_text); n++;
  11841.     XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_BEGINNING); n++;
  11842.     XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); n++;
  11843.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  11844.     XtSetArg(args[n], XmNbuttons, fe_SimpleOptionPixelPercent); n++;
  11845.     height_units = fe_CreateSimpleRadioGroup(form, "heightUnits", args, n);
  11846.     children[nchildren++] = height_units;
  11847.  
  11848.     /*
  11849.      *    Background..
  11850.      */
  11851.     n = 0;
  11852.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  11853.     XtSetArg(args[n], XmNtopWidget, height_text); n++;
  11854.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  11855.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  11856.     bg_group = fe_create_background_group(form, "background", args, n);
  11857.     children[nchildren++] = bg_group;
  11858.  
  11859.     XtManageChildren(children, nchildren);
  11860.  
  11861.     w_data->number_rows_text = rows_text;
  11862.     w_data->number_columns_text = columns_text;
  11863.     w_data->horizontal_alignment = horizontal_alignment;
  11864.     w_data->vertical_alignment = vertical_alignment;
  11865.     w_data->header_style = header_style;
  11866.     w_data->wrap_text = wrap_text;
  11867.     w_data->width_toggle = width_toggle;
  11868.     w_data->width_text = width_text;
  11869.     w_data->width_units = width_units;
  11870.     w_data->height_toggle = height_toggle;
  11871.     w_data->height_text = height_text;
  11872.     w_data->height_units = height_units;
  11873.     w_data->bg_group = bg_group;
  11874.  
  11875.     return form;
  11876. }
  11877.  
  11878. static void
  11879. fe_tables_cell_properties_init(MWContext* context,
  11880.                      fe_EditorTablesCellStruct* w_data)
  11881. {
  11882. #if 0
  11883.     Boolean is_nested = EDT_IsInsertPointInNestedTable(context);
  11884.     EDT_TableCellData cell_data;
  11885.     Boolean enabled = TRUE;
  11886.     Widget  widget;
  11887.  
  11888.     memset(&cell_data, 0, sizeof(EDT_TableCellData));
  11889.  
  11890.     if (!fe_EditorTableCellGetData(context, &cell_data)) {
  11891.         memset(&cell_data, 0, sizeof(EDT_TableCellData));
  11892.         cell_data.iColSpan = 1;
  11893.         cell_data.iRowSpan = 1;
  11894.         cell_data.align = ED_ALIGN_DEFAULT;
  11895.         cell_data.valign = ED_ALIGN_DEFAULT;
  11896.         cell_data.pColorBackground = NULL;
  11897.         enabled = FALSE;
  11898.     }
  11899.  
  11900.     fe_set_numeric_text_field(w_data->number_rows_text,
  11901.                               cell_data.iRowSpan);
  11902.     fe_TextFieldSetEditable(context, w_data->number_rows_text, enabled);
  11903.     fe_set_numeric_text_field(w_data->number_columns_text,
  11904.                               cell_data.iColSpan);
  11905.     fe_TextFieldSetEditable(context, w_data->number_columns_text, enabled);
  11906.  
  11907.     fe_SimpleRadioGroupSetWhich(w_data->horizontal_alignment,
  11908.                                 fe_ED_Alignment_to_index(cell_data.align));
  11909.     fe_SimpleRadioGroupSetSensitive(w_data->horizontal_alignment, enabled);
  11910.  
  11911.     fe_SimpleRadioGroupSetWhich(w_data->vertical_alignment,
  11912.                                 fe_ED_Alignment_to_index(cell_data.valign));
  11913.     fe_SimpleRadioGroupSetSensitive(w_data->vertical_alignment, enabled);
  11914.  
  11915.     XmToggleButtonGadgetSetState(w_data->header_style, cell_data.bHeader,
  11916.                                  FALSE);
  11917.     XtVaSetValues(w_data->header_style, XmNsensitive, enabled, 0);
  11918.     XmToggleButtonGadgetSetState(w_data->wrap_text, cell_data.bNoWrap, FALSE);
  11919.     XtVaSetValues(w_data->wrap_text, XmNsensitive, enabled, 0);
  11920.  
  11921.     fe_table_tbr_set(context, w_data->width_toggle,
  11922.                      w_data->width_text, w_data->width_units,
  11923.                      cell_data.bWidthDefined,
  11924.                      cell_data.iWidth,
  11925.                      (cell_data.bWidthPercent));
  11926.     XtVaSetValues(w_data->width_toggle, XmNsensitive, enabled, 0);
  11927.  
  11928.     widget = fe_SimpleRadioGroupGetChild(w_data->width_units, 1);
  11929.     fe_table_percent_label_set(widget, is_nested);
  11930.  
  11931.     fe_table_tbr_set(context, w_data->height_toggle,
  11932.                      w_data->height_text, w_data->height_units,
  11933.                      cell_data.bHeightDefined,
  11934.                      cell_data.iHeight,
  11935.                      (cell_data.bHeightPercent));
  11936.     XtVaSetValues(w_data->height_toggle, XmNsensitive, enabled, 0);
  11937.  
  11938.     widget = fe_SimpleRadioGroupGetChild(w_data->height_units, 1);
  11939.     fe_table_percent_label_set(widget, is_nested);
  11940.     
  11941.     /*
  11942.      *    Background stuff
  11943.      */
  11944.     fe_bg_group_set(w_data->bg_group,
  11945.                     cell_data.pColorBackground,
  11946.                     cell_data.pBackgroundImage,
  11947.                     cell_data.bBackgroundNoSave);
  11948. #else
  11949.     Boolean is_nested = EDT_IsInsertPointInNestedTable(context);
  11950.     EDT_TableCellData* cell_data = EDT_GetTableCellData(context);
  11951.     Boolean enabled = TRUE;
  11952.     Widget  widget;
  11953.  
  11954.     if (!cell_data) {
  11955.         cell_data = EDT_NewTableCellData();
  11956.         enabled = FALSE;
  11957.     }
  11958.  
  11959.     fe_set_numeric_text_field(w_data->number_rows_text,
  11960.                               cell_data->iRowSpan);
  11961.     fe_TextFieldSetEditable(context, w_data->number_rows_text, enabled);
  11962.     fe_set_numeric_text_field(w_data->number_columns_text,
  11963.                               cell_data->iColSpan);
  11964.     fe_TextFieldSetEditable(context, w_data->number_columns_text, enabled);
  11965.  
  11966.     fe_SimpleRadioGroupSetWhich(w_data->horizontal_alignment,
  11967.                                 fe_ED_Alignment_to_index(cell_data->align));
  11968.     fe_SimpleRadioGroupSetSensitive(w_data->horizontal_alignment, enabled);
  11969.  
  11970.     fe_SimpleRadioGroupSetWhich(w_data->vertical_alignment,
  11971.                                 fe_ED_Alignment_to_index(cell_data->valign));
  11972.     fe_SimpleRadioGroupSetSensitive(w_data->vertical_alignment, enabled);
  11973.  
  11974.     XmToggleButtonGadgetSetState(w_data->header_style, cell_data->bHeader,
  11975.                                  FALSE);
  11976.     XtVaSetValues(w_data->header_style, XmNsensitive, enabled, 0);
  11977.     XmToggleButtonGadgetSetState(w_data->wrap_text, cell_data->bNoWrap, FALSE);
  11978.     XtVaSetValues(w_data->wrap_text, XmNsensitive, enabled, 0);
  11979.  
  11980.     fe_table_tbr_set(context, w_data->width_toggle,
  11981.                      w_data->width_text, w_data->width_units,
  11982.                      cell_data->bWidthDefined,
  11983.                      cell_data->iWidth,
  11984.                      (cell_data->bWidthPercent));
  11985.     XtVaSetValues(w_data->width_toggle, XmNsensitive, enabled, 0);
  11986.  
  11987.     widget = fe_SimpleRadioGroupGetChild(w_data->width_units, 1);
  11988.     fe_table_percent_label_set(widget, is_nested);
  11989.  
  11990.     fe_table_tbr_set(context, w_data->height_toggle,
  11991.                      w_data->height_text, w_data->height_units,
  11992.                      cell_data->bHeightDefined,
  11993.                      cell_data->iHeight,
  11994.                      (cell_data->bHeightPercent));
  11995.     XtVaSetValues(w_data->height_toggle, XmNsensitive, enabled, 0);
  11996.  
  11997.     widget = fe_SimpleRadioGroupGetChild(w_data->height_units, 1);
  11998.     fe_table_percent_label_set(widget, is_nested);
  11999.     
  12000.     /*
  12001.      *    Background stuff
  12002.      */
  12003.     fe_bg_group_set(w_data->bg_group,
  12004.                     cell_data->pColorBackground,
  12005.                     cell_data->pBackgroundImage,
  12006.                     cell_data->bBackgroundNoSave);
  12007.  
  12008.     EDT_FreeTableCellData(cell_data);
  12009. #endif
  12010. }
  12011.  
  12012. static void
  12013. fe_tables_cell_properties_set_validate_common(MWContext* context,
  12014.                                           EDT_TableCellData* cell_data,
  12015.                                           fe_EditorTablesCellStruct* w_data)
  12016. {
  12017.     unsigned index;
  12018.  
  12019.     cell_data->iRowSpan = 
  12020.         fe_get_numeric_text_field(w_data->number_rows_text);
  12021.     cell_data->iColSpan = 
  12022.         fe_get_numeric_text_field(w_data->number_columns_text);
  12023.      
  12024.     index = fe_SimpleRadioGroupGetWhich(w_data->horizontal_alignment);
  12025.     cell_data->align = fe_index_to_ED_Alignment(index, TRUE);
  12026.  
  12027.     index = fe_SimpleRadioGroupGetWhich(w_data->vertical_alignment);
  12028.     cell_data->valign = fe_index_to_ED_Alignment(index, FALSE);
  12029.  
  12030.     cell_data->bHeader = XmToggleButtonGadgetGetState(w_data->header_style);
  12031.     cell_data->bNoWrap = XmToggleButtonGadgetGetState(w_data->wrap_text);
  12032.  
  12033.     cell_data->bWidthDefined = XmToggleButtonGetState(w_data->width_toggle);
  12034.     cell_data->iWidth = fe_get_numeric_text_field(w_data->width_text);
  12035.     cell_data->bWidthPercent =
  12036.       (fe_SimpleRadioGroupGetWhich(w_data->width_units) == 1);
  12037.  
  12038.     cell_data->bHeightDefined =
  12039.         XmToggleButtonGetState(w_data->height_toggle);
  12040.     cell_data->iHeight =
  12041.         fe_get_numeric_text_field(w_data->height_text);
  12042.     cell_data->bHeightPercent =
  12043.         (fe_SimpleRadioGroupGetWhich(w_data->height_units) == 1);
  12044.  
  12045. }
  12046.  
  12047. static Boolean
  12048. fe_tables_cell_properties_validate(MWContext* context,
  12049.                                    fe_EditorTablesCellStruct* w_data)
  12050. {
  12051.     EDT_TableCellData cell_data;
  12052.     EDT_TableCellData* c = &cell_data;
  12053.     unsigned         errors[16];
  12054.     unsigned         nerrors = 0;
  12055.     
  12056.     memset(&cell_data, 0, sizeof(EDT_TableCellData));
  12057.  
  12058.     fe_tables_cell_properties_set_validate_common(context,
  12059.                                                   &cell_data,
  12060.                                                   w_data);
  12061.  
  12062.     if (RANGE_CHECK(c->iRowSpan, TABLE_MIN_ROWS, TABLE_MAX_ROWS))
  12063.         errors[nerrors++] = XFE_INVALID_CELL_NROWS;
  12064.     if (RANGE_CHECK(c->iColSpan, TABLE_MIN_COLUMNS, TABLE_MAX_COLUMNS))
  12065.         errors[nerrors++] = XFE_INVALID_CELL_NCOLUMNS;
  12066.  
  12067.     if (c->bWidthDefined) {
  12068.         if (c->bWidthPercent) {
  12069.             if (RANGE_CHECK(c->iWidth,
  12070.                         TABLE_MIN_PERCENT_WIDTH, TABLE_MAX_PERCENT_WIDTH))
  12071.                 errors[nerrors++] = XFE_INVALID_CELL_WIDTH;
  12072.         } else {
  12073.             if (RANGE_CHECK(c->iWidth,
  12074.                             TABLE_MIN_PIXEL_WIDTH, TABLE_MAX_PIXEL_WIDTH))
  12075.                 errors[nerrors++] = XFE_INVALID_CELL_WIDTH;
  12076.         }
  12077.     }
  12078.         
  12079.     if (c->bHeightDefined) {
  12080.         if (c->bHeightPercent) {
  12081.             if (RANGE_CHECK(c->iHeight,
  12082.                         TABLE_MIN_PERCENT_HEIGHT, TABLE_MAX_PERCENT_HEIGHT))
  12083.                 errors[nerrors++] = XFE_INVALID_CELL_HEIGHT;
  12084.         } else {
  12085.             if (RANGE_CHECK(c->iHeight,
  12086.                             TABLE_MIN_PIXEL_HEIGHT, TABLE_MAX_PIXEL_HEIGHT))
  12087.                 errors[nerrors++] = XFE_INVALID_CELL_HEIGHT;
  12088.         }
  12089.     }
  12090.  
  12091.     if (nerrors > 0) {
  12092.         fe_editor_range_error_dialog(context, w_data->number_rows_text,
  12093.                                      errors, nerrors);
  12094.         return FALSE;
  12095.     }
  12096.  
  12097.     return TRUE;
  12098. }
  12099.  
  12100. static void
  12101. fe_tables_cell_properties_set(MWContext* context,
  12102.                               fe_EditorTablesCellStruct* w_data)
  12103. {
  12104.     EDT_TableCellData cell_data;
  12105.  
  12106.     memset(&cell_data, 0, sizeof(EDT_TableCellData));
  12107.  
  12108.     fe_tables_cell_properties_set_validate_common(context,
  12109.                                                   &cell_data,
  12110.                                                   w_data);
  12111.  
  12112.     /*
  12113.      *    Background stuff
  12114.      */
  12115.     fe_bg_group_get(w_data->bg_group,
  12116.                     &cell_data.pColorBackground,
  12117.                     &cell_data.pBackgroundImage,
  12118.                     &cell_data.bBackgroundNoSave);
  12119.  
  12120.     fe_EditorTableCellSetData(context, &cell_data);
  12121.  
  12122.     if (cell_data.pColorBackground)
  12123.         XP_FREE(cell_data.pColorBackground);
  12124.     if (cell_data.pBackgroundImage)
  12125.         XP_FREE(cell_data.pBackgroundImage);
  12126. }
  12127.  
  12128. static Widget
  12129. fe_CreateFolder(Widget parent, char* name, Arg* args, Cardinal n)
  12130. {
  12131.     Widget folder;
  12132.  
  12133.     folder = XtVaCreateWidget(name, xmlFolderWidgetClass, parent,
  12134.                               XmNshadowThickness, 2,
  12135.                               XmNtopAttachment, XmATTACH_FORM,
  12136.                               XmNleftAttachment, XmATTACH_FORM,
  12137.                               XmNrightAttachment, XmATTACH_FORM,
  12138.                               XmNbottomAttachment, XmATTACH_FORM,
  12139. #ifdef ALLOW_TAB_ROTATE
  12140.                               XmNtabPlacement, XmFOLDER_LEFT,
  12141.                               XmNrotateWhenLeftRight, FALSE,
  12142. #endif /* ALLOW_TAB_ROTATE */
  12143.                               XmNbottomOffset, 3,
  12144.                               XmNspacing, 1,
  12145.                               NULL);
  12146.  
  12147.     return folder;
  12148. }
  12149.  
  12150. void
  12151. fe_EditorTablePropertiesDialogDo(MWContext* context,
  12152.                                  fe_EditorPropertiesDialogType type)
  12153. {
  12154.     Widget dialog;
  12155.     Widget folder;
  12156.     Widget tab_form;
  12157.     int done;
  12158.     fe_EditorTablesTableStruct table;
  12159.     fe_EditorTablesRowStruct   row;
  12160.     fe_EditorTablesCellStruct  cell;
  12161.     Arg args[4];
  12162.     Cardinal n;
  12163.     unsigned tab_number;
  12164.  
  12165.     if (type == XFE_EDITOR_PROPERTIES_TABLE_ROW)
  12166.         tab_number = 1;
  12167.     else if (type == XFE_EDITOR_PROPERTIES_TABLE_CELL)
  12168.         tab_number = 2;
  12169.     else
  12170.         tab_number = 0;
  12171.  
  12172.     /*
  12173.      *    Make prompt with ok, cancel, no apply, separator.
  12174.      */
  12175.     dialog = fe_CreatePromptDialog(context, "tablePropertiesDialog",
  12176.                                  TRUE, TRUE, TRUE, FALSE, TRUE);
  12177.  
  12178.     n = 0;
  12179.     folder = fe_CreateFolder(dialog, "folder", args, n);
  12180.     XtManageChild(folder);
  12181.  
  12182.     n = 0;
  12183.     tab_form = fe_CreateTabForm(folder, "table", args, n);
  12184.     XtManageChild(tab_form);
  12185.     fe_tables_table_properties_create(context, tab_form, &table);
  12186.     fe_tables_table_properties_init(context, &table);
  12187.     
  12188.     n = 0;
  12189.     tab_form = fe_CreateTabForm(folder, "row", args, n);
  12190.     XtManageChild(tab_form);
  12191.     fe_tables_row_properties_create(context, tab_form, &row);
  12192.     fe_tables_row_properties_init(context, &row);
  12193.  
  12194.     n = 0;
  12195.     tab_form = fe_CreateTabForm(folder, "cell", args, n);
  12196.     XtManageChild(tab_form);
  12197.     fe_tables_cell_properties_create(context, tab_form, &cell);
  12198.     fe_tables_cell_properties_init(context, &cell);
  12199.  
  12200.     XmLFolderSetActiveTab(folder, tab_number, True);
  12201.  
  12202.     /*
  12203.      *   Add a bunch of callbacks to the buttons.
  12204.      */
  12205.     XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done);
  12206.     XtAddCallback(dialog, XmNapplyCallback, fe_hrule_apply_cb, &done);
  12207.     XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  12208.     XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  12209.  
  12210.     /*
  12211.      *    Popup.
  12212.      */
  12213.     XtManageChild(dialog);
  12214.  
  12215.     /*
  12216.      *    Wait.
  12217.      */
  12218.     fe_NukeBackingStore(dialog); /* what does this do? */
  12219.  
  12220.     done = XmDIALOG_NONE;
  12221.     EDT_BeginBatchChanges(context);
  12222.     while (done == XmDIALOG_NONE) {
  12223.         fe_EventLoop();
  12224.  
  12225.         if (done == XmDIALOG_OK_BUTTON || done == XmDIALOG_APPLY_BUTTON) {
  12226.             /*
  12227.              *    We can only handle one lot of errors at a time.
  12228.              *    This a little dumb, but it shouldn't happen often.
  12229.              */
  12230.             if (fe_tables_table_properties_validate(context, &table)) {
  12231.                 fe_tables_table_properties_set(context, &table);
  12232.             } else {
  12233.                 done = XmDIALOG_NONE;
  12234.                 continue;
  12235.             }
  12236.  
  12237.             if (fe_tables_cell_properties_validate(context, &cell)) {
  12238.                 fe_tables_cell_properties_set(context, &cell);
  12239.             } else {
  12240.                 done = XmDIALOG_NONE;
  12241.                 continue;
  12242.             }
  12243.  
  12244.             fe_tables_row_properties_set(context, &row);
  12245.  
  12246.             if (done == XmDIALOG_APPLY_BUTTON)
  12247.                 done = XmDIALOG_NONE;
  12248.         }
  12249.     }
  12250.     EDT_EndBatchChanges(context);
  12251.  
  12252.     if (done != XFE_DIALOG_DESTROY_BUTTON)
  12253.         XtDestroyWidget(dialog);
  12254. }
  12255.  
  12256. typedef struct fe_PublishDialogStruct
  12257. {
  12258.     MWContext* context;
  12259.     Widget local_publish_info;
  12260.     Widget local_include_images;
  12261.     Widget local_include_files;
  12262.     Widget local_list;
  12263.     Widget local_select_all;
  12264.     Widget local_select_none;
  12265.     Widget publish_combo;
  12266.     Widget publish_location_text;
  12267.     Widget publish_username_text;
  12268.     Widget publish_password_text;
  12269.     Widget publish_save_password;
  12270.     Widget publish_use_default;
  12271.     Widget title_text;
  12272.     char*  url_pathname;
  12273.     char** files;
  12274. } fe_PublishDialogStruct;
  12275.  
  12276. static void
  12277. fe_publish_set_xmlist_from_data(fe_PublishDialogStruct* w_data)
  12278. {
  12279.     unsigned n;
  12280.     XmString xm_string;
  12281.     char*    s;
  12282.     char*    tmp;
  12283.  
  12284.     XmListDeleteAllItems(w_data->local_list);
  12285.  
  12286.     if (w_data->files == NULL)
  12287.         return;
  12288.  
  12289.     for (n = 0; w_data->files[n] != NULL; n++) {
  12290.  
  12291.         s = w_data->files[n];
  12292.         tmp = NULL;
  12293.  
  12294. #if 0
  12295.         dirlen = strlen(w_data->directory);
  12296.  
  12297.         /* windows does not clean this up, let's see how we go */
  12298.         if (strncmp(s, w_data->directory, dirlen) == 0 && s[dirlen] == '/') {
  12299.             tmp = XP_STRDUP(&s[dirlen+1]);
  12300.             s = tmp;
  12301.         }
  12302. #endif
  12303.  
  12304.         xm_string = XmStringCreateLocalized(s);
  12305.         XmListAddItem(w_data->local_list, xm_string, n+1);
  12306.         XmStringFree(xm_string);
  12307.         if (tmp != NULL)
  12308.             XP_FREE(tmp);
  12309.     }
  12310. }
  12311.  
  12312. static void
  12313. fe_publish_include_select_all(fe_PublishDialogStruct* w_data)
  12314. {
  12315.     unsigned n;
  12316.     unsigned nitems;
  12317.  
  12318.     XtVaGetValues(w_data->local_list, XmNitemCount, &nitems, 0);
  12319.  
  12320.     for (n = 0; n < nitems; n++)
  12321.         XmListSelectPos(w_data->local_list, n+1, FALSE);
  12322. }
  12323.  
  12324. static void
  12325. free_string_array(char** vector)
  12326. {
  12327.     unsigned n;
  12328.     if (vector) {
  12329.         for (n = 0; vector[n] != NULL; n++)
  12330.             XP_FREE(vector[n]);
  12331.         XP_FREE(vector);
  12332.     }
  12333. }
  12334.  
  12335. static void
  12336. fe_publish_set_include_all_files(fe_PublishDialogStruct* w_data)
  12337. {
  12338.     MWContext* context = w_data->context;
  12339.     char**     all_files;
  12340.     unsigned   nfiles;
  12341.     char* local_filename;
  12342.     char* p;
  12343.  
  12344.     free_string_array(w_data->files);
  12345.  
  12346.     XP_ConvertUrlToLocalFile(w_data->url_pathname, &local_filename);
  12347.  
  12348.     if (!local_filename) /* oops */
  12349.         return;
  12350.  
  12351.     /* get the directory name */
  12352.     p = XP_STRRCHR(local_filename, '/');
  12353.     if (p != NULL && p != local_filename)
  12354.         *p = '\0';
  12355.      
  12356.     all_files = NET_AssembleAllFilesInDirectory(context, local_filename);
  12357.  
  12358.     nfiles = 0;
  12359.     if (all_files != NULL) {
  12360.         for (; all_files[nfiles] != NULL; nfiles++) {
  12361.             p = all_files[nfiles];
  12362.             if (*p == '/') { /* absolute */
  12363.                 p = (char*)XP_ALLOC(XP_STRLEN(p) + 6);
  12364.                 XP_STRCPY(p, "file:");
  12365.                 XP_STRCAT(p, all_files[nfiles]);
  12366.                 XP_FREE(all_files[nfiles]);
  12367.                 all_files[nfiles] = p;
  12368.             }
  12369.         }
  12370.     }
  12371.  
  12372.     if (nfiles > 0) {
  12373.         w_data->files = all_files;
  12374.     } else {
  12375.         w_data->files = NULL;
  12376.     }
  12377.  
  12378.     fe_publish_set_xmlist_from_data(w_data);
  12379.     fe_publish_include_select_all(w_data);
  12380.  
  12381.     XmToggleButtonGadgetSetState(w_data->local_include_images, FALSE, FALSE);
  12382.     XmToggleButtonGadgetSetState(w_data->local_include_files, TRUE, FALSE);
  12383.  
  12384.     XP_FREE(local_filename);
  12385. }
  12386.  
  12387. static void
  12388. fe_publish_set_include_image_files(fe_PublishDialogStruct* w_data)
  12389. {
  12390.     MWContext* context = w_data->context;
  12391.     unsigned   len;
  12392.     char*      s;
  12393.     unsigned   n;
  12394.     unsigned   nfiles;
  12395.     char*      filenames;
  12396.     XP_Bool*   selected = NULL;
  12397.     Boolean    links_p;
  12398.  
  12399.     free_string_array(w_data->files);
  12400.  
  12401.     fe_EditorPreferencesGetLinksAndImages(context, NULL, &links_p);
  12402.  
  12403.     filenames = EDT_GetAllDocumentFilesSelected(context, &selected, links_p);
  12404.  
  12405.     nfiles = 0;
  12406.     if (filenames != NULL && selected != NULL) {
  12407.         for (s = filenames; (len = XP_STRLEN(s)) != 0; s += len + 1)
  12408.             nfiles++;
  12409.     }
  12410.     
  12411.     if (nfiles > 0) {
  12412.         w_data->files = (char**)XP_ALLOC((nfiles+1)*sizeof(char*));
  12413.  
  12414.         for (n = 0, s = filenames; *s != '\0'; n++, s += XP_STRLEN(s) + 1) {
  12415.             w_data->files[n] = XP_STRDUP(s);
  12416.         }
  12417.         w_data->files[n] = NULL;
  12418.  
  12419.     } else {
  12420.         w_data->files = NULL;
  12421.     }
  12422.     XP_FREEIF(filenames);
  12423.  
  12424.     fe_publish_set_xmlist_from_data(w_data);
  12425.  
  12426.     /* Files that are selected by default. */
  12427.     for (n = 0; n < nfiles; n++) {
  12428.       if (selected[n]) {
  12429.         XmListSelectPos(w_data->local_list, n+1, FALSE);
  12430.       }
  12431.     }
  12432.     XP_FREEIF(selected);
  12433.  
  12434.     /*
  12435.      *    Gray out if there are no images in doc.
  12436.      */
  12437. #if 0
  12438.     XtVaSetValues(w_data->local_include_images, XmNsensitive, (nfiles > 0), 0);
  12439. #endif
  12440.     XmToggleButtonGadgetSetState(w_data->local_include_images, TRUE, FALSE);
  12441.     XmToggleButtonGadgetSetState(w_data->local_include_files, FALSE, FALSE);
  12442. }
  12443.  
  12444. static void
  12445. fe_publish_include_image_files_cb(Widget widget, XtPointer closure,
  12446.                                   XtPointer cb_data)
  12447. {
  12448.     XmToggleButtonCallbackStruct* info = 
  12449.         (XmToggleButtonCallbackStruct*)cb_data;
  12450.     fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure;
  12451.  
  12452.     if (!info->set)
  12453.         return;
  12454.  
  12455.     fe_publish_set_include_image_files(w_data);
  12456. }
  12457.  
  12458. static void
  12459. fe_publish_include_all_files_cb(Widget widget, XtPointer closure,
  12460.                                   XtPointer cb_data)
  12461. {
  12462.     XmToggleButtonCallbackStruct* info = 
  12463.         (XmToggleButtonCallbackStruct*)cb_data;
  12464.     fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure;
  12465.  
  12466.     if (!info->set)
  12467.         return;
  12468.  
  12469.     fe_publish_set_include_all_files(w_data);
  12470. }
  12471.  
  12472. static void
  12473. fe_publish_include_select_none_cb(Widget widget, XtPointer closure,
  12474.                                   XtPointer cb_data)
  12475. {
  12476.     fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure;
  12477.  
  12478.     XmListDeselectAllItems(w_data->local_list);
  12479. }
  12480.  
  12481. static void
  12482. fe_publish_include_select_all_cb(Widget widget, XtPointer closure,
  12483.                                   XtPointer cb_data)
  12484. {
  12485.     fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure;
  12486.     fe_publish_include_select_all(w_data);
  12487. }
  12488.  
  12489. static void
  12490. fe_publish_set_lup(fe_PublishDialogStruct* w_data,
  12491.                    char* location, char* username, char* password)
  12492. {
  12493.     if (location) {
  12494.         fe_TextFieldSetString(w_data->publish_location_text, location, FALSE);
  12495.         
  12496.         if (username) {
  12497.             fe_TextFieldSetString(w_data->publish_username_text,
  12498.                                   username, FALSE);
  12499.         } else {
  12500.             fe_TextFieldSetString(w_data->publish_username_text, "", FALSE);
  12501.         }
  12502.         
  12503.         if (password) {
  12504.             fe_TextFieldSetString(w_data->publish_password_text, password,
  12505.                                   FALSE);
  12506.             XtVaSetValues(w_data->publish_save_password, XmNset, TRUE, 0);
  12507.         } else {
  12508.             fe_TextFieldSetString(w_data->publish_password_text, "", FALSE);
  12509.             XtVaSetValues(w_data->publish_save_password, XmNset, FALSE, 0);
  12510.         }
  12511.     }
  12512. }
  12513.  
  12514. static void
  12515. fe_publish_combo_selection_cb(Widget w, XtPointer closure, XtPointer cb_data)
  12516. {
  12517.     fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure;
  12518.     DtComboBoxCallbackStruct* info = (DtComboBoxCallbackStruct*)cb_data;
  12519.     char* location;
  12520.     char* username;
  12521.     char* password;
  12522.  
  12523.     if (EDT_GetPublishingHistory(info->item_position,
  12524.                                  &location, &username, &password)) {
  12525. #if 0
  12526.         /* combo callback has already screwed us */
  12527.         char* target_file;
  12528.         char* last;
  12529.         int   len;
  12530.  
  12531.         /*
  12532.          *    If the new location is a directory, try to append the
  12533.          *    basename of the existing target onto the new location.
  12534.          */
  12535.         target_file = fe_TextFieldGetString(w_data->publish_location_text);
  12536.         if ((last = XP_STRRCHR(target_file, '/')) != NULL)
  12537.             last++;
  12538.         else
  12539.             last = target_file;
  12540.  
  12541.         len = XP_STRLEN(location);
  12542.         if (last != NULL && len > 0 && location[len-1] == '/') {
  12543.             char* tmp;
  12544.             len = len + XP_STRLEN(location) + 1;
  12545.             tmp = (char*)XP_ALLOC(len);
  12546.             XP_STRCPY(tmp, location);
  12547.             XP_STRCAT(tmp, last);
  12548.             XP_FREE(location);
  12549.             location = tmp;
  12550.         }
  12551.         XtFree(target_file);
  12552. #endif
  12553.  
  12554.         fe_publish_set_lup(w_data, location, username, password);
  12555.         if (location != NULL)
  12556.             XP_FREE(location);
  12557.         if (username != NULL)
  12558.             XP_FREE(username);
  12559.         if (password != NULL) {
  12560.             memset(password, 0, strlen(password));
  12561.             XP_FREE(password);
  12562.         }
  12563.     }
  12564. }
  12565.  
  12566. static void
  12567. fe_publish_use_default_cb(Widget widget, XtPointer closure,
  12568.                                   XtPointer cb_data)
  12569. {
  12570.     fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure;
  12571.     char* location;
  12572.     char* username;
  12573.     char* password;
  12574.  
  12575.     fe_EditorPreferencesGetPublishLocation(w_data->context,
  12576.                                            &location,
  12577.                                            &username,
  12578.                                            &password);
  12579.  
  12580.     if (location) {
  12581.         fe_publish_set_lup(w_data, location, username, password);
  12582.         if (location != NULL)
  12583.             XP_FREE(location);
  12584.         if (username != NULL)
  12585.             XP_FREE(username);
  12586.         if (password != NULL) {
  12587.             memset(password, 0, strlen(password));
  12588.             XP_FREE(password);
  12589.         }
  12590.     }
  12591. }
  12592.  
  12593. static void
  12594. fe_publish_dialog_init(MWContext* context, fe_PublishDialogStruct* w_data)
  12595. {
  12596.     XmString xm_string;
  12597.     History_entry* hist_ent;
  12598.     char  buf[MAXPATHLEN];
  12599.     char* location_dir;
  12600.     char* location_file;
  12601.     char* location;
  12602.     char* username;
  12603.     char* password;
  12604.     char* title;
  12605.     Boolean has_default;
  12606.     Boolean save_password;
  12607.     int n;
  12608.  
  12609.     w_data->url_pathname = NULL;
  12610.  
  12611.     /* get the location */
  12612.     hist_ent = SHIST_GetCurrent(&context->hist);
  12613.     if(hist_ent && hist_ent->address) {
  12614.  
  12615.         w_data->url_pathname = XP_STRDUP(hist_ent->address);
  12616.  
  12617.         FE_CondenseURL(buf, w_data->url_pathname, 40);
  12618.  
  12619.         xm_string = XmStringCreateLtoR(buf,XmFONTLIST_DEFAULT_TAG);
  12620.         XtVaSetValues(w_data->local_publish_info,
  12621.                       XmNlabelString, xm_string, 0);
  12622.         XmStringFree(xm_string);
  12623.     }
  12624.  
  12625.     fe_publish_set_include_image_files(w_data);
  12626.  
  12627.     location_file = username = password = NULL; /* settle over-zealous BE */
  12628.     location_dir = EDT_GetDefaultPublishURL(context,
  12629.                                             &location_file,
  12630.                                             &username,
  12631.                                             &password);
  12632.  
  12633.     /*
  12634.      *    Set the title
  12635.      */
  12636.     if (!(title = fe_EditorDocumentGetTitle(context)))
  12637.         title = EDT_GetPageTitleFromFilename(location_file);
  12638.  
  12639.     if (title != NULL) {
  12640.         fe_TextFieldSetString(w_data->title_text, title, False);
  12641.         XP_FREE(title);
  12642.     } else {
  12643.         fe_TextFieldSetString(w_data->title_text, "", False);
  12644.     }
  12645.     
  12646.     XtVaSetValues(w_data->local_include_files, XmNsensitive,
  12647.                   (NET_IsLocalFileURL(w_data->url_pathname)), 0);
  12648.  
  12649.     /*
  12650.      *    Set the history list first, as comobo will always callback
  12651.      *    on text field and set the location - we don't always want that.
  12652.      */
  12653.     for (n = 0; EDT_GetPublishingHistory(n, &location, 0, 0); n++) {
  12654.         xm_string = XmStringCreateLocalized(location);
  12655.         DtComboBoxAddItem(w_data->publish_combo, xm_string, n + 1, FALSE);
  12656.         XmStringFree(xm_string);
  12657.         XP_FREE(location);
  12658.     }
  12659.  
  12660.     if (n > 0) {
  12661.         XtVaSetValues(w_data->publish_combo,
  12662.                       XmNvisibleItemCount, (XtPointer)n,
  12663.                       0);
  12664.     } else {
  12665.         Widget arrow = XtNameToWidget(w_data->publish_combo, "ComboBoxArrow");
  12666.         XtVaSetValues(arrow, XmNsensitive, False, 0);
  12667.     }
  12668.  
  12669.     /*
  12670.      *    Setup lower half of dialog.
  12671.      */
  12672.     if (location_dir != NULL) {
  12673.         n = XP_STRLEN(location_dir) + 1;
  12674.         if (location_file != NULL)
  12675.             n += XP_STRLEN(location_file) + 1;
  12676.  
  12677.         location = (char*)XP_ALLOC(n);
  12678.         XP_STRCPY(location, location_dir);
  12679.         
  12680.         if (location_file != NULL)
  12681.             XP_STRCAT(location, location_file);
  12682.     } else {
  12683.         location = NULL;
  12684.     }
  12685.  
  12686.     save_password = (password != NULL);
  12687.     
  12688.     if (location) {
  12689.         fe_TextFieldSetString(w_data->publish_location_text, location, FALSE);
  12690.         XP_FREE(location);
  12691.     }
  12692.     
  12693.     if (username) {
  12694.         fe_TextFieldSetString(w_data->publish_username_text, username, FALSE);
  12695.         XP_FREE(username);
  12696.     }
  12697.     
  12698.     if (password) {
  12699.         fe_TextFieldSetString(w_data->publish_password_text, password, FALSE);
  12700.         memset(password, 0, strlen(password));
  12701.         XP_FREE(password);
  12702.     }
  12703.  
  12704.     /*
  12705.      *    Enable "Use Default Location"?
  12706.      */
  12707.     fe_EditorPreferencesGetPublishLocation(context, &location, NULL, NULL);
  12708.     if (location) {
  12709.         has_default = TRUE;
  12710.         XP_FREE(location);
  12711.     } else {
  12712.         has_default = FALSE;
  12713.     }
  12714.  
  12715.     XtVaSetValues(w_data->publish_use_default, XmNsensitive, has_default, 0);
  12716.     XtVaSetValues(w_data->publish_save_password, XmNset, save_password, 0);
  12717.     
  12718. }
  12719.  
  12720. Boolean
  12721. fe_EditorPublishFiles(MWContext* context,
  12722.                       char*      target_file,
  12723.                       char**     source_files,
  12724.                       char*      username,
  12725.                       char*      password)
  12726. {
  12727.     char*          full_location = NULL; /* MUST set to NULL */
  12728.     Boolean        rv;
  12729.     Boolean        links;
  12730.     Boolean        images;
  12731.     char*          primary_url = NULL;
  12732.     History_entry* hist_entry;
  12733.  
  12734.     rv = NET_MakeUploadURL(&full_location, target_file,
  12735.                            username, password);
  12736.  
  12737.     if (rv && full_location != NULL) {
  12738.  
  12739.         /* Get current history entry for source location */
  12740.         hist_entry = SHIST_GetCurrent(&context->hist);
  12741.         if (hist_entry != NULL
  12742.             && hist_entry->address != NULL
  12743.             && hist_entry->address[0] != '\0') {
  12744.             primary_url = hist_entry->address;
  12745.         } else {
  12746.             /* no source name. */
  12747.             /* Is there a define for file:///Untitled somewhere? */
  12748.             primary_url = "file:///Untitled";
  12749.         }
  12750.  
  12751.         fe_EditorPreferencesGetLinksAndImages(context, &links, &images);
  12752.  
  12753.         /*
  12754.          *    NOTE: we must donate source_files to the back-end,
  12755.          *    it will be freed there. All other arguments we own.
  12756.          */
  12757.         EDT_PublishFile(context, ED_FINISHED_REVERT_BUFFER,
  12758.                         primary_url,
  12759.                         source_files, full_location,
  12760.                         images, links, FALSE);
  12761.  
  12762.         XP_FREE(full_location);
  12763.  
  12764.         return TRUE;
  12765.     } else {
  12766.         return FALSE;
  12767.     }
  12768. }
  12769.  
  12770. static Boolean
  12771. fe_publish_dialog_validate(MWContext* context, fe_PublishDialogStruct* w_data)
  12772. {
  12773.     char* target_file;
  12774.     Boolean rv  = TRUE;
  12775.  
  12776.     target_file = fe_TextFieldGetString(w_data->publish_location_text);
  12777.  
  12778.     fe_StringTrim(target_file);
  12779.  
  12780.     /*
  12781.      *    Use new call in BE. This guy also posts the alert (via FE_Confirm).
  12782.      *    So we don't need to do a dialog ourselves. But, we don't get to
  12783.      *    place it either, sigh.
  12784.      */
  12785.     if (!EDT_CheckPublishURL(context, target_file))
  12786.         rv = FALSE;
  12787.  
  12788.     XtFree(target_file);
  12789.     return rv;
  12790. }
  12791.  
  12792. static void
  12793. fe_publish_dialog_set(MWContext* context, fe_PublishDialogStruct* w_data)
  12794. {
  12795.     int* items;
  12796.     int  nitems;
  12797.     int n;
  12798.     int item;
  12799.     char* target_file;
  12800.     char* username;
  12801.     char* password;
  12802.     char** source_files;
  12803.     Boolean  save_password;
  12804.     char* title;
  12805.  
  12806.     XmListGetSelectedPos(w_data->local_list, &items, &nitems);
  12807.  
  12808.     source_files = (char**)XP_ALLOC(sizeof(char*) * (nitems + 2));
  12809.  
  12810.     for (n = 0; n < nitems; n++) {
  12811.         item = items[n] - 1; /* XmList offset */
  12812.         source_files[n] = XP_STRDUP(w_data->files[item]); /* must do this */
  12813.     }
  12814.     source_files[n] = NULL;
  12815.  
  12816.     if (nitems > 0 && items != NULL) /* sometimes get non-zero items */
  12817.         XtFree((void*)items);
  12818.  
  12819.     target_file = fe_TextFieldGetString(w_data->publish_location_text);
  12820.     username = fe_TextFieldGetString(w_data->publish_username_text);
  12821.     password = fe_GetPasswdText(w_data->publish_password_text);
  12822.  
  12823.     fe_StringTrim(target_file);
  12824.     fe_StringTrim(username);
  12825.     fe_StringTrim(password);
  12826.  
  12827.     /*
  12828.      *    Save the location for next time.
  12829.      *
  12830.      *    Ok, this is totally wierd (but totally Motif). We were
  12831.      *    doing a GetValues() here, and we were doing it after the
  12832.      *    call to PublishFiles(). We would die in Xt event dispatch,
  12833.      *    with looked like a bogus mapnotify event. I suspect that
  12834.      *    this had something to do with the GetValues. PushBG's
  12835.      *    GetValues() does seem someone complicated, so 1) let's use
  12836.      *    a GetState() call (which just reads the boolean value in
  12837.      *    the widget), and do this before the call to publish,
  12838.      *    which we should probably do anyway.
  12839.      */
  12840.     save_password =
  12841.         XmToggleButtonGadgetGetState(w_data->publish_save_password);
  12842.  
  12843.     fe_EditorDefaultSetLastPublishLocation(context,
  12844.                                            target_file,
  12845.                                            username,
  12846.                                            save_password? password: NULL);
  12847.  
  12848.     /* title */
  12849.     title = fe_TextFieldGetString(w_data->title_text);
  12850.  
  12851.     if (title != NULL) {
  12852.         fe_EditorDocumentSetTitle(context, title);
  12853.         XtFree(title);
  12854.     }
  12855.  
  12856.     fe_EditorPublishFiles(context, target_file,
  12857.                           source_files, username, password);
  12858.  
  12859.     XtFree(target_file);
  12860.     XtFree(username);
  12861.     memset(password, 0, strlen(password));
  12862.     XtFree(password);
  12863. }
  12864.  
  12865. static void
  12866. fe_publish_dialog_delete(MWContext* context, fe_PublishDialogStruct* w_data)
  12867. {
  12868.     if (w_data->url_pathname)
  12869.         XtFree(w_data->url_pathname);
  12870.     free_string_array(w_data->files);
  12871. }
  12872.  
  12873. static void
  12874. fe_publish_dialog_create(MWContext* context, Widget parent,
  12875.                          fe_PublishDialogStruct* w_data)
  12876. {
  12877.     Widget form;
  12878.     Widget local_frame;
  12879.     Widget local_form;
  12880.     Widget local_publish_label;
  12881.     Widget local_publish_info;
  12882.     Widget local_include_label;
  12883.     Widget local_include_radio;
  12884.     Widget local_include_files;
  12885.     Widget local_include_images;
  12886.     Widget local_select_none;
  12887.     Widget local_select_all;
  12888.     Widget local_list;
  12889.     Widget list_parent;
  12890.  
  12891.     Widget publish_frame;
  12892.     Widget publish_form;
  12893.     Widget publish_label;
  12894.     Widget publish_drop;
  12895.     Widget publish_username_label;
  12896.     Widget publish_username_text;
  12897.     Widget publish_use_default;
  12898.     Widget publish_password_label;
  12899.     Widget publish_password_text;
  12900.     Widget publish_password_save;
  12901.  
  12902.     Widget title_frame;
  12903.     Widget title_text;
  12904.  
  12905.     Widget children[16];
  12906.     Cardinal nchildren;
  12907.     Cardinal n;
  12908.     Arg args[16];
  12909.     Dimension left_offset;
  12910.     Pixel parent_bg;
  12911.     Pixel select_bg;
  12912.     Dimension width;
  12913.     Widget fat_guy;
  12914.  
  12915.     Visual *v = 0;
  12916.     Colormap cmap = 0;
  12917.     Cardinal depth = 0;
  12918.  
  12919.     n = 0;
  12920.     form = XmCreateForm(parent, "publish", args, n);
  12921.     XtManageChild(form);
  12922.  
  12923.     n = 0;
  12924.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  12925.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  12926.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  12927.     local_frame = fe_CreateFrame(form, "localFiles", args, n);
  12928.     XtManageChild(local_frame);
  12929.  
  12930.     n = 0;
  12931.     local_form = XmCreateForm(local_frame, "localFiles", args, n);
  12932.     XtManageChild(local_form);
  12933.  
  12934.     nchildren = 0;
  12935.     n = 0;
  12936.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  12937.     local_publish_label = XmCreateLabelGadget(local_form, "publishLabel",
  12938.                                               args, n);
  12939.     children[nchildren++] = local_publish_label;
  12940.  
  12941.     n = 0;
  12942.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  12943.     local_include_label = XmCreateLabelGadget(local_form, "includeLabel",
  12944.                                               args, n);
  12945.     children[nchildren++] = local_include_label;
  12946.  
  12947.     n = 0;
  12948.     local_select_none = XmCreatePushButtonGadget(local_form, "selectNone",
  12949.                                               args, n);
  12950.     children[nchildren++] = local_select_none;
  12951.  
  12952.     n = 0;
  12953.     local_select_all = XmCreatePushButtonGadget(local_form, "selectAll",
  12954.                                               args, n);
  12955.     children[nchildren++] = local_select_all;
  12956.  
  12957.     left_offset = fe_get_offset_from_widest(children, nchildren);
  12958.  
  12959.     fat_guy = XfeBiggestWidget(TRUE, &children[nchildren-2], 2);
  12960.     XtVaGetValues(fat_guy, XmNwidth, &width, 0);
  12961.  
  12962.     n = 0;
  12963.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  12964.     local_publish_info = XmCreateLabelGadget(local_form, "publishInfo",
  12965.                                              args, n);
  12966.     children[nchildren++] = local_publish_info;
  12967.  
  12968.     n = 0;
  12969.     XtSetArg(args[n], XmNradioBehavior, TRUE); n++;
  12970.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  12971.     local_include_radio = XmCreateRowColumn(local_form, "includeRadio",
  12972.                                             args, n);
  12973.     children[nchildren++] = local_include_radio;
  12974.  
  12975.     n = 0;
  12976.     XtSetArg(args[n], XmNbackground, &parent_bg); n++;
  12977.     XtGetValues(local_form, args, n);
  12978.     
  12979.     XmGetColors(XtScreen(parent), fe_cmap(context),
  12980.                 parent_bg, NULL, NULL, NULL, &select_bg);
  12981.  
  12982.     n = 0;
  12983.     XtSetArg(args[n], XmNvisibleItemCount, 5); n++;
  12984.     XtSetArg(args[n], XmNselectionPolicy, XmMULTIPLE_SELECT); n++;
  12985.     XtSetArg(args[n], XmNbackground, select_bg); n++;
  12986.     local_list = XmCreateScrolledList(local_form, "includeList",
  12987.                                               args, n);
  12988.     children[nchildren++] = list_parent = XtParent(local_list);
  12989.  
  12990.     /*
  12991.      *    Now do attachments.
  12992.      */
  12993.     n = 0;
  12994.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  12995.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  12996.     XtSetValues(local_publish_label, args, n);
  12997.  
  12998.     n = 0;
  12999.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13000.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13001.     XtSetArg(args[n], XmNtopWidget, local_publish_info); n++;
  13002.     XtSetValues(local_include_label, args, n);
  13003.  
  13004. #if 0
  13005.     n = 0;
  13006.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13007.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13008.     XtSetArg(args[n], XmNtopWidget, local_include_label); n++;
  13009.     XtSetArg(args[n], XmNwidth, width); n++;
  13010.     XtSetValues(local_select_none, args, n);
  13011.     
  13012.     n = 0;
  13013.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13014.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13015.     XtSetArg(args[n], XmNtopWidget, local_select_none); n++;
  13016.     XtSetArg(args[n], XmNwidth, width); n++;
  13017.     XtSetValues(local_select_all, args, n);
  13018.  
  13019. #else
  13020.     n = 0;
  13021.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13022.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  13023.     XtSetArg(args[n], XmNbottomWidget, local_select_all); n++;
  13024.     XtSetArg(args[n], XmNwidth, width); n++;
  13025.     XtSetValues(local_select_none, args, n);
  13026.     
  13027.     n = 0;
  13028.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13029. #if 0
  13030.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  13031. #else
  13032.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  13033.     XtSetArg(args[n], XmNbottomWidget, list_parent); n++;
  13034. #endif
  13035.     XtSetArg(args[n], XmNwidth, width); n++;
  13036.     XtSetValues(local_select_all, args, n);
  13037. #endif
  13038.  
  13039.     n = 0;
  13040.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  13041.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13042.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  13043.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  13044.     XtSetValues(local_publish_info, args, n);
  13045.     
  13046.     n = 0;
  13047.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13048.     XtSetArg(args[n], XmNtopWidget, local_publish_info); n++;
  13049.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  13050.     XtSetArg(args[n], XmNleftWidget, local_publish_info); n++;
  13051.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  13052.     XtSetValues(local_include_radio, args, n);
  13053.     
  13054.     n = 0;
  13055.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13056.     XtSetArg(args[n], XmNtopWidget, local_include_radio); n++;
  13057.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  13058.     XtSetArg(args[n], XmNleftWidget, local_publish_info); n++;
  13059.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  13060. #if 0
  13061.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  13062. #endif
  13063.     XtSetValues(list_parent, args, n);
  13064.     
  13065.     XtManageChildren(children, nchildren);
  13066.  
  13067.     nchildren = 0;
  13068.     n = 0;
  13069.     XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  13070.     local_include_images = XmCreateToggleButtonGadget(local_include_radio,
  13071.                                                       "includeImages",
  13072.                                                       args, n);
  13073.     children[nchildren++] = local_include_images;
  13074.  
  13075.     n = 0;
  13076.     XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++;
  13077.     local_include_files = XmCreateToggleButtonGadget(local_include_radio,
  13078.                                                       "includeAll",
  13079.                                                       args, n);
  13080.     children[nchildren++] = local_include_files;
  13081.  
  13082.     XtManageChildren(children, nchildren);
  13083.  
  13084.     XtManageChild(local_list);
  13085.  
  13086.     XtAddCallback(local_select_none, XmNactivateCallback,
  13087.                   fe_publish_include_select_none_cb, (XtPointer)w_data);
  13088.  
  13089.     XtAddCallback(local_select_all, XmNactivateCallback,
  13090.                   fe_publish_include_select_all_cb, (XtPointer)w_data);
  13091.  
  13092.     XtAddCallback(local_include_images, XmNvalueChangedCallback,
  13093.                   fe_publish_include_image_files_cb, (XtPointer)w_data);
  13094.  
  13095.     XtAddCallback(local_include_files, XmNvalueChangedCallback,
  13096.                   fe_publish_include_all_files_cb, (XtPointer)w_data);
  13097.  
  13098.     /*
  13099.      *    Title group.
  13100.      */
  13101.     n = 0;
  13102.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13103.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  13104.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13105.     XtSetArg(args[n], XmNtopWidget, local_frame); n++;
  13106.     title_frame = fe_CreateFrame(form, "titleFrame", args, n);
  13107.     XtManageChild(title_frame);
  13108.  
  13109.     n = 0;
  13110.     title_text = fe_CreateTextField(title_frame, "titleText", args, n);
  13111.     XtManageChild(title_text);
  13112.     
  13113.     /*
  13114.      *    Publish group.
  13115.      */
  13116.     n = 0;
  13117.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13118.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  13119.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13120.     XtSetArg(args[n], XmNtopWidget, title_frame); n++;
  13121.     publish_frame = fe_CreateFrame(form, "publishLocation", args, n);
  13122.     XtManageChild(publish_frame);
  13123.  
  13124.     n = 0;
  13125.     publish_form = XmCreateForm(publish_frame, "publishLocation", args, n);
  13126.     XtManageChild(publish_form);
  13127.  
  13128.     nchildren = 0;
  13129.     n = 0;
  13130.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  13131.     publish_label = XmCreateLabelGadget(publish_form, "publishLabel", args, n);
  13132.     children[nchildren++] = publish_label;
  13133.  
  13134.     n = 0;
  13135. #if 0
  13136.     publish_drop = fe_CreateTextField(publish_form, "publishDrop", args, n);
  13137. #else
  13138.     XtVaGetValues(CONTEXT_WIDGET(context), XtNvisual, &v, XtNcolormap, &cmap,
  13139.                   XtNdepth, &depth, 0);
  13140.  
  13141.     n = 0;
  13142.     XtSetArg(args[n], XmNvisual, v); n++;
  13143.     XtSetArg(args[n], XmNdepth, depth); n++;
  13144.     XtSetArg(args[n], XmNcolormap, cmap); n++;
  13145.     XtSetArg(args[n], XmNtype, XmDROP_DOWN_COMBO_BOX); n++;
  13146.     XtSetArg(args[n], XmNshadowThickness, 1); n++;
  13147.     XtSetArg(args[n], XmNmarginWidth, 0); n++;
  13148.     XtSetArg(args[n], XmNmarginHeight, 0); n++;
  13149.     XtSetArg(args[n], XmNarrowType, XmMOTIF); n++;
  13150.     XtSetArg(args[n], XmNupdateLabel, False); n++;
  13151.     publish_drop = DtCreateComboBox(publish_form,
  13152.                                     "publishDrop",
  13153.                                     args, n);
  13154.     XtAddCallback(publish_drop, XmNselectionCallback,
  13155.                   fe_publish_combo_selection_cb, w_data);
  13156. #endif
  13157.     children[nchildren++] = publish_drop;
  13158.  
  13159.     n = 0;
  13160.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  13161.     publish_username_label = XmCreateLabelGadget(publish_form, "usernameLabel",
  13162.                                                  args, n);
  13163.     children[nchildren++] = publish_username_label;
  13164.  
  13165.     n = 0;
  13166.     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  13167.     publish_password_label = XmCreateLabelGadget(publish_form, "passwordLabel",
  13168.                                                  args, n);
  13169.     children[nchildren++] = publish_password_label;
  13170.  
  13171.     left_offset = fe_get_offset_from_widest(&children[nchildren-2], 2);
  13172.  
  13173.     n = 0;
  13174.     publish_username_text = fe_CreateTextField(publish_form, "usernameText",
  13175.                                                args, n);
  13176.     children[nchildren++] = publish_username_text;
  13177.  
  13178.     n = 0;
  13179.     publish_use_default = XmCreatePushButtonGadget(publish_form,
  13180.                                                    "useDefault",
  13181.                                                    args, n);
  13182.     children[nchildren++] = publish_use_default;
  13183.  
  13184.     XtAddCallback(publish_use_default, XmNactivateCallback,
  13185.                   fe_publish_use_default_cb, (XtPointer)w_data);
  13186.  
  13187.     n = 0;
  13188.     XtSetArg(args[n], XmNmaxLength, 1024); n++;
  13189.     publish_password_text = fe_CreatePasswordField(publish_form,
  13190.                                                    "passwordText",
  13191.                                                    args, n);
  13192.     children[nchildren++] = publish_password_text;
  13193.  
  13194.     n = 0;
  13195.     publish_password_save = XmCreateToggleButtonGadget(publish_form,
  13196.                                                        "savePassword",
  13197.                                                        args, n);
  13198.     children[nchildren++] = publish_password_save;
  13199.     
  13200.     /*
  13201.      *    Attachments.
  13202.      */
  13203.     n = 0;
  13204.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13205.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  13206.     XtSetValues(publish_label, args, n);
  13207.     
  13208.     n = 0;
  13209.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13210.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  13211.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13212.     XtSetArg(args[n], XmNtopWidget, publish_label); n++;
  13213.     XtSetValues(publish_drop, args, n);
  13214.     
  13215.     n = 0;
  13216.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13217.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13218.     XtSetArg(args[n], XmNtopWidget, publish_drop); n++;
  13219.     XtSetValues(publish_username_label, args, n);
  13220.     
  13221.     n = 0;
  13222.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13223.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13224.     XtSetArg(args[n], XmNtopWidget, publish_username_text); n++;
  13225.     XtSetValues(publish_password_label, args, n);
  13226.     
  13227.     n = 0;
  13228.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13229.     XtSetArg(args[n], XmNtopWidget, publish_drop); n++;
  13230.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  13231.     XtSetArg(args[n], XmNleftOffset, left_offset); n++;
  13232.     XtSetValues(publish_username_text, args, n);
  13233.     
  13234.     n = 0;
  13235.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13236.     XtSetArg(args[n], XmNtopWidget, publish_username_text); n++;
  13237.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  13238.     XtSetArg(args[n], XmNleftWidget, publish_username_text); n++;
  13239.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  13240.     XtSetArg(args[n], XmNrightWidget, publish_username_text); n++;
  13241.     XtSetValues(publish_password_text, args, n);
  13242.     
  13243.     n = 0;
  13244.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  13245.     XtSetArg(args[n], XmNleftWidget, publish_username_text); n++;
  13246.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13247.     XtSetArg(args[n], XmNtopWidget, publish_drop); n++;
  13248.     XtSetValues(publish_use_default, args, n);
  13249.     
  13250.     n = 0;
  13251.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  13252.     XtSetArg(args[n], XmNleftWidget, publish_use_default); n++;
  13253.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  13254.     XtSetArg(args[n], XmNtopWidget, publish_username_text); n++;
  13255.     XtSetValues(publish_password_save, args, n);
  13256.     
  13257.     XtManageChildren(children, nchildren);
  13258.  
  13259.     w_data->local_publish_info = local_publish_info;
  13260.     w_data->local_include_images = local_include_images;
  13261.     w_data->local_include_files = local_include_files;
  13262.     w_data->local_list = local_list;
  13263.     w_data->local_select_all = local_select_all;
  13264.     w_data->local_select_none = local_select_none;
  13265.     w_data->publish_combo = publish_drop;
  13266.     XtVaGetValues(publish_drop,
  13267.                   XmNtextField, &w_data->publish_location_text,
  13268.                   0);
  13269.  
  13270.     w_data->title_text = title_text;
  13271.  
  13272.     w_data->publish_username_text = publish_username_text;
  13273.     w_data->publish_password_text = publish_password_text;
  13274.     w_data->publish_save_password = publish_password_save;
  13275.     w_data->publish_use_default = publish_use_default;
  13276.     w_data->context = context;
  13277.     w_data->url_pathname = NULL;
  13278.     w_data->files = NULL;
  13279. }
  13280.  
  13281. Boolean
  13282. fe_EditorPublishDialogDo(MWContext* context)
  13283. {
  13284.     fe_PublishDialogStruct publish;
  13285.     Widget  dialog;
  13286.     int     done;
  13287.     Boolean rv;
  13288.  
  13289.     /*
  13290.      *    Make prompt with ok, cancel, no apply, separator.
  13291.      */
  13292.     dialog = fe_CreatePromptDialog(context, "publishFilesDialog",
  13293.                                    TRUE, TRUE, FALSE, FALSE, TRUE);
  13294.  
  13295.     fe_publish_dialog_create(context, dialog, &publish);
  13296.     fe_publish_dialog_init(context, &publish);
  13297.  
  13298.     /*
  13299.      *   Add a bunch of callbacks to the buttons.
  13300.      */
  13301.     XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done);
  13302.     XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  13303.     XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  13304.  
  13305.     /*
  13306.      *    Popup.
  13307.      */
  13308.     XtManageChild(dialog);
  13309.  
  13310.     /*
  13311.      *    Wait.
  13312.      */
  13313.     fe_NukeBackingStore(dialog); /* what does this do? */
  13314.  
  13315.     done = XmDIALOG_NONE;
  13316.     while (done == XmDIALOG_NONE) {
  13317.         fe_EventLoop();
  13318.  
  13319.         if (done == XmDIALOG_OK_BUTTON) {
  13320.             if (!fe_publish_dialog_validate(context, &publish)) {
  13321.                 done = XmDIALOG_NONE;
  13322.             }
  13323.         }
  13324.     }
  13325.  
  13326.     /* something is wrong here - benjie */
  13327.     /* if you put in a wrong domain, but with http:// and ftp:// 
  13328.      * the following call will fail, and then we loose btn callback 
  13329.      * action and hangs, the problem traces to the exit routine
  13330.      * we send in to NET_GetURL. For the editor, the exit routine,
  13331.      * after poping up the error message, calls fe_EditorGetURLExitRoutine,
  13332.      * which calls fe_EventLoop, and the code loops in there, but don't
  13333.        * pick up click actions on the buttons in this dialog
  13334.      */
  13335.  
  13336.     /* ok, so the following line temporarilly fix the above problem 
  13337.      * by poping down the modal dialog.
  13338.      * this fixes 26903. - benjie
  13339.      */
  13340.     XtUnmanageChild(dialog); 
  13341.  
  13342.     if (done == XmDIALOG_OK_BUTTON) {
  13343.         fe_publish_dialog_set(context, &publish);
  13344.         rv = TRUE;
  13345.      } else {
  13346.         rv = FALSE;
  13347.     }
  13348.  
  13349.     fe_publish_dialog_delete(context, &publish);
  13350.  
  13351.     if (done != XFE_DIALOG_DESTROY_BUTTON) 
  13352.         XtDestroyWidget(dialog); 
  13353.  
  13354.     return rv;
  13355. }
  13356.  
  13357. int
  13358. fe_YesNoCancelDialog(MWContext* context, char* name, char* message)
  13359. {
  13360.     Widget dialog;
  13361.     Widget mainw = CONTEXT_WIDGET(context);
  13362.     Widget yes_button;
  13363.     Widget no_button;
  13364.     Arg    args[8];
  13365.     Cardinal n;
  13366.     Visual*  v;
  13367.     Colormap cmap;
  13368.     Cardinal depth;
  13369.     int done;
  13370.     XmString xm_message;
  13371.  
  13372.     /*
  13373.      *    Popup the shell first, so that we gurantee its realized 
  13374.      */
  13375.     XtPopup(mainw, XtGrabNone);
  13376.     
  13377.     /*
  13378.      *    Force the window to the front and de-iconify if needed 
  13379.      */
  13380.     XMapRaised(XtDisplay(mainw), XtWindow(mainw));
  13381.     
  13382.     XtVaGetValues(mainw, XtNvisual, &v, XtNcolormap, &cmap,
  13383.                   XtNdepth, &depth, 0);
  13384.  
  13385.     xm_message = XmStringCreateLtoR(message,XmFONTLIST_DEFAULT_TAG);
  13386.     n = 0;
  13387.     XtSetArg(args[n], XmNvisual, v); n++;
  13388.     XtSetArg(args[n], XmNdepth, depth); n++;
  13389.     XtSetArg(args[n], XmNcolormap, cmap); n++;
  13390.     XtSetArg(args[n], XmNtransientFor, mainw); n++;
  13391.       XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
  13392.     XtSetArg(args[n], XmNdefaultButtonType, XmDIALOG_OK_BUTTON); n++;
  13393.     XtSetArg(args[n], XmNmessageString, xm_message); n++;
  13394.     dialog = XmCreateMessageDialog(mainw, name, args, n);
  13395.     XmStringFree(xm_message);
  13396.  
  13397.     /* Doesn't work as a create argument :-) */
  13398.     n = 0;
  13399.     XtSetArg(args[n], XmNdialogType, XmDIALOG_QUESTION); n++;
  13400.     XtSetValues(dialog, args, n);
  13401.  
  13402. #ifdef NO_HELP
  13403.     fe_UnmanageChild_safe(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
  13404. #endif
  13405.  
  13406.     n = 0;
  13407.     yes_button = XmCreatePushButtonGadget(dialog, "yes", args, n);
  13408.     XtManageChild(yes_button);
  13409.  
  13410.     n = 0;
  13411.     no_button = XmCreatePushButtonGadget(dialog, "no", args, n);
  13412.     XtManageChild(no_button);
  13413.  
  13414.     fe_UnmanageChild_safe(XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON));
  13415.  
  13416.     XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done);
  13417.     XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  13418.     XtAddCallback(yes_button, XmNactivateCallback, fe_hrule_ok_cb, &done);
  13419.     XtAddCallback(no_button, XmNactivateCallback, fe_hrule_apply_cb, &done);
  13420.  
  13421.     XtManageChild(dialog);
  13422.  
  13423.     done = XmDIALOG_NONE;
  13424.     while (done == XmDIALOG_NONE) {
  13425.         fe_EventLoop();
  13426.     }
  13427.     return done;
  13428. }
  13429.  
  13430. Boolean
  13431. fe_HintDialog(MWContext* context, char* message)
  13432. {
  13433.     Widget dialog;
  13434.     Widget mainw = CONTEXT_WIDGET(context);
  13435.     Arg    args[8];
  13436.     Cardinal n;
  13437.     Visual*  v;
  13438.     Colormap cmap;
  13439.     Cardinal depth;
  13440.     int done;
  13441.     Widget toggle_button;
  13442.     Widget toggle_row;
  13443.     XmString xm_message;
  13444.     Boolean  return_value;
  13445.  
  13446.     XtVaGetValues(mainw, XtNvisual, &v, XtNcolormap, &cmap,
  13447.                   XtNdepth, &depth, 0);
  13448.  
  13449.     xm_message = XmStringCreateLocalized(message);
  13450.  
  13451.     n = 0;
  13452.     XtSetArg(args[n], XmNvisual, v); n++;
  13453.     XtSetArg(args[n], XmNdepth, depth); n++;
  13454.     XtSetArg(args[n], XmNcolormap, cmap); n++;
  13455.     XtSetArg(args[n], XmNtransientFor, mainw); n++;
  13456.     XtSetArg(args[n], XmNdefaultButtonType, XmDIALOG_OK_BUTTON); n++;
  13457.     XtSetArg(args[n], XmNmessageString, xm_message); n++;
  13458.     dialog = XmCreateInformationDialog(mainw, "hintDialog", args, n);
  13459.     XmStringFree(xm_message);
  13460.  
  13461.     /*
  13462.      *    This is sooooooo lame. Dispite what the manual says, an
  13463.      *    additonal toggle button child is not placed above the push
  13464.      *    buttons, but rather along aside the. Stick the toggle in
  13465.      *    a row, just to get the thing to do what we want.
  13466.      */
  13467.     n = 0;
  13468.     toggle_row = XmCreateRowColumn(dialog, "dontDisplayAgainRow", args, n);
  13469.     XtManageChild(toggle_row);
  13470.     n = 0;
  13471.     XtSetArg(args [n], XmNindicatorType, XmN_OF_MANY); n++;
  13472.     toggle_button = XmCreateToggleButtonGadget(toggle_row, "dontDisplayAgain",
  13473.                                                args, n);
  13474.     XtManageChild(toggle_button);
  13475.  
  13476.     fe_UnmanageChild_safe(XmMessageBoxGetChild(dialog,XmDIALOG_CANCEL_BUTTON));
  13477. #ifdef NO_HELP
  13478.     fe_UnmanageChild_safe(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
  13479. #endif
  13480.  
  13481.     XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done);
  13482.     XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done);
  13483.     
  13484.     XtManageChild(dialog);
  13485.  
  13486.     done = XmDIALOG_NONE;
  13487.     while (done == XmDIALOG_NONE) {
  13488.         fe_EventLoop();
  13489.     }
  13490.  
  13491.     if (done != XFE_DIALOG_DESTROY_BUTTON) {
  13492.         return_value = XmToggleButtonGetState(toggle_button);
  13493.         XtDestroyWidget(dialog);
  13494.         return return_value;
  13495.     }
  13496.  
  13497.     return FALSE;
  13498. }
  13499. #endif
  13500.