/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* * * editordialogs.c --- Editor-specific dialogs. * Should only be built for the editor. * Created: David Williams , Mar-12-1996 * * RCSID: "$Id: editordialogs.c,v 3.2 1998/07/21 02:14:16 akkana%netscape.com Exp $" */ #include "mozilla.h" #include "xfe.h" #include /* for editor key translation */ #include /* tab folder stuff */ #include #include #include /* required for _XmFontListGetDefaultFont() */ #include "DtWidgets/ComboBox.h" #include /* for XP_GetString() */ #include /* for xfe widgets and utilities */ #ifdef EDITOR #include "edttypes.h" #include "edt.h" #include "menu.h" #include "xeditor.h" #include "il_icons.h" /* Image icon enumeration. */ #include "prefapi.h" /* Need some publishing prefs for EDT_PublishFile */ #include "felocale.h" /* no security btn on prefs #define _SECURITY_BTN_ON_PREFS */ /* * I don't like this "fix" for MAXPATHLEN, but I cannot log onto * a SCO machine to find the right way to do this...djw */ #ifdef SCO_SV #include "mcom_db.h" /* for MAXPATHLEN */ #endif void fe_browse_file_of_text (MWContext *context, Widget text_field, Boolean dirp); extern int XFE_ERROR_SAVING_OPTIONS; extern int XFE_VALUES_OUT_OF_RANGE; extern int XFE_VALUE_OUT_OF_RANGE; extern int XFE_ENTER_NEW_VALUE; extern int XFE_ENTER_NEW_VALUES; extern int XFE_EDITOR_LINK_TEXT_LABEL_NEW; extern int XFE_EDITOR_LINK_TEXT_LABEL_IMAGE; extern int XFE_EDITOR_LINK_TEXT_LABEL_TEXT; extern int XFE_EDITOR_LINK_TARGET_LABEL_NO_TARGETS; extern int XFE_EDITOR_LINK_TARGET_LABEL_SPECIFIED; extern int XFE_EDITOR_LINK_TARGET_LABEL_CURRENT; extern int XFE_EDITOR_WARNING_REMOVE_LINK; extern int XFE_UNKNOWN; extern int XFE_EDITOR_TAG_UNOPENED; extern int XFE_EDITOR_TAG_UNCLOSED; extern int XFE_EDITOR_TAG_UNTERMINATED_STRING; extern int XFE_EDITOR_TAG_PREMATURE_CLOSE; extern int XFE_EDITOR_TAG_TAGNAME_EXPECTED; extern int XFE_EDITOR_TAG_UNKNOWN; extern int XFE_EDITOR_TAG_OK; extern int XFE_EDITOR_AUTOSAVE_PERIOD_RANGE; extern int XFE_EDITOR_PUBLISH_LOCATION_INVALID; extern int XFE_EDITOR_IMAGE_IS_REMOTE; extern int XFE_CANNOT_READ_FILE; extern int XFE_EDITOR_TABLE_ROW_RANGE; extern int XFE_EDITOR_TABLE_COLUMN_RANGE; extern int XFE_EDITOR_TABLE_BORDER_RANGE; extern int XFE_EDITOR_TABLE_SPACING_RANGE; extern int XFE_EDITOR_TABLE_PADDING_RANGE; extern int XFE_EDITOR_TABLE_WIDTH_RANGE; extern int XFE_EDITOR_TABLE_HEIGHT_RANGE; extern int XFE_EDITOR_TABLE_IMAGE_WIDTH_RANGE; extern int XFE_EDITOR_TABLE_IMAGE_HEIGHT_RANGE; extern int XFE_EDITOR_TABLE_IMAGE_SPACE_RANGE; #define IMAGE_MIN_WIDTH 1 #define IMAGE_MAX_WIDTH 10000 #define IMAGE_MIN_HEIGHT 1 #define IMAGE_MAX_HEIGHT 10000 #define IMAGE_MIN_HSPACE 0 #define IMAGE_MAX_HSPACE 10000 #define IMAGE_MIN_VSPACE 0 #define IMAGE_MAX_VSPACE 10000 #define IMAGE_MIN_BORDER 0 #define IMAGE_MAX_BORDER 10000 #define TABLE_MAX_PERCENT_WIDTH 100 #define TABLE_MIN_PERCENT_WIDTH 1 #define TABLE_MAX_PERCENT_HEIGHT 100 #define TABLE_MIN_PERCENT_HEIGHT 1 #define HRULE_MIN_HEIGHT 1 #define HRULE_MAX_HEIGHT 10000 #define HRULE_MAX_PIXEL_WIDTH 10000 #define HRULE_MIN_PIXEL_WIDTH 1 #define HRULE_MAX_PERCENT_WIDTH 100 #define HRULE_MIN_PERCENT_WIDTH 1 #define AUTOSAVE_MIN_PERIOD 0 #define AUTOSAVE_MAX_PERIOD 600 #define RANGE_CHECK(o, a, b) ((o) < (a) || (o) > (b)) #define XFE_INVALID_TABLE_NROWS 1 #define XFE_INVALID_TABLE_NCOLUMNS 2 #define XFE_INVALID_TABLE_BORDER 3 #define XFE_INVALID_TABLE_SPACING 4 #define XFE_INVALID_TABLE_PADDING 5 #define XFE_INVALID_TABLE_WIDTH 6 #define XFE_INVALID_TABLE_HEIGHT 7 #define XFE_INVALID_CELL_NROWS 8 #define XFE_INVALID_CELL_NCOLUMNS 9 #define XFE_INVALID_CELL_WIDTH 10 #define XFE_INVALID_CELL_HEIGHT 11 #define XFE_INVALID_IMAGE_WIDTH 12 #define XFE_INVALID_IMAGE_HEIGHT 13 #define XFE_INVALID_IMAGE_HSPACE 14 #define XFE_INVALID_IMAGE_VSPACE 15 #define XFE_INVALID_IMAGE_BORDER 16 #define XFE_INVALID_HRULE_WIDTH 17 #define XFE_INVALID_HRULE_HEIGHT 18 static void fe_error_dialog(MWContext* context, Widget parent, char* s) { while (!XtIsWMShell(parent) && (XtParent(parent)!=0)) parent = XtParent(parent); fe_dialog(parent, "error", s, FALSE, 0, FALSE, FALSE, 0); } static void fe_message_dialog(MWContext* context, Widget parent, char* s) { Widget mainw; while (!XtIsWMShell(parent) && (XtParent(parent)!=0)) parent = XtParent(parent); /* yuck */ mainw = CONTEXT_WIDGET(context); CONTEXT_WIDGET(context) = parent; fe_Message(context, s); CONTEXT_WIDGET(context) = mainw; } void fe_editor_range_error_dialog(MWContext* context, Widget parent, unsigned* errors, unsigned nerrors) { unsigned i; int id; char be_lazy[8192]; if (nerrors > 1) id = XFE_VALUES_OUT_OF_RANGE; /* Some values are out of range: */ else if (nerrors == 1) id = XFE_VALUE_OUT_OF_RANGE; /* The following value is out of range: */ else return; strcpy(be_lazy, XP_GetString(id)); strcat(be_lazy, "\n\n"); for (i = 0; i < nerrors; i++) { switch (errors[i]) { case XFE_INVALID_TABLE_NROWS: case XFE_INVALID_CELL_NROWS: id = XFE_EDITOR_TABLE_ROW_RANGE; /* You can have between 1 and 100 rows. */ break; case XFE_INVALID_TABLE_NCOLUMNS: case XFE_INVALID_CELL_NCOLUMNS: id = XFE_EDITOR_TABLE_COLUMN_RANGE; /* You can have between 1 and 100 columns. */ break; case XFE_INVALID_TABLE_BORDER: id = XFE_EDITOR_TABLE_BORDER_RANGE; /* For border width, you can have 0 to 10000 pixels. */ break; case XFE_INVALID_TABLE_SPACING: id = XFE_EDITOR_TABLE_SPACING_RANGE; /* For cell spacing, you can have 0 to 10000 pixels. */ break; case XFE_INVALID_TABLE_PADDING: id = XFE_EDITOR_TABLE_PADDING_RANGE; /* For cell padding, you can have 0 to 10000 pixels. */ break; case XFE_INVALID_TABLE_WIDTH: case XFE_INVALID_CELL_WIDTH: case XFE_INVALID_HRULE_WIDTH: id = XFE_EDITOR_TABLE_WIDTH_RANGE; /* For width, you can have between 1 and 10000 pixels, */ /* or between 1 and 100%. */ break; case XFE_INVALID_TABLE_HEIGHT: case XFE_INVALID_CELL_HEIGHT: id = XFE_EDITOR_TABLE_HEIGHT_RANGE; /* For height, you can have between 1 and 10000 pixels, */ /* or between 1 and 100%. */ break; case XFE_INVALID_IMAGE_WIDTH: id = XFE_EDITOR_TABLE_IMAGE_WIDTH_RANGE; /* For width, you can have between 1 and 10000 pixels. */ break; case XFE_INVALID_IMAGE_HEIGHT: case XFE_INVALID_HRULE_HEIGHT: id = XFE_EDITOR_TABLE_IMAGE_HEIGHT_RANGE; /* For height, you can have between 1 and 10000 pixels. */ break; case XFE_INVALID_IMAGE_HSPACE: case XFE_INVALID_IMAGE_VSPACE: case XFE_INVALID_IMAGE_BORDER: id = XFE_EDITOR_TABLE_IMAGE_SPACE_RANGE; /* For space, you can have between 1 and 10000 pixels. */ break; } strcat(be_lazy, XP_GetString(id)); strcat(be_lazy, "\n"); } if (nerrors > 1) { id = XFE_ENTER_NEW_VALUES; /* Please enter new values and try again. */ } else if (nerrors == 1) { id = XFE_ENTER_NEW_VALUE; /* Please enter a new value and try again. */ } strcat(be_lazy, "\n"); strcat(be_lazy, XP_GetString(id)); fe_error_dialog(context, parent, be_lazy); } #endif /* EDITOR */ Widget fe_CreateTabForm(Widget parent, char* name, Arg* args, Cardinal n) { Widget form; Widget tab; Pixel bg; char* string; XmString xm_string; XtVaGetValues(parent, XmNbackground, &bg, 0); form = XtVaCreateWidget(name, xmFormWidgetClass, parent, XmNbackground, bg, NULL); string = XfeSubResourceGetWidgetStringValue(form, "tabLabelString", XmCXmString); if (!string) string = name; xm_string = XmStringCreateSimple(string); tab = XmLFolderAddTab(parent, xm_string); XtVaSetValues(tab, XmNtabManagedWidget, form, NULL); return form; } #ifdef EDITOR void fe_WidgetSetSensitive(Widget widget, Boolean sensitive) { XtVaSetValues(widget, XmNsensitive, sensitive, 0); } /* This routine has a name conflict with another fe_CreateSwatch * in colorpicker.c. The one in colorpicker.c looks much more * elaborate, so I'm choosing to rename this one. ...Akkana */ #define SWATCH_SIZE 60 Widget fe_CreateSwatchButton(Widget parent, char* name, Arg* p_args, Cardinal p_n) { return XmCreateDrawnButton(parent, name, p_args, p_n); } void fe_SwatchSetSensitive(Widget widget, Boolean sensitive) { XtVaSetValues(widget, XmNsensitive, sensitive, 0); } #endif /* EDITOR */ void fe_SwatchSetColor(Widget widget, LO_Color* color) { MWContext* context = fe_WidgetToMWContext(widget); Pixel pixel; if (color != NULL) { pixel = fe_GetPixel(context, color->red, color->green, color->blue); } else { XtVaGetValues(XtParent(widget), XmNbackground, &pixel, 0); } XtVaSetValues(widget, XmNbackground, pixel, 0); } #ifdef EDITOR Widget fe_CreatePasswordField(Widget parent, char* name, Arg* args, Cardinal n) { Widget widget; int max_length; widget = fe_CreateTextField(parent, name, args, n); XtVaGetValues(widget, XmNmaxLength, &max_length, 0); fe_SetupPasswdText(widget, max_length); return widget; } #endif /* EDITOR */ void fe_TextFieldSetString(Widget widget, char* value, Boolean notify) { XtCallbackRec buf[32]; /* hope that's enough! */ XtCallbackList callbacks; int i; if (notify == FALSE) { XtVaGetValues(widget, XmNvalueChangedCallback, &callbacks, 0); for (i = 0; callbacks[i].callback != NULL; i++) { buf[i] = callbacks[i]; } buf[i].callback = NULL; buf[i].closure = NULL; XtRemoveAllCallbacks(widget, XmNvalueChangedCallback); } fe_SetTextFieldAndCallBack(widget, value); if (notify == FALSE) { XtAddCallbacks(widget, XmNvalueChangedCallback, buf); } } #ifdef EDITOR static char* fe_TextFieldGetString(Widget widget) { return fe_GetTextField(widget); } static Pixel fe_get_text_field_background(Widget widget) { return XfeSubResourceGetPixelValue(widget, XtName(widget), XfeClassNameForWidget(widget), XmNbackground, XmCBackground, WhitePixelOfScreen(XtScreen(widget))); } void fe_TextFieldSetEditable(MWContext* context, Widget widget, Boolean editable) { Pixel bg_pixel; Arg args[16]; Cardinal n; /* * The TextField is so losing, it doesn't set the * background color to indicate the field is not-editable. * The Gods of Motif style say thou shalt bestow unto thine * non-editable TextField thine color of select color-ness. * * Hmmm this looks butt ugly, maybe have to use a label instead. */ if (editable) { bg_pixel = fe_get_text_field_background(widget); } else { n = 0; XtSetArg(args[n], XmNbackground, &bg_pixel); n++; XtGetValues(XtParent(widget), args, n); #if 0 /* use select color as background color */ XmGetColors(XtScreen(widget), fe_cmap(context), bg_pixel, NULL, /* foreground */ NULL, /* top shadow */ NULL, /* bottom shadow */ &select_pixel); bg_pixel = select_pixel; #endif } n = 0; XtSetArg(args[n], XmNeditable, editable); n++; XtSetArg(args[n], XmNcursorPositionVisible, editable); n++; XtSetArg(args[n], XmNtraversalOn, editable); n++; XtSetArg(args[n], XmNbackground, bg_pixel); n++; XtSetValues(widget, args, n); } Widget fe_CreateFrame(Widget parent, char* name, Arg* p_args, Cardinal p_n) { Widget frame; Widget title; char namebuf[256]; Arg args[16]; Cardinal n; for (n = 0; n < p_n; n++) { XtSetArg(args[n], p_args[n].name, p_args[n].value); } strcpy(namebuf, name); strcat(namebuf, "Frame"); XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_IN); n++; frame = XmCreateFrame(parent, namebuf, args, n); XtManageChild(frame); strcpy(namebuf, name); strcat(namebuf, "Title"); n = 0; XtSetArg(args[n], XmNlabelType, XmSTRING); n++; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; XtSetArg(args[n], XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNchildVerticalAlignment, XmALIGNMENT_CENTER); n++; title = XmCreateLabelGadget(frame, namebuf, args, n); XtManageChild(title); return frame; } Widget fe_CreateFramedForm(Widget parent, char* name, Arg* p_args, Cardinal p_n) { Widget frame; Widget form; Arg args[16]; Cardinal n; n = 0; frame = fe_CreateFrame(parent, name, args, n); XtManageChild(frame); for (n = 0; n < p_n; n++) { XtSetArg(args[n], p_args[n].name, p_args[n].value); } form = XmCreateForm(frame, name, args, n); return form; } Widget fe_CreateFramedRowColumn(Widget parent, char* name, Arg* p_args, Cardinal p_n) { Widget frame; Widget rowcol; Arg args[16]; Cardinal n; n = 0; frame = fe_CreateFrame(parent, name, args, n); XtManageChild(frame); for (n = 0; n < p_n; n++) { XtSetArg(args[n], p_args[n].name, p_args[n].value); } rowcol = XmCreateRowColumn(frame, name, args, n); return rowcol; } static Widget fe_CreateToggleButtonGadget(Widget parent, char* name, Arg* p_args, Cardinal p_nargs) { Arg args[16]; Cardinal n = 0; Widget widget; for (n = 0; n < p_nargs; n++) { XtSetArg(args[n], p_args[n].name, p_args[n].value); n++; } XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++; widget = XmCreateToggleButtonGadget(parent, name, args, n); return widget; } static Widget fe_CreateRadioButtonGadget(Widget parent, char* name, Arg* p_args, Cardinal p_nargs) { Arg args[16]; Cardinal n = 0; Widget widget; for (n = 0; n < p_nargs; n++) { XtSetArg(args[n], p_args[n].name, p_args[n].value); n++; } XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; widget = XmCreateToggleButtonGadget(parent, name, args, n); return widget; } #endif /* EDITOR */ Widget fe_CreatePulldownMenu(Widget parent, char* name, Arg* p_argv, Cardinal p_argc) { unsigned i; Widget popup_menu; Arg argv[8]; Cardinal argc; Visual* v = 0; Colormap cmap = 0; Cardinal depth = 0; Widget widget; XtCallbackRec* button_callback_rec = NULL; for (i = 0; i < p_argc; i++) { if (p_argv[i].name == XmNactivateCallback) button_callback_rec = (XtCallbackRec*)p_argv[i].value; } for (widget = parent; !XtIsWMShell(widget); widget = XtParent(widget)) ; XtVaGetValues(widget, XtNvisual, &v, XtNcolormap, &cmap, XtNdepth, &depth, 0); argc = 0; XtSetArg (argv[argc], XmNvisual, v); argc++; XtSetArg (argv[argc], XmNdepth, depth); argc++; XtSetArg (argv[argc], XmNcolormap, cmap); argc++; popup_menu = XmCreatePulldownMenu(parent, name, argv, argc); return popup_menu; } #ifdef EDITOR static Widget fe_CreateOptionMenuNoLabel(Widget widget, char* name, Arg* args, Cardinal n) { Widget menu = fe_CreateOptionMenu(widget, name, args, n); fe_UnmanageChild_safe(XmOptionLabelGadget(menu)); return menu; } /* * This dialog builder stuff was a wishful attempt at doing declarative * dialogs for XFE. I only got as far as using them for the simplest of * dialogs - the Horizontal Rule pref dialog. That's all that uses it, * so it could be ripped and replaced by some simple code for that dialog. * We really should spend the time to do some kind of easier dialog * builder for XFE. One day....djw */ typedef struct fe_DialogBuilderCreator { char* name; Widget (*func)(Widget parent, char* name, ArgList args, Cardinal argcount); Boolean recurse; } fe_DialogBuilderCreator; static char XFE_DB_PUSHBUTTONGADGET[] = "XmPushButtonGadget"; static char XFE_DB_LABELGADGET[] = "XmLabelGadget"; static char XFE_DB_FRAME[] = "XmFrame"; static char XFE_DB_FORM[] = "XmForm"; static char XFE_DB_TEXTFIELD[] = "XmTextField"; static char XFE_DB_OPTIONMENU[] = "XmOptionMenu"; static char XFE_DB_PULLDOWNMENU[] = "fe_PulldownMenu"; static char XFE_DB_ROWCOL[] = "XmRowColumn"; static char XFE_DB_FRAMEDFORM[] = "fe_FramedForm"; static char XFE_DB_TOGGLEGADGET[] = "fe_ToggleButtonGadget"; static char XFE_DB_RADIOGADGET[] = "fe_RadioButtonGadget"; static char XFE_DB_FRAMEDROWCOL[] = "fe_FramedRowCol"; static fe_DialogBuilderCreator fe_DialogBuilderDefaultCreators[] = { { XFE_DB_PUSHBUTTONGADGET, XmCreatePushButtonGadget, FALSE }, { XFE_DB_LABELGADGET, XmCreateLabelGadget, FALSE }, { XFE_DB_TEXTFIELD, fe_CreateTextField, FALSE }, { XFE_DB_TOGGLEGADGET, fe_CreateToggleButtonGadget, FALSE }, { XFE_DB_RADIOGADGET, fe_CreateRadioButtonGadget, FALSE }, { XFE_DB_FRAME, XmCreateFrame, TRUE }, { XFE_DB_FORM, XmCreateForm, TRUE }, { XFE_DB_PULLDOWNMENU, fe_CreatePulldownMenu, TRUE }, { XFE_DB_OPTIONMENU, fe_CreateOptionMenuNoLabel, FALSE }, { XFE_DB_ROWCOL, XmCreateRowColumn, TRUE }, { XFE_DB_FRAMEDFORM, fe_CreateFramedForm, TRUE }, { XFE_DB_FRAMEDROWCOL, fe_CreateFramedRowColumn, TRUE }, { 0 } }; static char XFE_DB_END[] = "end"; static char XFE_DB_PUSH[] = "push"; static char XFE_DB_POP[] = "pop"; static char XFE_DB_WIDGETCALLED[] = "widgetcalled"; static char XFE_DB_WIDEST[] = "widest"; static char XFE_DB_TALLEST[] = "tallest"; static char XFE_DB_SETVAL[] = "setval"; static char XFE_DB_SETDATA[] = "setdata"; static char XFE_DB_SETVALCALLED[] = "setvalcalled"; static char XFE_DB_CALLBACK[] = "callback"; typedef struct fe_DialogBuilderArg { char* name; XtPointer value; } fe_DialogBuilderArg; static fe_DialogBuilderCreator* find_creator(fe_DialogBuilderCreator* creators, char* name) { int i; for (i = 0; creators[i].name; i++) { if (creators[i].name == name || strcmp(creators[i].name, name) == 0) return &creators[i]; } return NULL; } Widget db_do_work( MWContext* context, Widget parent, fe_DialogBuilderCreator* creators, fe_DialogBuilderArg** instructions_a, void* data) { #define MACHINE_NARGS 16 #define MACHINE_NSTACK 16 #define MACHINE_NCALLBACK 16 #define MACHINE_NWIDGETS 32 Arg args[MACHINE_NARGS]; XtPointer stack[MACHINE_NSTACK]; XtCallbackRec callbacks[MACHINE_NCALLBACK]; Cardinal stackposn; #define POP() (stack[--stackposn]) #define PUSH(x) (stack[stackposn++] = (XtPointer)(x)) Cardinal nargs; Cardinal ncallbacks; Widget children[MACHINE_NWIDGETS]; Cardinal nchildren; char* name; XtPointer value; Dimension width; Dimension max_width; Dimension height; Dimension max_height; Widget widget = NULL; Widget max_widget; int i; fe_DialogBuilderCreator* creator; nargs = 0; stackposn = 0; ncallbacks = 0; nchildren = 0; for (; (*instructions_a)->name != XFE_DB_END; (*instructions_a)++) { name = (*instructions_a)->name; value = (*instructions_a)->value; if (value == (XtPointer)XFE_DB_POP) /* pop is only ever a value */ value = POP(); if (name == XFE_DB_PUSH) { /* push is only ever a name */ PUSH(value); } else if (name == XFE_DB_WIDGETCALLED) { for (i = 0; i < nchildren; i++) { if (strcmp(XtName(children[i]), (char*)value) == 0) { PUSH(children[i]); break; } } XP_ASSERT(i < nchildren); } else if (name == XFE_DB_WIDEST) { max_width = 0; max_widget = 0; for (i = 0; i < (unsigned)value; i++) { widget = (Widget)POP(); XtVaGetValues(widget, XtNwidth, &width, 0); if (width > max_width) { max_width = width; max_widget = widget; } } PUSH(max_widget); } else if (name == XFE_DB_TALLEST) { max_height = 0; max_widget = 0; for (i = 0; i < (unsigned)value; i++) { widget = (Widget)POP(); XtVaGetValues(widget, XtNheight, &height, 0); if (height > max_height) { max_height = height; max_widget = widget; } } PUSH(max_widget); } else if (name == XFE_DB_SETVAL) { widget = (Widget)POP(); XtSetValues(widget, args, nargs); nargs = 0; } else if (name == XFE_DB_SETVALCALLED) { for (i = 0; i < nchildren; i++) { if (strcmp(XtName(children[i]), (char*)value) == 0) { XtSetValues(children[i], args, nargs); nargs = 0; break; } } XP_ASSERT(i < nchildren); } else if (name == XFE_DB_SETDATA) { Widget* foo = (Widget*)(((char*) data) + (int) (value)); *foo = (Widget)POP(); } else if (name == XFE_DB_CALLBACK) { callbacks[ncallbacks].callback = (XtCallbackProc)POP(); callbacks[ncallbacks].closure = (XtPointer)POP(); PUSH(&callbacks[ncallbacks++]); /* * See if it's a creator. */ } else if ((creator = find_creator(creators, name))) { widget = (*creator->func)( parent, (char*)value, args, nargs ); /* * Hack, hack, hack for menus which get managed by cascades. */ if (creator->name != XFE_DB_PULLDOWNMENU) XtManageChild(widget); children[nchildren++] = widget; nargs = 0; /* if (XtIsSubclass(widget, compositeWidgetClass)) { */ if (creator->recurse) { (*instructions_a)++; db_do_work( context, widget, creators, instructions_a, data); /* call ourselves */ } } else { /* * Must be an argument. */ args[nargs].name = name; args[nargs].value = (XtArgVal)value; nargs++; } } #if 0 XtManageChildren(children, nchildren); #endif return children[0]; } /* * Stuff for dialogs. */ typedef struct fe_HorizontalRulePropertiesDialogData { MWContext* context; Widget height; Widget width; Widget width_menu; Widget width_units; Widget width_pixels; Widget width_percent; Widget align_left; Widget align_center; Widget align_right; Widget three_d_shading; } fe_HorizontalRulePropertiesDialogData; /* * DB program to build Horizontal Rule properties Dialog. */ static fe_DialogBuilderArg fe_HorizontalRulePropertiesDialogProgram[] = { #define OFFSET(x) XtOffset(fe_HorizontalRulePropertiesDialogData *, x) { XmNorientation, (XtPointer)XmVERTICAL }, { XFE_DB_ROWCOL, (XtPointer)"rowcol" }, { XFE_DB_FRAMEDFORM, "dimensions" }, { XFE_DB_LABELGADGET, "heightLabel" }, { XFE_DB_TEXTFIELD, "heightText" }, { XFE_DB_LABELGADGET, "pixels" }, { XFE_DB_LABELGADGET, "widthLabel" }, { XFE_DB_TEXTFIELD, "widthText" }, { XFE_DB_PULLDOWNMENU, "widthUnitsPulldown" }, { XFE_DB_PUSHBUTTONGADGET, "percent" }, { XFE_DB_PUSHBUTTONGADGET, "pixels" }, { XFE_DB_WIDGETCALLED, "percent" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(width_percent) }, { XFE_DB_WIDGETCALLED, "pixels" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(width_pixels) }, { XFE_DB_END, "widthUnitsPulldown" }, { XFE_DB_WIDGETCALLED, "widthUnitsPulldown" }, { XmNsubMenuId, XFE_DB_POP }, { XFE_DB_OPTIONMENU, "widthUnits" }, /* now do computed attachments, oh boy, we need a compiler */ { XmNtopAttachment, (XtPointer)XmATTACH_FORM }, { XmNleftAttachment, (XtPointer)XmATTACH_FORM }, { XFE_DB_SETVALCALLED, "heightLabel" }, /* set heightLabel */ { XmNtopAttachment, (XtPointer)XmATTACH_FORM }, { XmNleftAttachment, (XtPointer)XmATTACH_WIDGET }, { XFE_DB_WIDGETCALLED, "heightLabel" }, { XFE_DB_WIDGETCALLED, "widthLabel" }, { XFE_DB_WIDEST, (XtPointer)2 }, { XmNleftWidget, XFE_DB_POP }, { XFE_DB_SETVALCALLED, "heightText" }, /* set heightText */ { XmNtopAttachment, (XtPointer)XmATTACH_FORM }, { XmNleftAttachment, (XtPointer)XmATTACH_WIDGET }, { XFE_DB_WIDGETCALLED, "heightText" }, { XmNleftWidget, XFE_DB_POP }, { XFE_DB_SETVALCALLED, "pixels" }, /* set pixel */ { XmNtopAttachment, (XtPointer)XmATTACH_WIDGET }, { XFE_DB_WIDGETCALLED, "heightText" }, { XmNtopWidget, XFE_DB_POP }, { XmNleftAttachment, (XtPointer)XmATTACH_FORM }, { XFE_DB_SETVALCALLED, "widthLabel" }, /* set widthLabel */ { XmNtopAttachment, (XtPointer)XmATTACH_WIDGET }, { XFE_DB_WIDGETCALLED, "heightText" }, { XmNtopWidget, XFE_DB_POP }, { XmNleftAttachment, (XtPointer)XmATTACH_WIDGET }, { XFE_DB_WIDGETCALLED, "heightLabel" }, { XFE_DB_WIDGETCALLED, "widthLabel" }, { XFE_DB_WIDEST, (XtPointer)2 }, { XmNleftWidget, XFE_DB_POP }, { XFE_DB_SETVALCALLED, "widthText" }, /* set widthText */ { XmNtopAttachment, (XtPointer)XmATTACH_WIDGET }, { XFE_DB_WIDGETCALLED, "heightText" }, { XmNtopWidget, XFE_DB_POP }, { XmNleftAttachment, (XtPointer)XmATTACH_WIDGET }, { XFE_DB_WIDGETCALLED, "widthText" }, { XmNleftWidget, XFE_DB_POP }, #if 0 { XmNrightAttachment, (XtPointer)XmATTACH_FORM }, #endif { XFE_DB_SETVALCALLED, "widthUnits" }, /* set widthUnits */ /* do offsets */ { XFE_DB_WIDGETCALLED, "widthText" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(width) }, { XFE_DB_WIDGETCALLED, "heightText" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(height) }, { XFE_DB_WIDGETCALLED, "widthUnitsPulldown" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(width_menu) }, { XFE_DB_WIDGETCALLED, "widthUnits" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(width_units) }, { XFE_DB_END, "dimensions" }, { XmNorientation, (XtPointer)XmHORIZONTAL }, { XmNradioBehavior, (XtPointer)TRUE }, { XFE_DB_FRAMEDROWCOL, "align" }, { XFE_DB_RADIOGADGET, "left" }, { XFE_DB_RADIOGADGET, "center" }, { XFE_DB_RADIOGADGET, "right" }, { XFE_DB_WIDGETCALLED, "left" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(align_left) }, { XFE_DB_WIDGETCALLED, "center" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(align_center) }, { XFE_DB_WIDGETCALLED, "right" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(align_right) }, { XFE_DB_END, "align" }, { XFE_DB_TOGGLEGADGET, "threeDShading" }, { XFE_DB_WIDGETCALLED, "threeDShading" }, { XFE_DB_SETDATA, (XtPointer)OFFSET(three_d_shading) }, { XFE_DB_END, "rowcol" }, { XFE_DB_END, "program" } #undef OFFSET }; #endif /* EDITOR */ Widget fe_CreatePromptDialog(MWContext *context, char* name, Boolean ok, Boolean cancel, Boolean apply, Boolean separator, Boolean modal) { Widget mainw = CONTEXT_WIDGET(context); Widget dialog; Visual *v = 0; Colormap cmap = 0; Cardinal depth = 0; Arg av [20]; int ac; XtVaGetValues (mainw, XtNvisual, &v, XtNcolormap, &cmap, XtNdepth, &depth, 0); ac = 0; XtSetArg (av[ac], XmNvisual, v); ac++; XtSetArg (av[ac], XmNdepth, depth); ac++; XtSetArg (av[ac], XmNcolormap, cmap); ac++; XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++; XtSetArg (av[ac], XmNtransientFor, mainw); ac++; if (modal) { XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ac++; } XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++; XtSetArg (av[ac], XmNdeleteResponse, XmDESTROY); ac++; XtSetArg (av[ac], XmNautoUnmanage, False); ac++; XtSetArg (av[ac], XmNnoResize, True); ac++; dialog = XmCreatePromptDialog (mainw, name, av, ac); if (!separator) fe_UnmanageChild_safe(XmSelectionBoxGetChild(dialog, XmDIALOG_SEPARATOR)); fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT)); fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL)); if (!ok) fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON)); if (!cancel) fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON)); #ifdef NO_HELP fe_UnmanageChild_safe (XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON)); #endif if (apply) XtManageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_APPLY_BUTTON)); return dialog; } #ifdef EDITOR int fe_get_numeric_text_field(Widget widget) { char* p = XmTextFieldGetString(widget); /* numeric so no JIS fix */ char* q; if (p) { while (isspace(*p)) p++; if (*p == '\0') return -1; for (q = p; *q != '\0'; q++) { if (!(isdigit(*q) || isspace(*q))) return -1; /* force error */ } return atoi(p); } else { return -1; } } static void fe_editor_hrule_properties_common(MWContext* context, EDT_HorizRuleData* data, fe_HorizontalRulePropertiesDialogData* w_data) { Widget widget; /* height */ data->size = fe_get_numeric_text_field(w_data->height); /* width */ XtVaGetValues(w_data->width_menu, XmNmenuHistory, &widget, 0); if (widget == w_data->width_pixels) data->bWidthPercent = FALSE; else data->bWidthPercent = TRUE; data->iWidth = fe_get_numeric_text_field(w_data->width); /* align */ if (XmToggleButtonGadgetGetState(w_data->align_right) == TRUE) data->align = ED_ALIGN_RIGHT; else if (XmToggleButtonGadgetGetState(w_data->align_left) == TRUE) data->align = ED_ALIGN_LEFT; else data->align = ED_ALIGN_CENTER; /* shading */ if (XmToggleButtonGadgetGetState(w_data->three_d_shading) == TRUE) data->bNoShade = FALSE; else data->bNoShade = TRUE; data->pExtra = 0; } static Boolean fe_editor_hrule_properties_validate(MWContext* context, fe_HorizontalRulePropertiesDialogData* w_data) { EDT_HorizRuleData data; EDT_HorizRuleData* h = &data; unsigned errors[16]; unsigned nerrors = 0; fe_editor_hrule_properties_common(context, &data, w_data); if (RANGE_CHECK(h->size, HRULE_MIN_HEIGHT, HRULE_MAX_HEIGHT)) errors[nerrors++] = XFE_INVALID_HRULE_HEIGHT; if (h->bWidthPercent == TRUE) { if (RANGE_CHECK(h->iWidth, HRULE_MIN_PERCENT_WIDTH, HRULE_MAX_PERCENT_WIDTH)) errors[nerrors++] = XFE_INVALID_HRULE_WIDTH; } else { if (RANGE_CHECK(h->iWidth, HRULE_MIN_PIXEL_WIDTH, HRULE_MAX_PIXEL_WIDTH)) errors[nerrors++] = XFE_INVALID_HRULE_WIDTH; } if (nerrors > 0) { fe_editor_range_error_dialog(context, w_data->width, errors, nerrors); return FALSE; } return TRUE; } static void fe_HorizontalRulePropertiesDialogSet(MWContext* context, fe_HorizontalRulePropertiesDialogData* w_data) { EDT_HorizRuleData e_data; EDT_BeginBatchChanges(context); fe_editor_hrule_properties_common(context, &e_data, w_data); e_data.pExtra = 0; fe_EditorHorizontalRulePropertiesSet(context, &e_data); EDT_EndBatchChanges(context); } void fe_table_percent_label_set(Widget widget, Boolean nested) { char * name = (nested ? "percentOfCell" : "percentOfWindow"); XmString xm_string = XfeSubResourceGetXmStringValue(widget, name, XfeClassNameForWidget(widget), XmNlabelString, XmCXmString, NULL); if (!xm_string) { xm_string = XmStringCreateLocalized(name); XtVaSetValues(widget, XmNlabelString, xm_string, 0); XmStringFree(xm_string); } /* No need to free xm_string. The resource converter dtor will */ else { XtVaSetValues(widget, XmNlabelString, xm_string, 0); } } static void fe_HorizontalRulePropertiesDialogDataGet( MWContext* context, fe_HorizontalRulePropertiesDialogData* w_data ) { EDT_HorizRuleData e_data; char buf[16]; Boolean left; Boolean center; Boolean right; Boolean shading; Widget widget; Boolean is_nested; fe_EditorHorizontalRulePropertiesGet(context, &e_data); /* height */ sprintf(buf, "%d", e_data.size); fe_SetTextFieldAndCallBack(w_data->height, buf); /* width */ sprintf(buf, "%d", e_data.iWidth); fe_SetTextFieldAndCallBack(w_data->width, buf); if (e_data.bWidthPercent) widget = w_data->width_percent; else widget = w_data->width_pixels; is_nested = EDT_IsInsertPointInTable(context); fe_table_percent_label_set(w_data->width_percent, is_nested); XtVaSetValues(w_data->width_units, XmNmenuHistory, widget, 0); /* align */ if (e_data.align == ED_ALIGN_RIGHT) { left = FALSE; center = FALSE; right = TRUE; } else if (e_data.align == ED_ALIGN_LEFT) { left = TRUE; center = FALSE; right = FALSE; } else { left = FALSE; center = TRUE; right = FALSE; } XmToggleButtonGadgetSetState(w_data->align_right, right, FALSE); XmToggleButtonGadgetSetState(w_data->align_left, left, FALSE); XmToggleButtonGadgetSetState(w_data->align_center, center, FALSE); if (e_data.bNoShade) shading = FALSE; else shading = TRUE; XmToggleButtonGadgetSetState(w_data->three_d_shading, shading, FALSE); } Widget fe_EditorHorizontalRulePropertiesCreate( MWContext* context, fe_HorizontalRulePropertiesDialogData* data ) { fe_DialogBuilderArg* code; Widget dialog; /* * Make shell. */ dialog = fe_CreatePromptDialog(context, "horizontalLineProperties", TRUE, TRUE, FALSE, TRUE, TRUE); /* * Make the rowcol, because we want to manage it. */ code = fe_HorizontalRulePropertiesDialogProgram; db_do_work(context, dialog, fe_DialogBuilderDefaultCreators, &code, data); return dialog; } static void fe_hrule_destroy_cb (Widget widget, XtPointer closure, XtPointer call_data) { int* done = (int*)closure; *done = XFE_DIALOG_DESTROY_BUTTON; } static void fe_hrule_ok_cb (Widget widget, XtPointer closure, XtPointer call_data) { int* done = (int*)closure; *done = XmDIALOG_OK_BUTTON; } static void fe_hrule_apply_cb (Widget widget, XtPointer closure, XtPointer call_data) { int* done = (int*)closure; *done = XmDIALOG_APPLY_BUTTON; } static void fe_hrule_cancel_cb (Widget widget, XtPointer closure, XtPointer call_data) { int* done = (int*)closure; *done = XmDIALOG_CANCEL_BUTTON; } void fe_EditorHorizontalRulePropertiesDialogDo(MWContext* context) { fe_HorizontalRulePropertiesDialogData widgets; int done; Widget dialog; #if 0 if (!fe_EditorHorizontalRulePropertiesCanDo(context)) { XBell(XtDisplay(CONTEXT_WIDGET(context)), 0); return; } #endif dialog = fe_EditorHorizontalRulePropertiesCreate(context, &widgets); /* * Add a bunch of callbacks to the buttons. */ XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done); XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done); XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done); /* * Load values. */ fe_HorizontalRulePropertiesDialogDataGet(context, &widgets); /* * Popup. */ XtManageChild(dialog); /* * Wait. */ fe_NukeBackingStore(dialog); /* what does this do? */ done = XmDIALOG_NONE; while (done == XmDIALOG_NONE) { fe_EventLoop(); /* * Unload data. */ if (done == XmDIALOG_OK_BUTTON && !fe_editor_hrule_properties_validate(context, &widgets)) { done = XmDIALOG_NONE; } } if (done == XmDIALOG_OK_BUTTON) fe_HorizontalRulePropertiesDialogSet(context, &widgets); if (done != XFE_DIALOG_DESTROY_BUTTON) XtDestroyWidget(dialog); } static void fe_destroy_cleanup_cb(Widget widget, XtPointer closure, XtPointer cb) { if (closure) XtFree(closure); } void fe_DependentListAddDependent(fe_DependentList** list_a, Widget widget, fe_Dependency mask, XtCallbackProc proc, XtPointer closure) { fe_DependentList* list = XtNew(fe_DependentList); list->next = *list_a; list->widget = widget; list->mask = mask; list->callback.callback = proc; list->callback.closure = closure; *list_a = list; } void fe_DependentListDestroy(fe_DependentList* list) { fe_DependentList* next; for (; list; list = next) { next = list->next; XtFree((XtPointer)list); } } typedef struct fe_DependentListCallbackStruct { int reason; XEvent *event; fe_Dependency mask; Widget caller; XtPointer callers_data; } fe_DependentListCallbackStruct; void fe_DependentListCallDependents(Widget caller, fe_DependentList* list, fe_Dependency mask, XtPointer callers_data) { fe_DependentListCallbackStruct call_data; call_data.reason = 0; call_data.event = 0; call_data.mask = mask; call_data.caller = caller; call_data.callers_data = callers_data; for (; list; list = list->next) { if ((list->mask & mask) != 0) (*list->callback.callback)(list->widget, list->callback.closure, &call_data); } } void fe_MakeDependent(Widget widget, fe_Dependency mask, XtCallbackProc proc, XtPointer closure) { MWContext* context = (MWContext *)fe_WidgetToMWContext(widget); fe_DependentListAddDependent( &(CONTEXT_DATA(context)->dependents), widget, mask, proc, closure); } void fe_CallDependents(MWContext* context, fe_Dependency mask) { fe_DependentListCallDependents(NULL, CONTEXT_DATA(context)->dependents, mask, NULL); } struct fe_EditorParagraphPropertiesWidgets; struct fe_EditorCharacterPropertiesWidgets; struct fe_EditorLinkPropertiesWidgets; struct fe_EditorImagePropertiesWidgets; typedef struct fe_EditorPropertiesWidgets { MWContext* context; fe_DependentList* dependents; struct fe_EditorCharacterPropertiesWidgets* character; struct fe_EditorLinkPropertiesWidgets* link; struct fe_EditorParagraphPropertiesWidgets* paragraph; struct fe_EditorImagePropertiesWidgets* image; fe_Dependency changed; } fe_EditorPropertiesWidgets; typedef struct fe_EditorParagraphPropertiesWidgets { fe_EditorPropertiesWidgets* properties; Widget style_menu; Widget additional_menu; Widget list_style_menu; Widget bullet_style_menu; Widget start_text; Widget numbering_pulldown; Widget bullet_pulldown; TagType paragraph_style; TagType additional_style; TagType list_style; ED_ListType bullet_style; ED_Alignment align; unsigned start; } fe_EditorParagraphPropertiesWidgets; typedef enum fe_JavaScriptModes { JAVASCRIPT_NONE = 0, JAVASCRIPT_SERVER, JAVASCRIPT_CLIENT } fe_JavaScriptModes; typedef struct fe_EditorCharacterPropertiesWidgets { fe_EditorPropertiesWidgets* properties; Widget form; Widget color_default; Widget color_custom; Widget color_swatch; /* something else to hold custom color I guess */ Widget bold; Widget italic; Widget fixed; Widget strike_thru; Widget super_script; Widget sub_script; Widget blink; ED_FontSize font_size; ED_TextFormat text_attributes; ED_TextFormat changed_mask; LO_Color color; Boolean is_custom_color; fe_JavaScriptModes js_mode; } fe_EditorCharacterPropertiesWidgets; typedef char* EDT_LtabbList_t; typedef struct fe_EditorLinkPropertiesWidgets { fe_EditorPropertiesWidgets* properties; Widget form; Widget displayed_label; Widget displayed_text; Widget link_text; /* others I don't understand */ Widget target_list; EDT_LtabbList_t target_list_data; Widget target_current_doc; Widget target_selected_file; Widget target_label; char* selected_filename; char* url; char* text; } fe_EditorLinkPropertiesWidgets; typedef struct fe_EditorImagePropertiesWidgets { fe_EditorPropertiesWidgets* properties; EDT_ImageData image_data; Widget main_image; Widget alt_image; Widget alt_text; Widget image_height; Widget image_width; Widget margin_height; Widget margin_width; Widget margin_solid; Widget constrain; Boolean existing_image; /* means there was an image when we loaded */ Boolean new_image; /* means a new image gets loaded */ Boolean do_constrain; Boolean do_custom_size; Boolean default_border; /* Don't output a BORDER attribute at all. */ } fe_EditorImagePropertiesWidgets; #define PROP_CHAR_BOLD (0x1<<0) #define PROP_CHAR_ITALIC (0x1<<1) #define PROP_CHAR_FIXED (0x1<<2) #define PROP_CHAR_SUPER (0x1<<3) #define PROP_CHAR_SUB (0x1<<4) #define PROP_CHAR_STRIKE (0x1<<5) #define PROP_CHAR_BLINK (0x1<<6) #define PROP_CHAR_COLOR (0x1<<7) #define PROP_CHAR_SIZE (0x1<<8) #define PROP_CHAR_SERVER (0x1<<10) #define PROP_CHAR_CLIENT (0x1<<11) #define PROP_CHAR_UNDERLINE (0x1<<12) #define PROP_PARA_STYLE (0x1<<13) #define PROP_PARA_LIST (0x1<<14) #define PROP_PARA_BULLET (0x1<<15) #define PROP_PARA_ALIGN (0x1<<16) #define PROP_LINK_TEXT (0x1<<17) #define PROP_LINK_HREF (0x1<<18) #define PROP_IMAGE_MAIN_IMAGE (0x1<<19) #define PROP_IMAGE_ALT_IMAGE (0x1<<20) #define PROP_IMAGE_ALT_TEXT (0x1<<21) #define PROP_IMAGE_ALIGN (0x1<<22) #define PROP_IMAGE_HEIGHT (0x1<<23) #define PROP_IMAGE_WIDTH (0x1<<24) #define PROP_IMAGE_MARGIN_HEIGHT (0x1<<25) #define PROP_IMAGE_MARGIN_WIDTH (0x1<<26) #define PROP_IMAGE_MARGIN_BORDER (0x1<<27) #define PROP_IMAGE_COPY (0x1<<28) #define PROP_IMAGE_IMAP (0x1<<29) #define PROP_LINK_LIST (0x1<<30) #define PROP_CHAR_STYLE \ (PROP_CHAR_BOLD|PROP_CHAR_ITALIC|PROP_CHAR_UNDERLINE|PROP_CHAR_FIXED| \ PROP_CHAR_STRIKE|PROP_CHAR_SUPER|PROP_CHAR_SUB|PROP_CHAR_BLINK) #define PROP_CHAR_JAVASCRIPT (PROP_CHAR_CLIENT|PROP_CHAR_SERVER) #define PROP_CHAR_ALL \ (PROP_CHAR_STYLE|PROP_CHAR_COLOR|PROP_CHAR_SIZE|PROP_CHAR_JAVASCRIPT) #define PROP_PARA_ALL \ (PROP_PARA_STYLE|PROP_PARA_LIST|PROP_PARA_BULLET|PROP_PARA_ALIGN) #define PROP_LINK_ALL \ (PROP_LINK_TEXT|PROP_LINK_HREF|PROP_LINK_LIST) #define PROP_IMAGE_DIMENSIONS (PROP_IMAGE_HEIGHT|PROP_IMAGE_WIDTH) #define PROP_IMAGE_SPACE \ (PROP_IMAGE_MARGIN_HEIGHT|PROP_IMAGE_MARGIN_WIDTH|PROP_IMAGE_MARGIN_BORDER) #define PROP_IMAGE_ALL \ (PROP_IMAGE_MAIN_IMAGE|PROP_IMAGE_ALT_IMAGE|PROP_IMAGE_ALT_TEXT| \ PROP_IMAGE_ALIGN|PROP_IMAGE_DIMENSIONS|PROP_IMAGE_SPACE| \ PROP_IMAGE_COPY|PROP_IMAGE_IMAP) static void fe_update_dependents(Widget caller, fe_EditorPropertiesWidgets* p_data, fe_Dependency mask) { p_data->changed |= mask; fe_DependentListCallDependents(caller, p_data->dependents, mask, NULL); } static void fe_register_dependent(fe_EditorPropertiesWidgets* p_data, Widget widget, fe_Dependency mask, XtCallbackProc proc, XtPointer closure) { fe_DependentListAddDependent(&p_data->dependents, widget, mask, proc, closure); } typedef struct fe_style_data { char* name; unsigned data; } fe_style_data; static struct fe_style_data fe_paragraph_style[] = { { "normal", P_NSDT }, { "headingOne", P_HEADER_1 }, { "headingTwo", P_HEADER_2 }, { "headingThree", P_HEADER_3 }, { "headingFour", P_HEADER_4 }, { "headingFive", P_HEADER_5 }, { "headingSix", P_HEADER_6 }, { "address", P_ADDRESS }, { "formatted", P_PREFORMAT }, { "listItem", P_LIST_ITEM }, { "descriptionItem", P_DESC_TITLE }, { "descriptionText", P_DESC_TEXT }, { 0 } }; static struct fe_style_data fe_additional_style[] = { { "default", P_NSDT }, { "list", P_LIST_ITEM }, { "blockQuote", P_BLOCKQUOTE }, { 0 } }; static struct fe_style_data fe_list_style[] = { { "unnumbered", P_UNUM_LIST }, { "numbered", P_NUM_LIST }, { "directory", P_DIRECTORY }, { "menu", P_MENU }, { "description", P_DESC_LIST }, { 0 } }; static struct fe_style_data fe_bullet_style[] = { { "automatic", ED_LIST_TYPE_DEFAULT }, { "solidCircle", ED_LIST_TYPE_DISC }, { "openSquare", ED_LIST_TYPE_SQUARE }, { "openCircle", ED_LIST_TYPE_CIRCLE }, { 0 } }; static struct fe_style_data fe_numbering_style[] = { { "automatic", ED_LIST_TYPE_DEFAULT }, { "digital", ED_LIST_TYPE_DIGIT }, { "upperRoman", ED_LIST_TYPE_BIG_ROMAN }, { "lowerRoman", ED_LIST_TYPE_SMALL_ROMAN }, { "upperAlpha", ED_LIST_TYPE_BIG_LETTERS }, { "lowerAlpha", ED_LIST_TYPE_SMALL_LETTERS }, { 0 } }; static struct fe_style_data fe_align_style[] = { { "left", ED_ALIGN_LEFT }, { "center", ED_ALIGN_ABSCENTER }, { "right", ED_ALIGN_RIGHT }, { 0 } }; static unsigned fe_convert_value_to_index(fe_style_data* style_data, unsigned value) { unsigned i; for (i = 0; style_data[i].name; i++) { if (style_data[i].data == value) return i; } /* maybe should assert */ return 0; } static void fe_paragraph_style_menu_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; TagType type = w_data->paragraph_style; unsigned index = fe_convert_value_to_index(fe_paragraph_style, type); fe_OptionMenuSetHistory(widget, index); } static void fe_paragraph_style_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; unsigned foo = (unsigned)fe_GetUserData(widget); TagType type = (TagType)foo; w_data->paragraph_style = type; if (type == P_LIST_ITEM) { w_data->additional_style = P_LIST_ITEM; } else if (w_data->additional_style == P_LIST_ITEM) { w_data->additional_style = P_NSDT; /* default */ } fe_update_dependents(widget, w_data->properties, PROP_PARA_STYLE|PROP_PARA_LIST); } static void fe_additional_style_menu_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; TagType type = w_data->additional_style; unsigned index = fe_convert_value_to_index(fe_additional_style, type); fe_OptionMenuSetHistory(widget, index); } static void fe_additional_style_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; unsigned foo = (unsigned)fe_GetUserData(widget); TagType type = (TagType)foo; w_data->additional_style = type; if (type == P_LIST_ITEM) w_data->paragraph_style = P_LIST_ITEM; fe_update_dependents(widget, w_data->properties, PROP_PARA_STYLE|PROP_PARA_LIST); } static void fe_list_style_menu_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; TagType type = w_data->additional_style; Boolean enabled = FALSE; unsigned index; if (type == P_LIST_ITEM) { type = w_data->list_style; index = fe_convert_value_to_index(fe_list_style, type); enabled = TRUE; fe_OptionMenuSetHistory(widget, index); } XtVaSetValues(XmOptionButtonGadget(widget), XmNsensitive, enabled, 0); } static void fe_list_style_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; unsigned foo = (unsigned)fe_GetUserData(widget); TagType type = (TagType)foo; w_data->list_style = type; fe_update_dependents(widget, w_data->properties, PROP_PARA_LIST|PROP_PARA_BULLET); } static void fe_bullet_style_menu_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; TagType type = w_data->additional_style; Boolean enabled = FALSE; unsigned index = 0; /* keep -O happy */ Widget cascade = XmOptionButtonGadget(widget); Widget pulldown = NULL; /* keep -O happy */ if (type == P_LIST_ITEM) { type = w_data->list_style; if (type == P_NUM_LIST) { enabled = TRUE; index = fe_convert_value_to_index(fe_numbering_style, w_data->bullet_style); pulldown = w_data->numbering_pulldown; } else if (type == P_UNUM_LIST) { enabled = TRUE; index = fe_convert_value_to_index(fe_bullet_style, w_data->bullet_style); pulldown = w_data->bullet_pulldown; } if (enabled) { XtVaSetValues(cascade, XmNsubMenuId, pulldown, 0); fe_OptionMenuSetHistory(widget, index); } } XtVaSetValues(cascade, XmNsensitive, enabled, 0); } static void fe_bullet_style_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; ED_ListType type = (ED_ListType)fe_GetUserData(widget); w_data->bullet_style = type; fe_update_dependents(widget, w_data->properties, PROP_PARA_BULLET); } static Widget fe_create_style_pulldown(Widget parent, char* name, fe_style_data* style_data, Arg* p_args, Cardinal p_n) { Cardinal nchildren; Widget children[16]; Widget pulldown; Arg args[8]; Cardinal n; Cardinal m; XtCallbackRec* button_callback_rec = 0; XtCallbackRec* update_callback_rec = 0; for (n = m = 0; n < p_n; n++) { if (p_args[n].name == XmNactivateCallback) button_callback_rec = (XtCallbackRec*)p_args[n].value; else if (p_args[n].name == XmNvalueChangedCallback) update_callback_rec = (XtCallbackRec*)p_args[n].value; else { XtSetArg(args[m], p_args[n].name, p_args[n].value); m++; } } n = m; pulldown = fe_CreatePulldownMenu(parent, name, args, n); for (nchildren = 0; style_data[nchildren].name; nchildren++) { n = 0; XtSetArg(args[n], XmNuserData, style_data[nchildren].data); n++; children[nchildren] = XmCreatePushButtonGadget( pulldown, style_data[nchildren].name, args, n ); if (button_callback_rec) { XtAddCallback(children[nchildren], XmNactivateCallback, button_callback_rec->callback, (XtPointer)button_callback_rec->closure); } } XtManageChildren(children, nchildren); return pulldown; } static Widget fe_create_style_menu(Widget parent, char* name, fe_style_data* style_data, Arg* p_args, Cardinal p_n) { Widget pulldown; Widget option; Arg args[8]; Arg rc_args[8]; Cardinal n; Cardinal my_n; Cardinal rc_n; for (my_n = rc_n = n = 0; n < p_n; n++) { if ( p_args[n].name == XmNactivateCallback || p_args[n].name == XmNvalueChangedCallback ) { XtSetArg(rc_args[rc_n], p_args[n].name, p_args[n].value); rc_n++; } else { XtSetArg(args[my_n], p_args[n].name, p_args[n].value); my_n++; } } pulldown = fe_create_style_pulldown(parent, name, style_data, rc_args, rc_n); XtSetArg(args[my_n], XmNsubMenuId, pulldown); my_n++; option = fe_CreateOptionMenu(parent, name, args, my_n); fe_UnmanageChild_safe(XmOptionLabelGadget(option)); return option; } static void fe_paragraph_align_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; /* * We get a callback on both the unset of the old toggle, * and the set of the new, so ignore the former, it's not * interesting. */ if (info->set) { w_data->align = (ED_Alignment)fe_GetUserData(widget); fe_update_dependents(widget, w_data->properties, PROP_PARA_ALIGN); } } static void fe_paragraph_align_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; ED_Alignment align = (ED_Alignment)fe_GetUserData(widget); ED_Alignment w_align = w_data->align; if (w_align == ED_ALIGN_DEFAULT) w_align = ED_ALIGN_LEFT; if (w_align == ED_ALIGN_CENTER) /* just in case the BE changes */ w_align = ED_ALIGN_ABSCENTER; XmToggleButtonGadgetSetState(widget, (w_align == align), FALSE); } static void fe_set_text_field(Widget widget, char* value, XtCallbackProc cb, XtPointer closure) { if (cb) XtRemoveCallback(widget, XmNvalueChangedCallback, cb, closure); if (!value) value = ""; fe_SetTextFieldAndCallBack(widget, value); if (cb) XtAddCallback(widget, XmNvalueChangedCallback, cb, closure); } void fe_set_numeric_text_field(Widget widget, unsigned value) { char buf[32]; sprintf(buf, "%d", value); fe_TextFieldSetString(widget, buf, FALSE); } static void fe_paragraph_start_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; fe_update_dependents(widget, w_data->properties, PROP_PARA_BULLET); } #if 0 static unsigned fe_aztoui(char* s, Boolean upper) { char* p; unsigned rv = 0; unsigned high; unsigned low; if (upper) { low = 'A'; high = 'Z'; } else { low = 'a'; high = 'z'; } for (p = s; *p >= low && *p <= high; p++) { rv *= 26; rv += (*p - low) + 1; } return rv; } static int fe_uitoaz(char* buf, unsigned value, Boolean upper) { char* p; unsigned base = 26; unsigned low; if (upper) { low = 'A'; } else { low = 'a'; } if (value == 0) { buf[0] = '\0'; return 0; } value--; for (p = buf; base < value; p++) base = base * 26; p[1] = '\0'; for (; p >= buf; p--) { *p = (value % 26) + low; value /= 26; } return strlen(buf); } #endif static void fe_paragraph_start_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorParagraphPropertiesWidgets* w_data = (fe_EditorParagraphPropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; char buf[256]; Boolean enabled; if (info->caller == widget) return; /* don't call ourselves */ if (w_data->paragraph_style == P_LIST_ITEM && w_data->list_style==P_NUM_LIST) { #if 0 if ( w_data->bullet_style == ED_LIST_TYPE_DIGIT || w_data->bullet_style == ED_LIST_TYPE_BIG_ROMAN || w_data->bullet_style == ED_LIST_TYPE_SMALL_ROMAN ) { sprintf(buf, "%d", w_data->start); } else if (w_data->bullet_style == ED_LIST_TYPE_BIG_LETTERS) { fe_uitoaz(buf, w_data->start, TRUE); } else if (w_data->bullet_style == ED_LIST_TYPE_SMALL_LETTERS) { fe_uitoaz(buf, w_data->start, FALSE); } #else if (w_data->start < 1) w_data->start = 1; sprintf(buf, "%d", w_data->start); #endif enabled = TRUE; } else { buf[0] = '\0'; enabled = FALSE; } fe_TextFieldSetEditable(w_data->properties->context, widget, enabled); fe_set_text_field(widget, buf, fe_paragraph_start_cb, (XtPointer)w_data); } static void fe_EditorParagraphPropertiesDialogDataGet( MWContext* context, fe_EditorParagraphPropertiesWidgets* w_data) { EDT_ListData list_data; fe_EditorParagraphPropertiesGetAll(context, &w_data->paragraph_style, &list_data, &w_data->align); switch (list_data.iTagType) { case P_BLOCKQUOTE: /* block quotes */ w_data->additional_style = P_BLOCKQUOTE; w_data->list_style = P_UNUM_LIST; w_data->bullet_style = ED_LIST_TYPE_DEFAULT; break; case P_NUM_LIST: /* lists */ w_data->start = list_data.iStart; if (w_data->start < 1) w_data->start = 1; /*FALLTHRU*/ case P_UNUM_LIST: case P_DIRECTORY: case P_MENU: case P_DESC_LIST: w_data->additional_style = P_LIST_ITEM; w_data->list_style = list_data.iTagType; w_data->bullet_style = list_data.eType; break; default: w_data->additional_style = P_NSDT; w_data->list_style = P_UNUM_LIST; w_data->bullet_style = ED_LIST_TYPE_DEFAULT; break; } /* * Update the display. */ fe_update_dependents(NULL, w_data->properties, PROP_PARA_ALL); } static void fe_EditorParagraphPropertiesDialogSet( MWContext* context, fe_EditorParagraphPropertiesWidgets* w_data) { EDT_ListData list_data; char* p = NULL; memset(&list_data, 0, sizeof(EDT_ListData)); if (w_data->paragraph_style == P_LIST_ITEM) { /* do list stuff */ list_data.iTagType = w_data->list_style; list_data.bCompact = 0; /* ??? */ list_data.eType = w_data->bullet_style; p = fe_TextFieldGetString(w_data->start_text); list_data.iStart = atoi(p); if (p) XtFree(p); fe_EditorParagraphPropertiesSetAll(context, w_data->paragraph_style, &list_data, w_data->align); } else if (w_data->additional_style == P_BLOCKQUOTE) { /* do quote */ list_data.iTagType = P_BLOCKQUOTE; list_data.bCompact = 0; /* ??? */ list_data.eType = ED_LIST_TYPE_DEFAULT; fe_EditorParagraphPropertiesSetAll(context, w_data->paragraph_style, &list_data, w_data->align); } else { fe_EditorParagraphPropertiesSetAll(context, w_data->paragraph_style, NULL, w_data->align); } } static void fe_make_paragraph_page( MWContext *context, Widget parent, fe_EditorParagraphPropertiesWidgets* w_data) { Arg args[16]; Cardinal n; Widget form; Widget paragraph_label; Widget paragraph_option; Widget additional_label; Widget additional_option; Widget list_frame; Widget list_form; Widget list_style_label; Widget list_style_option; Widget bullet_style_option; Widget starting_text; Widget starting_label; Widget align_frame; Widget align_rc; Widget children[16]; Cardinal nchildren; XtCallbackRec callback; #if 0 n = 0; form = XmCreateForm(parent, "paragraphProperties", args, n); XtManageChild(form); #else form = parent; #endif /* * Paragraph Style. */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; paragraph_label = XmCreateLabelGadget(form, "styleLabel", args, n); XtManageChild(paragraph_label); n = 0; callback.callback = fe_paragraph_style_cb; callback.closure = (XtPointer)w_data; XtSetArg(args[n], XmNactivateCallback, &callback); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, paragraph_label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; paragraph_option = fe_create_style_menu(form, "style", fe_paragraph_style, args, n); XtManageChild(paragraph_option); fe_register_dependent(w_data->properties, paragraph_option, FE_MAKE_DEPENDENCY(PROP_PARA_STYLE|PROP_PARA_LIST), fe_paragraph_style_menu_update_cb, (XtPointer)w_data); /* * Additional Style. */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, paragraph_option); n++; additional_label = XmCreateLabelGadget(form, "additionalLabel", args, n); XtManageChild(additional_label); n = 0; callback.callback = fe_additional_style_cb; callback.closure = (XtPointer)w_data; XtSetArg(args[n], XmNactivateCallback, &callback); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, paragraph_label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, paragraph_option); n++; additional_option = fe_create_style_menu(form, "additional", fe_additional_style, args, n); XtManageChild(additional_option); fe_register_dependent(w_data->properties, additional_option, FE_MAKE_DEPENDENCY(PROP_PARA_STYLE|PROP_PARA_LIST), fe_additional_style_menu_update_cb, (XtPointer)w_data); /* * List frame and friends. THIS IS SO BORING!!!!!!!!!!!!! */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, paragraph_option); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; list_frame = fe_CreateFrame(form, "list", args, n); XtManageChild(list_frame); n = 0; list_form = XmCreateForm(list_frame, "list", args, n); XtManageChild(list_form); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; list_style_label = XmCreateLabelGadget(list_form, "listLabel", args, n); XtManageChild(list_style_label); n = 0; callback.callback = fe_list_style_cb; callback.closure = (XtPointer)w_data; XtSetArg(args[n], XmNactivateCallback, &callback); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, list_style_label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; list_style_option = fe_create_style_menu(list_form, "listStyle", fe_list_style, args, n); XtManageChild(list_style_option); fe_register_dependent(w_data->properties, list_style_option, FE_MAKE_DEPENDENCY(PROP_PARA_LIST), fe_list_style_menu_update_cb, (XtPointer)w_data); n = 0; callback.callback = fe_bullet_style_cb; callback.closure = (XtPointer)w_data; XtSetArg(args[n], XmNactivateCallback, &callback); n++; w_data->numbering_pulldown = fe_create_style_pulldown(list_form, "bulletStyle", fe_numbering_style, args, n); w_data->bullet_pulldown = fe_create_style_pulldown(list_form, "bulletStyle", fe_bullet_style, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, list_style_label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, list_style_option); n++; XtSetArg(args[n], XmNsubMenuId, w_data->bullet_pulldown); n++; bullet_style_option = fe_CreateOptionMenu(list_form, "bulletStyle", args, n); fe_UnmanageChild_safe(XmOptionLabelGadget(bullet_style_option)); XtManageChild(bullet_style_option); fe_register_dependent(w_data->properties, bullet_style_option, FE_MAKE_DEPENDENCY(PROP_PARA_BULLET|PROP_PARA_LIST), fe_bullet_style_menu_update_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, bullet_style_option); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, bullet_style_option); n++; w_data->start_text = starting_text = fe_CreateTextField(list_form, "startText", args, n); XtManageChild(starting_text); XtAddCallback(starting_text, XmNvalueChangedCallback, fe_paragraph_start_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, starting_text, FE_MAKE_DEPENDENCY(PROP_PARA_BULLET|PROP_PARA_LIST), fe_paragraph_start_update_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, bullet_style_option); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, starting_text); n++; starting_label = XmCreateLabelGadget(list_form, "startLabel", args, n); XtManageChild(starting_label); /* * Align. */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, list_frame); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; align_frame = fe_CreateFrame(form, "align", args, n); XtManageChild(align_frame); n = 0; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNradioBehavior, TRUE); n++; align_rc = XmCreateRowColumn(align_frame, "align", args, n); XtManageChild(align_rc); for (nchildren = 0; fe_align_style[nchildren].name; nchildren++) { n = 0; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; XtSetArg(args[n], XmNuserData, fe_align_style[nchildren].data); n++; children[nchildren] = XmCreateToggleButtonGadget( align_rc, fe_align_style[nchildren].name, args, n); XtAddCallback(children[nchildren], XmNvalueChangedCallback, fe_paragraph_align_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, children[nchildren], FE_MAKE_DEPENDENCY(PROP_PARA_ALIGN), fe_paragraph_align_update_cb, (XtPointer)w_data); } XtManageChildren(children, nchildren); #if 0 /* Humour for Beta */ /* Apparently our testers have no humour - oh well */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, align_frame); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; align_rc = XmCreateLabelGadget(form, "spaceAvailable", args, n); XtManageChild(align_rc); #endif } static void fe_link_text_changed_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; fe_update_dependents(widget, w_data->properties, PROP_LINK_TEXT); } static char* fe_image_get_name(fe_EditorImagePropertiesWidgets* w_data) { char* p = NULL; if (w_data->main_image) p = fe_TextFieldGetString(w_data->main_image); if (!p && w_data->alt_image) p = fe_TextFieldGetString(w_data->alt_image); if (!p && w_data->alt_text) p = fe_TextFieldGetString(w_data->alt_text); return p; } static void fe_link_text_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; Boolean enabled = FALSE; char* text; char* free_text = NULL; char* label_string; int id; XmString xm_string; if (info->caller == widget) return; /* don't call ourselves */ /* * If we have an image, use the image name as the current * displayed text. */ if (w_data->properties->image != NULL) { free_text = text = fe_image_get_name(w_data->properties->image); enabled = FALSE; id = XFE_EDITOR_LINK_TEXT_LABEL_IMAGE; /* Linked image: */ } else if (w_data->text) { text = w_data->text; enabled = FALSE; id = XFE_EDITOR_LINK_TEXT_LABEL_TEXT; /* Linked text: */ } else { text = ""; enabled = TRUE; id = XFE_EDITOR_LINK_TEXT_LABEL_NEW; /* Enter the text of the link: */ } fe_set_text_field(widget, text, fe_link_text_changed_cb,(XtPointer)w_data); fe_TextFieldSetEditable(w_data->properties->context, widget, enabled); /* * While we are here set the label also. */ label_string = XP_GetString(id); xm_string = XmStringCreateLocalized(label_string); XtVaSetValues(w_data->displayed_label, XmNlabelString, xm_string, 0); XmStringFree(xm_string); if (free_text) XtFree(free_text); } static void fe_link_href_changed_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; fe_update_dependents(widget, w_data->properties, PROP_LINK_HREF); } static void fe_link_href_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; char* text; if (info->caller == widget) return; /* don't call ourselves */ /* * If we have an image, use the image name as the current * displayed text. */ if (w_data->url) { text = w_data->url; } else { text = ""; } fe_set_text_field(widget, text, fe_link_href_changed_cb,(XtPointer)w_data); w_data->url = NULL; } static char* fe_basename(char* target, char* source) { char* p; p = strrchr(source, '/'); /* find last slash */ if (p) { /* should be */ strcpy(target, p+1); } else { strcpy(target, source); } return target; } static char* fe_dirname(char* target, char* source) { char* p; p = strrchr(source, '/'); /* find last slash */ if (p) { /* should be */ if (p == source) { strcpy(target, "/"); } else { memcpy(target, source, p - source); target[p - source] = '\0'; } } else { strcpy(target, "."); } return target; } static Boolean fe_file_has_same_directory(MWContext* context, char* pathname) { char my_dirname[MAXPATHLEN]; char your_dirname[MAXPATHLEN]; fe_EditorMakeName(context, your_dirname, sizeof(your_dirname)); fe_dirname(my_dirname, your_dirname); fe_dirname(your_dirname, pathname); return (strcmp(my_dirname, your_dirname) == 0); } static void fe_link_properties_list_update(fe_EditorLinkPropertiesWidgets*, Boolean); static void fe_editor_browse_file_of_text(MWContext* context, Widget text_field) { char* before_save; char* before_changed = NULL; char* after; char* p; /* * Strip #target from the browse default filename. */ before_save = fe_TextFieldGetString(text_field); /* * If the text field is a http: form URL, then zero it, * because we are not browsing for a file. */ if (before_save != NULL) { fe_StringTrim(before_save); if ((p = strchr(before_save, ':')) != NULL) { if (NET_IsLocalFileURL(before_save)) { before_changed = XtNewString(&p[1]); } else { before_changed = XtNewString(""); } } else if ((p = strchr(before_save, '#')) != NULL) { *p = '\0'; before_changed = XtNewString(before_save); *p = '#'; } if (before_changed != NULL) fe_TextFieldSetString(text_field, before_changed, FALSE); } fe_browse_file_of_text(context, text_field, FALSE); after = fe_TextFieldGetString(text_field); fe_StringTrim(after); /* * If we zapped it, and there was no change by the user, * put it back the way it was. */ if (before_changed != NULL && strcmp(after, before_changed) == 0) { fe_TextFieldSetString(text_field, before_save, FALSE); } /* * Or, if the main file, and the link file are in the same * directory, simplfy the name. */ else if (fe_file_has_same_directory(context, after)) { char basename[MAXPATHLEN]; fe_basename(basename, after); fe_TextFieldSetString(text_field, basename, FALSE); } if (before_save) XtFree(before_save); if (before_changed) XtFree(before_changed); if (after) XtFree(after); } static void fe_link_href_browse_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; MWContext* context = w_data->properties->context; Widget text_field = w_data->link_text; fe_editor_browse_file_of_text(context, text_field); fe_update_dependents(widget, w_data->properties, PROP_LINK_LIST); /* * Set the toggle to selected file, and update. */ XmToggleButtonGadgetSetState(w_data->target_current_doc, FALSE, FALSE); XmToggleButtonGadgetSetState(w_data->target_selected_file, TRUE, FALSE); fe_link_properties_list_update(w_data, FALSE); } static void fe_browse_to_text_field_cb(Widget widget, XtPointer closure, XtPointer call_data) { MWContext* context = (MWContext*)closure; Widget text_field = (Widget)fe_GetUserData(widget); fe_browse_file_of_text(context, text_field, FALSE); } static void fe_link_tab_remove_link(fe_EditorLinkPropertiesWidgets* w_data) { w_data->url = NULL; fe_update_dependents(NULL, w_data->properties, PROP_LINK_HREF); } static void fe_link_href_remove_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; fe_link_tab_remove_link(w_data); } static Boolean fe_link_tab_has_link(fe_EditorLinkPropertiesWidgets* w_data) { char* link_text; Boolean rv = FALSE; if (w_data != NULL) { /* * get the link text, to see if there any. */ link_text = fe_TextFieldGetString(w_data->link_text); if (link_text != NULL) { if (link_text[0] != '\0') /* has a link */ rv = TRUE; XP_FREEIF(link_text); } } return rv; } static void fe_link_href_remove_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; Boolean sensitive = fe_link_tab_has_link(w_data); fe_WidgetSetSensitive(widget, sensitive); } #if 0 static void fe_ListAddItems(Widget widget, char** items, unsigned nitems) { unsigned i; XmString xm_string; XmListDeleteAllItems(widget); for (i = 0; i < nitems; i++) { xm_string = XmStringCreateLocalized(items[i]); XmListAddItem(widget, xm_string, i + 1); /* MOTIFism */ XmStringFree(xm_string); } } #endif static void fe_ListSetFromLtabbList(Widget widget, EDT_LtabbList_t ltabb_list) { char* p; XmString xm_string; unsigned len; unsigned i; XmListDeleteAllItems(widget); if (ltabb_list) { for (p = ltabb_list, i = 0; (len = XP_STRLEN(p)) > 0; i++) { xm_string = XmStringCreateLocalized(p); XmListAddItem(widget, xm_string, i + 1); /* MOTIFism */ XmStringFree(xm_string); p += len + 1; } } } static char* fe_LtabbListGetItem(EDT_LtabbList_t ltabb_list, unsigned index) { unsigned i; char* p; unsigned len; if (ltabb_list) { for (p = ltabb_list, i = 0; (len = XP_STRLEN(p)) > 0; i++) { if (i == index) return p; p += len + 1; } } return NULL; } static void fe_link_properties_list_cb(Widget widget, XtPointer closure, XtPointer foo) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; XmListCallbackStruct* cb_data = (XmListCallbackStruct*)foo; char basename[MAXPATHLEN]; char buf[MAXPATHLEN]; char* pathname; char* p; char* target_name; Boolean current_doc; current_doc = XmToggleButtonGadgetGetState(w_data->target_current_doc); if (cb_data->reason != XmCR_SINGLE_SELECT) return; if (cb_data->item_position > 0) { target_name = fe_LtabbListGetItem(w_data->target_list_data, cb_data->item_position - 1); } else { target_name = NULL; } if (current_doc) { pathname = NULL; } else { pathname = fe_TextFieldGetString(w_data->link_text); if ((p = strchr(pathname, '#')) != NULL) { memcpy(basename, pathname, p - pathname); basename[p - pathname] = '\0'; } else { strcpy(basename, pathname); } XtFree(pathname); pathname = basename; if (pathname[0] == '\0') pathname = NULL; } if (pathname != NULL && target_name != NULL) { strcpy(buf, pathname); strcat(buf, "#"); strcat(buf, target_name); } else if (target_name != NULL) { strcpy(buf, "#"); strcat(buf, target_name); } else { buf[0] = '\0'; } fe_TextFieldSetString(w_data->link_text, buf, FALSE); w_data->properties->changed |= PROP_LINK_HREF; } static void fe_link_properties_list_update(fe_EditorLinkPropertiesWidgets* w_data, Boolean current_file) { MWContext* context = w_data->properties->context; char* link_text; EDT_LtabbList_t list_data = NULL; char* crazy; XmString xm_string; int id; if (w_data->target_list_data) XP_FREE(w_data->target_list_data); if (current_file) { list_data = EDT_GetAllDocumentTargets(context); } else { link_text = fe_TextFieldGetString(w_data->link_text); if (link_text && link_text[0] != '\0') { list_data = EDT_GetAllDocumentTargetsInFile(context, link_text); } XtFree(link_text); } if (list_data && XP_STRLEN(list_data) == 0) { XP_FREE(list_data); list_data = NULL; } if (list_data && current_file) id = XFE_EDITOR_LINK_TARGET_LABEL_CURRENT; /* Link to a named target in the current document (optional.) */ else if (list_data && !current_file) id = XFE_EDITOR_LINK_TARGET_LABEL_SPECIFIED; /* Link to a named target in the specified document (optional.) */ else id = XFE_EDITOR_LINK_TARGET_LABEL_NO_TARGETS; /* No targets in the selected document */ crazy = XP_GetString(id); xm_string = XmStringCreateLocalized(crazy); XtVaSetValues(w_data->target_label, XmNlabelString, xm_string, 0); XmStringFree(xm_string); w_data->target_list_data = list_data; fe_ListSetFromLtabbList(w_data->target_list, w_data->target_list_data); XmToggleButtonGadgetSetState(w_data->target_current_doc, current_file, FALSE); XmToggleButtonGadgetSetState(w_data->target_selected_file, !current_file, FALSE); } static void fe_link_properties_list_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; Boolean set = XmToggleButtonGadgetGetState(w_data->target_current_doc); fe_link_properties_list_update(w_data, set); } static void fe_link_properties_target_toggle_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorLinkPropertiesWidgets* w_data = (fe_EditorLinkPropertiesWidgets*)closure; Boolean current_file = (widget == w_data->target_current_doc); Boolean set = XmToggleButtonGadgetGetState(widget); fe_link_properties_list_update(w_data, (set == current_file)); } /* * Load the form context. */ static void fe_editor_link_properties_dialog_data_init( MWContext* context, fe_EditorLinkPropertiesWidgets* w_data) { char* text; char* href; char* p; Boolean text_exists; /* * If we are on something a link, we display the text that is * selected, or nothing. Text is read only. If we are not on * a link, text field is editable. * * If we are on a link, we display that link, this field * is always editable. */ text_exists = fe_EditorHrefGet(context, &text, &href); /* if (!text_exists) return; */ /* * Replace CR/LF with spaces to avoid ugly break in static display */ if (text) { for (p = text; *p; p++) { if (*p == '\n' || *p == '\r') *p = ' '; } w_data->text = text; } else { w_data->text = NULL; } if (href) { w_data->url = href; if (w_data->text == NULL) w_data->text = ""; } else { w_data->url = NULL; } fe_update_dependents(NULL, w_data->properties, PROP_LINK_ALL); /* * Don't know what these are yet. */ w_data->selected_filename = NULL; fe_link_properties_list_update(w_data, TRUE); if (text) XtFree(text); if (href) XtFree(href); } static void fe_editor_link_properties_dialog_set( MWContext* context, fe_EditorLinkPropertiesWidgets* w_data) { char* displayed_text; char* link_text; displayed_text = fe_TextFieldGetString(w_data->displayed_text); link_text = fe_TextFieldGetString(w_data->link_text); /* * If the text field was editable, then we are creating a new * link. I don't really like carrying state around in the * values of the widgets, but this should work ok...djw. */ if (XmTextFieldGetEditable(w_data->displayed_text)) { if (link_text && (link_text[0] != '\0')) /* don't anything if no link! */ fe_EditorHrefInsert(context, displayed_text, link_text); } else { /* modify exiting link/text */ if (link_text && link_text[0] == '\0') fe_EditorHrefSetUrl(context, NULL); else fe_EditorHrefSetUrl(context, link_text); } if (displayed_text) XP_FREEIF(displayed_text); if (link_text) XP_FREEIF(link_text); } static void fe_make_link_page( MWContext* context, Widget parent, fe_EditorLinkPropertiesWidgets* w_data ) { Arg av [50]; int ac; Widget form; Widget linkSourceLabel, sourceFrame, sourceForm; Widget linkToLabel, linkToFrame, linkToForm; Widget sourceTextLabel; Widget linkedTextLabel; Widget linkToTarget; Widget linkToBrowseFile; Widget linkToRemoveLink; Widget linkPageTextField; Widget sourceTextField; Widget target_list; Widget SelectedFileToggle; Widget currentDocToggle; Widget linkToShowTargets; Widget kids [100]; Widget target_rc; Widget list_parent; Pixel parent_bg; int i; XtVaGetValues(parent, XmNbackground, &parent_bg, 0); #if 0 ac = 0; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; form = XmCreateForm(parent, "linkProperties", av, ac); XtManageChild (form); #else form = parent; #endif w_data->form = form; /**********************************************************************/ /* Create the Link source frame and form 28FEB96RCJ */ /**********************************************************************/ ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++; sourceFrame = XmCreateFrame (form, "linkSourceFrame", av, ac); ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_NONE); ac++; sourceForm = XmCreateForm (sourceFrame, "linkSourceForm", av, ac); /**********************************************************************/ /* Create the Link To frame and form 28FEB96RCJ */ /**********************************************************************/ ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNtopWidget, sourceFrame); ac++; #if 0 XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; #endif linkToFrame = XmCreateFrame (form, "linkToFrame", av, ac); ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; linkToForm = XmCreateForm (linkToFrame, "linkToForm", av, ac); /**********************************************************************/ /* Create the titles for the frames 28FEB96RCJ */ /**********************************************************************/ ac = 0; XtSetArg (av [ac], XmNchildType, XmFRAME_TITLE_CHILD); ac++; linkSourceLabel = XmCreateLabelGadget (sourceFrame, "linkSourceTitle", av, ac); linkToLabel = XmCreateLabelGadget (linkToFrame, "linkToTitle", av, ac); /**********************************************************************/ /* Create and manage the contents of the source form and frame */ /**********************************************************************/ ac = 0; i = 0; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; kids [i++] = sourceTextLabel = XmCreateLabelGadget (sourceForm, "linkSourceLabel", av, ac); w_data->displayed_label = sourceTextLabel; ac = 0; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNtopWidget, sourceTextLabel); ac++; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; kids [i++] = sourceTextField = fe_CreateTextField (sourceForm, "linkSourceText", av, ac); w_data->displayed_text = sourceTextField; XtAddCallback(sourceTextField, XmNvalueChangedCallback, fe_link_text_changed_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, sourceTextField, FE_MAKE_DEPENDENCY(PROP_LINK_TEXT), fe_link_text_update_cb, (XtPointer)w_data); XtManageChildren (kids, i); XtManageChild (linkSourceLabel); XtManageChild (sourceForm); /**********************************************************************/ /* Create and manage the contents of the Link to form and frame */ /**********************************************************************/ ac = 0; i = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; kids [i++] = linkedTextLabel = XmCreateLabelGadget (linkToForm, "linkToLabel", av, ac); ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNleftWidget, linkedTextLabel); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; kids [i++] = linkToBrowseFile = XmCreatePushButtonGadget (linkToForm, "browseFile", av, ac); XtAddCallback(linkToBrowseFile, XmNactivateCallback, fe_link_href_browse_cb, (XtPointer)w_data); ac = 0; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNleftWidget, linkToBrowseFile); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++; kids [i++] = linkToRemoveLink = XmCreatePushButtonGadget (linkToForm, "removeLink", av, ac); XtAddCallback(linkToRemoveLink, XmNactivateCallback, fe_link_href_remove_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, linkToRemoveLink, FE_MAKE_DEPENDENCY(PROP_LINK_HREF), fe_link_href_remove_update_cb, (XtPointer)w_data); ac = 0; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNtopWidget, linkedTextLabel); ac++; XtSetArg (av [ac], XmNtopOffset, 10); ac++; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; kids [i++] = linkPageTextField = fe_CreateTextField (linkToForm, "linkPageTextField", av, ac); w_data->link_text = linkPageTextField; XtAddCallback(linkPageTextField, XmNvalueChangedCallback, fe_link_href_changed_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, linkPageTextField, FE_MAKE_DEPENDENCY(PROP_LINK_HREF), fe_link_href_update_cb, (XtPointer)w_data); ac = 0; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNtopWidget, linkPageTextField); ac++; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; kids [i++] = linkToTarget = XmCreateLabelGadget (linkToForm, "linkTarget", av, ac); w_data->target_label = linkToTarget; /* * RowColumn to hold the buttons to right of target text. */ ac = 0; XtSetArg (av [ac], XmNorientation, XmVERTICAL); ac++; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNtopWidget, linkToTarget); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNpacking, XmPACK_TIGHT); ac++; kids[i++] = target_rc = XmCreateRowColumn(linkToForm, "targetRowColumn", av, ac); ac = 0; XtSetArg (av [ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNtopWidget, linkToTarget); ac++; XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg (av [ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; XtSetArg (av [ac], XmNrightWidget, target_rc); ac++; #if 0 XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++; #endif XtSetArg(av[ac], XmNvisibleItemCount, 6); ac++; XtSetArg(av[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++; XtSetArg(av[ac], XmNbackground, parent_bg); ac++; target_list = XmCreateScrolledList(linkToForm, "targetList", av, ac); XtManageChild(target_list); kids [i++] = list_parent = XtParent(target_list); XtAddCallback(target_list, XmNsingleSelectionCallback, fe_link_properties_list_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, target_list, FE_MAKE_DEPENDENCY(PROP_LINK_LIST), fe_link_properties_list_update_cb, (XtPointer)w_data); w_data->target_list = target_list; XtManageChildren (kids, i); /* children of form */ XtManageChild (linkToLabel); XtManageChild (linkToForm); i = 0; /* no kids */ ac = 0; XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; kids [i++] = linkToShowTargets = XmCreateLabelGadget(target_rc, "showTargets", av, ac); ac = 0; XtSetArg (av [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; XtSetArg(av[ac], XmNset, TRUE); ac++; XtSetArg(av[ac], XmNindicatorType, XmONE_OF_MANY); ac++; kids [i++] = currentDocToggle = XmCreateToggleButtonGadget(target_rc, "currentDocument", av, ac); w_data->target_current_doc = currentDocToggle; ac = 0; XtSetArg (av [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; XtSetArg(av[ac], XmNset, FALSE); ac++; XtSetArg(av[ac], XmNindicatorType, XmONE_OF_MANY); ac++; kids [i++] = SelectedFileToggle = XmCreateToggleButtonGadget (target_rc, "selectedFile", av, ac); w_data->target_selected_file = SelectedFileToggle; XtManageChildren (kids, i); /* children of rc */ XtAddCallback(currentDocToggle, XmNvalueChangedCallback, fe_link_properties_target_toggle_cb, (XtPointer)w_data); XtAddCallback(SelectedFileToggle, XmNvalueChangedCallback, fe_link_properties_target_toggle_cb, (XtPointer)w_data); /**********************************************************************/ /* Manage all of the frame comprising the Link dialog box */ /**********************************************************************/ i = 0; kids [i++] = sourceFrame; kids [i++] = linkToFrame; XtManageChildren (kids, i); } /* end fe_make_link_page */ static struct fe_style_data fe_style_types[] = { { "bold", TF_BOLD }, { "italic", TF_ITALIC }, { "underline", TF_UNDERLINE }, { "fixed", TF_FIXED }, { "strikethrough", TF_STRIKEOUT }, { "superscript", TF_SUPER }, { "subscript", TF_SUB }, { "blink", TF_BLINK }, { 0 } }; static struct fe_style_data fe_font_size_types[] = { { "minusTwo", ED_FONTSIZE_MINUS_TWO }, { "minusOne", ED_FONTSIZE_MINUS_ONE }, { "plusZero", ED_FONTSIZE_ZERO }, { "plusOne", ED_FONTSIZE_PLUS_ONE }, { "plusTwo", ED_FONTSIZE_PLUS_TWO }, { "plusThree", ED_FONTSIZE_PLUS_THREE }, { "plusFour", ED_FONTSIZE_PLUS_FOUR }, { NULL } }; static void fe_font_size_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; if (w_data->js_mode == JAVASCRIPT_NONE) { fe_OptionMenuSetHistory(widget, w_data->font_size - 1); fe_WidgetSetSensitive(XmOptionButtonGadget(widget), TRUE); } else { fe_OptionMenuSetHistory(widget, ED_FONTSIZE_ZERO - 1); fe_WidgetSetSensitive(XmOptionButtonGadget(widget), FALSE); } /*FIXME*/ /* fix sensitivity */ } static void fe_font_size_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; ED_FontSize size = (ED_FontSize)fe_GetUserData(widget); w_data->font_size = size; w_data->changed_mask |= TF_FONT_SIZE; fe_update_dependents(widget, w_data->properties, PROP_CHAR_SIZE); } static void fe_style_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; ED_TextFormat type; Boolean set; Boolean enabled; unsigned foo; if (w_data->js_mode == JAVASCRIPT_NONE) { foo = (unsigned)fe_GetUserData(widget); type = foo; if ((type & w_data->text_attributes) != 0) set = TRUE; else set = FALSE; enabled = TRUE; } else { set = FALSE; enabled = FALSE; } XmToggleButtonGadgetSetState(widget, set, FALSE); fe_WidgetSetSensitive(widget, enabled); } static void fe_style_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; ED_TextFormat type; unsigned foo; foo = (unsigned)fe_GetUserData(widget); type = foo; if (info->set) { w_data->text_attributes |= type; /* * Super and Sub should be mutually exclusive. */ if (type == TF_SUPER) w_data->text_attributes &= ~TF_SUB; else if (type == TF_SUB) w_data->text_attributes &= ~TF_SUPER; } else { w_data->text_attributes &= ~type; } w_data->changed_mask |= type; fe_update_dependents(widget, w_data->properties, PROP_CHAR_STYLE); } static void fe_clear_style_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; w_data->text_attributes &= ~TF_ALL_MASK; w_data->changed_mask |= TF_ALL_MASK; fe_update_dependents(widget, w_data->properties, PROP_CHAR_STYLE); } static void fe_clearall_settings_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; MWContext* context; char* link_text; if (w_data->properties->link != NULL) { /* * get the link text, to see if there any. */ link_text = fe_TextFieldGetString(w_data->properties->link->link_text); if (link_text != NULL && link_text[0] != '\0') { /* has a link */ context = w_data->properties->context; /* Do you want to remove the link? */ if (XFE_Confirm(context, XP_GetString(XFE_EDITOR_WARNING_REMOVE_LINK))) fe_link_tab_remove_link(w_data->properties->link); } if (link_text != NULL) XP_FREEIF(link_text); } w_data->js_mode = JAVASCRIPT_NONE; w_data->text_attributes &= ~TF_ALL_MASK; w_data->is_custom_color = FALSE; w_data->font_size = ED_FONTSIZE_ZERO; w_data->changed_mask |= TF_FONT_COLOR|TF_FONT_SIZE|TF_ALL_MASK|\ PROP_CHAR_CLIENT|PROP_CHAR_SERVER; fe_update_dependents(widget, w_data->properties, PROP_CHAR_ALL); } static int fe_color_do_work(MWContext* context, LO_Color* color_rv) { Widget mainw = CONTEXT_WIDGET(context); Widget dialog; Arg args[8]; Cardinal n; int done; n = 0; dialog = fe_CreateColorPickerDialog(mainw, "setColors", args, n); fe_ColorPickerDialogSetColor(dialog, color_rv); /* * Add a bunch of callbacks to the buttons. */ XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done); XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done); XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done); /* * Popup. */ XtManageChild(dialog); /* * Wait. */ fe_NukeBackingStore(dialog); /* what does this do? */ done = XmDIALOG_NONE; while (done == XmDIALOG_NONE) { fe_EventLoop(); } if (done == XmDIALOG_OK_BUTTON) fe_ColorPickerDialogGetColor(dialog, color_rv); if (done != XFE_DIALOG_DESTROY_BUTTON) XtDestroyWidget(dialog); if (done == XmDIALOG_OK_BUTTON) return XmDIALOG_OK_BUTTON; else return XmDIALOG_NONE; } static void fe_color_swatch_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; LO_Color pooh; LO_Color* color; Boolean sensitive = FALSE; /*FIXME*/ /* * I'm not sure how to generate these colors. */ if (w_data->js_mode == JAVASCRIPT_CLIENT) { pooh.red = 255; pooh.blue = 0; pooh.green = 0; color = &pooh; } else if (w_data->js_mode == JAVASCRIPT_SERVER) { pooh.red = 0; pooh.blue = 255; pooh.green = 0; color = &pooh; } else { /* JAVASCRIPT_NONE */ if (w_data->is_custom_color) { color = &w_data->color; sensitive = TRUE; } else { MWContext* context = (MWContext *)fe_WidgetToMWContext(widget); fe_EditorDocumentGetColors(context, NULL, /* bg image */ NULL, NULL, /* bg color */ &pooh,/* normal color */ NULL, /* link color */ NULL, /* active color */ NULL); /* followed color */ color = &pooh; } } fe_SwatchSetColor(widget, color); fe_SwatchSetSensitive(widget, sensitive); } Boolean fe_ColorPicker(MWContext* context, LO_Color* in_out) { LO_Color color = *in_out; if (fe_color_do_work(context, &color) == XmDIALOG_OK_BUTTON) { *in_out = color; return TRUE; } return FALSE; } static void fe_editor_props_color_picker_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; LO_Color color; color = w_data->color; if (fe_ColorPicker(w_data->properties->context, &color)) { w_data->color = color; w_data->is_custom_color = TRUE; w_data->changed_mask |= TF_FONT_COLOR; } fe_update_dependents(widget, w_data->properties, PROP_CHAR_COLOR); } static void fe_color_default_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; Boolean sensitive = (w_data->js_mode == JAVASCRIPT_NONE); Boolean set = !sensitive || (w_data->is_custom_color == FALSE); XmToggleButtonSetState(widget, set, FALSE); fe_WidgetSetSensitive(widget, sensitive); } static void fe_color_default_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; if (info->set) { w_data->changed_mask |= TF_FONT_COLOR; w_data->is_custom_color = FALSE; fe_update_dependents(widget, w_data->properties, PROP_CHAR_COLOR); } } static void fe_color_custom_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; Boolean sensitive = (w_data->js_mode == JAVASCRIPT_NONE); Boolean set = sensitive && (w_data->is_custom_color == TRUE); XmToggleButtonSetState(widget, set, FALSE); fe_WidgetSetSensitive(widget, sensitive); } static void fe_choose_color_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; Boolean sensitive = (w_data->js_mode == JAVASCRIPT_NONE) && (w_data->is_custom_color == TRUE); fe_WidgetSetSensitive(widget, sensitive); } static void fe_clear_styles_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; Boolean sensitive = (w_data->js_mode == JAVASCRIPT_NONE); fe_WidgetSetSensitive(widget, sensitive); } static void fe_color_custom_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; if (info->set) { w_data->changed_mask |= TF_FONT_COLOR; w_data->is_custom_color = TRUE; fe_update_dependents(widget, w_data->properties, PROP_CHAR_COLOR); } } static void fe_javascript_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; Boolean is_server = (fe_GetUserData(widget) != NULL); if (info->set) { if (is_server) { w_data->js_mode = JAVASCRIPT_SERVER; } else { w_data->js_mode = JAVASCRIPT_CLIENT; } /* * Javascript text doesn't have links, clear it.. */ if (w_data->properties->link != NULL) fe_link_tab_remove_link(w_data->properties->link); } else { w_data->js_mode = JAVASCRIPT_NONE; } w_data->changed_mask |= PROP_CHAR_CLIENT|PROP_CHAR_SERVER; fe_update_dependents(widget, w_data->properties, PROP_CHAR_ALL); } static void fe_javascript_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorCharacterPropertiesWidgets* w_data = (fe_EditorCharacterPropertiesWidgets*)closure; Boolean is_server = (fe_GetUserData(widget) != NULL); Boolean set = FALSE; if (is_server && (w_data->js_mode == JAVASCRIPT_SERVER)) set = TRUE; else if (!is_server && (w_data->js_mode == JAVASCRIPT_CLIENT)) set = TRUE; XmToggleButtonGadgetSetState(widget, set, FALSE); } static void fe_EditorCharacterPropertiesDialogDataGet( MWContext* context, fe_EditorCharacterPropertiesWidgets* w_data) { w_data->text_attributes = fe_EditorCharacterPropertiesGet(context); w_data->font_size = fe_EditorFontSizeGet(context); w_data->changed_mask = 0; if ((w_data->text_attributes & TF_SERVER)) w_data->js_mode = JAVASCRIPT_SERVER; else if ((w_data->text_attributes & TF_SCRIPT)) w_data->js_mode = JAVASCRIPT_CLIENT; else w_data->js_mode = JAVASCRIPT_NONE; w_data->text_attributes &= ~(TF_SERVER|TF_SCRIPT); if (fe_EditorColorGet(context, &w_data->color)) w_data->is_custom_color = TRUE; else w_data->is_custom_color = FALSE; fe_update_dependents(NULL, w_data->properties, PROP_CHAR_ALL); } static void fe_EditorCharacterPropertiesDialogSet( MWContext* context, fe_EditorCharacterPropertiesWidgets* w_data) { LO_Color* color; if ((w_data->js_mode == JAVASCRIPT_SERVER)) { fe_EditorCharacterPropertiesSet(context, TF_SERVER); } else if ((w_data->js_mode == JAVASCRIPT_CLIENT)) { fe_EditorCharacterPropertiesSet(context, TF_SCRIPT); } else { /* clear javascript */ if (w_data->changed_mask & (PROP_CHAR_CLIENT|PROP_CHAR_SERVER)) { fe_EditorCharacterPropertiesSet(context, (TF_SERVER|TF_SCRIPT)); w_data->changed_mask = ~0; } if ((w_data->changed_mask & TF_ALL_MASK)!= 0) { fe_EditorCharacterPropertiesSet(context, (w_data->text_attributes & TF_ALL_MASK)); } if ((w_data->changed_mask & TF_FONT_SIZE)!= 0) fe_EditorFontSizeSet(context, w_data->font_size); if ((w_data->changed_mask & TF_FONT_COLOR)!= 0) { if (w_data->is_custom_color) color = &w_data->color; else color = NULL; fe_EditorColorSet(context, color); } } } static void fe_make_character_page( MWContext *context, Widget parent, fe_EditorCharacterPropertiesWidgets* w_data) { Arg args[32]; Cardinal n; Widget form; Widget color_frame; Widget color_form; Widget color_label; Widget color_swatch; Widget color_default; Widget color_custom; Widget color_choose; Widget color_text; Widget size_frame; Widget size_form; Widget size_menu; Widget size_text; Widget size_cascade; Widget style_frame; Widget style_outer_rc; Widget style_inner_rc; Widget style_clear; Widget java_frame; Widget java_rc; Widget clear_all; Dimension width; Dimension height; Widget children[16]; Cardinal nchildren; #if 0 n = 0; form = XmCreateForm(parent, "characterProperties", args, n); XtManageChild(form); #else form = parent; #endif w_data->form = form; /* * Color group. */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; color_frame = fe_CreateFrame(form, "color", args, n); XtManageChild(color_frame); n = 0; color_form = XmCreateForm(color_frame, "color", args, n); XtManageChild(color_form); nchildren = 0; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; children[nchildren++] = color_label = XmCreateLabelGadget(color_form, "colorLabel", args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, color_label); n++; XtSetArg(args[n], XmNshadowThickness, 2); n++; /* make it look like label */ children[nchildren++] = color_swatch = fe_CreateSwatchButton(color_form, "colorSwatch", args, n); w_data->color_swatch = color_swatch; fe_register_dependent(w_data->properties, color_swatch, FE_MAKE_DEPENDENCY(PROP_CHAR_COLOR), fe_color_swatch_update_cb, (XtPointer)w_data); XtAddCallback(color_swatch, XmNactivateCallback, fe_editor_props_color_picker_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_label); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; XtSetArg(args[n], XmNset, TRUE); n++; children[nchildren++] = color_default = XmCreateToggleButtonGadget(color_form, "default", args, n); XtAddCallback(color_default, XmNvalueChangedCallback, fe_color_default_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, color_default, FE_MAKE_DEPENDENCY(PROP_CHAR_COLOR), fe_color_default_update_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_default); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; XtSetArg(args[n], XmNset, FALSE); n++; children[nchildren++] = color_custom = XmCreateToggleButtonGadget(color_form, "custom", args, n); XtAddCallback(color_custom, XmNvalueChangedCallback, fe_color_custom_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, color_custom, FE_MAKE_DEPENDENCY(PROP_CHAR_COLOR), fe_color_custom_update_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_default); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, color_custom); n++; children[nchildren++] = color_choose = XmCreatePushButtonGadget(color_form, "chooseColor", args, n); XtAddCallback(color_choose, XmNactivateCallback, fe_editor_props_color_picker_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, color_choose, FE_MAKE_DEPENDENCY(PROP_CHAR_COLOR), fe_choose_color_update_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_custom); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; children[nchildren++] = color_text = XmCreateLabelGadget(color_form, "colorText", args, n); XtManageChildren(children, nchildren); /* children of color form */ /* * Set the swatch to be same height as label, and width as * choose button. */ XtVaGetValues(color_label, XmNheight, &height, 0); XtVaGetValues(color_choose, XmNwidth, &width, 0); n = 0; XtSetArg(args[n], XmNwidth, width); n++; XtSetArg(args[n], XmNheight, height); n++; XtSetValues(color_swatch, args, n); /* * Size group. */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, color_frame); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, color_frame); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; size_frame = fe_CreateFrame(form, "size", args, n); XtManageChild(size_frame); n = 0; size_form = XmCreateForm(size_frame, "size", args, n); XtManageChild(size_form); nchildren = 0; n = 0; size_menu = fe_CreatePulldownMenu(size_form, "fontSize", args, n); nchildren = 0; for (nchildren = 0; fe_font_size_types[nchildren].name; nchildren++) { n = 0; XtSetArg(args[n], XmNuserData, fe_font_size_types[nchildren].data); n++; children[nchildren] = XmCreatePushButtonGadget( size_menu, fe_font_size_types[nchildren].name, args, n ); XtAddCallback(children[nchildren], XmNactivateCallback, fe_font_size_cb, (XtPointer)w_data); } XtManageChildren(children, nchildren); /* size buttons */ n = 0; XtSetArg(args[n], XmNsubMenuId, size_menu); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; size_cascade = fe_CreateOptionMenu( size_form, "fontSizeOptionMenu", args, n); fe_UnmanageChild_safe(XmOptionLabelGadget(size_cascade)); fe_register_dependent(w_data->properties, size_cascade, FE_MAKE_DEPENDENCY(PROP_CHAR_SIZE), fe_font_size_update_cb, (XtPointer)w_data); XtManageChild(size_cascade); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, size_cascade); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; size_text = XmCreateLabelGadget(size_form, "sizeText", args, n); XtManageChild(size_text); /* * Style group. */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_frame); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, color_frame); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; style_frame = fe_CreateFrame(form, "style", args, n); XtManageChild(style_frame); n = 0; style_outer_rc = XmCreateForm(style_frame, "style", args, n); XtManageChild(style_outer_rc); n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNnumColumns, 2); n++; XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; style_inner_rc = XmCreateRowColumn(style_outer_rc, "charProperties", args, n); XtManageChild(style_inner_rc); for (nchildren = 0; fe_style_types[nchildren].name; nchildren++) { n = 0; XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++; XtSetArg(args[n], XmNuserData, fe_style_types[nchildren].data); n++; children[nchildren] = XmCreateToggleButtonGadget( style_inner_rc, fe_style_types[nchildren].name, args, n); XtAddCallback(children[nchildren], XmNvalueChangedCallback, fe_style_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, children[nchildren], FE_MAKE_DEPENDENCY(fe_style_types[nchildren].data), fe_style_update_cb, (XtPointer)w_data); } XtManageChildren(children, nchildren); /* style toggles */ n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, style_inner_rc); n++; style_clear = XmCreatePushButtonGadget(style_outer_rc, "clearStyles", args, n); XtAddCallback(style_clear, XmNactivateCallback, fe_clear_style_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, style_clear, FE_MAKE_DEPENDENCY(PROP_CHAR_JAVASCRIPT), fe_clear_styles_update_cb, (XtPointer)w_data); XtManageChild(style_clear); /* * Java group. */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, color_frame); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, color_frame); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; java_frame = fe_CreateFrame(form, "java", args, n); XtManageChild(java_frame); n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; java_rc = XmCreateRowColumn(java_frame, "java", args, n); XtManageChild(java_rc); nchildren = 0; n = 0; XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++; XtSetArg(args[n], XmNuserData, FALSE); n++; children[nchildren] = XmCreateToggleButtonGadget(java_rc, "client", args, n); XtAddCallback(children[nchildren], XmNvalueChangedCallback, fe_javascript_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, children[nchildren], FE_MAKE_DEPENDENCY(PROP_CHAR_JAVASCRIPT), /* lazy */ fe_javascript_update_cb, (XtPointer)w_data); nchildren++; n = 0; XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++; XtSetArg(args[n], XmNuserData, TRUE); n++; children[nchildren] = XmCreateToggleButtonGadget(java_rc, "server", args, n); XtAddCallback(children[nchildren], XmNvalueChangedCallback, fe_javascript_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, children[nchildren], FE_MAKE_DEPENDENCY(PROP_CHAR_JAVASCRIPT), /* lazy */ fe_javascript_update_cb, (XtPointer)w_data); nchildren++; XtManageChildren(children, nchildren); /* java toggles */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, java_frame); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, java_frame); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, java_frame); n++; clear_all = XmCreatePushButtonGadget(form, "clearAll", args, n); XtManageChild(clear_all); XtAddCallback(clear_all, XmNactivateCallback, fe_clearall_settings_cb, (XtPointer)w_data); } static void fe_image_main_image_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; /* * Update changed tag, but don't call dependents (that's us). * Well we have to, so that we update the copy button. * No, we don't we'll set the tag here, but we'll only * call update_dependents from the browse cb. That way * we won't be *busy*. No, we have to, oh too bad! */ w_data->new_image = TRUE; fe_update_dependents(widget, w_data->properties, PROP_IMAGE_MAIN_IMAGE|PROP_IMAGE_COPY|PROP_LINK_TEXT); } static void fe_image_main_image_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; if (info->caller == widget) return; /* don't call ourselves */ fe_set_text_field(widget, w_data->image_data.pSrc, fe_image_main_image_cb, (XtPointer)w_data); } static void fe_url_browse_file_of_text(MWContext* context, Widget text_field) { char* before_save; char* after; char* p = NULL; int type; before_save = fe_TextFieldGetString(text_field); if (before_save != NULL) fe_StringTrim(before_save); type = NET_URL_Type(before_save); if (type == 0) { /* unknown, might be file path */ History_entry* hist_ent; if (!EDT_IS_NEW_DOCUMENT(context)) { /* don't bother looking */ hist_ent = SHIST_GetCurrent(&context->hist); if (hist_ent != NULL && hist_ent->address != NULL && NET_IsLocalFileURL(hist_ent->address)) { if (before_save[0] == '/' && before_save[1] != '/') p = before_save; } } } else if (type == FILE_TYPE_URL) { if (XP_STRNCASECMP(before_save, "file:///", 8) == 0) p = &before_save[7]; else if (XP_STRNCASECMP(before_save, "file://", 7) == 0) p = &before_save[6]; else if (XP_STRNCASECMP(before_save, "file:/", 6) == 0) p = &before_save[5]; } if (p == NULL) p = ""; if (p != before_save) fe_TextFieldSetString(text_field, p, FALSE); fe_browse_file_of_text(context, text_field, FALSE); after = fe_TextFieldGetString(text_field); fe_StringTrim(after); if (XP_STRCMP(after, before_save) != 0) { p = (char*)XP_ALLOC(XP_STRLEN(after) + 8); XP_STRCPY(p, "file://"); XP_STRCAT(p, after); fe_TextFieldSetString(text_field, p, FALSE); XP_FREE(p); } if (before_save) XtFree(before_save); if (after) XtFree(after); } static void fe_image_main_image_browse_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_url_browse_file_of_text(w_data->properties->context, w_data->main_image); } static void fe_image_alt_image_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; /* * See discussion for main above. */ w_data->new_image = TRUE; fe_update_dependents(widget, w_data->properties, PROP_IMAGE_ALT_IMAGE|PROP_IMAGE_COPY|PROP_LINK_TEXT); } static void fe_image_alt_image_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; if (info->caller == widget) return; /* don't call ourselves */ fe_set_text_field(w_data->alt_image, w_data->image_data.pLowSrc, fe_image_alt_image_cb, (XtPointer)w_data); } static void fe_image_alt_image_browse_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_url_browse_file_of_text(w_data->properties->context, w_data->alt_image); } static void fe_image_alt_text_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_update_dependents(widget, w_data->properties, PROP_IMAGE_ALT_TEXT|PROP_IMAGE_COPY|PROP_LINK_TEXT); } static void fe_image_alt_text_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; if (info->caller == widget) return; /* don't call ourselves */ fe_set_text_field(w_data->alt_text, w_data->image_data.pAlt, fe_image_alt_text_cb, (XtPointer)w_data); } static void fe_image_align_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; /* * We get a callback on both the unset of the old toggle, * and the set of the new, so ignore the former, it's not * interesting. */ if (info->set) { w_data->image_data.align = (ED_Alignment)fe_GetUserData(widget); fe_update_dependents(widget, w_data->properties, PROP_IMAGE_ALIGN); } } static void fe_image_align_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; ED_Alignment align = (ED_Alignment)fe_GetUserData(widget); XmToggleButtonGadgetSetState(widget, (w_data->image_data.align == align), FALSE); } static void fe_image_dimensions_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; Boolean constrainable = !(w_data->image_data.bHeightPercent || w_data->image_data.bWidthPercent); w_data->properties->changed |= PROP_IMAGE_DIMENSIONS; /* * If constrain is on, adjust the other value. */ if (w_data->do_constrain && constrainable) { unsigned long new_value = fe_get_numeric_text_field(widget); unsigned long tmp; unsigned long foo; if (widget == w_data->image_width) { /* adjusting width, do height */ w_data->image_data.iWidth = new_value; foo = w_data->image_data.iOriginalWidth; if (foo == 0) foo++; tmp = new_value * w_data->image_data.iOriginalHeight; tmp = tmp / foo; w_data->image_data.iHeight = tmp; } else { /* adjusting height, do width */ w_data->image_data.iHeight = new_value; foo = w_data->image_data.iOriginalHeight; if (foo == 0) foo++; tmp = new_value * w_data->image_data.iOriginalWidth; tmp = tmp / foo; w_data->image_data.iWidth = tmp; } fe_update_dependents(widget, w_data->properties, PROP_IMAGE_DIMENSIONS); } } static void fe_image_dimensions_height_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; Boolean enabled = w_data->do_custom_size; unsigned height; if (info->caller == widget) return; /* don't call ourselves */ if (enabled) height = w_data->image_data.iHeight; else height = w_data->image_data.iOriginalHeight; fe_set_numeric_text_field(widget, height); fe_TextFieldSetEditable(w_data->properties->context, widget, enabled); } static void fe_image_dimensions_width_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; Boolean enabled = w_data->do_custom_size; unsigned width; if (info->caller == widget) return; /* don't call ourselves */ if (enabled) width = w_data->image_data.iWidth; else width = w_data->image_data.iOriginalWidth; fe_set_numeric_text_field(widget, width); fe_TextFieldSetEditable(w_data->properties->context, widget, enabled); } static void fe_image_margin_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; w_data->properties->changed |= PROP_IMAGE_SPACE; } static void fe_image_margin_height_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; if (info->caller == widget) return; /* don't call ourselves */ fe_set_numeric_text_field(widget, w_data->image_data.iVSpace); } static void fe_image_margin_width_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; if (info->caller == widget) return; /* don't call ourselves */ fe_set_numeric_text_field(widget, w_data->image_data.iHSpace); } static void fe_image_margin_border_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)call_data; if (info->caller == widget) return; /* don't call ourselves */ /* Logic for dealing with w_data->image_data.iBorder possibly being -1 is now in fe_EditorImagePropertiesDialogDataGet. */ fe_set_numeric_text_field(widget, w_data->image_data.iBorder); } static void fe_image_original_size_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; w_data->do_custom_size = (info->set == FALSE); fe_update_dependents(widget, w_data->properties, PROP_IMAGE_DIMENSIONS); } static void fe_image_original_size_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; Boolean set = !w_data->do_custom_size; Boolean enabled = w_data->existing_image || w_data->new_image; XtVaSetValues(widget, XmNset, set, XmNsensitive, enabled, 0); } static void fe_image_custom_size_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; w_data->do_custom_size = info->set; fe_update_dependents(widget, w_data->properties, PROP_IMAGE_DIMENSIONS); } static void fe_image_custom_size_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; Boolean set = w_data->do_custom_size; Boolean enabled = w_data->existing_image || w_data->new_image; XtVaSetValues(widget, XmNset, set, XmNsensitive, enabled, 0); } static void fe_image_copy_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; w_data->image_data.bNoSave = info->set; fe_update_dependents(widget, w_data->properties, PROP_IMAGE_COPY); } static void fe_image_copy_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; Arg args[8]; Cardinal n; n = 0; XtSetArg(args[n], XmNset, (w_data->image_data.bNoSave)); n++; XtSetValues(widget, args, n); } static void fe_image_remove_imap_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; w_data->image_data.bIsMap = FALSE; fe_update_dependents(widget, w_data->properties, PROP_IMAGE_IMAP); } static void fe_image_remove_imap_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; Arg args[8]; Cardinal n; n = 0; XtSetArg(args[n], XmNsensitive, (w_data->image_data.bIsMap != FALSE)); n++; XtSetValues(widget, args, n); } static void fe_image_edit_image_do(MWContext* context, Widget widget, Widget image_widget) { History_entry* hist_ent = SHIST_GetCurrent(&(context->hist)); char* image; char* url; char* local_name; char buf[512]; if (hist_ent == NULL || hist_ent->address == NULL) return; /* should not happen */ image = fe_TextFieldGetString(image_widget); if (image == NULL || image[0] == '\0') return; /* also shouldn't happen */ if (NET_IsHTTP_URL(image)) { /* remote url */ fe_error_dialog(context, widget, XP_GetString(XFE_EDITOR_IMAGE_IS_REMOTE)); return; } url = NET_MakeAbsoluteURL(hist_ent->address, image); /* alloc */ if (XP_ConvertUrlToLocalFile(url, &local_name)) { fe_EditorEditImage(context, local_name); } else { sprintf(buf, XP_GetString(XFE_CANNOT_READ_FILE), image); fe_error_dialog(context, widget, buf); } if (image) XP_FREEIF(image); if (url) XtFree(url); if (local_name) XtFree(local_name); } static void fe_image_edit_image_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; MWContext* context = w_data->properties->context; fe_image_edit_image_do(context, widget, w_data->main_image); } static void fe_image_edit_image_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; Boolean sensitive = XmTextFieldGetLastPosition(w_data->main_image) != 0; XtVaSetValues(widget, XmNsensitive, sensitive, 0); } static void fe_image_edit_alt_image_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; MWContext* context = w_data->properties->context; fe_image_edit_image_do(context, widget, w_data->alt_image); } static void fe_image_edit_alt_image_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; Boolean sensitive = XmTextFieldGetLastPosition(w_data->alt_image) != 0; XtVaSetValues(widget, XmNsensitive, sensitive, 0); } static void fe_image_height_pixel_percent_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; XP_Bool percent = (strcmp(XtName(widget), "percent") == 0); w_data->image_data.bHeightPercent = percent; fe_update_dependents(widget, w_data->properties, PROP_IMAGE_HEIGHT); } static void fe_image_width_pixel_percent_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; XP_Bool percent = (strcmp(XtName(widget), "percent") == 0); w_data->image_data.bWidthPercent = percent; fe_update_dependents(widget, w_data->properties, PROP_IMAGE_WIDTH); } /* * Forward decalres for stuff used around here, because I'm just too * tired to move stuff aorund. */ char* fe_SimpleOptionPixelPercent[]; Widget fe_CreateSimpleOptionMenu(Widget, char*, Arg*, Cardinal); static void fe_image_height_pixel_percent_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; unsigned index = 0; Boolean enabled = w_data->do_custom_size; if (enabled && w_data->image_data.bHeightPercent) index = 1; XfeOptionMenuSetItem(widget, index); XtVaSetValues(widget, XmNsensitive, enabled, 0); } static void fe_image_width_pixel_percent_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; unsigned index = 0; Boolean enabled = w_data->do_custom_size; if (enabled && w_data->image_data.bWidthPercent) index = 1; XfeOptionMenuSetItem(widget, index); XtVaSetValues(widget, XmNsensitive, enabled, 0); } static void fe_image_constrain_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)call_data; w_data->do_constrain = info->set; } static void fe_image_constrain_update_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorImagePropertiesWidgets* w_data = (fe_EditorImagePropertiesWidgets*)closure; Boolean enabled = w_data->do_custom_size; Boolean sensitive = !(w_data->image_data.bHeightPercent || w_data->image_data.bWidthPercent); Boolean set = (w_data->do_constrain) && sensitive; #if 0 if (info->caller == widget) return; /* don't call ourselves */ #endif XtVaSetValues(widget, XmNsensitive, (sensitive && enabled), XmNset, set, 0); } static void fe_EditorImagePropertiesDialogDataGet(MWContext* context, fe_EditorImagePropertiesWidgets* w_data) { EDT_ImageData* old = NULL; if (EDT_GetCurrentElementType(context) == ED_ELEMENT_IMAGE) { old = EDT_GetImageData(context); memcpy(&w_data->image_data, old, sizeof(EDT_ImageData)); if (w_data->image_data.iOriginalWidth != w_data->image_data.iWidth || w_data->image_data.iOriginalHeight != w_data->image_data.iHeight) w_data->do_custom_size = TRUE; else w_data->do_custom_size = FALSE; w_data->existing_image = TRUE; } else { old = EDT_NewImageData(); memcpy(&w_data->image_data, old, sizeof(EDT_ImageData)); w_data->do_custom_size = FALSE; w_data->existing_image = FALSE; } w_data->new_image = FALSE; w_data->do_constrain = TRUE; /* ooo, we like this */ if (w_data->image_data.iBorder == -1) { w_data->default_border = TRUE; w_data->image_data.iBorder = EDT_GetDefaultBorderWidth(context); } else { w_data->default_border = FALSE; } fe_update_dependents(NULL, w_data->properties, PROP_IMAGE_ALL); /* yes, that's all sally */ if (old) EDT_FreeImageData(old); } static void fe_copy_string_over(char** tgt, Widget widget) { char* p = fe_TextFieldGetString(widget); if (*tgt) XP_FREE(*tgt); if (p && *p != '\0') *tgt = XP_STRDUP(p); else *tgt = NULL; if (p) XtFree(p); } static void fe_editor_image_properties_common_set(MWContext* context, EDT_ImageData* data, fe_EditorImagePropertiesWidgets* w_data) { if (w_data->do_custom_size) { /* * probably don't nee dto do this now, as the valueChanged * callbacks keep this up to date. */ data->iWidth = fe_get_numeric_text_field(w_data->image_width); data->iHeight = fe_get_numeric_text_field(w_data->image_height); data->bWidthPercent = w_data->image_data.bWidthPercent;; data->bHeightPercent = w_data->image_data.bHeightPercent; } else { data->iWidth = w_data->image_data.iOriginalWidth; data->iHeight = w_data->image_data.iOriginalHeight; data->bWidthPercent = FALSE; data->bHeightPercent = FALSE; } data->iHSpace = fe_get_numeric_text_field(w_data->margin_width); data->iVSpace = fe_get_numeric_text_field(w_data->margin_height); data->iBorder = fe_get_numeric_text_field(w_data->margin_solid); } static Boolean fe_editor_image_properties_validate(MWContext* context, fe_EditorImagePropertiesWidgets* w_data) { EDT_ImageData image_data; EDT_ImageData* i = &image_data; unsigned errors[16]; unsigned nerrors = 0; fe_editor_image_properties_common_set(context, &image_data, w_data); if (w_data->do_custom_size) { unsigned low; unsigned high; if (i->bWidthPercent) { low = TABLE_MIN_PERCENT_WIDTH; high = TABLE_MAX_PERCENT_WIDTH; } else { low = IMAGE_MIN_WIDTH; high = IMAGE_MAX_WIDTH; } if (RANGE_CHECK(i->iWidth, low, high)) errors[nerrors++] = XFE_EDITOR_TABLE_WIDTH_RANGE; if (i->bHeightPercent) { low = TABLE_MIN_PERCENT_HEIGHT; high = TABLE_MAX_PERCENT_HEIGHT; } else { low = IMAGE_MIN_HEIGHT; high = IMAGE_MAX_HEIGHT; } if (RANGE_CHECK(i->iHeight, low, high)) errors[nerrors++] = XFE_EDITOR_TABLE_HEIGHT_RANGE; } if (RANGE_CHECK(i->iHSpace, IMAGE_MIN_HSPACE, IMAGE_MAX_HSPACE)) errors[nerrors++] = XFE_INVALID_IMAGE_HSPACE; if (RANGE_CHECK(i->iVSpace, IMAGE_MIN_VSPACE, IMAGE_MAX_VSPACE)) errors[nerrors++] = XFE_INVALID_IMAGE_VSPACE; if (RANGE_CHECK(i->iBorder, IMAGE_MIN_BORDER, IMAGE_MAX_BORDER)) errors[nerrors++] = XFE_INVALID_IMAGE_BORDER; if (nerrors > 0) { fe_editor_range_error_dialog(context, w_data->image_width, errors, nerrors); return FALSE; } return TRUE; } static void fe_editor_image_properties_set(MWContext* context, fe_EditorImagePropertiesWidgets* w_data) { EDT_ImageData* old; if (w_data->existing_image) old = EDT_GetImageData(context); else old = EDT_NewImageData(); if ((w_data->properties->changed & PROP_IMAGE_MAIN_IMAGE) != 0) fe_copy_string_over(&old->pSrc, w_data->main_image); if ((w_data->properties->changed & PROP_IMAGE_ALT_IMAGE) != 0) fe_copy_string_over(&old->pLowSrc, w_data->alt_image); if ((w_data->properties->changed & PROP_IMAGE_ALT_TEXT) != 0) fe_copy_string_over(&old->pAlt, w_data->alt_text); fe_editor_image_properties_common_set(context, old, w_data); old->align = w_data->image_data.align; old->bIsMap = w_data->image_data.bIsMap; old->bNoSave = w_data->image_data.bNoSave; if (w_data->default_border && old->iBorder == w_data->image_data.iBorder) { old->iBorder = -1; } /* * We don't handle the link data here, let the link sheet * do that. */ if (old->pSrc != NULL) { if (w_data->existing_image) EDT_SetImageData(context, old, !w_data->image_data.bNoSave); else EDT_InsertImage(context, old, !w_data->image_data.bNoSave); } EDT_FreeImageData(old); } static struct fe_style_data fe_image_button_names[] = { { "alignTop", ED_ALIGN_TOP }, { "alignAbsCenter", ED_ALIGN_ABSCENTER }, { "alignCenter", ED_ALIGN_CENTER }, { "alignBaseline", ED_ALIGN_BASELINE }, { "alignAbsBottom", ED_ALIGN_ABSBOTTOM }, { "alignLeft", ED_ALIGN_LEFT }, { "alignRight", ED_ALIGN_RIGHT }, { 0 } #if 0 { "alignAbsTop", ED_ALIGN_ABSTOP }, { "alignBottom", ED_ALIGN_BOTTOM }, #endif }; static void fe_make_image_icons(MWContext *context, Widget parent, fe_EditorImagePropertiesWidgets* w_data) { Pixmap p; Arg args[16]; Cardinal n; Cardinal i; Widget children[16]; char* name; for (i = 0; fe_image_button_names[i].name; i++) { MWContextType old = context->type; context->type = MWContextEditor; p = fe_ToolbarPixmap(context, IL_ALIGN1_RAISED+(2*i), False, False); context->type = old; name = fe_image_button_names[i].name; n = 0; XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++; XtSetArg(args[n], XmNlabelPixmap, p); n++; XtSetArg(args[n], XmNuserData, fe_image_button_names[i].data); n++; XtSetArg(args[n], XmNindicatorOn, FALSE); n++; /* Windows-esk */ #if 0 /* looks ugly */ XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; #endif children[i] = XmCreateToggleButtonGadget(parent, name, args, n); XtAddCallback(children[i], XmNvalueChangedCallback, fe_image_align_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, children[i], FE_MAKE_DEPENDENCY(PROP_IMAGE_ALIGN), fe_image_align_update_cb, (XtPointer)w_data); } XtManageChildren(children, i); } static void fe_make_image_page(MWContext *context, Widget parent, fe_EditorImagePropertiesWidgets* w_data) { Arg av [32]; int ac; Widget form; Widget kids[32]; Widget main_image_frame; Widget main_image_form; Widget main_image_text; Widget main_image_browse; Widget main_image_edit; Widget main_image_leave; Widget alt_frame; Widget alt_form; Widget alt_image_label; Widget alt_image_text; Widget alt_image_browse; Widget alt_image_edit; Widget alt_text_label; Widget alt_text_text; Widget align_frame; Widget align_form; Widget align_rc; Widget align_info; Widget dimensions_frame; Widget dimensions_form; Widget original_radio; Widget custom_radio; Widget height_label; Widget height_text; Widget height_pixels; Widget width_label; Widget width_text; Widget width_pixels; Widget constrain; Widget space_frame; Widget space_form; Widget left_right_label; Widget left_right_text; Widget left_right_pixels; Widget top_bottom_label; Widget top_bottom_text; Widget top_bottom_pixels; Widget solid_border_label; Widget solid_text; Widget solid_pixels; Widget remove_image_map; Dimension width; Dimension height; Widget wide_guy; int i; XtCallbackRec callback; #if 0 ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; form = XmCreateForm(parent, "imageProperties", av, ac); #else form = parent; #endif /**********************************************************************/ /* Define the Image file name Frame and its form 4MAR96RCJ */ /**********************************************************************/ ac = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; main_image_frame = fe_CreateFrame(form, "imageFile", av, ac); ac = 0; main_image_form = XmCreateForm(main_image_frame, "form", av, ac); i = 0; /* number of children */ /* top row: text, browse, edit */ ac = 0; kids[i++] = main_image_text = fe_CreateTextField(main_image_form, "imageFile", av, ac); w_data->main_image = main_image_text; XtAddCallback(main_image_text, XmNvalueChangedCallback, fe_image_main_image_cb,(XtPointer)w_data); ac = 0; kids[i++] = main_image_browse = XmCreatePushButtonGadget(main_image_form, "browse", av, ac); XtAddCallback(main_image_browse, XmNactivateCallback, fe_image_main_image_browse_cb, (XtPointer)w_data); ac = 0; XtSetArg(av[ac], XmNsensitive, False); ac++; kids[i++] = main_image_edit = XmCreatePushButtonGadget(main_image_form, "editImage", av, ac); XtAddCallback(main_image_edit, XmNactivateCallback, fe_image_edit_image_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, main_image_edit, FE_MAKE_DEPENDENCY(PROP_IMAGE_MAIN_IMAGE), fe_image_edit_image_update_cb, (XtPointer)w_data); /* attachments */ ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNrightWidget, main_image_browse); ac++; XtSetValues(main_image_text, av, ac); XtVaGetValues(main_image_text, XmNheight, &height, NULL); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNrightWidget, main_image_edit); ac++; XtSetArg(av[ac], XmNheight, height); ac++; XtSetValues(main_image_browse, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNheight, height); ac++; XtSetValues(main_image_edit, av, ac); /* next row: leave at original location, use as background */ ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, main_image_browse); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; kids[i++] = main_image_leave = XmCreateToggleButtonGadget(main_image_form, "leaveImage", av, ac); XtAddCallback(main_image_leave, XmNvalueChangedCallback, fe_image_copy_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, main_image_leave, FE_MAKE_DEPENDENCY(PROP_IMAGE_COPY), fe_image_copy_update_cb, (XtPointer)w_data); #if 0 Widget use_as_background; ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, main_image_browse); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, main_image_leave); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; use_as_background = XmCreateToggleButtonGadget(main_image_form, "useAsBackground", av, ac); kids[i++] = use_as_background; XtAddCallback(use_as_background, XmNvalueChangedCallback, fe_image_copy_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, use_as_background, FE_MAKE_DEPENDENCY(PROP_IMAGE_COPY), fe_image_copy_update_cb, (XtPointer)w_data); #endif XtManageChildren(kids, i); /* alternative frame */ ac = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, main_image_frame); ac++; alt_frame = fe_CreateFrame(form, "alternativeImage", av, ac); XtManageChild(alt_frame); ac = 0; alt_form = XmCreateForm(alt_frame, "form", av, ac); XtManageChild(alt_form); i = 0; /* number of children */ /* next row: alternative label, text, browse, edit */ ac = 0; XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; kids[i++] = alt_image_label = XmCreateLabelGadget(alt_form, "alternativeImageLabel", av, ac); ac = 0; kids[i++] = alt_image_text = fe_CreateTextField(alt_form, "alternativeImage", av, ac); w_data->alt_image = alt_image_text; XtAddCallback(alt_image_text, XmNvalueChangedCallback, fe_image_alt_image_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, alt_image_text, FE_MAKE_DEPENDENCY(PROP_IMAGE_ALT_IMAGE), fe_image_alt_image_update_cb, (XtPointer)w_data); ac = 0; kids[i++] = alt_image_browse = XmCreatePushButtonGadget(alt_form, "browse", av, ac); XtAddCallback(alt_image_browse, XmNactivateCallback, fe_image_alt_image_browse_cb, (XtPointer)w_data); ac = 0; XtSetArg(av[ac], XmNsensitive, False); ac++; kids[i++] = alt_image_edit = XmCreatePushButtonGadget(alt_form, "editImage", av, ac); XtAddCallback(alt_image_edit, XmNactivateCallback, fe_image_edit_alt_image_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, alt_image_edit, FE_MAKE_DEPENDENCY(PROP_IMAGE_ALT_IMAGE), fe_image_edit_alt_image_update_cb, (XtPointer)w_data); /* attachments */ ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, alt_image_label); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNrightWidget, alt_image_browse); ac++; XtSetValues(alt_image_text, av, ac); XtVaGetValues(alt_image_text, XmNheight, &height, NULL); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNheight, height); ac++; XtSetValues(alt_image_label, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNrightWidget, alt_image_edit); ac++; XtSetArg(av[ac], XmNheight, height); ac++; XtSetValues(alt_image_browse, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNheight, height); ac++; XtSetValues(alt_image_edit, av, ac); /* next row: alternative text label, text */ ac = 0; XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; kids[i++] = alt_text_label = XmCreateLabelGadget(alt_form, "alternativeTextLabel", av, ac); ac = 0; kids[i++] = alt_text_text = fe_CreateTextField(alt_form, "alternativeText", av, ac); w_data->alt_text = alt_text_text; XtAddCallback(alt_text_text, XmNvalueChangedCallback, fe_image_alt_text_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, alt_text_text, FE_MAKE_DEPENDENCY(PROP_IMAGE_ALT_TEXT), fe_image_alt_text_update_cb, (XtPointer)w_data); /* attachments */ ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, alt_image_text); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, alt_image_label); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetValues(alt_text_text, av, ac); XtVaGetValues(alt_text_text, XmNheight, &height, NULL); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, alt_image_text); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNheight, height); ac++; XtSetValues(alt_text_label, av, ac); XtManageChildren(kids, i); /**********************************************************************/ /* Define the Alignment Frame and its form 4MAR96RCJ */ /**********************************************************************/ ac = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, alt_frame); ac++; align_frame = fe_CreateFrame(form, "alignment", av, ac); ac = 0; align_form = XmCreateForm(align_frame, "alignmentForm", av, ac); ac = 0; XtSetArg(av[ac], XmNorientation, XmHORIZONTAL); ac++; XtSetArg(av[ac], XmNradioBehavior, TRUE); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNspacing, 0); ac++; align_rc = XmCreateRowColumn(align_form, "alignmentRowColumn", av, ac); XtManageChild(align_rc); fe_make_image_icons(context, align_rc, w_data); ac = 0; XtSetArg(av[ac], XmNalignment, XmALIGNMENT_END); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, align_rc); ac++; #if 0 XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; #endif align_info = XmCreateLabelGadget(align_form, "alignmentInfoLabel", av, ac); XtManageChild(align_info); /**********************************************************************/ /* Define the Buttons at bottom of Image Properties Tab Panel */ /**********************************************************************/ i = 0; ac = 0; XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNsensitive, False); ac++; kids[i++] = remove_image_map = XmCreatePushButtonGadget(form, "removeImageMap", av, ac); XtAddCallback(remove_image_map, XmNactivateCallback, fe_image_remove_imap_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, remove_image_map, FE_MAKE_DEPENDENCY(PROP_IMAGE_IMAP), fe_image_remove_imap_update_cb, (XtPointer)w_data); XtManageChildren(kids, i); /**********************************************************************/ /* Define the Dimensions Frame and its form 4MAR96RCJ */ /**********************************************************************/ ac = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, align_frame); ac++; XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNbottomWidget, remove_image_map); ac++; dimensions_frame = fe_CreateFrame(form, "dimensions", av, ac); ac = 0; dimensions_form = XmCreateForm(dimensions_frame, "dimensionsForm", av, ac); i = 0; ac = 0; kids[i++] = height_label = XmCreateLabelGadget(dimensions_form, "heightLabel", av, ac); ac = 0; kids[i++] = width_label = XmCreateLabelGadget(dimensions_form, "widthLabel", av, ac); #define PROP_DIM_UPDATE (PROP_IMAGE_COPY|PROP_IMAGE_DIMENSIONS) ac = 0; XtSetArg(av[ac], XmNuserData, FALSE); ac++; XtSetArg(av[ac], XmNindicatorType, XmONE_OF_MANY); ac++; kids[i++] = original_radio = XmCreateToggleButtonGadget(dimensions_form, "originalSize", av, ac); XtAddCallback(original_radio, XmNvalueChangedCallback, fe_image_original_size_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, original_radio, FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE), fe_image_original_size_update_cb, (XtPointer)w_data); ac = 0; XtSetArg(av[ac], XmNuserData, TRUE); ac++; XtSetArg(av[ac], XmNindicatorType, XmONE_OF_MANY); ac++; kids[i++] = custom_radio = XmCreateToggleButtonGadget(dimensions_form, "customSize", av, ac); XtAddCallback(custom_radio, XmNvalueChangedCallback, fe_image_custom_size_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, custom_radio, FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE), fe_image_custom_size_update_cb, (XtPointer)w_data); ac = 0; XtSetArg(av[ac], XmNcolumns, 4); ac++; kids[i++] = height_text = fe_CreateTextField(dimensions_form, "imageHeight", av, ac); w_data->image_height = height_text; XtAddCallback(height_text, XmNvalueChangedCallback, fe_image_dimensions_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, height_text, FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE), fe_image_dimensions_height_update_cb, (XtPointer)w_data); callback.callback = fe_image_height_pixel_percent_cb; callback.closure = (XtPointer)w_data; ac = 0; XtSetArg(av[ac], XmNsimpleCallback, &callback); ac++; XtSetArg(av[ac], XmNbuttons, fe_SimpleOptionPixelPercent); ac++; XtSetArg(av[ac], XmNmarginHeight, 0); ac++; XtSetArg(av[ac], XmNmarginWidth, 0); ac++; height_pixels = fe_CreateSimpleOptionMenu(dimensions_form, "heightUnits", av, ac); fe_register_dependent(w_data->properties, height_pixels, FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE), fe_image_height_pixel_percent_update_cb, (XtPointer)w_data); kids[i++] = height_pixels; ac = 0; kids[i++] = width_text = fe_CreateTextField(dimensions_form, "imageWidth", av, ac); w_data->image_width = width_text; XtAddCallback(width_text, XmNvalueChangedCallback, fe_image_dimensions_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, width_text, FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE), fe_image_dimensions_width_update_cb, (XtPointer)w_data); callback.callback = fe_image_width_pixel_percent_cb; callback.closure = (XtPointer)w_data; ac = 0; XtSetArg(av[ac], XmNsimpleCallback, &callback); ac++; XtSetArg(av[ac], XmNbuttons, fe_SimpleOptionPixelPercent); ac++; XtSetArg(av[ac], XmNmarginHeight, 0); ac++; XtSetArg(av[ac], XmNmarginWidth, 0); ac++; width_pixels = fe_CreateSimpleOptionMenu(dimensions_form, "widthUnits", av, ac); fe_register_dependent(w_data->properties, width_pixels, FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE), fe_image_width_pixel_percent_update_cb, (XtPointer)w_data); kids[i++] = width_pixels; ac = 0; kids[i++] = constrain = XmCreateToggleButtonGadget(dimensions_form, "constrain", av, ac); XtAddCallback(constrain, XmNvalueChangedCallback, fe_image_constrain_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, constrain, FE_MAKE_DEPENDENCY(PROP_DIM_UPDATE), fe_image_constrain_update_cb, (XtPointer)w_data); /* do attachments */ ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetValues(original_radio, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, original_radio); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetValues(custom_radio, av, ac); wide_guy = XfeBiggestWidget(TRUE, kids, 2); /* the two labels */ XtVaGetValues(wide_guy, XmNwidth, &width, 0); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, custom_radio); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNwidth, width); ac++; XtSetValues(height_label, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, height_label); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, wide_guy); ac++; XtSetValues(height_text, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, height_label); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, height_text); ac++; XtSetValues(height_pixels, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, height_text); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNwidth, width); ac++; XtSetValues(width_label, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, width_label); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, wide_guy); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; XtSetArg(av[ac], XmNrightWidget, height_text); ac++; XtSetValues(width_text, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, width_label); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, height_text); ac++; XtSetValues(width_pixels, av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, width_text); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; XtSetValues(constrain, av, ac); XtManageChildren(kids, i); /**********************************************************************/ /* Create Space Around Image Frame, Form, Contents 6MAR96RCJ */ /**********************************************************************/ ac = 0; i = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, dimensions_frame); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, align_frame); ac++; XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNbottomWidget, remove_image_map); ac++; space_frame = fe_CreateFrame(form, "imageSpace", av, ac); ac = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; space_form = XmCreateForm(space_frame, "imageSpaceForm", av, ac); ac = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; kids[i++] = left_right_label = XmCreateLabelGadget(space_form, "leftRightLabel", av, ac); ac = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; kids[i++] = top_bottom_label = XmCreateLabelGadget(space_form, "topBottomLabel", av, ac); XtVaGetValues(top_bottom_label, XmNwidth,&width,NULL); XtVaSetValues(left_right_label, XmNwidth, width,NULL); ac = 0; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; kids[i++] = left_right_pixels = XmCreateLabelGadget(space_form, "pixels", av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, left_right_label); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNrightWidget, left_right_pixels); ac++; XtSetArg(av[ac], XmNcolumns, 3); ac++; kids[i++] = left_right_text = fe_CreateTextField(space_form, "spaceWidth", av, ac); w_data->margin_width = left_right_text; XtAddCallback(left_right_text, XmNvalueChangedCallback, fe_image_margin_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, left_right_text, FE_MAKE_DEPENDENCY(PROP_IMAGE_MARGIN_WIDTH), fe_image_margin_width_update_cb, (XtPointer)w_data); XtVaSetValues(top_bottom_label, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, left_right_text, NULL); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, left_right_text); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, top_bottom_label); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNrightWidget, left_right_pixels); ac++; XtSetArg(av[ac], XmNcolumns, 3); ac++; kids[i++] = top_bottom_text = fe_CreateTextField(space_form, "spaceHeight", av, ac); w_data->margin_height = top_bottom_text; XtAddCallback(top_bottom_text, XmNvalueChangedCallback, fe_image_margin_cb, (XtPointer)w_data); fe_register_dependent(w_data->properties, top_bottom_text, FE_MAKE_DEPENDENCY(PROP_IMAGE_MARGIN_HEIGHT), fe_image_margin_height_update_cb, (XtPointer)w_data); ac = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, top_bottom_text); ac++; kids[i++] = solid_border_label = XmCreateLabelGadget(space_form, "solidBorderLabel", av, ac); ac = 0; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, left_right_text); ac++; kids[i++] = top_bottom_pixels = XmCreateLabelGadget(space_form, "pixels", av, ac); ac = 0; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, top_bottom_text); ac++; kids[i++] = solid_pixels = XmCreateLabelGadget(space_form, "pixels", av, ac); ac = 0; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNtopWidget, top_bottom_text); ac++; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNleftWidget, top_bottom_label); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++; XtSetArg(av[ac], XmNrightWidget, left_right_pixels); ac++; XtSetArg(av[ac], XmNcolumns, 3); ac++; kids[i++] = solid_text = fe_CreateTextField(space_form, "spaceBorder", av, ac); w_data->margin_solid = solid_text; XtAddCallback(solid_text, XmNvalueChangedCallback, fe_image_margin_cb, (XtPointer)w_data); /* * Note border is dependent on link href, as it effects the * default value. */ fe_register_dependent(w_data->properties, solid_text, FE_MAKE_DEPENDENCY(PROP_LINK_HREF|PROP_IMAGE_MARGIN_BORDER), fe_image_margin_border_update_cb, (XtPointer)w_data); XtManageChildren(kids, i); /* * Add this last, as other update methoda are dependent on it * having run during init. */ fe_register_dependent(w_data->properties, main_image_text, FE_MAKE_DEPENDENCY(PROP_IMAGE_MAIN_IMAGE), fe_image_main_image_update_cb, (XtPointer)w_data); /**********************************************************************/ /* Display form by managing all of the Manager widgets 6MAR96RCJ */ /**********************************************************************/ XtManageChild(space_form); XtManageChild(space_frame); XtManageChild(main_image_form); XtManageChild(main_image_frame); XtManageChild(align_form); XtManageChild(align_frame); XtManageChild(dimensions_form); XtManageChild(dimensions_frame); XtManageChild(form); } /* end fe_make_image_page */ Widget fe_EditorPropertiesDialogCreate( MWContext *context, fe_EditorPropertiesWidgets* p_data, Boolean is_image ) { Widget dialog; Widget form; Widget tab_form; char* name = (is_image)? "imagePropertiesDialog": "textPropertiesDialog"; /* * Make prompt with ok, apply, cancel, no separator. */ dialog = fe_CreatePromptDialog(context, name, TRUE, TRUE, TRUE, FALSE, TRUE); form = XtVaCreateManagedWidget( "folder", xmlFolderWidgetClass, dialog, XmNshadowThickness, 2, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, #ifdef ALLOW_TAB_ROTATE XmNtabPlacement, XmFOLDER_LEFT, XmNrotateWhenLeftRight, FALSE, #endif /* ALLOW_TAB_ROTATE */ XmNbottomOffset, 3, XmNspacing, 1, NULL); if (is_image) { tab_form = fe_CreateTabForm(form, "imageProperties", NULL, 0); fe_make_image_page(context, tab_form, p_data->image); } else { tab_form = fe_CreateTabForm(form, "characterProperties", NULL, 0); fe_make_character_page(context, tab_form, p_data->character); } tab_form = fe_CreateTabForm(form, "linkProperties", NULL, 0); fe_make_link_page(context, tab_form, p_data->link); tab_form = fe_CreateTabForm(form, "paragraphProperties", NULL, 0); fe_make_paragraph_page(context, tab_form, p_data->paragraph); XtManageChild(dialog); return form; } void fe_EditorPropertiesDialogDo(MWContext* context, fe_EditorPropertiesDialogType tab_type) { fe_EditorPropertiesWidgets properties; fe_EditorParagraphPropertiesWidgets paragraph; fe_EditorLinkPropertiesWidgets link; fe_EditorCharacterPropertiesWidgets character; fe_EditorImagePropertiesWidgets image; int done; Widget dialog; Widget form; Widget apply_button; Boolean apply_sensitized; unsigned tab_number; Boolean is_image; is_image = fe_EditorPropertiesDialogCanDo(context, XFE_EDITOR_PROPERTIES_IMAGE); /* * Pick the tab. */ switch (tab_type) { case XFE_EDITOR_PROPERTIES_TARGET: fe_EditorTargetPropertiesDialogDo(context); return; case XFE_EDITOR_PROPERTIES_HTML_TAG: fe_EditorHtmlPropertiesDialogDo(context); return; case XFE_EDITOR_PROPERTIES_TABLE: fe_EditorTablePropertiesDialogDo(context, XFE_EDITOR_PROPERTIES_TABLE); return; case XFE_EDITOR_PROPERTIES_IMAGE: if (!is_image) return; /*FALLTHRU*/ case XFE_EDITOR_PROPERTIES_IMAGE_INSERT: is_image = TRUE; tab_number = 0; break; case XFE_EDITOR_PROPERTIES_CHARACTER: is_image = FALSE; tab_number = 0; break; case XFE_EDITOR_PROPERTIES_LINK_INSERT: case XFE_EDITOR_PROPERTIES_LINK: tab_number = 1; break; case XFE_EDITOR_PROPERTIES_PARAGRAPH: tab_number = 2; break; case XFE_EDITOR_PROPERTIES_HRULE: fe_EditorHorizontalRulePropertiesDialogDo(context); return; default: return; } memset(&properties, 0, sizeof(fe_EditorPropertiesWidgets)); memset(¶graph, 0, sizeof(fe_EditorParagraphPropertiesWidgets)); memset(&link, 0, sizeof(fe_EditorLinkPropertiesWidgets)); memset(&character, 0, sizeof(fe_EditorCharacterPropertiesWidgets)); memset(&image, 0, sizeof(fe_EditorImagePropertiesWidgets)); /* * I'll show you mine if you show me yours. */ link.properties = &properties; paragraph.properties = &properties; image.properties = &properties; character.properties = &properties; properties.link = &link; properties.paragraph = ¶graph; if (is_image) properties.image = ℑ else properties.character = &character; properties.context = context; form = fe_EditorPropertiesDialogCreate(context, &properties, is_image); dialog = XtParent(form); /* * Add a bunch of callbacks to the buttons. */ XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done); XtAddCallback(dialog, XmNapplyCallback, fe_hrule_apply_cb, &done); XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done); XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done); /* * Load values. */ if (is_image) fe_EditorImagePropertiesDialogDataGet(context, &image); else fe_EditorCharacterPropertiesDialogDataGet(context, &character); fe_editor_link_properties_dialog_data_init(context, &link); fe_EditorParagraphPropertiesDialogDataGet(context, ¶graph); /* * We toggle the sensitivity of the apply button on/off * depending if there are changes to apply. It would be * nice to use the depdency meahcnism, but it might get * very busy. */ apply_button = XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON); XtVaSetValues(apply_button, XmNsensitive, FALSE, 0); apply_sensitized = FALSE; properties.changed = 0; /* * Popup. */ XtManageChild(form); XmLFolderSetActiveTab(form, tab_number, True); /* * Wait. */ fe_NukeBackingStore(dialog); /* what does this do? */ done = XmDIALOG_NONE; EDT_BeginBatchChanges(context); while (done == XmDIALOG_NONE) { Boolean new_image_override = FALSE; fe_EventLoop(); if (done == XFE_DIALOG_DESTROY_BUTTON||done == XmDIALOG_CANCEL_BUTTON) break; /* * This is a horrible crock to get around the fact * that imageinsert() moves the context away from * the image. Better solutions??? */ new_image_override = (properties.image && image.new_image); if (new_image_override) { if (apply_sensitized == TRUE) { XtVaSetValues(apply_button, XmNsensitive, FALSE, 0); apply_sensitized = TRUE; } } else { if (apply_sensitized == FALSE && properties.changed != 0) { XtVaSetValues(apply_button, XmNsensitive, TRUE, 0); apply_sensitized = TRUE; } } if (done == XmDIALOG_APPLY_BUTTON || done == XmDIALOG_OK_BUTTON) { /* apply */ if ((properties.changed & PROP_IMAGE_ALL) != 0 && !fe_editor_image_properties_validate(context, &image)) { done = XmDIALOG_NONE; continue; } if (properties.changed != 0) { if ((properties.changed & PROP_CHAR_ALL) != 0) fe_EditorCharacterPropertiesDialogSet(context, &character); if ((properties.changed & PROP_IMAGE_ALL) != 0) fe_editor_image_properties_set(context, &image); if ((properties.changed & PROP_LINK_ALL) != 0) fe_editor_link_properties_dialog_set(context, &link); if ((properties.changed & PROP_PARA_ALL) != 0) fe_EditorParagraphPropertiesDialogSet(context, ¶graph); } if (done == XmDIALOG_APPLY_BUTTON) { properties.changed = 0; XtVaSetValues(apply_button, XmNsensitive, FALSE, 0); apply_sensitized = FALSE; done = XmDIALOG_NONE; /* keep looping */ } } } EDT_EndBatchChanges(context); /* * Unload data. */ fe_DependentListDestroy(properties.dependents); if (done != XFE_DIALOG_DESTROY_BUTTON) XtDestroyWidget(dialog); } void fe_EditorSetColorsDialogDo(MWContext* context) { LO_Color color; fe_EditorColorGet(context, &color); if (fe_ColorPicker(context, &color)) fe_EditorColorSet(context, &color); } Widget fe_CreateCombo(Widget parent, char* name, Arg* p_args, Cardinal p_n) { Widget pulldown; Arg args[8]; Cardinal n; Widget button; char buf[64]; sprintf(buf, "%sMenu", name); n = 0; pulldown = fe_CreatePulldownMenu(parent, buf, args, n); n = 0; button = XmCreatePushButtonGadget(pulldown, "emptyList", args, n); XtManageChild(button); n = 0; XtSetArg(args[n], XmNsubMenuId, pulldown); n++; return fe_CreateOptionMenuNoLabel(parent, name, args, n); } struct fe_EditorDocumentPropertiesStruct; typedef struct fe_EditorDocumentGeneralPropertiesStruct { struct fe_EditorDocumentPropertiesStruct* properties; Widget location; Widget title; Widget author; Widget description; #ifdef EDITOR_SHOW_CREATE_DATE Widget created; Widget updated; #endif /*EDITOR_SHOW_CREATE_DATE*/ Widget keywords; Widget classification; unsigned changed; } fe_EditorDocumentGeneralPropertiesStruct; #if 0 static LO_Color** fe_document_appearance_color_configure( fe_EditorDocumentAppearancePropertiesStruct* w_data, ED_EColor c_type, LO_Color** def_color_r) { LO_Color** result_addr; *def_color_r = &w_data->colors[c_type]; switch (c_type) { case DOCUMENT_BACKGROUND_COLOR: result_addr = &w_data->page_data.pColorBackground; break; case DOCUMENT_LINK_TEXT_COLOR: result_addr = &w_data->page_data.pColorLink; break; case DOCUMENT_NORMAL_TEXT_COLOR: result_addr = &w_data->page_data.pColorText; break; case DOCUMENT_FOLLOWED_TEXT_COLOR: result_addr = &w_data->page_data.pColorFollowedLink; break; default: result_addr = &w_data->page_data.pColorActiveLink; break; } return result_addr; } #endif #if 0 static void fe_PreviewPanelSetColors(Widget widget, MWContext* context, unsigned mask, Pixmap bg_pixmap, LO_Color* colors) { LO_Color* color; Pixel pixel; Pixel bg_pixel; WidgetList children; Cardinal num_children; Arg args[2]; Cardinal n; int color_n; Boolean set_bg = FALSE; Boolean set_fg; XtVaGetValues(widget, XmNchildren, &children, XmNnumChildren, &num_children, 0); if ((mask & DOCUMENT_USE_CUSTOM_MASK) != 0) mask = ~0; /* do everything */ if ((mask & DOCUMENT_BACKGROUND_COLOR_MASK) != 0) { color = &colors[DOCUMENT_BACKGROUND_COLOR]; bg_pixel = fe_GetPixel(context, color->red, color->green, color->blue); XtVaSetValues(widget, XmNbackground, bg_pixel, 0); set_bg = TRUE; } for (color_n = 0; color_n < 4; color_n++) { n = 0; set_fg = FALSE; if ((mask & (1<red,color->green,color->blue); XtSetArg(args[n], XmNforeground, pixel); n++; set_fg = TRUE; } if (set_bg || set_fg) { if (set_bg) XtSetArg(args[n], XmNbackground, bg_pixel); n++; XtSetValues(children[color_n], args, n); } } } static char* fe_PreviewPanelCreate_names[] = { "normal", "link", "active", "followed", 0 }; static Widget fe_PreviewPanelCreate(Widget parent, char* name, Arg* p_args, Cardinal p_n) { Widget rc; Widget children[4]; Cardinal nchildren; Arg args[8]; Cardinal n; XtSetArg(p_args[p_n], XmNorientation, XmVERTICAL); n++; rc = XmCreateRowColumn(parent, name, p_args, p_n); for (nchildren = 0; nchildren < 4; nchildren++) { name = fe_PreviewPanelCreate_names[nchildren]; n = 0; children[nchildren] = XmCreateLabel(rc, name, args, n); } XtManageChildren(children, nchildren); return rc; } #else typedef struct fe_PreviewPanelStruct { Pixmap bg_pixmap; Pixel bg_pixel; Pixel string_pixels[4]; XmString strings[4]; XmFontList fontList; Dimension margin_height; Dimension margin_width; Dimension height; Dimension width; Dimension shadow_thickness; Dimension highlight_thickness; Dimension spacing; } fe_PreviewPanelStruct; static void fe_preview_draw_string(Display* display, Drawable window, Pixel bg, Pixel fg, XmFontList fontList, XmString string, Position x, Position y, Dimension width, Dimension height, Boolean underline) { XGCValues gc_values; XtGCMask gc_mask; GC gc; XRectangle clip_rect; XFontStruct* font = NULL; memset (&gc_values, ~0, sizeof (gc_values)); gc_values.foreground = fg; gc_values.background = bg; _XmFontListGetDefaultFont(fontList, &font); /* must include XmP.h */ gc_mask = GCForeground|GCBackground; if (font != NULL) { gc_values.font = font->fid; gc_mask |= GCFont; } gc = fe_GetGCfromDW(display, window, gc_mask, &gc_values, NULL); clip_rect.x = x; clip_rect.y = y; clip_rect.width = width; clip_rect.height = height; if (underline) { XmStringDrawUnderline(display, window, fontList, string, gc, x, y, width, XmALIGNMENT_BEGINNING, 0, /* layout direction */ &clip_rect, /*clip_rectangle*/ string); } else { XmStringDraw(display, window, fontList, string, gc, x, y, width, XmALIGNMENT_BEGINNING, 0, /* layout direction */ &clip_rect /*clip_rectangle*/); } } static void fe_preview_panel_paint(Display* display, Drawable window, fe_PreviewPanelStruct* stuff) { Position x; Position y; Dimension height; Dimension width; Dimension height_delta; Dimension margin_height; XmString string; Pixel fg_pixel; int i; /* use background color instead */ XClearArea(display, window, 0, 0, 0, 0, FALSE); /* no expose */ for (height = stuff->height; (height % 4) != 0; height++) ; height_delta = height/4; margin_height = stuff->highlight_thickness + stuff->shadow_thickness + stuff->margin_height; x = stuff->highlight_thickness + stuff->shadow_thickness + stuff->margin_width; y = margin_height; for (i = DOCUMENT_NORMAL_TEXT_COLOR; i <= DOCUMENT_FOLLOWED_TEXT_COLOR; i++) { fg_pixel = stuff->string_pixels[i]; string = stuff->strings[i]; XmStringExtent(stuff->fontList, string, &width, &height); fe_preview_draw_string(display, window, stuff->bg_pixel, fg_pixel, stuff->fontList, string, x, y, width, height, (i != DOCUMENT_NORMAL_TEXT_COLOR)); y += height + (2*margin_height) + stuff->spacing; /* note: spacing */ } } static void fe_preview_panel_expose_cb(Widget widget, XtPointer closure, XtPointer cb) { XmDrawingAreaCallbackStruct* cb_data = (XmDrawingAreaCallbackStruct*)cb; fe_PreviewPanelStruct* stuff = (fe_PreviewPanelStruct*)fe_GetUserData(widget); fe_preview_panel_paint(XtDisplay(widget), cb_data->window, stuff); } static void fe_PreviewPanelSetColors(Widget widget, MWContext* context, unsigned mask, Pixmap bg_pixmap, LO_Color* colors) { fe_PreviewPanelStruct* stuff = (fe_PreviewPanelStruct*)fe_GetUserData(widget); LO_Color* color; Pixel pixel; int color_n; Boolean set_bg = FALSE; Boolean set_fg; set_fg = FALSE; if ((mask & DOCUMENT_BACKGROUND_COLOR_MASK) != 0) { color = &colors[DOCUMENT_BACKGROUND_COLOR]; pixel = fe_GetPixel(context, color->red, color->green, color->blue); if (pixel != stuff->bg_pixel) { stuff->bg_pixel = pixel; /* this will generate an expose event -> cb */ XtVaSetValues(widget, XmNbackground, stuff->bg_pixel, 0); set_bg = TRUE; } } for (color_n = 0; color_n < 4; color_n++) { if ((mask & (1<red,color->green,color->blue); stuff->string_pixels[color_n] = pixel; set_fg = TRUE; } } if (set_fg && !set_bg) /* if we set bg, we'll get an expose anyway */ fe_preview_panel_paint(XtDisplay(widget), XtWindow(widget), stuff); } /* static */ char* fe_PreviewPanelCreate_names[] = { "normal", "link", "active", "followed", "background", 0 }; static XtResource fe_PreviewPanelResources [] = { { "normalLabelString", XmCXmString, XmRXmString, sizeof(XmString), XtOffset(fe_PreviewPanelStruct*, strings[DOCUMENT_NORMAL_TEXT_COLOR]), XmRImmediate, (XtPointer)NULL }, { "linkLabelString", XmCXmString, XmRXmString, sizeof(XmString), XtOffset(fe_PreviewPanelStruct*, strings[DOCUMENT_LINK_TEXT_COLOR]), XmRImmediate, (XtPointer)NULL }, { "activeLabelString", XmCXmString, XmRXmString, sizeof(XmString), XtOffset(fe_PreviewPanelStruct*, strings[DOCUMENT_ACTIVE_TEXT_COLOR]), XmRImmediate, (XtPointer)NULL }, { "followedLabelString", XmCXmString, XmRXmString, sizeof(XmString), XtOffset(fe_PreviewPanelStruct*, strings[DOCUMENT_FOLLOWED_TEXT_COLOR]), XmRImmediate, (XtPointer)NULL }, { XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList), XtOffset(fe_PreviewPanelStruct*, fontList), XmRImmediate, (XtPointer)NULL }, { XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension, sizeof(Dimension), XtOffset(fe_PreviewPanelStruct*, margin_height), XmRImmediate, (XtPointer)2 }, { XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, sizeof(Dimension), XtOffset(fe_PreviewPanelStruct*, margin_width), XmRImmediate, (XtPointer)2 }, { XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension, sizeof (Dimension), XtOffset(fe_PreviewPanelStruct*, highlight_thickness), XmRImmediate, (XtPointer) 0 /* makes up for frame around us */ }, { XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension, sizeof (Dimension), XtOffset(fe_PreviewPanelStruct*, shadow_thickness), XmRImmediate, (XtPointer) 0 }, { XmNspacing, XmCSpacing, XmRVerticalDimension, sizeof (Dimension), XtOffset(fe_PreviewPanelStruct*, spacing), XmRImmediate, (XtPointer)4 } }; /* static */ Widget fe_PreviewPanelCreate(Widget parent, char* name, Arg* p_args, Cardinal p_n) { Widget drawing_area; XmString xm_string; char* resource_name; Pixel bg; XtResource copy_resources[XtNumber(fe_PreviewPanelResources)]; Dimension height; Dimension width; Dimension total_height; Dimension max_width; fe_PreviewPanelStruct* stuff = XtNew(fe_PreviewPanelStruct); int i; XtSetArg(p_args[p_n], XmNuserData, stuff); p_n++; drawing_area = XmCreateDrawingArea(parent, name, p_args, p_n); XtVaGetValues(drawing_area, XmNbackground, &bg, XmNheight, &stuff->height, XmNwidth, &stuff->width, 0); stuff->bg_pixel = bg; /* * Get resources. */ memcpy(copy_resources, fe_PreviewPanelResources, sizeof(fe_PreviewPanelResources)); XtGetSubresources(drawing_area, (XtPointer)stuff, name, "NsPreviewPanel", copy_resources, XtNumber(fe_PreviewPanelResources), NULL, 0); max_width = 0; total_height = 0; for (i = 0; i < 4; i++) { if (stuff->strings[i] == NULL) { /* not set in resources */ resource_name = fe_PreviewPanelResources[i].resource_name; xm_string = XmStringCreateLocalized(resource_name); stuff->strings[i] = xm_string; } XmStringExtent(stuff->fontList, stuff->strings[i], &width, &height); if (width > max_width) max_width = width; total_height += height; stuff->string_pixels[i] = bg; } max_width += 2 * (stuff->highlight_thickness + stuff->shadow_thickness + stuff->margin_width); if (stuff->width < max_width) { stuff->width = max_width; XtVaSetValues(drawing_area, XmNwidth, stuff->width, 0); } total_height += (2 * stuff->highlight_thickness) + (8 * (stuff->shadow_thickness + stuff->margin_height)) + (3 * stuff->spacing); if (stuff->height < total_height) { stuff->height = total_height; XtVaSetValues(drawing_area, XmNheight, stuff->height, 0); } XtAddCallback(drawing_area, XmNexposeCallback, fe_preview_panel_expose_cb, (XtPointer)stuff); XtAddCallback(drawing_area, XmNdestroyCallback, fe_destroy_cleanup_cb, (XtPointer)stuff); return drawing_area; } #endif /* static */ void fe_document_appearance_preview_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; fe_DependentListCallbackStruct* cb = (fe_DependentListCallbackStruct*)cb_data; fe_Dependency mask = cb->mask; LO_Color* colors; if (w_data->use_custom) colors = w_data->colors; else colors = w_data->default_colors; if ((mask & DOCUMENT_USE_CUSTOM_MASK) != 0) mask = ~0; /* do all colors */ fe_PreviewPanelSetColors(widget, w_data->context, mask, 0, /*Pixmap bg_pixmap*/ colors); } /* static */ void fe_document_appearance_swatch_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { ED_EColor c_type = (ED_EColor)fe_GetUserData(widget); fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; LO_Color* default_color; LO_Color* colors; Boolean sensitive; if (w_data->use_custom) colors = w_data->colors; else colors = w_data->default_colors; default_color = &colors[c_type]; sensitive = w_data->use_custom; fe_SwatchSetColor(widget, default_color); fe_SwatchSetSensitive(widget, sensitive); } static void fe_document_appearance_color_picker_do( MWContext* context, Widget widget, fe_EditorDocumentAppearancePropertiesStruct* w_data, unsigned which) { LO_Color default_color; LO_Color* colors; fe_Dependency mask; if (w_data->use_custom) colors = w_data->colors; else colors = w_data->default_colors; default_color = colors[which]; mask = (1 << which); if (fe_ColorPicker(w_data->context, &default_color)) { w_data->colors[which] = default_color; w_data->changed |= mask; fe_DependentListCallDependents(widget, w_data->dependents, mask, (XtPointer)w_data); } } /* static */ void fe_document_appearance_color_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_Dependency mask; ED_EColor c_type = (ED_EColor)fe_GetUserData(widget); fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; LO_Color default_color; LO_Color* colors; if (w_data->use_custom) colors = w_data->colors; else colors = w_data->default_colors; default_color = colors[c_type]; mask = (1 << ((unsigned)c_type)); if (fe_ColorPicker(w_data->context, &default_color)) { w_data->colors[c_type] = default_color; w_data->changed |= mask; fe_DependentListCallDependents(widget, w_data->dependents, mask, closure); } } /* static */void fe_preview_panel_click_cb(Widget widget, XtPointer closure, XtPointer cb) { XmDrawingAreaCallbackStruct* cb_data = (XmDrawingAreaCallbackStruct*)cb; fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; Dimension height; Dimension height_delta; int i; if (!w_data->use_custom) /* hack, hack, hack */ return; if (cb_data->event->type == ButtonRelease) { unsigned y = cb_data->event->xbutton.y; XtVaGetValues(widget, XmNheight, &height, 0); for (; (height % 4) != 0; height++) ; height_delta = height/4; for (i = 0 ; i < 3; i++) { if (y < ((i+1)*height_delta)) break; } fe_document_appearance_color_picker_do(w_data->context, widget, w_data, i); } } /* static */ void fe_document_appearance_use_custom_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; Boolean is_custom_button = (fe_GetUserData(widget) != NULL); Boolean set = (is_custom_button == w_data->use_custom); XmToggleButtonGadgetSetState(widget, set, FALSE); } /* static */ void fe_document_appearance_use_custom_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; Boolean is_custom_button = (fe_GetUserData(widget) != NULL); Boolean set = XmToggleButtonGadgetGetState(widget); w_data->use_custom = (set == is_custom_button); w_data->changed |= DOCUMENT_USE_CUSTOM_MASK; fe_DependentListCallDependents(widget, w_data->dependents, DOCUMENT_USE_CUSTOM_MASK, closure); } /* static */ void fe_document_appearance_use_image_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; XmToggleButtonGadgetSetState(widget, w_data->use_image, FALSE); } /* static */ void fe_document_appearance_use_image_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; Boolean set = XmToggleButtonGadgetGetState(widget); w_data->use_image = set; w_data->changed |= DOCUMENT_USE_IMAGE_MASK; fe_DependentListCallDependents(widget, w_data->dependents, DOCUMENT_USE_IMAGE_MASK, closure); } static void fe_document_appearance_leave_image_cb(Widget widget, XtPointer closure, XtPointer cbs) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; XmToggleButtonCallbackStruct* cb = (XmToggleButtonCallbackStruct*)cbs; w_data->leave_image = cb->set; w_data->changed |= DOCUMENT_USE_IMAGE_MASK; } static void fe_document_appearance_leave_image_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; XmToggleButtonGadgetSetState(widget, w_data->leave_image, FALSE); } /* static */ void fe_document_appearance_sensitized_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; Boolean sensitive; sensitive = w_data->use_custom; XtVaSetValues(widget, XmNsensitive, sensitive, 0); } /* static */ void fe_document_appearance_image_text_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; w_data->changed |= DOCUMENT_BACKGROUND_IMAGE_MASK; } /* static */ void fe_document_appearance_image_text_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)cb_data; Boolean sensitive = w_data->use_image; if (info->caller == widget) return; /* don't call ourselves */ if ((info->mask & DOCUMENT_BACKGROUND_IMAGE_MASK) != 0) fe_set_text_field(widget, w_data->image_path, fe_document_appearance_image_text_cb, (XtPointer)w_data); fe_TextFieldSetEditable(w_data->context, widget, sensitive); } /* static */ void fe_document_appearance_image_text_browse_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; Widget image_text = (Widget)fe_GetUserData(widget); fe_editor_browse_file_of_text(w_data->context, image_text); } /* static */ void fe_document_appearance_use_image_button_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAppearancePropertiesStruct* w_data = (fe_EditorDocumentAppearancePropertiesStruct*)closure; Boolean sensitive = w_data->use_image; XtVaSetValues(widget, XmNsensitive, sensitive, 0); } /* static */ void fe_document_appearance_set( MWContext* context, fe_EditorDocumentAppearancePropertiesStruct* w_data) { LO_Color* bg_color; LO_Color* normal_color; LO_Color* link_color; LO_Color* active_color; LO_Color* followed_color; char* bg_image; char* p; char buf[MAXPATHLEN]; char docname[MAXPATHLEN]; XP_Bool leave_image = FALSE; if (w_data->use_custom) { bg_color = &w_data->colors[DOCUMENT_BACKGROUND_COLOR]; normal_color = &w_data->colors[DOCUMENT_NORMAL_TEXT_COLOR]; link_color = &w_data->colors[DOCUMENT_LINK_TEXT_COLOR]; active_color = &w_data->colors[DOCUMENT_ACTIVE_TEXT_COLOR]; followed_color = &w_data->colors[DOCUMENT_FOLLOWED_TEXT_COLOR]; } else { bg_color = NULL; normal_color = link_color = active_color = followed_color = NULL; } if (w_data->use_image) { bg_image = fe_TextFieldGetString(w_data->image_text); /* * Make sure bg image is fully qualified URL. */ if (bg_image != NULL) { fe_StringTrim(bg_image); if ((p = strchr(bg_image, ':')) == NULL) { if (bg_image[0] != '/' && !w_data->is_editor_preferences) { strcpy(buf, "file:"); fe_EditorMakeName(context, docname, sizeof(buf) - 5); fe_dirname(&buf[5], docname); strcat(buf, "/"); strcat(buf, bg_image); } else { sprintf(buf, "file:%s", bg_image); } XtFree(bg_image); bg_image = XtNewString(buf); } } leave_image = w_data->leave_image; } else { bg_image = NULL; } if (w_data->is_editor_preferences) fe_EditorPreferencesSetColors(context, bg_image, bg_color, normal_color, link_color, active_color, followed_color); else fe_EditorDocumentSetColors(context, bg_image, leave_image, bg_color, normal_color, link_color, active_color, followed_color); if (bg_image) XtFree(bg_image); } /* static */ void fe_document_appearance_init( MWContext* context, fe_EditorDocumentAppearancePropertiesStruct* w_data) { Boolean use_custom; Boolean leave_image = FALSE; char bg_image[MAXPATHLEN]; w_data->context = context; fe_EditorDefaultGetColors( &w_data->default_colors[DOCUMENT_BACKGROUND_COLOR], &w_data->default_colors[DOCUMENT_NORMAL_TEXT_COLOR], &w_data->default_colors[DOCUMENT_LINK_TEXT_COLOR], &w_data->default_colors[DOCUMENT_ACTIVE_TEXT_COLOR], &w_data->default_colors[DOCUMENT_FOLLOWED_TEXT_COLOR]); if (w_data->is_editor_preferences) use_custom = fe_EditorPreferencesGetColors(context, bg_image, &w_data->colors[DOCUMENT_BACKGROUND_COLOR], &w_data->colors[DOCUMENT_NORMAL_TEXT_COLOR], &w_data->colors[DOCUMENT_LINK_TEXT_COLOR], &w_data->colors[DOCUMENT_ACTIVE_TEXT_COLOR], &w_data->colors[DOCUMENT_FOLLOWED_TEXT_COLOR]); else use_custom = fe_EditorDocumentGetColors(context, bg_image, &leave_image, &w_data->colors[DOCUMENT_BACKGROUND_COLOR], &w_data->colors[DOCUMENT_NORMAL_TEXT_COLOR], &w_data->colors[DOCUMENT_LINK_TEXT_COLOR], &w_data->colors[DOCUMENT_ACTIVE_TEXT_COLOR], &w_data->colors[DOCUMENT_FOLLOWED_TEXT_COLOR]); w_data->use_custom = use_custom; if (bg_image[0] != '\0') { w_data->use_image = TRUE; w_data->leave_image = leave_image; w_data->image_path = bg_image; } else { w_data->use_image = FALSE; w_data->leave_image = FALSE; w_data->image_path = NULL; } fe_DependentListCallDependents(NULL, w_data->dependents, ~0, (XtPointer)w_data); w_data->image_path = NULL; /* held in TextField */ } Dimension fe_get_offset_from_widest(Widget* children, Cardinal nchildren) { Dimension width; Dimension margin_width; Widget fat_guy = XfeBiggestWidget(TRUE, children, nchildren); XtVaGetValues(fat_guy, XmNwidth, &width, 0); XtVaGetValues(XtParent(fat_guy), XmNmarginWidth, &margin_width, 0); return width + margin_width; } static Widget fe_document_appearance_create( MWContext* context, Widget parent, fe_EditorDocumentAppearancePropertiesStruct* w_data) { Arg args[16]; Cardinal n; Widget main_rc; Widget colors_frame; Widget colors_rc; Widget strategy_rc; Widget strategy_custom; Widget strategy_browser; #ifdef DOCUMENT_COLOR_SCHEMES Widget schemes_frame; Widget schemes_form; Widget schemes_combo; Widget schemes_save; Widget schemes_remove; #endif Widget custom_form; Widget custom_frame; Widget custom_preview_rc; Widget background_info; Widget fat_guy; Widget top_guy; Widget bottom_guy; Widget children[6]; Widget swatches[6]; Cardinal nchildren; Cardinal nswatch; Dimension width; int i; Widget background_frame; Widget background_form; Widget background_image_toggle; Widget background_image_text; Widget background_image_leave; Widget background_image_button; Widget info_label; n = 0; XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; main_rc = XmCreateRowColumn(parent, "appearance", args, n); XtManageChild(main_rc); /* * Custom colors. */ n = 0; colors_frame = fe_CreateFrame(main_rc, "documentColors", args, n); XtManageChild(colors_frame); n = 0; XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_CENTER); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; colors_rc = XmCreateRowColumn(colors_frame, "colors", args, n); XtManageChild(colors_rc); /* * Top row. */ n = 0; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); n++; XtSetArg(args[n], XmNentryVerticalAlignment, XmALIGNMENT_BASELINE_TOP); n++; strategy_rc = XmCreateRowColumn(colors_rc, "strategy", args, n); XtManageChild(strategy_rc); n = 0; XtSetArg(args[n], XmNuserData, TRUE); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; strategy_custom = XmCreateToggleButtonGadget(strategy_rc, "custom", args, n); XtManageChild(strategy_custom); XtAddCallback(strategy_custom, XmNvalueChangedCallback, fe_document_appearance_use_custom_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, strategy_custom, DOCUMENT_USE_CUSTOM_MASK, fe_document_appearance_use_custom_update_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNuserData, FALSE); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; strategy_browser = XmCreateToggleButtonGadget(strategy_rc, "browser", args, n); XtManageChild(strategy_browser); XtAddCallback(strategy_browser, XmNvalueChangedCallback, fe_document_appearance_use_custom_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, strategy_browser, DOCUMENT_USE_CUSTOM_MASK, fe_document_appearance_use_custom_update_cb, (XtPointer)w_data); #ifdef DOCUMENT_COLOR_SCHEMES /* * Color Schemes. */ n = 0; schemes_frame = fe_CreateFrame(colors_rc, "schemes", args, n); XtManageChild(schemes_frame); n = 0; schemes_form = XmCreateForm(schemes_frame, "schemes", args, n); XtManageChild(schemes_form); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNsensitive, FALSE); n++; schemes_remove = XmCreatePushButtonGadget(schemes_form, "remove", args, n); XtManageChild(schemes_remove); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, schemes_remove); n++; XtSetArg(args[n], XmNsensitive, FALSE); n++; schemes_save = XmCreatePushButtonGadget(schemes_form, "save", args, n); XtManageChild(schemes_save); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, schemes_save); n++; XtSetArg(args[n], XmNsensitive, FALSE); n++; schemes_combo = fe_CreateCombo(schemes_form, "combo", args, n); XtManageChild(schemes_combo); #else #if 0 /* * make something to break up the top row from the colro buttons. */ n = 0; custom_form = XmCreateSeparatorGadget(colors_rc, "separator", args, n); XtManageChild(custom_form); #endif #endif n = 0; custom_form = XmCreateForm(colors_rc, "custom", args, n); XtManageChild(custom_form); for (nchildren = DOCUMENT_NORMAL_TEXT_COLOR; nchildren <= DOCUMENT_BACKGROUND_COLOR; nchildren++) { Widget button; char* name = fe_PreviewPanelCreate_names[nchildren]; unsigned flags; n = 0; XtSetArg(args[n], XmNuserData, nchildren); n++; button = XmCreatePushButtonGadget(custom_form, name, args, n); XtAddCallback(button, XmNactivateCallback, fe_document_appearance_color_cb, (XtPointer)w_data); flags = DOCUMENT_USE_CUSTOM_MASK; if (nchildren == DOCUMENT_BACKGROUND_COLOR) flags |= DOCUMENT_USE_IMAGE_MASK; fe_DependentListAddDependent(&w_data->dependents, button, flags, fe_document_appearance_sensitized_update_cb, (XtPointer)w_data); children[nchildren] = button; } XtManageChildren(children, nchildren); fat_guy = XfeBiggestWidget(TRUE, children, nchildren); XtVaGetValues(fat_guy, XmNwidth, &width, 0); /* swatches */ for (nswatch = DOCUMENT_NORMAL_TEXT_COLOR; nswatch <= DOCUMENT_BACKGROUND_COLOR; nswatch++) { Widget foo; char name[32]; unsigned flags; sprintf(name, "%sSwatch", fe_PreviewPanelCreate_names[nswatch]); n = 0; XtSetArg(args[n], XmNuserData, nswatch); n++; XtSetArg(args[n], XmNwidth, SWATCH_SIZE); n++; foo = fe_CreateSwatchButton(custom_form, name, args, n); XtAddCallback(foo, XmNactivateCallback, fe_document_appearance_color_cb, (XtPointer)w_data); flags = DOCUMENT_USE_CUSTOM_MASK|(1<dependents, foo, flags, fe_document_appearance_swatch_update_cb, (XtPointer)w_data); swatches[nswatch] = foo; } XtManageChildren(swatches, nswatch); /* * Do attachments. */ for (top_guy = NULL, i = 0; i < nchildren; i++) { n = 0; if (top_guy) { XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_guy); n++; } else { XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; } XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; top_guy = children[i]; if (top_guy != fat_guy) { /* * Have to do this to avoid circular dependency in * losing XmForm. */ XtSetArg(args[n], XmNwidth, width); n++; #if 0 XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n],XmNrightWidget, fat_guy); n++; #endif } XtSetValues(top_guy, args, n); /* Do swatch. */ n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, top_guy); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_guy); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, top_guy); n++; XtSetValues(swatches[i], args, n); } top_guy = swatches[DOCUMENT_NORMAL_TEXT_COLOR]; bottom_guy = swatches[DOCUMENT_FOLLOWED_TEXT_COLOR]; n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, top_guy); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_guy); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, bottom_guy); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; #if 1 custom_frame = /*fe_*/XmCreateFrame(custom_form, "previewFrame", args, n); XtManageChild(custom_frame); n = 0; /* I'm tired of changing resources to get this right */ XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetValues(custom_frame, args, n); #else n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNborderWidth, 1); n++; XtSetArg(args[n], XmNborderColor, CONTEXT_DATA(w_data->context)->default_fg_pixel); n++; #endif custom_preview_rc = fe_PreviewPanelCreate(custom_frame, "preview", args, n); XtManageChild(custom_preview_rc); XtAddCallback(custom_preview_rc, XmNinputCallback, fe_preview_panel_click_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, custom_preview_rc, (DOCUMENT_USE_CUSTOM_MASK|DOCUMENT_ALL_APPEARANCE), fe_document_appearance_preview_update_cb, (XtPointer)w_data); #if 1 fe_DependentListAddDependent(&w_data->dependents, custom_preview_rc, DOCUMENT_USE_CUSTOM_MASK, fe_document_appearance_sensitized_update_cb, (XtPointer)w_data); #endif top_guy = swatches[DOCUMENT_BACKGROUND_COLOR]; n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, top_guy); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, top_guy); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, top_guy); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; background_info = XmCreateLabelGadget(custom_form, "backgroundInfo", args, n); XtManageChild(background_info); /* * Background. */ n = 0; background_frame = fe_CreateFrame(main_rc, "backgroundImage", args, n); XtManageChild(background_frame); n = 0; background_form = XmCreateForm(background_frame, "backgroundImage", args, n); XtManageChild(background_form); nchildren = 0; n = 0; XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++; background_image_toggle = XmCreateToggleButtonGadget(background_form, "useImage", args, n); children[nchildren++] = background_image_toggle; XtAddCallback(background_image_toggle, XmNvalueChangedCallback, fe_document_appearance_use_image_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, background_image_toggle, (DOCUMENT_USE_IMAGE_MASK|DOCUMENT_USE_CUSTOM_MASK), fe_document_appearance_use_image_update_cb, (XtPointer)w_data); n = 0; background_image_text = fe_CreateTextField(background_form, "imageText", args, n); XtAddCallback(background_image_text, XmNvalueChangedCallback, fe_document_appearance_image_text_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, background_image_text, (DOCUMENT_BACKGROUND_IMAGE_MASK| DOCUMENT_USE_IMAGE_MASK| DOCUMENT_USE_CUSTOM_MASK), fe_document_appearance_image_text_update_cb, (XtPointer)w_data); w_data->image_text = background_image_text; children[nchildren++] = background_image_text; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; background_image_leave = XmCreateToggleButtonGadget(background_form, "leaveImage", args, n); children[nchildren++] = background_image_leave; XtAddCallback(background_image_leave, XmNvalueChangedCallback, fe_document_appearance_leave_image_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, background_image_leave, (DOCUMENT_USE_IMAGE_MASK|DOCUMENT_USE_CUSTOM_MASK), fe_document_appearance_leave_image_update_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNuserData, background_image_text); n++; background_image_button = XmCreatePushButtonGadget(background_form, "browseImageFile", args, n); XtAddCallback(background_image_button, XmNactivateCallback, fe_document_appearance_image_text_browse_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, background_image_button, (DOCUMENT_USE_IMAGE_MASK|DOCUMENT_USE_CUSTOM_MASK), fe_document_appearance_use_image_button_update_cb, (XtPointer)w_data); children[nchildren++] = background_image_button; /* * Do background image group attachments. */ n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetValues(background_image_toggle, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, background_image_toggle); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetValues(background_image_text, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, background_image_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, background_image_button); n++; XtSetValues(background_image_leave, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, background_image_text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetValues(background_image_button, args, n); XtManageChildren(children, nchildren); /* * Bottom line info text. */ n = 0; info_label = XmCreateLabelGadget(main_rc, "infoLabel", args, n); XtManageChild(info_label); return main_rc; } #define DOCUMENT_GENERAL_TITLE (0x1<<0) #define DOCUMENT_GENERAL_AUTHOR (0x1<<1) #define DOCUMENT_GENERAL_DESCRIPTION (0x1<<2) #define DOCUMENT_GENERAL_KEYWORDS (0x1<<3) #define DOCUMENT_GENERAL_CLASSIFICATION (0x1<<4) static void fe_document_general_changed_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorDocumentGeneralPropertiesStruct* w_data = (fe_EditorDocumentGeneralPropertiesStruct*)closure; unsigned mask = (unsigned)fe_GetUserData(widget); w_data->changed |= mask; } /* * Purpose: Condense a URL to a given length. * Lifted the algorithm from winfe/popup.cpp/WFE_CondenseURL() */ char* FE_CondenseURL(char* target, char* source, unsigned target_len) { unsigned source_len = strlen(source); unsigned first_half_len; unsigned second_half_len; if (source_len < target_len) { strcpy(target, source); } else { first_half_len = (target_len - 3)/2; second_half_len = target_len - first_half_len - 4; /* -1 for NUL */ strncpy(target, source, first_half_len); strcpy(&target[first_half_len], "..."); strcat(target, &source[source_len - second_half_len]); } return target; } static void fe_document_general_init(MWContext* context, fe_EditorDocumentGeneralPropertiesStruct* w_data) { XmString xm_string; char buf[40]; /* will specifiy size of maximum location text length */ char* value; /* set defaults */ /* */ xm_string = XmStringCreateLocalized(XP_GetString(XFE_UNKNOWN)); #ifdef EDITOR_SHOW_CREATE_DATE XtVaSetValues(w_data->created, XmNlabelString, xm_string, 0); XtVaSetValues(w_data->updated, XmNlabelString, xm_string, 0); #endif /*EDITOR_SHOW_CREATE_DATE*/ XtVaSetValues(w_data->location, XmNlabelString, xm_string, 0); XmStringFree(xm_string); /* get the location */ fe_EditorMakeName(context, buf, sizeof(buf)); xm_string = XmStringCreateLocalized(buf); XtVaSetValues(w_data->location, XmNlabelString, xm_string, 0); XmStringFree(xm_string); /* get the title */ if ((value = fe_EditorDocumentGetTitle(context)) != NULL) { fe_SetTextFieldAndCallBack(w_data->title, value); XP_FREE(value); } /* get the author */ if ((value = fe_EditorDocumentGetMetaData(context, "Author")) != NULL) fe_SetTextFieldAndCallBack(w_data->author, value); /* get the description */ if ((value = fe_EditorDocumentGetMetaData(context, "Description"))) fe_SetTextFieldAndCallBack(w_data->description, value); /* get the keywords */ if ((value = fe_EditorDocumentGetMetaData(context, "Keywords"))) fe_SetTextFieldAndCallBack(w_data->keywords, value); /* get the classification */ if ((value = fe_EditorDocumentGetMetaData(context, "Classification"))) fe_SetTextFieldAndCallBack(w_data->classification, value); #ifdef EDITOR_SHOW_CREATE_DATE /* get the created */ if ((value = fe_EditorDocumentGetMetaData(context, "Created"))) { xm_string = XmStringCreateLocalized(value); XtVaSetValues(w_data->created, XmNlabelString, xm_string, 0); XmStringFree(xm_string); } /* get the updated */ if ((value = fe_EditorDocumentGetMetaData(context, "Last-Modified"))) { xm_string = XmStringCreateLocalized(value); XtVaSetValues(w_data->updated, XmNlabelString, xm_string, 0); XmStringFree(xm_string); } #endif /*EDITOR_SHOW_CREATE_DATE*/ w_data->changed = 0; } static void fe_document_general_set(MWContext* context, fe_EditorDocumentGeneralPropertiesStruct* w_data) { char* value; /* set the title */ if ((w_data->changed & DOCUMENT_GENERAL_TITLE) != 0) { value = fe_TextFieldGetString(w_data->title); fe_EditorDocumentSetTitle(context, value); XtFree(value); } /* author */ if ((w_data->changed & DOCUMENT_GENERAL_AUTHOR) != 0) { value = fe_TextFieldGetString(w_data->author); fe_EditorDocumentSetMetaData(context, "Author", value); XtFree(value); } /* description */ if ((w_data->changed & DOCUMENT_GENERAL_DESCRIPTION) != 0) { value = fe_TextFieldGetString(w_data->description); fe_EditorDocumentSetMetaData(context, "Description", value); XtFree(value); } /* keywords */ if ((w_data->changed & DOCUMENT_GENERAL_KEYWORDS) != 0) { value = fe_TextFieldGetString(w_data->keywords); fe_EditorDocumentSetMetaData(context, "Keywords", value); XtFree(value); } /* classification */ if ((w_data->changed & DOCUMENT_GENERAL_CLASSIFICATION) != 0) { value = fe_TextFieldGetString(w_data->classification); fe_EditorDocumentSetMetaData(context, "Classification", value); XtFree(value); } w_data->changed = 0; } static Widget fe_document_general_create( MWContext* context, Widget parent, fe_EditorDocumentGeneralPropertiesStruct* w_data) { Widget form; Widget location_label; Widget location_text; Widget title_label; Widget title_text; Widget author_label; Widget author_text; Widget description_label; Widget description_text; #ifdef EDITOR_SHOW_CREATE_DATE Widget created_label; Widget created_text; Widget updated_label; Widget updated_text; Widget fat_guy; #endif /*EDITOR_SHOW_CREATE_DATE*/ Widget other_frame; Widget other_form; Widget info_label; Widget keywords_label; Widget keywords_text; Widget classification_label; Widget classification_text; Widget children[16]; Cardinal nchildren; Dimension left_offset; Arg args[8]; Cardinal n; Cardinal i; n = 0; form = XmCreateForm(parent, "general", args, n); nchildren = 0; n = 0; location_label = XmCreateLabelGadget(form, "locationLabel", args, n); children[nchildren++] = location_label; n = 0; title_label = XmCreateLabelGadget(form, "titleLabel", args, n); children[nchildren++] = title_label; n = 0; author_label = XmCreateLabelGadget(form, "authorLabel", args, n); children[nchildren++] = author_label; n = 0; description_label = XmCreateLabelGadget(form, "descriptionLabel", args, n); children[nchildren++] = description_label; left_offset = fe_get_offset_from_widest(children, nchildren); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; location_text = XmCreateLabelGadget(form, "locationText", args, n); children[nchildren++] = location_text; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, children[nchildren-1]); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, location_text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_TITLE); n++; title_text = fe_CreateTextField(form, "titleText", args, n); children[nchildren++] = title_text; XtAddCallback(title_text, XmNvalueChangedCallback, fe_document_general_changed_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, children[nchildren-1]); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, location_text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_AUTHOR); n++; author_text = fe_CreateTextField(form, "authorText", args, n); children[nchildren++] = author_text; XtAddCallback(author_text, XmNvalueChangedCallback, fe_document_general_changed_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg(args[n], XmNrows, 2); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, children[nchildren-1]); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, location_text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_DESCRIPTION); n++; description_text = fe_CreateText(form, "descriptionText", args, n); children[nchildren++] = description_text; XtAddCallback(description_text, XmNvalueChangedCallback, fe_document_general_changed_cb, (XtPointer)w_data); /* go back and do label attachments */ for (i = 0; i < 4; i++) { n = 0; if (i == 0) { XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; } else { XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, children[i+3]); n++; } XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetValues(children[i], args, n); } XtManageChildren(children, nchildren); nchildren = 0; #ifdef EDITOR_SHOW_CREATE_DATE n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, description_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; created_label = XmCreateLabelGadget(form, "createdLabel", args, n); children[nchildren++] = created_label; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, created_label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; updated_label = XmCreateLabelGadget(form, "updatedLabel", args, n); children[nchildren++] = updated_label; fat_guy = XfeBiggestWidget(TRUE, children, nchildren); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, description_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, fat_guy); n++; created_text = XmCreateLabelGadget(form, "createdText", args, n); children[nchildren++] = created_text; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, created_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, fat_guy); n++; updated_text = XmCreateLabelGadget(form, "updatedText", args, n); children[nchildren++] = updated_text; #endif /*EDITOR_SHOW_CREATE_DATE*/ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; #ifdef EDITOR_SHOW_CREATE_DATE XtSetArg(args[n], XmNtopWidget, updated_text); n++; #else XtSetArg(args[n], XmNtopWidget, description_text); n++; #endif /*EDITOR_SHOW_CREATE_DATE*/ XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; other_frame = fe_CreateFrame(form, "otherAttributes", args, n); children[nchildren++] = other_frame; XtManageChildren(children, nchildren); #if 1 n = 0; other_form = XmCreateForm(other_frame, "form", args, n); XtManageChild(other_form); nchildren = 0; n = 0; keywords_label = XmCreateLabelGadget(other_form, "keywordsLabel", args, n); children[nchildren++] = keywords_label; n = 0; classification_label = XmCreateLabelGadget(other_form, "classificationLabel", args, n); children[nchildren++] = classification_label; left_offset = fe_get_offset_from_widest(children, nchildren); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; info_label = XmCreateLabelGadget(other_form, "infoLabel", args, n); children[nchildren++] = info_label; n = 0; XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg(args[n], XmNrows, 2); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, info_label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, info_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_KEYWORDS); n++; keywords_text = fe_CreateText(other_form, "keywordsText", args, n); children[nchildren++] = keywords_text; XtAddCallback(keywords_text, XmNvalueChangedCallback, fe_document_general_changed_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg(args[n], XmNrows, 2); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, keywords_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, info_label); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNuserData, DOCUMENT_GENERAL_CLASSIFICATION); n++; classification_text = fe_CreateText(other_form, "classificationText", args, n); children[nchildren++] = classification_text; XtAddCallback(classification_text, XmNvalueChangedCallback, fe_document_general_changed_cb, (XtPointer)w_data); /* go back set attachments for labels */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, info_label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetValues(keywords_label, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, keywords_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetValues(classification_label, args, n); XtManageChildren(children, nchildren); #endif XtManageChild(form); w_data->location = location_text; w_data->title = title_text; w_data->author = author_text; w_data->description = description_text; #ifdef EDITOR_SHOW_CREATE_DATE w_data->created = created_text; w_data->updated = updated_text; #endif /*EDITOR_SHOW_CREATE_DATE*/ w_data->keywords = keywords_text; w_data->classification = classification_text; return form; } typedef enum { XFE_USERMETA_VIEW, XFE_USERMETA_MODIFY, XFE_USERMETA_NEW } fe_AdvancedUserState; typedef struct fe_NameValueItemList { fe_NameValueItem* items; unsigned nitems; /* logical number of items */ unsigned size; /* size of vector */ Widget widget; Boolean is_dirty; int selected_item; unsigned mask; } fe_NameValueItemList; #define NOTHING_SELECTED (-1) typedef struct fe_EditorDocumentAdvancedPropertiesStruct { MWContext* context; fe_NameValueItemList system_list; fe_NameValueItemList user_list; fe_NameValueItemList* active_list; Boolean item_is_new; Boolean item_is_dirty; Widget name_text; Widget value_text; unsigned changed; fe_DependentList* dependents; } fe_EditorDocumentAdvancedPropertiesStruct; #define DOCUMENT_ADVANCED_HTTP_LIST (0x1<<0) #define DOCUMENT_ADVANCED_META_LIST (0x1<<1) #define DOCUMENT_ADVANCED_ITEM (0x1<<2) #define DOCUMENT_ADVANCED_SELECTION (0x1<<3) static void fe_document_advanced_tell_me_eh(Widget widget, XtPointer closure, XEvent* event, Boolean* keep_going) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; fe_NameValueItemList* my_list; *keep_going = TRUE; XmProcessTraversal(widget, XmTRAVERSE_CURRENT); /* * We may get called after the callback (next), so.. */ if (w_data->active_list != NULL && w_data->active_list->widget == widget) return; if (w_data->user_list.widget == widget) my_list = &w_data->user_list; else my_list = &w_data->system_list; w_data->active_list = my_list; my_list->selected_item = NOTHING_SELECTED; my_list->is_dirty = FALSE; if (my_list->nitems == 0) w_data->item_is_new = TRUE; else w_data->item_is_new = FALSE; w_data->item_is_dirty = FALSE; fe_DependentListCallDependents(widget, w_data->dependents, DOCUMENT_ADVANCED_SELECTION, closure); } static void fe_document_advanced_list_cb(Widget widget, XtPointer closure, XtPointer foo) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; XmListCallbackStruct* cb_data = (XmListCallbackStruct*)foo; fe_NameValueItemList* my_list; if (cb_data->reason != XmCR_SINGLE_SELECT) return; if (w_data->user_list.widget == widget) my_list = &w_data->user_list; else my_list = &w_data->system_list; /* * For some strange and unknown reason this callback * adds one to the list position it provides. */ if (cb_data->item_position > 0 && cb_data->selected_item_count > 0) { my_list->selected_item = cb_data->item_position - 1; } else { my_list->selected_item = NOTHING_SELECTED; } if (my_list->nitems == 0) w_data->item_is_new = TRUE; else w_data->item_is_new = FALSE; w_data->active_list = my_list; my_list->is_dirty = FALSE; w_data->item_is_dirty = FALSE; fe_DependentListCallDependents(widget, w_data->dependents, DOCUMENT_ADVANCED_SELECTION, closure); } static void fe_copy_name_value_to_xm_list(Widget widget, fe_NameValueItem* list) { unsigned i; char buf[512]; XmString xm_string; XmListDeleteAllItems(widget); for (i = 0; list[i].name != NULL; i++) { strcpy(buf, list[i].name); strcat(buf, "="); strcat(buf, list[i].value); xm_string = XmStringCreateLocalized(buf); XmListAddItem(widget, xm_string, i + 1); /* MOTIFism */ XmStringFree(xm_string); } } static void fe_document_advanced_list_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; fe_NameValueItemList* my_list; Pixel parent_bg; Pixel select_bg; XtVaGetValues(XtParent(widget), XmNbackground, &parent_bg, 0); XmGetColors(XtScreen(widget), fe_cmap(w_data->context), parent_bg, NULL, NULL, NULL, &select_bg); if (w_data->user_list.widget == widget) my_list = &w_data->user_list; else my_list = &w_data->system_list; if (my_list->is_dirty) { fe_copy_name_value_to_xm_list(widget, my_list->items); my_list->is_dirty = FALSE; } if (w_data->active_list == my_list && my_list->selected_item != NOTHING_SELECTED) { XmListSelectPos(widget, my_list->selected_item + 1, FALSE); } else { XmListDeselectAllItems(widget); } if (w_data->active_list == my_list) XtVaSetValues(widget, XmNbackground, select_bg, 0); else XtVaSetValues(widget, XmNbackground, parent_bg, 0); } static void fe_document_advanced_value_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; if (w_data->item_is_dirty == FALSE) { w_data->item_is_dirty = TRUE; fe_DependentListCallDependents(widget, w_data->dependents, DOCUMENT_ADVANCED_ITEM, closure); } } static void fe_document_advanced_name_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)cb_data; char* name; if (info->caller == widget) return; if (w_data->item_is_new) { fe_TextFieldSetString(widget, "", FALSE); fe_TextFieldSetEditable(w_data->context, widget, TRUE); XtVaSetValues(XtParent(widget), XmNinitialFocus, widget, 0); } else { fe_NameValueItemList* active_list = w_data->active_list; if (active_list != NULL && active_list->selected_item != NOTHING_SELECTED) { name = active_list->items[active_list->selected_item].name; fe_TextFieldSetString(widget, name, FALSE); } else { fe_TextFieldSetString(widget, "", FALSE); } fe_TextFieldSetEditable(w_data->context, widget, FALSE); } } static void fe_document_advanced_value_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; fe_DependentListCallbackStruct* info = (fe_DependentListCallbackStruct*)cb_data; char* value; if (info->caller == widget) return; if (w_data->item_is_new) { fe_TextFieldSetString(widget, "", FALSE); fe_TextFieldSetEditable(w_data->context, widget, TRUE); } else { fe_NameValueItemList* active_list = w_data->active_list; if (active_list != NULL && active_list->selected_item != NOTHING_SELECTED) { value = active_list->items[active_list->selected_item].value; if (value == NULL) value = ""; fe_TextFieldSetString(widget, value, FALSE); fe_TextFieldSetEditable(w_data->context, widget, TRUE); #if 0 XmProcessTraversal(widget, XmTRAVERSE_CURRENT); #endif } else { /* nothing selected */ fe_TextFieldSetString(widget, "", FALSE); fe_TextFieldSetEditable(w_data->context, widget, FALSE); } } } static void fe_document_advanced_new_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; w_data->item_is_new = TRUE; w_data->item_is_dirty = FALSE; fe_DependentListCallDependents(widget, w_data->dependents, DOCUMENT_ADVANCED_SELECTION, closure); } #if 0 static void fe_document_advanced_new_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; Boolean sensitive = (w_data->item_is_new == FALSE); XtVaSetValues(widget, XmNsensitive, sensitive, 0); } #endif static void list_set_item(fe_NameValueItemList* active_list, unsigned index, char* name, char* value) { unsigned size; if (active_list == NULL) /* this should be error */ return; if (index == active_list->nitems) active_list->nitems++; if (active_list->nitems > active_list->size) { active_list->size = active_list->nitems; size = sizeof(fe_NameValueItem) * (active_list->size+1); if (active_list->size == 0) active_list->items = (fe_NameValueItem*)XtMalloc(size); else active_list->items = (fe_NameValueItem*)XtRealloc((void*)active_list->items, size); active_list->items[active_list->nitems].name = NULL; active_list->items[active_list->nitems].value = NULL; } if (active_list->items[index].name != NULL) XtFree(active_list->items[index].name); if (active_list->items[index].value != NULL) XtFree(active_list->items[index].value); active_list->items[index].name = XtNewString(name); if (value) active_list->items[index].value = XtNewString(value); else active_list->items[index].value = NULL; active_list->is_dirty = TRUE; } static void list_delete_item(fe_NameValueItemList* active_list, unsigned index) { if (active_list == NULL) /* this should be error */ return; if (active_list->items[index].name) XtFree(active_list->items[index].name); if (active_list->items[index].value) XtFree(active_list->items[index].value); active_list->nitems--; if (index < active_list->nitems) { memcpy(&active_list->items[index], &active_list->items[index+1], (sizeof(fe_NameValueItem) * (active_list->nitems - index))); } active_list->items[active_list->nitems].name = NULL; active_list->items[active_list->nitems].value = NULL; active_list->is_dirty = TRUE; } static void fe_document_advanced_delete_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; fe_NameValueItemList* active_list = w_data->active_list; if (active_list == NULL || active_list->selected_item == NOTHING_SELECTED) return; list_delete_item(active_list, active_list->selected_item); if (active_list->selected_item > 0) active_list->selected_item--; w_data->item_is_dirty = w_data->item_is_new = FALSE; fe_DependentListCallDependents(widget, w_data->dependents, w_data->active_list->mask, closure); w_data->changed |= w_data->active_list->mask; } static void fe_document_advanced_delete_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; Boolean sensitive = (w_data->item_is_new == FALSE) && (w_data->active_list != NULL) && (w_data->active_list->selected_item != NOTHING_SELECTED); XtVaSetValues(widget, XmNsensitive, sensitive, 0); } static void fe_document_advanced_set_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; char* name; char* value; if (w_data->active_list == NULL) return; name = fe_TextFieldGetString(w_data->name_text); value = fe_TextFieldGetString(w_data->value_text); if (w_data->item_is_new) w_data->active_list->selected_item = w_data->active_list->nitems; list_set_item(w_data->active_list, w_data->active_list->selected_item, name, value); XtFree(name); XtFree(value); w_data->item_is_new = FALSE; w_data->item_is_dirty = FALSE; fe_DependentListCallDependents(widget, w_data->dependents, w_data->active_list->mask, closure); w_data->changed |= w_data->active_list->mask; } static void fe_document_advanced_set_update_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_EditorDocumentAdvancedPropertiesStruct* w_data = (fe_EditorDocumentAdvancedPropertiesStruct*)closure; Boolean sensitive = (w_data->item_is_dirty); XtVaSetValues(widget, XmNsensitive, sensitive, 0); } static void fe_document_advanced_init(MWContext* context, fe_EditorDocumentAdvancedPropertiesStruct* w_data) { int i; fe_NameValueItem* list; list = fe_EditorDocumentGetHttpEquivMetaDataList(context); w_data->system_list.items = list; for (i = 0; list[i].name != NULL; i++) ; w_data->system_list.nitems = i; w_data->system_list.size = i; w_data->system_list.is_dirty = TRUE; w_data->system_list.selected_item = NOTHING_SELECTED; w_data->system_list.mask = DOCUMENT_ADVANCED_HTTP_LIST; list = fe_EditorDocumentGetAdvancedMetaDataList(context); w_data->user_list.items = list; for (i = 0; list[i].name != NULL; i++) ; w_data->user_list.nitems = i; w_data->user_list.size = i; w_data->user_list.is_dirty = TRUE; w_data->user_list.selected_item = NOTHING_SELECTED; w_data->user_list.mask = DOCUMENT_ADVANCED_META_LIST; fe_DependentListCallDependents(NULL, w_data->dependents, ~0, (XtPointer)w_data); } static void fe_document_advanced_set(MWContext* context, fe_EditorDocumentAdvancedPropertiesStruct* w_data) { if ((w_data->changed & DOCUMENT_ADVANCED_HTTP_LIST) != 0) { fe_EditorDocumentSetHttpEquivMetaDataList(context, w_data->system_list.items); } if ((w_data->changed & DOCUMENT_ADVANCED_META_LIST) != 0) { fe_EditorDocumentSetAdvancedMetaDataList(context, w_data->user_list.items); } } static Widget fe_document_advanced_create( MWContext* context, Widget parent, fe_EditorDocumentAdvancedPropertiesStruct* w_data) { Widget form; Widget system_label; Widget system_list; Widget user_label; Widget user_list; Widget name_label; Widget name_text; Widget name_new; Widget name_set; Widget value_label; Widget value_text; Widget name_delete; Widget list_parent; Widget fat_guy; Dimension left_offset; Arg args[16]; Cardinal n; Widget children[12]; Cardinal nchildren; Dimension width; #if 1 form = parent; #else n = 0; form = XmCreateForm(parent, "advanced", args, n); XtManageChild(form); #endif nchildren = 0; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; system_label = XmCreateLabelGadget(form, "systemLabel", args, n); children[nchildren++] = system_label; #define SCROLLED_LIST_SIZE 5 n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, system_label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNvisibleItemCount, SCROLLED_LIST_SIZE); n++; XtSetArg(args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++; XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); n++; system_list = XmCreateScrolledList(form, "systemList", args, n); XtManageChild(system_list); children[nchildren++] = list_parent = XtParent(system_list); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, list_parent); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; user_label = XmCreateLabelGadget(form, "userLabel", args, n); children[nchildren++] = user_label; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, user_label); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNvisibleItemCount, SCROLLED_LIST_SIZE); n++; XtSetArg(args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++; XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); n++; user_list = XmCreateScrolledList(form, "userList", args, n); XtManageChild(user_list); children[nchildren++] = list_parent = XtParent(user_list); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, list_parent); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; name_label = XmCreateLabelGadget(form, "nameLabel", args, n); children[nchildren++] = name_label; n = 0; value_label = XmCreateLabelGadget(form, "valueLabel", args, n); children[nchildren++] = value_label; left_offset = fe_get_offset_from_widest(&children[nchildren-2], 2); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, list_parent); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; name_new = XmCreatePushButtonGadget(form, "new", args, n); children[nchildren++] = name_new; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, list_parent); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, name_new); n++; name_delete = XmCreatePushButtonGadget(form, "delete", args, n); children[nchildren++] = name_delete; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, list_parent); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, name_delete); n++; name_text = fe_CreateTextField(form, "nameText", args, n); children[nchildren++] = name_text; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, name_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetValues(value_label, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, name_text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; name_set = XmCreatePushButtonGadget(form, "set", args, n); children[nchildren++] = name_set; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, name_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, name_set); n++; value_text = fe_CreateTextField(form, "valueText", args, n); children[nchildren++] = value_text; XtManageChildren(children, nchildren); nchildren = 0; children[nchildren++] = name_new; children[nchildren++] = name_delete; children[nchildren++] = name_set; fat_guy = XfeBiggestWidget(TRUE, children, nchildren); XtVaGetValues(fat_guy, XmNwidth, &width, 0); for (n = 0; n < nchildren; n++) { XtVaSetValues(children[n], XmNwidth, width, 0); } XtAddCallback(system_list, XmNsingleSelectionCallback, fe_document_advanced_list_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, system_list, (DOCUMENT_ADVANCED_SELECTION|DOCUMENT_ADVANCED_HTTP_LIST), fe_document_advanced_list_update_cb, (XtPointer)w_data); XtInsertEventHandler(system_list, ButtonPressMask, False, fe_document_advanced_tell_me_eh, (XtPointer)w_data, XtListTail); XtAddCallback(user_list, XmNsingleSelectionCallback, fe_document_advanced_list_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, user_list, (DOCUMENT_ADVANCED_SELECTION|DOCUMENT_ADVANCED_META_LIST), fe_document_advanced_list_update_cb, (XtPointer)w_data); XtInsertEventHandler(user_list, ButtonPressMask, False, fe_document_advanced_tell_me_eh, (XtPointer)w_data, XtListTail); XtAddCallback(name_text, XmNvalueChangedCallback, fe_document_advanced_value_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, name_text, (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_SELECTION), fe_document_advanced_name_update_cb, (XtPointer)w_data); XtAddCallback(value_text, XmNvalueChangedCallback, fe_document_advanced_value_cb, (XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, value_text, (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_SELECTION), fe_document_advanced_value_update_cb, (XtPointer)w_data); XtAddCallback(name_new, XmNactivateCallback, fe_document_advanced_new_cb,(XtPointer)w_data); #if 0 fe_DependentListAddDependent(&w_data->dependents, name_new, (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_SELECTION), fe_document_advanced_new_update_cb, (XtPointer)w_data); #endif XtAddCallback(name_delete, XmNactivateCallback, fe_document_advanced_delete_cb,(XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, name_delete, (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_SELECTION), fe_document_advanced_delete_update_cb, (XtPointer)w_data); XtAddCallback(name_set, XmNactivateCallback, fe_document_advanced_set_cb,(XtPointer)w_data); fe_DependentListAddDependent(&w_data->dependents, name_set, (DOCUMENT_ADVANCED_HTTP_LIST|DOCUMENT_ADVANCED_META_LIST|DOCUMENT_ADVANCED_ITEM |DOCUMENT_ADVANCED_SELECTION), fe_document_advanced_set_update_cb, (XtPointer)w_data); w_data->name_text = name_text; w_data->value_text = value_text; w_data->system_list.widget = system_list; w_data->user_list.widget = user_list; w_data->context = context; return form; } typedef struct fe_EditorDocumentPropertiesStruct { MWContext* context; fe_EditorDocumentAppearancePropertiesStruct* appearance; fe_EditorDocumentGeneralPropertiesStruct* general; fe_EditorDocumentAdvancedPropertiesStruct* advanced; } fe_EditorDocumentPropertiesStruct; static Widget fe_EditorDocumentPropertiesCreate(MWContext* context, fe_EditorDocumentPropertiesStruct* p_data) { Widget dialog; Widget form; Widget tab_form; char* name = "documentPropertiesDialog"; Arg args[8]; Cardinal n; /* * Make prompt with ok, apply, cancel, no separator. */ dialog = fe_CreatePromptDialog(context, name, TRUE, TRUE, TRUE, FALSE, TRUE); form = XtVaCreateManagedWidget( "folder", xmlFolderWidgetClass, dialog, XmNshadowThickness, 2, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, #ifdef ALLOW_TAB_ROTATE XmNtabPlacement, XmFOLDER_LEFT, XmNrotateWhenLeftRight, FALSE, #endif /* ALLOW_TAB_ROTATE */ XmNbottomOffset, 3, XmNspacing, 1, NULL); n = 0; tab_form = fe_CreateTabForm(form, "appearanceProperties", args, n); fe_document_appearance_create(context, tab_form, p_data->appearance); tab_form = fe_CreateTabForm(form, "generalProperties", args, n); fe_document_general_create(context, tab_form, p_data->general); tab_form = fe_CreateTabForm(form, "advanced", args, n); fe_document_advanced_create(context, tab_form, p_data->advanced); XtManageChild(dialog); return form; } void fe_EditorDocumentPropertiesDialogDo(MWContext* context, fe_EditorDocumentPropertiesDialogType tab_type) { fe_EditorDocumentPropertiesStruct properties; fe_EditorDocumentAppearancePropertiesStruct appearance; fe_EditorDocumentGeneralPropertiesStruct general; fe_EditorDocumentAdvancedPropertiesStruct advanced; int done; Widget dialog; Widget form; Widget apply_button; Boolean apply_sensitized; unsigned tab_number; Boolean three_tabs = (context->type == MWContextEditor); /* hack */ /* * Pick the tab. */ tab_number = tab_type - 1; memset(&properties, 0, sizeof(fe_EditorDocumentPropertiesStruct)); memset(&appearance, 0, sizeof(fe_EditorDocumentAppearancePropertiesStruct)); memset(&general, 0, sizeof(fe_EditorDocumentGeneralPropertiesStruct)); memset(&advanced, 0, sizeof(fe_EditorDocumentAdvancedPropertiesStruct)); properties.appearance = &appearance; properties.general = &general; properties.advanced = &advanced; properties.context = context; if (three_tabs) { form = fe_EditorDocumentPropertiesCreate(context, &properties); fe_document_appearance_init(context, &appearance); fe_document_general_init(context, &general); fe_document_advanced_init(context, &advanced); XmLFolderSetActiveTab(form, tab_number, True); dialog = XtParent(form); } else { /* * Make prompt with ok, apply, cancel, no separator. */ dialog = fe_CreatePromptDialog(context, "documentPropertiesDialog", TRUE, TRUE, TRUE, TRUE, TRUE); form = XmCreateForm(dialog, "appearanceProperties", NULL, 0); XtManageChild(form); fe_document_appearance_create(context, form, &appearance); XtManageChild(dialog); fe_document_appearance_init(context, &appearance); form = dialog; } /* * Initialize. */ #if 0 fe_DependentListCallDependents(NULL, properties.dependents, ~0, (XtPointer)&properties); #endif /* * Add a bunch of callbacks to the buttons. */ XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done); XtAddCallback(dialog, XmNapplyCallback, fe_hrule_apply_cb, &done); XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done); XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done); /* * We toggle the sensitivity of the apply button on/off * depending if there are changes to apply. It would be * nice to use the depdency meahcnism, but it might get * very busy. */ apply_button = XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON); XtVaSetValues(apply_button, XmNsensitive, FALSE, 0); apply_sensitized = FALSE; /* * Popup. */ XtManageChild(form); /* * Wait. */ fe_NukeBackingStore(dialog); /* what does this do? */ done = XmDIALOG_NONE; while (done == XmDIALOG_NONE) { fe_EventLoop(); if (done == XFE_DIALOG_DESTROY_BUTTON||done == XmDIALOG_CANCEL_BUTTON) break; #define SOMETHING_CHANGED() \ (appearance.changed != 0 || general.changed != 0 || advanced.changed != 0) if (SOMETHING_CHANGED() && apply_sensitized == FALSE) { XtVaSetValues(apply_button, XmNsensitive, TRUE, 0); apply_sensitized = TRUE; } if (done == XmDIALOG_APPLY_BUTTON || done == XmDIALOG_OK_BUTTON) { /* apply */ if (SOMETHING_CHANGED()) { EDT_BeginBatchChanges(context); if (appearance.changed != 0) { fe_document_appearance_set(context, &appearance); appearance.changed = 0; } if (general.changed != 0) { fe_document_general_set(context, &general); general.changed = 0; } if (advanced.changed != 0) { fe_document_advanced_set(context, &advanced); advanced.changed = 0; } EDT_EndBatchChanges(context); } if (done == XmDIALOG_APPLY_BUTTON) { done = XmDIALOG_NONE; /* keep looping */ XtVaSetValues(apply_button, XmNsensitive, FALSE, 0); apply_sensitized = FALSE; } } } #undef SOMETHING_CHANGED /* * Unload data. */ fe_DependentListDestroy(appearance.dependents); if (done != XFE_DIALOG_DESTROY_BUTTON) XtDestroyWidget(dialog); } typedef struct fe_EditorGeneralPreferencesStruct { MWContext* context; Widget author; Widget html_editor; Widget image_editor; Widget template; Widget autosave_toggle; Widget autosave_text; unsigned changed; } fe_EditorGeneralPreferencesStruct; #define EDITOR_GENERAL_AUTHOR (0x1<<0) #define EDITOR_GENERAL_HTML_EDITOR (0x1<<1) #define EDITOR_GENERAL_IMAGE_EDITOR (0x1<<2) #define EDITOR_GENERAL_TEMPLATE (0x1<<3) #define EDITOR_GENERAL_AUTOSAVE (0x1<<4) static void fe_general_preferences_restore_template_cb(Widget widget, XtPointer closure, XtPointer call_data) { char* value; fe_EditorGeneralPreferencesStruct* w_data = (fe_EditorGeneralPreferencesStruct*)closure; /* get the template */ if ((value = fe_EditorDefaultGetTemplate()) == NULL) value = ""; fe_SetTextFieldAndCallBack(w_data->template, value); w_data->changed |= EDITOR_GENERAL_TEMPLATE; } static void fe_general_preferences_changed_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorGeneralPreferencesStruct* w_data = (fe_EditorGeneralPreferencesStruct*)closure; unsigned mask = (unsigned)fe_GetUserData(widget); w_data->changed |= mask; } static void fe_general_preferences_autosave_toggle_cb(Widget widget, XtPointer closure, XtPointer call_data) { fe_EditorGeneralPreferencesStruct* w_data = (fe_EditorGeneralPreferencesStruct*)closure; XmToggleButtonCallbackStruct* cb = (XmToggleButtonCallbackStruct*)call_data; fe_TextFieldSetEditable(w_data->context, w_data->autosave_text, cb->set); w_data->changed |= EDITOR_GENERAL_AUTOSAVE; } static void fe_general_preferences_init(MWContext* context, fe_EditorGeneralPreferencesStruct* w_data) { char* value; char* value2; Boolean as_enable; unsigned as_time; /* get the author */ if ((value = fe_EditorPreferencesGetAuthor(context)) != NULL) fe_SetTextFieldAndCallBack(w_data->author, value); /* get the editors */ fe_EditorPreferencesGetEditors(context, &value, &value2); if (value != NULL) fe_SetTextFieldAndCallBack(w_data->html_editor, value); if (value2 != NULL) fe_SetTextFieldAndCallBack(w_data->image_editor, value2); /* get the template */ if ((value = fe_EditorPreferencesGetTemplate(context))) fe_SetTextFieldAndCallBack(w_data->template, value); /* get the autosave state */ fe_EditorPreferencesGetAutoSave(context, &as_enable, &as_time); if (!as_enable) as_time = 10; fe_set_numeric_text_field(w_data->autosave_text, as_time); fe_TextFieldSetEditable(context, w_data->autosave_text, as_enable); XmToggleButtonGadgetSetState(w_data->autosave_toggle, as_enable, FALSE); w_data->context = context; w_data->changed = 0; } static Boolean fe_general_preferences_validate(MWContext* context, fe_EditorGeneralPreferencesStruct* w_data) { Boolean as_enable; int as_time; /* autosave */ if ((w_data->changed & EDITOR_GENERAL_AUTOSAVE) != 0) { as_time = fe_get_numeric_text_field(w_data->autosave_text); as_enable = XmToggleButtonGadgetGetState(w_data->autosave_toggle); if (as_time == 0) as_enable = FALSE; if (as_enable) { if (RANGE_CHECK(as_time,AUTOSAVE_MIN_PERIOD,AUTOSAVE_MAX_PERIOD)) { char* msg = XP_GetString(XFE_EDITOR_AUTOSAVE_PERIOD_RANGE); fe_error_dialog(context, w_data->autosave_text, msg); return FALSE; } } } return TRUE; } static void fe_general_preferences_set(MWContext* context, fe_EditorGeneralPreferencesStruct* w_data) { char* value; Boolean as_enable; unsigned as_time; /* author */ if ((w_data->changed & EDITOR_GENERAL_AUTHOR) != 0) { value = fe_TextFieldGetString(w_data->author); fe_EditorPreferencesSetAuthor(context, value); XtFree(value); } /* editors */ value = NULL; if ((w_data->changed & EDITOR_GENERAL_HTML_EDITOR) != 0) { value = fe_TextFieldGetString(w_data->html_editor); fe_EditorPreferencesSetEditors(context, value, NULL); XtFree(value); } if ((w_data->changed & EDITOR_GENERAL_IMAGE_EDITOR) != 0) { value = fe_TextFieldGetString(w_data->image_editor); fe_EditorPreferencesSetEditors(context, NULL, value); XtFree(value); } /* template */ if ((w_data->changed & EDITOR_GENERAL_TEMPLATE) != 0) { value = fe_TextFieldGetString(w_data->template); fe_EditorPreferencesSetTemplate(context, value); XtFree(value); } /* autosave */ if ((w_data->changed & EDITOR_GENERAL_AUTOSAVE) != 0) { as_time = fe_get_numeric_text_field(w_data->autosave_text); as_enable = XmToggleButtonGadgetGetState(w_data->autosave_toggle); fe_EditorPreferencesSetAutoSave(context, as_enable, as_time); } w_data->changed = 0; } static Widget fe_general_preferences_create(MWContext* context, Widget parent, fe_EditorGeneralPreferencesStruct* w_data) { Widget main_rc; Widget author_frame; Widget author_text; Widget external_frame; Widget external_form; Widget html_label; Widget html_text; Widget html_browse; Widget image_label; Widget image_text; Widget image_browse; Widget template_frame; Widget template_form; Widget template_label; Widget template_text; Widget template_info_label; Widget template_restore; Widget autosave_frame; Widget autosave_form; Widget autosave_toggle; Widget autosave_text; Widget autosave_label; Widget children[8]; Cardinal nchildren; Dimension left_offset; Dimension right_offset; Arg args[8]; Cardinal n; Cardinal i; n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; main_rc = XmCreateRowColumn(parent, "general", args, n); XtManageChild(main_rc); n = 0; author_frame = fe_CreateFrame(main_rc, "author", args, n); XtManageChild(author_frame); n = 0; XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_AUTHOR); n++; author_text = fe_CreateTextField(author_frame, "authorText", args, n); XtManageChild(author_text); w_data->author = author_text; XtAddCallback(author_text, XmNvalueChangedCallback, fe_general_preferences_changed_cb, (XtPointer)w_data); n = 0; external_frame = fe_CreateFrame(main_rc, "external", args, n); XtManageChild(external_frame); n = 0; external_form = XmCreateForm(external_frame, "external", args, n); XtManageChild(external_form); nchildren = 0; n = 0; html_label = XmCreateLabelGadget(external_form, "htmlLabel", args, n); children[nchildren++] = html_label; n = 0; image_label = XmCreateLabelGadget(external_form, "imageLabel", args, n); children[nchildren++] = image_label; left_offset = fe_get_offset_from_widest(children, nchildren); n = 0; html_browse = XmCreatePushButtonGadget(external_form, "browse", args, n); children[nchildren++] = html_browse; n = 0; image_browse = XmCreatePushButtonGadget(external_form, "browse", args, n); children[nchildren++] = image_browse; right_offset = fe_get_offset_from_widest(&children[2], 2); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightOffset, right_offset); n++; XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_HTML_EDITOR); n++; html_text = fe_CreateTextField(external_form, "htmlText", args, n); children[nchildren++] = html_text; w_data->html_editor = html_text; XtAddCallback(html_text, XmNvalueChangedCallback, fe_general_preferences_changed_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, html_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightOffset, right_offset); n++; XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_IMAGE_EDITOR); n++; image_text = fe_CreateTextField(external_form, "imageText", args, n); children[nchildren++] = image_text; w_data->image_editor = image_text; XtAddCallback(image_text, XmNvalueChangedCallback, fe_general_preferences_changed_cb, (XtPointer)w_data); /* * Go back for browse callbacks */ XtVaSetValues(image_browse, XmNuserData, image_text, 0); XtAddCallback(image_browse, XmNactivateCallback, fe_browse_to_text_field_cb, (XtPointer)context); XtVaSetValues(html_browse, XmNuserData, html_text, 0); XtAddCallback(html_browse, XmNactivateCallback, fe_browse_to_text_field_cb, (XtPointer)context); /* * Go back and attach the labels and browse buttons. */ for (i = 0; i < 4; i++) { n = 0; if ((i & 0x1) == 0) { /* even, therefore topmost of pair */ XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; } else { XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, html_text); n++; } if (i < 2) { /* label, attach to left */ XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; } else { /* button, attach to right */ XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; } XtSetValues(children[i], args, n); } XtManageChildren(children, nchildren); n = 0; template_frame = fe_CreateFrame(main_rc, "template", args, n); XtManageChild(template_frame); n = 0; template_form = XmCreateForm(template_frame, "template", args, n); XtManageChild(template_form); nchildren = 0; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; template_label = XmCreateLabelGadget(template_form, "locationLabel", args, n); children[nchildren++] = template_label; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftWidget, template_label); n++; XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_TEMPLATE); n++; template_text = fe_CreateTextField(template_form, "templateText", args, n); children[nchildren++] = template_text; w_data->template = template_text; XtAddCallback(template_text, XmNvalueChangedCallback, fe_general_preferences_changed_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, template_text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; template_restore = XmCreatePushButtonGadget(template_form, "restoreDefault", args, n); children[nchildren++] = template_restore; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, template_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, template_restore); n++; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; template_info_label = XmCreateLabelGadget(template_form, "templateInfo", args, n); children[nchildren++] = template_info_label; XtAddCallback(template_restore, XmNactivateCallback, fe_general_preferences_restore_template_cb, (XtPointer)w_data); XtManageChildren(children, nchildren); /* * Auto Save. */ n = 0; autosave_frame = fe_CreateFrame(main_rc, "autosave", args, n); XtManageChild(autosave_frame); n = 0; autosave_form = XmCreateForm(autosave_frame, "autosave", args, n); XtManageChild(autosave_form); nchildren = 0; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++; autosave_toggle = XmCreateToggleButtonGadget(autosave_form, "autosaveEnable", args, n); children[nchildren++] = autosave_toggle; XtAddCallback(autosave_toggle, XmNvalueChangedCallback, fe_general_preferences_autosave_toggle_cb, (XtPointer)w_data); w_data->autosave_toggle = autosave_toggle; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, autosave_toggle); n++; XtSetArg(args[n], XmNcolumns, 4); n++; XtSetArg(args[n], XmNuserData, EDITOR_GENERAL_AUTOSAVE); n++; autosave_text = fe_CreateTextField(autosave_form, "autosaveText", args, n); children[nchildren++] = autosave_text; XtAddCallback(autosave_text, XmNvalueChangedCallback, fe_general_preferences_changed_cb, (XtPointer)w_data); w_data->autosave_text = autosave_text; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, autosave_text); n++; autosave_label = XmCreateLabelGadget(autosave_form, "minutes", args, n); children[nchildren++] = autosave_label; XtManageChildren(children, nchildren); return main_rc; } typedef struct fe_EditorPublishPreferencesStruct { Widget maintain_links; Widget keep_images; Widget publish_text; Widget browse_text; Widget username_text; Widget password_text; Widget save_password; unsigned changed; } fe_EditorPublishPreferencesStruct; #define EDITOR_PUBLISH_LINKS (0x1<<0) #define EDITOR_PUBLISH_IMAGES (0x1<<1) #define EDITOR_PUBLISH_PUBLISH (0x1<<2) #define EDITOR_PUBLISH_BROWSE (0x1<<3) #define EDITOR_PUBLISH_USERNAME (0x1<<4) #define EDITOR_PUBLISH_PASSWORD (0x1<<5) #define EDITOR_PUBLISH_PASSWORD_SAVE (0x1<<6) static void fe_publish_page_changed(Widget widget, XtPointer closure, XtPointer cb) { fe_EditorPublishPreferencesStruct* w_data = (fe_EditorPublishPreferencesStruct*)closure; w_data->changed |= (unsigned)fe_GetUserData(widget); } static void fe_publish_password_changed(Widget widget, XtPointer closure, XtPointer cb) { fe_EditorPublishPreferencesStruct* w_data = (fe_EditorPublishPreferencesStruct*)closure; w_data->changed |= EDITOR_PUBLISH_PASSWORD; } static void fe_publish_preferences_set(MWContext* context, fe_EditorPublishPreferencesStruct* w_data) { char* location = NULL; char* browse_location = NULL; char* username = NULL; char* password = NULL; Boolean new_links; Boolean new_images; Boolean old_links; Boolean old_images; new_links = XmToggleButtonGetState(w_data->maintain_links); new_images = XmToggleButtonGetState(w_data->keep_images); fe_EditorPreferencesGetLinksAndImages(context, &old_links, &old_images); if (new_links != old_links || new_images != old_images) { fe_EditorPreferencesSetLinksAndImages(context, new_links, new_images); } #ifdef _SECURITY_BTN_ON_PREFS /* don't need save password in prefs anymore - benjie */ new_save_password = XmToggleButtonGetState(w_data->save_password); old_save_password = fe_EditorPreferencesGetPublishLocation(context, NULL, NULL, NULL); #endif #define PUBLISH_MASK (EDITOR_PUBLISH_PUBLISH| \ EDITOR_PUBLISH_BROWSE| \ EDITOR_PUBLISH_USERNAME| \ EDITOR_PUBLISH_PASSWORD|EDITOR_PUBLISH_PASSWORD_SAVE) #ifdef _SECURITY_BTN_ON_PREFS if (new_save_password != old_save_password || (w_data->changed & PUBLISH_MASK) != 0) { #else if ((w_data->changed & PUBLISH_MASK) != 0) { #endif location = fe_TextFieldGetString(w_data->publish_text); browse_location = fe_TextFieldGetString(w_data->browse_text); username = fe_TextFieldGetString(w_data->username_text); password = fe_GetPasswdText(w_data->password_text); fe_EditorPreferencesSetPublishLocation(context, location, username, password); /* new_save_password? password: 0); */ fe_EditorPreferencesSetBrowseLocation(context, browse_location); } #undef PUBLISH_MASK if (browse_location) { XtFree(browse_location); } if (location) { XtFree(location); } if (username) { XtFree(username); } if (password) { memset(password, 0, strlen(password)); XtFree(password); } } static void fe_publish_preferences_init(MWContext* context, fe_EditorPublishPreferencesStruct* w_data) { char* location; char* browse_location; char* username; char* password; Boolean links; Boolean images; Boolean save_password; fe_EditorPreferencesGetLinksAndImages(context, &links, &images); save_password = fe_EditorPreferencesGetPublishLocation(context, &location, &username, &password); browse_location = fe_EditorPreferencesGetBrowseLocation(context); XmToggleButtonSetState(w_data->maintain_links, links, FALSE); XmToggleButtonSetState(w_data->keep_images, images, FALSE); /*XmToggleButtonSetState(w_data->save_password, save_password, FALSE);*/ if (location) { fe_TextFieldSetString(w_data->publish_text, location, FALSE); if (username) fe_TextFieldSetString(w_data->username_text, username, FALSE); else fe_TextFieldSetString(w_data->username_text, "", FALSE); if (password) fe_TextFieldSetString(w_data->password_text, password, FALSE); else fe_TextFieldSetString(w_data->password_text, "", FALSE); } if (browse_location) fe_TextFieldSetString(w_data->browse_text, browse_location, FALSE); else fe_TextFieldSetString(w_data->browse_text, "", FALSE); if (browse_location) { XtFree(browse_location); } if (location) { XtFree(location); } if (username) { XtFree(username); } if (password) { memset(password, 0, strlen(password)); XtFree(password); } } static Widget fe_publish_preferences_create(MWContext* context, Widget parent, fe_EditorPublishPreferencesStruct* w_data) { Widget main_rc; Widget links_frame; Widget links_main_rc; Widget links_main_info; Widget links_sub_rc; Widget links_toggle; Widget links_info; Widget images_toggle; Widget images_info; Widget links_main_tip; Widget publish_frame; Widget publish_form; Widget publish_label; Widget publish_text; Widget browse_label; Widget browse_text; Widget username_label; Widget username_text; Widget password_label; Widget password_text; Widget children[16]; Cardinal nchildren; Dimension left_offset; Arg args[16]; Cardinal n; n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; main_rc = XmCreateRowColumn(parent, "publish", args, n); XtManageChild(main_rc); n = 0; links_frame = fe_CreateFrame(main_rc, "linksAndImages", args, n); XtManageChild(links_frame); n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; links_main_rc = XmCreateRowColumn(links_frame, "linksAndImages", args, n); XtManageChild(links_main_rc); nchildren = 0; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; links_main_info = XmCreateLabelGadget(links_main_rc, "linksAndImagesLabel", args, n); children[nchildren++] = links_main_info; n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNisAligned, TRUE); n++; XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_BEGINNING); n++; links_sub_rc = XmCreateRowColumn(links_main_rc, "linksAndImagesToggles", args, n); children[nchildren++] = links_sub_rc; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; links_main_tip = XmCreateLabelGadget(links_main_rc, "linksAndImagesTip", args, n); children[nchildren++] = links_main_tip; XtManageChildren(children, nchildren); nchildren = 0; n = 0; links_toggle = XmCreateToggleButtonGadget(links_sub_rc, "linksToggle", args, n); children[nchildren++] = links_toggle; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; links_info = XmCreateLabelGadget(links_sub_rc, "linksInfo", args, n); children[nchildren++] = links_info; n = 0; images_toggle = XmCreateToggleButtonGadget(links_sub_rc, "imagesToggle", args, n); children[nchildren++] = images_toggle; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; images_info = XmCreateLabelGadget(links_sub_rc, "imagesInfo", args, n); children[nchildren++] = images_info; XtManageChildren(children, nchildren); n = 0; publish_frame = fe_CreateFrame(main_rc, "publish", args, n); XtManageChild(publish_frame); n = 0; publish_form = XmCreateForm(publish_frame, "publish", args, n); XtManageChild(publish_form); nchildren = 0; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; publish_label = XmCreateLabelGadget(publish_form, "publishLabel", args, n); children[nchildren++] = publish_label; n = 0; browse_label = XmCreateLabelGadget(publish_form, "browseLabel", args, n); children[nchildren++] = browse_label; left_offset = fe_get_offset_from_widest(children, 2); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetArg(args[n], XmNuserData, EDITOR_PUBLISH_PUBLISH); n++; publish_text = fe_CreateTextField(publish_form, "publishText", args, n); children[nchildren++] = publish_text; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, publish_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetArg(args[n], XmNuserData, EDITOR_PUBLISH_BROWSE); n++; browse_text = fe_CreateTextField(publish_form, "browseText", args, n); children[nchildren++] = browse_text; /* * Go back for browse label attachments. */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, publish_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetValues(browse_label, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, browse_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; username_label = XmCreateLabelGadget(publish_form, "usernameLabel", args, n); children[nchildren++] = username_label; n = 0; password_label = XmCreateLabelGadget(publish_form, "passwordLabel", args, n); children[nchildren++] = password_label; left_offset = fe_get_offset_from_widest(&children[4], 2); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, browse_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetArg(args[n], XmNuserData, EDITOR_PUBLISH_USERNAME); n++; username_text = fe_CreateTextField(publish_form, "usernameText", args, n); children[nchildren++] = username_text; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, username_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetArg(args[n], XmNmaxLength, 1024); n++; password_text = fe_CreatePasswordField(publish_form, "passwordText", args, n); children[nchildren++] = password_text; n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, username_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetValues(password_label, args, n); /* we don't need this anymore - benjie */ /* according to the bugsplat */ #ifdef _SECURITY_BTN_ON_PREFS n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, username_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, password_text); n++; password_save = XmCreateToggleButtonGadget(publish_form, "savePassword", args, n); children[nchildren++] = password_save; #endif XtManageChildren(children, nchildren); w_data->maintain_links = links_toggle; w_data->keep_images = images_toggle; w_data->publish_text = publish_text; w_data->browse_text = browse_text; w_data->username_text = username_text; w_data->password_text = password_text; #ifdef _SECURITY_BTN_ON_PREFS w_data->save_password = password_save; #endif XtVaSetValues(links_toggle, XmNuserData, EDITOR_PUBLISH_LINKS, 0); XtAddCallback(links_toggle, XmNvalueChangedCallback, fe_publish_page_changed, (XtPointer)w_data); XtVaSetValues(images_toggle, XmNuserData, EDITOR_PUBLISH_IMAGES, 0); XtAddCallback(images_toggle, XmNvalueChangedCallback, fe_publish_page_changed, (XtPointer)w_data); XtVaSetValues(publish_text, XmNuserData, EDITOR_PUBLISH_PUBLISH, 0); XtAddCallback(publish_text, XmNvalueChangedCallback, fe_publish_page_changed, (XtPointer)w_data); XtVaSetValues(browse_text, XmNuserData, EDITOR_PUBLISH_BROWSE, 0); XtAddCallback(browse_text, XmNvalueChangedCallback, fe_publish_page_changed, (XtPointer)w_data); XtVaSetValues(username_text, XmNuserData, EDITOR_PUBLISH_USERNAME, 0); XtAddCallback(username_text, XmNvalueChangedCallback, fe_publish_page_changed, (XtPointer)w_data); XtAddCallback(password_text, XmNvalueChangedCallback, fe_publish_password_changed, (XtPointer)w_data); #ifdef _SECURITY_BTN_ON_PREFS XtVaSetValues(password_save, XmNuserData, EDITOR_PUBLISH_PASSWORD_SAVE, 0); XtAddCallback(password_save, XmNvalueChangedCallback, fe_publish_page_changed, (XtPointer)w_data); #endif return main_rc; } typedef struct fe_EditorPreferencesStruct { fe_EditorGeneralPreferencesStruct* general; fe_EditorDocumentAppearancePropertiesStruct* appearance; fe_EditorPublishPreferencesStruct* publish; } fe_EditorPreferencesStruct; static Widget fe_editor_preferences_dialog_create(MWContext* context, fe_EditorPreferencesStruct* p_data) { Widget dialog; Widget form; Widget tab_form; char* name = "editorPreferencesDialog"; /* * Make prompt with ok, apply, cancel, no separator. */ dialog = fe_CreatePromptDialog(context, name, TRUE, TRUE, TRUE, FALSE, TRUE); form = XtVaCreateManagedWidget( "folder", xmlFolderWidgetClass, dialog, XmNshadowThickness, 2, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, #ifdef ALLOW_TAB_ROTATE XmNtabPlacement, XmFOLDER_LEFT, XmNrotateWhenLeftRight, FALSE, #endif /* ALLOW_TAB_ROTATE */ XmNbottomOffset, 3, XmNspacing, 1, NULL); tab_form = fe_CreateTabForm(form, "appearanceProperties", NULL, 0); fe_document_appearance_create(context, tab_form, p_data->appearance); tab_form = fe_CreateTabForm(form, "generalPreferences", NULL, 0); fe_general_preferences_create(context, tab_form, p_data->general); tab_form = fe_CreateTabForm(form, "publishPreferences", NULL, 0); fe_publish_preferences_create(context, tab_form, p_data->publish); XtManageChild(dialog); return form; } void fe_EditorPreferencesDialogDo(MWContext* context, unsigned tab_type) { fe_EditorPreferencesStruct properties; fe_EditorDocumentAppearancePropertiesStruct appearance; fe_EditorGeneralPreferencesStruct general; fe_EditorPublishPreferencesStruct publish; int done; Widget dialog; Widget form; Widget apply_button; Boolean apply_sensitized; unsigned tab_number; /* * Pick the tab. */ tab_number = tab_type - 1; memset(&properties, 0, sizeof(fe_EditorPreferencesStruct)); memset(&appearance, 0, sizeof(fe_EditorDocumentAppearancePropertiesStruct)); memset(&general, 0, sizeof(fe_EditorGeneralPreferencesStruct)); memset(&publish, 0, sizeof(fe_EditorPublishPreferencesStruct)); properties.appearance = &appearance; properties.general = &general; properties.publish = &publish; form = fe_editor_preferences_dialog_create(context, &properties); dialog = XtParent(form); appearance.is_editor_preferences = TRUE; fe_document_appearance_init(context, &appearance); fe_general_preferences_init(context, &general); fe_publish_preferences_init(context, &publish); /* * Add a bunch of callbacks to the buttons. */ XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done); XtAddCallback(dialog, XmNapplyCallback, fe_hrule_apply_cb, &done); XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done); XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done); /* * We toggle the sensitivity of the apply button on/off * depending if there are changes to apply. It would be * nice to use the depdency meahcnism, but it might get * very busy. */ apply_button = XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON); XtVaSetValues(apply_button, XmNsensitive, FALSE, 0); apply_sensitized = FALSE; /* * Popup. */ XtManageChild(form); XmLFolderSetActiveTab(form, tab_number, True); /* * Wait. */ fe_NukeBackingStore(dialog); /* what does this do? */ done = XmDIALOG_NONE; while (done == XmDIALOG_NONE) { fe_EventLoop(); if (done == XFE_DIALOG_DESTROY_BUTTON||done == XmDIALOG_CANCEL_BUTTON) break; #define SOMETHING_CHANGED() \ (appearance.changed != 0 || general.changed != 0 || publish.changed != 0) if (SOMETHING_CHANGED() && apply_sensitized == FALSE) { XtVaSetValues(apply_button, XmNsensitive, TRUE, 0); apply_sensitized = TRUE; } if (done == XmDIALOG_APPLY_BUTTON || done == XmDIALOG_OK_BUTTON) { /* apply */ if (SOMETHING_CHANGED()) { if (!fe_general_preferences_validate(context, &general)) { done = XmDIALOG_NONE; continue; /* you are not going anywhere buddy */ } EDT_BeginBatchChanges(context); if (appearance.changed != 0) { fe_document_appearance_set(context, &appearance); appearance.changed = 0; } if (general.changed != 0) { fe_general_preferences_set(context, &general); general.changed = 0; } if (publish.changed != 0) { fe_publish_preferences_set(context, &publish); publish.changed = 0; } EDT_EndBatchChanges(context); /* * Save options. */ if (!XFE_SavePrefs((char *)fe_globalData.user_prefs_file, &fe_globalPrefs)) { fe_perror(context, XP_GetString(XFE_ERROR_SAVING_OPTIONS)); } else { appearance.changed = 0; general.changed = 0; publish.changed = 0; } } if (done == XmDIALOG_APPLY_BUTTON) { done = XmDIALOG_NONE; /* keep looping */ XtVaSetValues(apply_button, XmNsensitive, FALSE, 0); apply_sensitized = FALSE; } } } #undef SOMETHING_CHANGED /* * Unload data. */ fe_DependentListDestroy(appearance.dependents); if (done != XFE_DIALOG_DESTROY_BUTTON) XtDestroyWidget(dialog); } typedef struct fe_EditorTargetPropertiesStruct { Widget text; Boolean inserting; } fe_EditorTargetPropertiesStruct; static char* cleanup_selection(char* target, char* source, unsigned max_size) { char* p; char* q; char* end; for (p = source; isspace(*p); p++) /* skip beginning whitespace */ ; end = &p[max_size-1]; q = target; while (p < end) { /* * Stop if we detect an unprintable, or newline. */ if (!isprint(*p) || *p == '\n' || *p == '\r') break; if (isspace(*p)) *q++ = ' ', p++; else *q++ = *p++; } /* strip trailing whitespace */ while (q > target && isspace(q[-1])) q--; *q = '\0'; return target; } static void fe_target_properties_init(MWContext* context, fe_EditorTargetPropertiesStruct* w_data) { char* value; char buf[64]; w_data->inserting = FALSE; if (EDT_GetCurrentElementType(context) == ED_ELEMENT_TARGET) { value = EDT_GetTargetData(context); } else { w_data->inserting = TRUE; /* * Use current selected text as suggested target name... */ if ((value = (char*)LO_GetSelectionText(context))) { cleanup_selection(buf, value, sizeof(buf)); XP_FREE(value); value = buf; } else { value = ""; } } /* * Zap text field. */ fe_TextFieldSetString(w_data->text, value, FALSE); } static char* cleanup_string(char* target, char* source, unsigned max_size) { char* p; char* q; char* end; if (max_size == 0) return NULL; for (p = source; isspace(*p); p++) /* skip beginning whitespace */ ; end = &p[max_size-1]; q = target; if (strcmp(p,"")==0) return NULL; while (p < end) { /* * Stop if we detect an unprintable, or newline. */ if (*p == '\"') p++; else *q++ = *p++; } /* strip trailing whitespace */ while (q > target && isspace(q[-1])) q--; *q = '\0'; return target; } static void fe_target_properties_set(MWContext* context, fe_EditorTargetPropertiesStruct* w_data) { char* xm_value; char* value; char* target_list; char buf[512]; xm_value = fe_TextFieldGetString(w_data->text); target_list = EDT_GetAllDocumentTargets(context); /*FIXME*/ /* look at this thing */ value = cleanup_string(buf, xm_value, sizeof(buf)); if (value == NULL) { XtFree(xm_value); return; } EDT_BeginBatchChanges(context); if (value[0] == '#') value++; if (w_data->inserting) EDT_InsertTarget(context, value); else EDT_SetTargetData(context, value); EDT_EndBatchChanges(context); XtFree(xm_value); } static Widget fe_target_properties_create(MWContext* context, Widget form, fe_EditorTargetPropertiesStruct* w_data) { Widget main_rc; Widget label; Widget text; Arg args[8]; Cardinal n; n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; main_rc = XmCreateRowColumn(form, "targetRC", args, n); XtManageChild(main_rc); n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; label = XmCreateLabelGadget(main_rc, "targetLabel", args, n); XtManageChild(label); n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; XtSetArg(args[n], XmNcolumns, 40); n++; /* room to move dude! */ text = fe_CreateTextField(main_rc, "targetText", args, n); XtManageChild(text); w_data->text = text; return main_rc; } void fe_EditorTargetPropertiesDialogDo(MWContext* context) { Widget dialog; Widget form; fe_EditorTargetPropertiesStruct data; int done; /* * Make prompt with ok, no apply, cancel, separator. */ form = fe_CreatePromptDialog(context, "targetPropertiesDialog", TRUE, TRUE, FALSE, TRUE, TRUE); dialog = XtParent(form); fe_target_properties_create(context, form, &data); fe_target_properties_init(context, &data); /* * Add a bunch of callbacks to the buttons. */ XtAddCallback(form, XmNokCallback, fe_hrule_ok_cb, &done); XtAddCallback(form, XmNcancelCallback, fe_hrule_cancel_cb, &done); XtAddCallback(form, XmNdestroyCallback, fe_hrule_destroy_cb, &done); /* * Popup. */ XtManageChild(form); /* * Wait. */ fe_NukeBackingStore(dialog); /* what does this do? */ done = XmDIALOG_NONE; while (done == XmDIALOG_NONE) fe_EventLoop(); if (done == XmDIALOG_OK_BUTTON) fe_target_properties_set(context, &data); if (done != XFE_DIALOG_DESTROY_BUTTON) XtDestroyWidget(dialog); } typedef struct fe_EditorHtmlPropertiesStruct { Widget text; unsigned changed; Boolean inserting; } fe_EditorHtmlPropertiesStruct; static void fe_html_properties_init(MWContext* context, fe_EditorHtmlPropertiesStruct* w_data) { char* value; char buf[64]; w_data->inserting = FALSE; if (EDT_GetCurrentElementType(context) == ED_ELEMENT_UNKNOWN_TAG) { value = EDT_GetUnknownTagData(context); } else { w_data->inserting = TRUE; /* * Use current selected text as suggested target name... */ if ((value = (char*)LO_GetSelectionText(context))) { cleanup_selection(buf, value, sizeof(buf)); XP_FREE(value); value = buf; } else { value = ""; } } /* * Zap text field. */ fe_SetTextFieldAndCallBack(w_data->text, value); w_data->changed = 0; } static void fe_html_properties_set(MWContext* context, fe_EditorHtmlPropertiesStruct* w_data) { char* xm_value; xm_value = fe_TextFieldGetString(w_data->text); EDT_BeginBatchChanges(context); if (EDT_GetCurrentElementType(context) == ED_ELEMENT_UNKNOWN_TAG) EDT_SetUnknownTagData(context, xm_value); else EDT_InsertUnknownTag(context, xm_value); EDT_EndBatchChanges(context); XtFree(xm_value); } Boolean fe_html_properties_verify(MWContext* context, fe_EditorHtmlPropertiesStruct* w_data) { char* xm_value; int id = XFE_EDITOR_TAG_UNKNOWN; /* keep -O happy */ ED_TagValidateResult e; Widget parent; xm_value = fe_TextFieldGetString(w_data->text); e = EDT_ValidateTag(xm_value, FALSE ); switch (e) { case ED_TAG_OK: break; case ED_TAG_UNOPENED: id = XFE_EDITOR_TAG_UNOPENED; /* Unopened Tag: '<' was expected */ break; case ED_TAG_UNCLOSED: id = XFE_EDITOR_TAG_UNCLOSED; /* Unopened Tag: '>' was expected */ break; case ED_TAG_UNTERMINATED_STRING: id = XFE_EDITOR_TAG_UNTERMINATED_STRING; /* Unterminated String in tag: closing quote expected */ break; case ED_TAG_PREMATURE_CLOSE: id = XFE_EDITOR_TAG_PREMATURE_CLOSE; /* Premature close of tag */ break; case ED_TAG_TAGNAME_EXPECTED: id = XFE_EDITOR_TAG_TAGNAME_EXPECTED; /* Tagname was expected */ break; default: id = XFE_EDITOR_TAG_UNKNOWN; /* Unknown tag error */ break; } XtFree(xm_value); parent = w_data->text; if (e == ED_TAG_OK) { return TRUE; } else { fe_error_dialog(context, w_data->text, XP_GetString(id)); return FALSE; } } static void fe_html_text_changed_cb(Widget widget, XtPointer closure, XtPointer cb) { fe_EditorHtmlPropertiesStruct* w_data = (fe_EditorHtmlPropertiesStruct*)closure; w_data->changed = 0x1; } static Widget fe_html_properties_create(MWContext* context, Widget form, fe_EditorHtmlPropertiesStruct* w_data) { Widget main_rc; Widget label; Widget text; Arg args[8]; Cardinal n; n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; main_rc = XmCreateRowColumn(form, "htmlRC", args, n); XtManageChild(main_rc); n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; label = XmCreateLabelGadget(main_rc, "htmlPropertiesInfo", args, n); XtManageChild(label); n = 0; XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg(args[n], XmNcolumns, 70); n++; XtSetArg(args[n], XmNrows, 8); n++; text = XmCreateScrolledText(main_rc, "htmlText", args, n); fe_HackTextTranslations(text); XtAddCallback(text, XmNvalueChangedCallback, fe_html_text_changed_cb, (XtPointer)w_data); XtManageChild(text); w_data->text = text; return main_rc; } void fe_EditorHtmlPropertiesDialogDo(MWContext* context) { Widget dialog; Widget form; Widget ok_button; fe_EditorHtmlPropertiesStruct data; int done; /* * Make prompt with ok, no apply, cancel, separator. */ form = fe_CreatePromptDialog(context, "htmlPropertiesDialog", TRUE, TRUE, TRUE, TRUE, TRUE); dialog = XtParent(form); fe_html_properties_create(context, form, &data); fe_html_properties_init(context, &data); /* * Add a bunch of callbacks to the buttons. */ XtAddCallback(form, XmNokCallback, fe_hrule_ok_cb, &done); XtAddCallback(form, XmNapplyCallback, fe_hrule_apply_cb, &done); XtAddCallback(form, XmNcancelCallback, fe_hrule_cancel_cb, &done); XtAddCallback(form, XmNdestroyCallback, fe_hrule_destroy_cb, &done); ok_button = XmSelectionBoxGetChild(form, XmDIALOG_OK_BUTTON); /* * Popup. */ XtManageChild(form); /* * Wait. */ fe_NukeBackingStore(dialog); /* what does this do? */ done = XmDIALOG_NONE; while (done == XmDIALOG_NONE) { fe_EventLoop(); if (done == XmDIALOG_APPLY_BUTTON || done == XmDIALOG_OK_BUTTON) { if (fe_html_properties_verify(context, &data) == FALSE) { done = XmDIALOG_NONE; } else if (done == XmDIALOG_APPLY_BUTTON) { /* but verified */ /* Tag seems ok */ fe_message_dialog(context, dialog, XP_GetString(XFE_EDITOR_TAG_OK)); done = XmDIALOG_NONE; } } } if (done == XmDIALOG_OK_BUTTON && data.changed != 0) fe_html_properties_set(context, &data); if (done != XFE_DIALOG_DESTROY_BUTTON) XtDestroyWidget(dialog); } char* fe_SimpleTableAlignment[3] = { "left", "center", "right" }; char* fe_SimpleOptionAboveBelow[2] = { "above", "below" }; char* fe_SimpleOptionPixelPercent[2] = { "pixels", "percent" }; char* fe_SimpleOptionHorizontalAlignment[4] = { "default", "left", "center", "right" }; char* fe_SimpleOptionVerticalAlignment[5] = { "default", "top", "center", "bottom", "baselines" }; Widget fe_CreateSimpleOptionMenu(Widget parent, char* name, Arg* p_args, Cardinal p_n) { Widget pulldown; Widget button; Widget option_menu; Widget history_widget = NULL; char namebuf[64]; Arg args[32]; Cardinal n; Cardinal i; char** button_names = NULL; unsigned button_count = 0; unsigned button_set = 0; char* button_name; XtCallbackRec* callback = NULL; strcpy(namebuf, name); strcat(namebuf, "Menu"); n = 0; pulldown = fe_CreatePulldownMenu(parent, namebuf, args, n); n = 0; for (i = 0; i < p_n; i++) { if (p_args[i].name == XmNsimpleCallback) callback = (XtCallbackRec*)p_args[i].value; else if (p_args[i].name == XmNbuttons) button_names = (char**)p_args[i].value; else if (p_args[i].name == XmNbuttonCount) button_count = (unsigned)p_args[i].value; else if (p_args[i].name == XmNbuttonSet) button_set = (unsigned)p_args[i].value; else args[n++] = p_args[i]; } if (button_names == fe_SimpleOptionAboveBelow) button_count = XtNumber(fe_SimpleOptionAboveBelow); else if (button_names == fe_SimpleOptionPixelPercent) button_count = XtNumber(fe_SimpleOptionPixelPercent); else if (button_names == fe_SimpleOptionHorizontalAlignment) button_count = XtNumber(fe_SimpleOptionHorizontalAlignment); else if (button_names == fe_SimpleOptionVerticalAlignment) button_count = XtNumber(fe_SimpleOptionVerticalAlignment); for (i = 0; i < button_count; i++) { if (button_names) { button_name = button_names[i]; } else { sprintf(namebuf, "button%d", i); button_name = namebuf; } button = XmCreatePushButtonGadget(pulldown, button_name, NULL, 0); XtManageChild(button); if (i == button_set) history_widget = button; if (callback != NULL) { XtAddCallback(button, XmNactivateCallback, callback->callback, callback->closure); } } XtSetArg(args[n], XmNsubMenuId, pulldown); n++; option_menu = fe_CreateOptionMenu(parent, name, args, n); fe_UnmanageChild_safe(XmOptionLabelGadget(option_menu)); if (history_widget) XtVaSetValues(option_menu, XmNmenuHistory, history_widget, 0); return option_menu; } #endif /* EDITOR */ #ifdef EDITOR Widget fe_CreateSimpleRadioGroup(Widget parent, char* name, Arg* p_args, Cardinal p_n) { Widget button; Widget option_menu; char namebuf[64]; Arg args[32]; Cardinal n; Cardinal i; char** button_names = NULL; unsigned button_count = 0; unsigned button_set = 0; char* button_name; strcpy(namebuf, name); strcat(namebuf, "Radio"); n = 0; for (i = 0; i < p_n; i++) { if (p_args[i].name == XmNbuttons) button_names = (char**)p_args[i].value; else if (p_args[i].name == XmNbuttonCount) button_count = (unsigned)p_args[i].value; else if (p_args[i].name == XmNbuttonSet) button_set = (unsigned)p_args[i].value; else args[n++] = p_args[i]; } XtSetArg(args[n], XmNradioBehavior, TRUE); n++; option_menu = XmCreateRowColumn(parent, name, args, n); if (button_names == fe_SimpleOptionAboveBelow) button_count = XtNumber(fe_SimpleOptionAboveBelow); else if (button_names == fe_SimpleOptionPixelPercent) button_count = XtNumber(fe_SimpleOptionPixelPercent); else if (button_names == fe_SimpleOptionHorizontalAlignment) button_count = XtNumber(fe_SimpleOptionHorizontalAlignment); else if (button_names == fe_SimpleOptionVerticalAlignment) button_count = XtNumber(fe_SimpleOptionVerticalAlignment); else if (button_names == fe_SimpleTableAlignment) button_count = XtNumber(fe_SimpleTableAlignment); for (i = 0; i < button_count; i++) { if (button_names) { button_name = button_names[i]; } else { sprintf(namebuf, "button%d", i); button_name = namebuf; } n = 0; XtSetArg(args[n], XmNset, (i == button_set)); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; button = XmCreateToggleButtonGadget(option_menu, button_name, args, n); XtManageChild(button); } return option_menu; } void fe_SimpleRadioGroupSetWhich(Widget widget, unsigned which) { Widget* children; Cardinal num_children; Cardinal i; XtVaGetValues(widget, XmNchildren, &children, XmNnumChildren, &num_children, 0); if (which < num_children) { for (i = 0; i < num_children; i++) { XmToggleButtonGadgetSetState(children[i], (i == which), FALSE); } } } void fe_SimpleRadioGroupSetSensitive(Widget widget, Boolean sensitive) { Widget* children; Cardinal num_children; Cardinal i; XtVaGetValues(widget, XmNchildren, &children, XmNnumChildren, &num_children, 0); for (i = 0; i < num_children; i++) { XtVaSetValues(children[i], XmNsensitive, sensitive, 0); } } int fe_SimpleRadioGroupGetWhich(Widget widget) { Widget* children; Cardinal num_children; Cardinal i; XtVaGetValues(widget, XmNchildren, &children, XmNnumChildren, &num_children, 0); for (i = 0; i < num_children; i++) { if (XmToggleButtonGadgetGetState(children[i]) == TRUE) return i; } return -1; /* ?? */ } Widget fe_SimpleRadioGroupGetChild(Widget widget, unsigned n) { Widget* children; Cardinal num_children; XtVaGetValues(widget, XmNchildren, &children, XmNnumChildren, &num_children, 0); if (n < num_children) return children[n]; else return NULL; } unsigned fe_ED_Alignment_to_index(ED_Alignment type) { switch (type) { case ED_ALIGN_LEFT: case ED_ALIGN_ABSTOP: case ED_ALIGN_TOP: return 1; case ED_ALIGN_CENTER: case ED_ALIGN_ABSCENTER: return 2; case ED_ALIGN_RIGHT: case ED_ALIGN_BOTTOM: case ED_ALIGN_ABSBOTTOM: return 3; case ED_ALIGN_BASELINE: return 4; case ED_ALIGN_DEFAULT: default: return 0; } } #if 0 static void check_children(Widget* children, Cardinal nchildren) { Widget widget; Widget parent; int i; for (i = 0; i < nchildren; i++) { widget = children[i]; parent = XtParent(widget); fprintf(real_stderr, "parent(%s) = %s, ", XtName(widget), XtName(parent)); } fprintf(real_stderr, "\n"); } #endif #define RGB_TO(r,g,b) (((r)<<16)+((g)<<8)+(b)) #define R_FROM(l) (((l)>>16)&0xff) #define G_FROM(l) (((l)>>8)&0xff) #define B_FROM(l) ((l)&0xff) void fe_NewSwatchSetColor(Widget widget, LO_Color* color) { unsigned long pack_color = 0; if (color) pack_color = RGB_TO(color->red, color->green, color->blue); XtVaSetValues(widget, XmNuserData, pack_color, 0); fe_SwatchSetColor(widget, color); } LO_Color* fe_NewSwatchGetColor(Widget widget, LO_Color* color) { unsigned long pack_color; XtVaGetValues(widget, XmNuserData, &pack_color, 0); color->red = R_FROM(pack_color); color->green = G_FROM(pack_color); color->blue = B_FROM(pack_color); return color; } void fe_bg_group_use_color_cb(Widget widget, XtPointer closure, XtPointer cbd) { XmToggleButtonCallbackStruct* cbs = (XmToggleButtonCallbackStruct*)cbd; Widget swatch = (Widget)closure; fe_WidgetSetSensitive(swatch, cbs->set); } void fe_bg_group_swatch_cb(Widget widget, XtPointer closure, XtPointer cbd) { MWContext* context = fe_WidgetToMWContext(widget); LO_Color color; Widget toggle = (Widget)closure; fe_NewSwatchGetColor(widget, &color); if (fe_ColorPicker(context, &color)) { fe_NewSwatchSetColor(widget, &color); XmToggleButtonSetState(toggle, TRUE, FALSE); } } void fe_bg_use_image_cb(Widget widget, XtPointer closure, XtPointer cbd) { XmToggleButtonCallbackStruct* cbs = (XmToggleButtonCallbackStruct*)cbd; MWContext* context = fe_WidgetToMWContext(widget); Widget text_widget = (Widget)closure; fe_TextFieldSetEditable(context, text_widget, cbs->set); } void fe_bg_image_browse_cb(Widget widget, XtPointer closure, XtPointer cbd) { MWContext* context = fe_WidgetToMWContext(widget); Widget text_widget = (Widget)closure; fe_url_browse_file_of_text(context, text_widget); } static void fe_cancel_button_set_cancel(Widget widget, Boolean can_cancel) { char* name; char* string; XmString xm_string; if (can_cancel) name = "cancelLabelString"; else name = "closeLabelString"; string = XfeSubResourceGetWidgetStringValue(widget, name, XmCXmString); if (!string) string = name; xm_string = XmStringCreateLocalized(string); XtVaSetValues(widget, XmNlabelString, xm_string, 0); XmStringFree(xm_string); } typedef struct fe_PublishDialogStruct { MWContext* context; Widget local_publish_info; Widget local_include_images; Widget local_include_files; Widget local_list; Widget local_select_all; Widget local_select_none; Widget publish_combo; Widget publish_location_text; Widget publish_username_text; Widget publish_password_text; Widget publish_save_password; Widget publish_use_default; Widget title_text; char* url_pathname; char** files; } fe_PublishDialogStruct; static void fe_publish_set_xmlist_from_data(fe_PublishDialogStruct* w_data) { unsigned n; XmString xm_string; char* s; char* tmp; XmListDeleteAllItems(w_data->local_list); if (w_data->files == NULL) return; for (n = 0; w_data->files[n] != NULL; n++) { s = w_data->files[n]; tmp = NULL; #if 0 dirlen = strlen(w_data->directory); /* windows does not clean this up, let's see how we go */ if (strncmp(s, w_data->directory, dirlen) == 0 && s[dirlen] == '/') { tmp = XP_STRDUP(&s[dirlen+1]); s = tmp; } #endif xm_string = XmStringCreateLocalized(s); XmListAddItem(w_data->local_list, xm_string, n+1); XmStringFree(xm_string); if (tmp != NULL) XP_FREE(tmp); } } static void fe_publish_include_select_all(fe_PublishDialogStruct* w_data) { unsigned n; unsigned nitems; XtVaGetValues(w_data->local_list, XmNitemCount, &nitems, 0); for (n = 0; n < nitems; n++) XmListSelectPos(w_data->local_list, n+1, FALSE); } static void free_string_array(char** vector) { unsigned n; if (vector) { for (n = 0; vector[n] != NULL; n++) XP_FREE(vector[n]); XP_FREE(vector); } } static void fe_publish_set_include_all_files(fe_PublishDialogStruct* w_data) { MWContext* context = w_data->context; char** all_files; unsigned nfiles; char* local_filename; char* p; free_string_array(w_data->files); XP_ConvertUrlToLocalFile(w_data->url_pathname, &local_filename); if (!local_filename) /* oops */ return; /* get the directory name */ p = XP_STRRCHR(local_filename, '/'); if (p != NULL && p != local_filename) *p = '\0'; all_files = NET_AssembleAllFilesInDirectory(context, local_filename); nfiles = 0; if (all_files != NULL) { for (; all_files[nfiles] != NULL; nfiles++) { p = all_files[nfiles]; if (*p == '/') { /* absolute */ p = (char*)XP_ALLOC(XP_STRLEN(p) + 6); XP_STRCPY(p, "file:"); XP_STRCAT(p, all_files[nfiles]); XP_FREE(all_files[nfiles]); all_files[nfiles] = p; } } } if (nfiles > 0) { w_data->files = all_files; } else { w_data->files = NULL; } fe_publish_set_xmlist_from_data(w_data); fe_publish_include_select_all(w_data); XmToggleButtonGadgetSetState(w_data->local_include_images, FALSE, FALSE); XmToggleButtonGadgetSetState(w_data->local_include_files, TRUE, FALSE); XP_FREE(local_filename); } static void fe_publish_set_include_image_files(fe_PublishDialogStruct* w_data) { MWContext* context = w_data->context; unsigned len; char* s; unsigned n; unsigned nfiles; char* filenames; XP_Bool* selected = NULL; Boolean links_p; free_string_array(w_data->files); fe_EditorPreferencesGetLinksAndImages(context, NULL, &links_p); filenames = EDT_GetAllDocumentFilesSelected(context, &selected, links_p); nfiles = 0; if (filenames != NULL && selected != NULL) { for (s = filenames; (len = XP_STRLEN(s)) != 0; s += len + 1) nfiles++; } if (nfiles > 0) { w_data->files = (char**)XP_ALLOC((nfiles+1)*sizeof(char*)); for (n = 0, s = filenames; *s != '\0'; n++, s += XP_STRLEN(s) + 1) { w_data->files[n] = XP_STRDUP(s); } w_data->files[n] = NULL; } else { w_data->files = NULL; } XP_FREEIF(filenames); fe_publish_set_xmlist_from_data(w_data); /* Files that are selected by default. */ for (n = 0; n < nfiles; n++) { if (selected[n]) { XmListSelectPos(w_data->local_list, n+1, FALSE); } } XP_FREEIF(selected); /* * Gray out if there are no images in doc. */ #if 0 XtVaSetValues(w_data->local_include_images, XmNsensitive, (nfiles > 0), 0); #endif XmToggleButtonGadgetSetState(w_data->local_include_images, TRUE, FALSE); XmToggleButtonGadgetSetState(w_data->local_include_files, FALSE, FALSE); } static void fe_publish_include_image_files_cb(Widget widget, XtPointer closure, XtPointer cb_data) { XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)cb_data; fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure; if (!info->set) return; fe_publish_set_include_image_files(w_data); } static void fe_publish_include_all_files_cb(Widget widget, XtPointer closure, XtPointer cb_data) { XmToggleButtonCallbackStruct* info = (XmToggleButtonCallbackStruct*)cb_data; fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure; if (!info->set) return; fe_publish_set_include_all_files(w_data); } static void fe_publish_include_select_none_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure; XmListDeselectAllItems(w_data->local_list); } static void fe_publish_include_select_all_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure; fe_publish_include_select_all(w_data); } static void fe_publish_set_lup(fe_PublishDialogStruct* w_data, char* location, char* username, char* password) { if (location) { fe_TextFieldSetString(w_data->publish_location_text, location, FALSE); if (username) { fe_TextFieldSetString(w_data->publish_username_text, username, FALSE); } else { fe_TextFieldSetString(w_data->publish_username_text, "", FALSE); } if (password) { fe_TextFieldSetString(w_data->publish_password_text, password, FALSE); XtVaSetValues(w_data->publish_save_password, XmNset, TRUE, 0); } else { fe_TextFieldSetString(w_data->publish_password_text, "", FALSE); XtVaSetValues(w_data->publish_save_password, XmNset, FALSE, 0); } } } static void fe_publish_combo_selection_cb(Widget w, XtPointer closure, XtPointer cb_data) { fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure; DtComboBoxCallbackStruct* info = (DtComboBoxCallbackStruct*)cb_data; char* location; char* username; char* password; if (EDT_GetPublishingHistory(info->item_position, &location, &username, &password)) { #if 0 /* combo callback has already screwed us */ char* target_file; char* last; int len; /* * If the new location is a directory, try to append the * basename of the existing target onto the new location. */ target_file = fe_TextFieldGetString(w_data->publish_location_text); if ((last = XP_STRRCHR(target_file, '/')) != NULL) last++; else last = target_file; len = XP_STRLEN(location); if (last != NULL && len > 0 && location[len-1] == '/') { char* tmp; len = len + XP_STRLEN(location) + 1; tmp = (char*)XP_ALLOC(len); XP_STRCPY(tmp, location); XP_STRCAT(tmp, last); XP_FREE(location); location = tmp; } XtFree(target_file); #endif fe_publish_set_lup(w_data, location, username, password); if (location != NULL) XP_FREE(location); if (username != NULL) XP_FREE(username); if (password != NULL) { memset(password, 0, strlen(password)); XP_FREE(password); } } } static void fe_publish_use_default_cb(Widget widget, XtPointer closure, XtPointer cb_data) { fe_PublishDialogStruct* w_data = (fe_PublishDialogStruct*)closure; char* location; char* username; char* password; fe_EditorPreferencesGetPublishLocation(w_data->context, &location, &username, &password); if (location) { fe_publish_set_lup(w_data, location, username, password); if (location != NULL) XP_FREE(location); if (username != NULL) XP_FREE(username); if (password != NULL) { memset(password, 0, strlen(password)); XP_FREE(password); } } } static void fe_publish_dialog_init(MWContext* context, fe_PublishDialogStruct* w_data) { XmString xm_string; History_entry* hist_ent; char buf[MAXPATHLEN]; char* location_dir; char* location_file; char* location; char* username; char* password; char* title; Boolean has_default; Boolean save_password; int n; w_data->url_pathname = NULL; /* get the location */ hist_ent = SHIST_GetCurrent(&context->hist); if(hist_ent && hist_ent->address) { w_data->url_pathname = XP_STRDUP(hist_ent->address); FE_CondenseURL(buf, w_data->url_pathname, 40); xm_string = XmStringCreateLtoR(buf,XmFONTLIST_DEFAULT_TAG); XtVaSetValues(w_data->local_publish_info, XmNlabelString, xm_string, 0); XmStringFree(xm_string); } fe_publish_set_include_image_files(w_data); location_file = username = password = NULL; /* settle over-zealous BE */ location_dir = EDT_GetDefaultPublishURL(context, &location_file, &username, &password); /* * Set the title */ if (!(title = fe_EditorDocumentGetTitle(context))) title = EDT_GetPageTitleFromFilename(location_file); if (title != NULL) { fe_TextFieldSetString(w_data->title_text, title, False); XP_FREE(title); } else { fe_TextFieldSetString(w_data->title_text, "", False); } XtVaSetValues(w_data->local_include_files, XmNsensitive, (NET_IsLocalFileURL(w_data->url_pathname)), 0); /* * Set the history list first, as comobo will always callback * on text field and set the location - we don't always want that. */ for (n = 0; EDT_GetPublishingHistory(n, &location, 0, 0); n++) { xm_string = XmStringCreateLocalized(location); DtComboBoxAddItem(w_data->publish_combo, xm_string, n + 1, FALSE); XmStringFree(xm_string); XP_FREE(location); } if (n > 0) { XtVaSetValues(w_data->publish_combo, XmNvisibleItemCount, (XtPointer)n, 0); } else { Widget arrow = XtNameToWidget(w_data->publish_combo, "ComboBoxArrow"); XtVaSetValues(arrow, XmNsensitive, False, 0); } /* * Setup lower half of dialog. */ if (location_dir != NULL) { n = XP_STRLEN(location_dir) + 1; if (location_file != NULL) n += XP_STRLEN(location_file) + 1; location = (char*)XP_ALLOC(n); XP_STRCPY(location, location_dir); if (location_file != NULL) XP_STRCAT(location, location_file); } else { location = NULL; } save_password = (password != NULL); if (location) { fe_TextFieldSetString(w_data->publish_location_text, location, FALSE); XP_FREE(location); } if (username) { fe_TextFieldSetString(w_data->publish_username_text, username, FALSE); XP_FREE(username); } if (password) { fe_TextFieldSetString(w_data->publish_password_text, password, FALSE); memset(password, 0, strlen(password)); XP_FREE(password); } /* * Enable "Use Default Location"? */ fe_EditorPreferencesGetPublishLocation(context, &location, NULL, NULL); if (location) { has_default = TRUE; XP_FREE(location); } else { has_default = FALSE; } XtVaSetValues(w_data->publish_use_default, XmNsensitive, has_default, 0); XtVaSetValues(w_data->publish_save_password, XmNset, save_password, 0); } Boolean fe_EditorPublishFiles(MWContext* context, char* target_file, char** source_files, char* username, char* password) { char* full_location = NULL; /* MUST set to NULL */ Boolean rv; Boolean links; Boolean images; char* primary_url = NULL; History_entry* hist_entry; rv = NET_MakeUploadURL(&full_location, target_file, username, password); if (rv && full_location != NULL) { /* Get current history entry for source location */ hist_entry = SHIST_GetCurrent(&context->hist); if (hist_entry != NULL && hist_entry->address != NULL && hist_entry->address[0] != '\0') { primary_url = hist_entry->address; } else { /* no source name. */ /* Is there a define for file:///Untitled somewhere? */ primary_url = "file:///Untitled"; } fe_EditorPreferencesGetLinksAndImages(context, &links, &images); /* * NOTE: we must donate source_files to the back-end, * it will be freed there. All other arguments we own. */ EDT_PublishFile(context, ED_FINISHED_REVERT_BUFFER, primary_url, source_files, full_location, images, links, FALSE); XP_FREE(full_location); return TRUE; } else { return FALSE; } } static Boolean fe_publish_dialog_validate(MWContext* context, fe_PublishDialogStruct* w_data) { char* target_file; Boolean rv = TRUE; target_file = fe_TextFieldGetString(w_data->publish_location_text); fe_StringTrim(target_file); /* * Use new call in BE. This guy also posts the alert (via FE_Confirm). * So we don't need to do a dialog ourselves. But, we don't get to * place it either, sigh. */ if (!EDT_CheckPublishURL(context, target_file)) rv = FALSE; XtFree(target_file); return rv; } static void fe_publish_dialog_set(MWContext* context, fe_PublishDialogStruct* w_data) { int* items; int nitems; int n; int item; char* target_file; char* username; char* password; char** source_files; Boolean save_password; char* title; XmListGetSelectedPos(w_data->local_list, &items, &nitems); source_files = (char**)XP_ALLOC(sizeof(char*) * (nitems + 2)); for (n = 0; n < nitems; n++) { item = items[n] - 1; /* XmList offset */ source_files[n] = XP_STRDUP(w_data->files[item]); /* must do this */ } source_files[n] = NULL; if (nitems > 0 && items != NULL) /* sometimes get non-zero items */ XtFree((void*)items); target_file = fe_TextFieldGetString(w_data->publish_location_text); username = fe_TextFieldGetString(w_data->publish_username_text); password = fe_GetPasswdText(w_data->publish_password_text); fe_StringTrim(target_file); fe_StringTrim(username); fe_StringTrim(password); /* * Save the location for next time. * * Ok, this is totally wierd (but totally Motif). We were * doing a GetValues() here, and we were doing it after the * call to PublishFiles(). We would die in Xt event dispatch, * with looked like a bogus mapnotify event. I suspect that * this had something to do with the GetValues. PushBG's * GetValues() does seem someone complicated, so 1) let's use * a GetState() call (which just reads the boolean value in * the widget), and do this before the call to publish, * which we should probably do anyway. */ save_password = XmToggleButtonGadgetGetState(w_data->publish_save_password); fe_EditorDefaultSetLastPublishLocation(context, target_file, username, save_password? password: NULL); /* title */ title = fe_TextFieldGetString(w_data->title_text); if (title != NULL) { fe_EditorDocumentSetTitle(context, title); XtFree(title); } fe_EditorPublishFiles(context, target_file, source_files, username, password); XtFree(target_file); XtFree(username); memset(password, 0, strlen(password)); XtFree(password); } static void fe_publish_dialog_delete(MWContext* context, fe_PublishDialogStruct* w_data) { if (w_data->url_pathname) XtFree(w_data->url_pathname); free_string_array(w_data->files); } static void fe_publish_dialog_create(MWContext* context, Widget parent, fe_PublishDialogStruct* w_data) { Widget form; Widget local_frame; Widget local_form; Widget local_publish_label; Widget local_publish_info; Widget local_include_label; Widget local_include_radio; Widget local_include_files; Widget local_include_images; Widget local_select_none; Widget local_select_all; Widget local_list; Widget list_parent; Widget publish_frame; Widget publish_form; Widget publish_label; Widget publish_drop; Widget publish_username_label; Widget publish_username_text; Widget publish_use_default; Widget publish_password_label; Widget publish_password_text; Widget publish_password_save; Widget title_frame; Widget title_text; Widget children[16]; Cardinal nchildren; Cardinal n; Arg args[16]; Dimension left_offset; Pixel parent_bg; Pixel select_bg; Dimension width; Widget fat_guy; Visual *v = 0; Colormap cmap = 0; Cardinal depth = 0; n = 0; form = XmCreateForm(parent, "publish", args, n); XtManageChild(form); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; local_frame = fe_CreateFrame(form, "localFiles", args, n); XtManageChild(local_frame); n = 0; local_form = XmCreateForm(local_frame, "localFiles", args, n); XtManageChild(local_form); nchildren = 0; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; local_publish_label = XmCreateLabelGadget(local_form, "publishLabel", args, n); children[nchildren++] = local_publish_label; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; local_include_label = XmCreateLabelGadget(local_form, "includeLabel", args, n); children[nchildren++] = local_include_label; n = 0; local_select_none = XmCreatePushButtonGadget(local_form, "selectNone", args, n); children[nchildren++] = local_select_none; n = 0; local_select_all = XmCreatePushButtonGadget(local_form, "selectAll", args, n); children[nchildren++] = local_select_all; left_offset = fe_get_offset_from_widest(children, nchildren); fat_guy = XfeBiggestWidget(TRUE, &children[nchildren-2], 2); XtVaGetValues(fat_guy, XmNwidth, &width, 0); n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; local_publish_info = XmCreateLabelGadget(local_form, "publishInfo", args, n); children[nchildren++] = local_publish_info; n = 0; XtSetArg(args[n], XmNradioBehavior, TRUE); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; local_include_radio = XmCreateRowColumn(local_form, "includeRadio", args, n); children[nchildren++] = local_include_radio; n = 0; XtSetArg(args[n], XmNbackground, &parent_bg); n++; XtGetValues(local_form, args, n); XmGetColors(XtScreen(parent), fe_cmap(context), parent_bg, NULL, NULL, NULL, &select_bg); n = 0; XtSetArg(args[n], XmNvisibleItemCount, 5); n++; XtSetArg(args[n], XmNselectionPolicy, XmMULTIPLE_SELECT); n++; XtSetArg(args[n], XmNbackground, select_bg); n++; local_list = XmCreateScrolledList(local_form, "includeList", args, n); children[nchildren++] = list_parent = XtParent(local_list); /* * Now do attachments. */ n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetValues(local_publish_label, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, local_publish_info); n++; XtSetValues(local_include_label, args, n); #if 0 n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, local_include_label); n++; XtSetArg(args[n], XmNwidth, width); n++; XtSetValues(local_select_none, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, local_select_none); n++; XtSetArg(args[n], XmNwidth, width); n++; XtSetValues(local_select_all, args, n); #else n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, local_select_all); n++; XtSetArg(args[n], XmNwidth, width); n++; XtSetValues(local_select_none, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; #if 0 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; #else XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, list_parent); n++; #endif XtSetArg(args[n], XmNwidth, width); n++; XtSetValues(local_select_all, args, n); #endif n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetValues(local_publish_info, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, local_publish_info); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, local_publish_info); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetValues(local_include_radio, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, local_include_radio); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, local_publish_info); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; #if 0 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; #endif XtSetValues(list_parent, args, n); XtManageChildren(children, nchildren); nchildren = 0; n = 0; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; local_include_images = XmCreateToggleButtonGadget(local_include_radio, "includeImages", args, n); children[nchildren++] = local_include_images; n = 0; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; local_include_files = XmCreateToggleButtonGadget(local_include_radio, "includeAll", args, n); children[nchildren++] = local_include_files; XtManageChildren(children, nchildren); XtManageChild(local_list); XtAddCallback(local_select_none, XmNactivateCallback, fe_publish_include_select_none_cb, (XtPointer)w_data); XtAddCallback(local_select_all, XmNactivateCallback, fe_publish_include_select_all_cb, (XtPointer)w_data); XtAddCallback(local_include_images, XmNvalueChangedCallback, fe_publish_include_image_files_cb, (XtPointer)w_data); XtAddCallback(local_include_files, XmNvalueChangedCallback, fe_publish_include_all_files_cb, (XtPointer)w_data); /* * Title group. */ n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, local_frame); n++; title_frame = fe_CreateFrame(form, "titleFrame", args, n); XtManageChild(title_frame); n = 0; title_text = fe_CreateTextField(title_frame, "titleText", args, n); XtManageChild(title_text); /* * Publish group. */ n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, title_frame); n++; publish_frame = fe_CreateFrame(form, "publishLocation", args, n); XtManageChild(publish_frame); n = 0; publish_form = XmCreateForm(publish_frame, "publishLocation", args, n); XtManageChild(publish_form); nchildren = 0; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; publish_label = XmCreateLabelGadget(publish_form, "publishLabel", args, n); children[nchildren++] = publish_label; n = 0; #if 0 publish_drop = fe_CreateTextField(publish_form, "publishDrop", args, n); #else XtVaGetValues(CONTEXT_WIDGET(context), XtNvisual, &v, XtNcolormap, &cmap, XtNdepth, &depth, 0); n = 0; XtSetArg(args[n], XmNvisual, v); n++; XtSetArg(args[n], XmNdepth, depth); n++; XtSetArg(args[n], XmNcolormap, cmap); n++; XtSetArg(args[n], XmNtype, XmDROP_DOWN_COMBO_BOX); n++; XtSetArg(args[n], XmNshadowThickness, 1); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; XtSetArg(args[n], XmNarrowType, XmMOTIF); n++; XtSetArg(args[n], XmNupdateLabel, False); n++; publish_drop = DtCreateComboBox(publish_form, "publishDrop", args, n); XtAddCallback(publish_drop, XmNselectionCallback, fe_publish_combo_selection_cb, w_data); #endif children[nchildren++] = publish_drop; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; publish_username_label = XmCreateLabelGadget(publish_form, "usernameLabel", args, n); children[nchildren++] = publish_username_label; n = 0; XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; publish_password_label = XmCreateLabelGadget(publish_form, "passwordLabel", args, n); children[nchildren++] = publish_password_label; left_offset = fe_get_offset_from_widest(&children[nchildren-2], 2); n = 0; publish_username_text = fe_CreateTextField(publish_form, "usernameText", args, n); children[nchildren++] = publish_username_text; n = 0; publish_use_default = XmCreatePushButtonGadget(publish_form, "useDefault", args, n); children[nchildren++] = publish_use_default; XtAddCallback(publish_use_default, XmNactivateCallback, fe_publish_use_default_cb, (XtPointer)w_data); n = 0; XtSetArg(args[n], XmNmaxLength, 1024); n++; publish_password_text = fe_CreatePasswordField(publish_form, "passwordText", args, n); children[nchildren++] = publish_password_text; n = 0; publish_password_save = XmCreateToggleButtonGadget(publish_form, "savePassword", args, n); children[nchildren++] = publish_password_save; /* * Attachments. */ n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetValues(publish_label, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, publish_label); n++; XtSetValues(publish_drop, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, publish_drop); n++; XtSetValues(publish_username_label, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, publish_username_text); n++; XtSetValues(publish_password_label, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, publish_drop); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, left_offset); n++; XtSetValues(publish_username_text, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, publish_username_text); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, publish_username_text); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, publish_username_text); n++; XtSetValues(publish_password_text, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, publish_username_text); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, publish_drop); n++; XtSetValues(publish_use_default, args, n); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, publish_use_default); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, publish_username_text); n++; XtSetValues(publish_password_save, args, n); XtManageChildren(children, nchildren); w_data->local_publish_info = local_publish_info; w_data->local_include_images = local_include_images; w_data->local_include_files = local_include_files; w_data->local_list = local_list; w_data->local_select_all = local_select_all; w_data->local_select_none = local_select_none; w_data->publish_combo = publish_drop; XtVaGetValues(publish_drop, XmNtextField, &w_data->publish_location_text, 0); w_data->title_text = title_text; w_data->publish_username_text = publish_username_text; w_data->publish_password_text = publish_password_text; w_data->publish_save_password = publish_password_save; w_data->publish_use_default = publish_use_default; w_data->context = context; w_data->url_pathname = NULL; w_data->files = NULL; } Boolean fe_EditorPublishDialogDo(MWContext* context) { fe_PublishDialogStruct publish; Widget dialog; int done; Boolean rv; /* * Make prompt with ok, cancel, no apply, separator. */ dialog = fe_CreatePromptDialog(context, "publishFilesDialog", TRUE, TRUE, FALSE, FALSE, TRUE); fe_publish_dialog_create(context, dialog, &publish); fe_publish_dialog_init(context, &publish); /* * Add a bunch of callbacks to the buttons. */ XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done); XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done); XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done); /* * Popup. */ XtManageChild(dialog); /* * Wait. */ fe_NukeBackingStore(dialog); /* what does this do? */ done = XmDIALOG_NONE; while (done == XmDIALOG_NONE) { fe_EventLoop(); if (done == XmDIALOG_OK_BUTTON) { if (!fe_publish_dialog_validate(context, &publish)) { done = XmDIALOG_NONE; } } } /* something is wrong here - benjie */ /* if you put in a wrong domain, but with http:// and ftp:// * the following call will fail, and then we loose btn callback * action and hangs, the problem traces to the exit routine * we send in to NET_GetURL. For the editor, the exit routine, * after poping up the error message, calls fe_EditorGetURLExitRoutine, * which calls fe_EventLoop, and the code loops in there, but don't * pick up click actions on the buttons in this dialog */ /* ok, so the following line temporarilly fix the above problem * by poping down the modal dialog. * this fixes 26903. - benjie */ XtUnmanageChild(dialog); if (done == XmDIALOG_OK_BUTTON) { fe_publish_dialog_set(context, &publish); rv = TRUE; } else { rv = FALSE; } fe_publish_dialog_delete(context, &publish); if (done != XFE_DIALOG_DESTROY_BUTTON) XtDestroyWidget(dialog); return rv; } int fe_YesNoCancelDialog(MWContext* context, char* name, char* message) { Widget dialog; Widget mainw = CONTEXT_WIDGET(context); Widget yes_button; Widget no_button; Arg args[8]; Cardinal n; Visual* v; Colormap cmap; Cardinal depth; int done; XmString xm_message; /* * Popup the shell first, so that we gurantee its realized */ XtPopup(mainw, XtGrabNone); /* * Force the window to the front and de-iconify if needed */ XMapRaised(XtDisplay(mainw), XtWindow(mainw)); XtVaGetValues(mainw, XtNvisual, &v, XtNcolormap, &cmap, XtNdepth, &depth, 0); xm_message = XmStringCreateLtoR(message,XmFONTLIST_DEFAULT_TAG); n = 0; XtSetArg(args[n], XmNvisual, v); n++; XtSetArg(args[n], XmNdepth, depth); n++; XtSetArg(args[n], XmNcolormap, cmap); n++; XtSetArg(args[n], XmNtransientFor, mainw); n++; XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); n++; XtSetArg(args[n], XmNdefaultButtonType, XmDIALOG_OK_BUTTON); n++; XtSetArg(args[n], XmNmessageString, xm_message); n++; dialog = XmCreateMessageDialog(mainw, name, args, n); XmStringFree(xm_message); /* Doesn't work as a create argument :-) */ n = 0; XtSetArg(args[n], XmNdialogType, XmDIALOG_QUESTION); n++; XtSetValues(dialog, args, n); #ifdef NO_HELP fe_UnmanageChild_safe(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON)); #endif n = 0; yes_button = XmCreatePushButtonGadget(dialog, "yes", args, n); XtManageChild(yes_button); n = 0; no_button = XmCreatePushButtonGadget(dialog, "no", args, n); XtManageChild(no_button); fe_UnmanageChild_safe(XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON)); XtAddCallback(dialog, XmNcancelCallback, fe_hrule_cancel_cb, &done); XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done); XtAddCallback(yes_button, XmNactivateCallback, fe_hrule_ok_cb, &done); XtAddCallback(no_button, XmNactivateCallback, fe_hrule_apply_cb, &done); XtManageChild(dialog); done = XmDIALOG_NONE; while (done == XmDIALOG_NONE) { fe_EventLoop(); } return done; } Boolean fe_HintDialog(MWContext* context, char* message) { Widget dialog; Widget mainw = CONTEXT_WIDGET(context); Arg args[8]; Cardinal n; Visual* v; Colormap cmap; Cardinal depth; int done; Widget toggle_button; Widget toggle_row; XmString xm_message; Boolean return_value; XtVaGetValues(mainw, XtNvisual, &v, XtNcolormap, &cmap, XtNdepth, &depth, 0); xm_message = XmStringCreateLocalized(message); n = 0; XtSetArg(args[n], XmNvisual, v); n++; XtSetArg(args[n], XmNdepth, depth); n++; XtSetArg(args[n], XmNcolormap, cmap); n++; XtSetArg(args[n], XmNtransientFor, mainw); n++; XtSetArg(args[n], XmNdefaultButtonType, XmDIALOG_OK_BUTTON); n++; XtSetArg(args[n], XmNmessageString, xm_message); n++; dialog = XmCreateInformationDialog(mainw, "hintDialog", args, n); XmStringFree(xm_message); /* * This is sooooooo lame. Dispite what the manual says, an * additonal toggle button child is not placed above the push * buttons, but rather along aside the. Stick the toggle in * a row, just to get the thing to do what we want. */ n = 0; toggle_row = XmCreateRowColumn(dialog, "dontDisplayAgainRow", args, n); XtManageChild(toggle_row); n = 0; XtSetArg(args [n], XmNindicatorType, XmN_OF_MANY); n++; toggle_button = XmCreateToggleButtonGadget(toggle_row, "dontDisplayAgain", args, n); XtManageChild(toggle_button); fe_UnmanageChild_safe(XmMessageBoxGetChild(dialog,XmDIALOG_CANCEL_BUTTON)); #ifdef NO_HELP fe_UnmanageChild_safe(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON)); #endif XtAddCallback(dialog, XmNokCallback, fe_hrule_ok_cb, &done); XtAddCallback(dialog, XmNdestroyCallback, fe_hrule_destroy_cb, &done); XtManageChild(dialog); done = XmDIALOG_NONE; while (done == XmDIALOG_NONE) { fe_EventLoop(); } if (done != XFE_DIALOG_DESTROY_BUTTON) { return_value = XmToggleButtonGetState(toggle_button); XtDestroyWidget(dialog); return return_value; } return FALSE; } #endif