#define HAVE_TEST /* * $Id: io-motif.c,v 1.66 2001/03/09 11:33:29 danny Exp $ * * This file is part of Oleo, the GNU spreadsheet. * * Copyright © 1998-2000 by the Free Software Foundation, Inc. * Written by Danny Backx . * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ static char rcsid[] = "$Id: io-motif.c,v 1.66 2001/03/09 11:33:29 danny Exp $"; #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WITH_DMALLOC #include #endif #include #include #include #include #include #include #ifdef HAVE_LOCALE_H #include #endif #include #include #include #include #include #include #ifdef HAVE_XLT #include #ifndef HAVE_SciPlot_H #define HAVE_SciPlot_H #endif #else #ifdef HAVE_SciPlot_H #include #endif #endif #ifdef HAVE_LIBXPM #include #include "oleo_icon.xpm" #endif #include "global.h" #ifdef HAVE_LIBPLOT #include #include "sciplot.h" #endif #include "oleo_plot.h" #ifdef HAVE_LIBMYSQLCLIENT #include #endif #include "oleosql.h" #ifdef HAVE_LIBCUPS #include #endif #include "utils.h" #include "io-generic.h" #include "io-edit.h" #include "io-utils.h" #include "io-term.h" #include "cmd.h" #include "window.h" #include "line.h" #include "font.h" #include "lists.h" #include "ir.h" #include "display.h" #include "io-abstract.h" #include "regions.h" #include "input.h" #include "info.h" #include "eval.h" #include "basic.h" #include "graph.h" #include "print.h" #include "mdi.h" #include "userpref.h" #include "io-motif.h" /* To get warnings when inconsistent */ #ifdef HAVE_XmHTML_H #include #endif static Widget w; /* Fallback resources, application resources */ extern char *fallback[]; #include "appres.h" GnuSheetAppres AppRes; /* Forward declarations */ void CancelTemplate(Widget w, XtPointer client, XtPointer call); void DestroyTemplate(Widget w, XtPointer client, XtPointer call); static void FixA0(); static void PopDownSplash(); static void UpdateStatus(void); void helpUsingCB(Widget w, XtPointer client, XtPointer call); static void MotifSelectGlobal(Widget); Widget GscBuildMainWindow(Widget parent); void DestroyToplevel(Widget w, XtPointer client, XtPointer call); Widget ConfigureBarChart(Widget parent); Widget ConfigurePieChart(Widget parent); Widget ConfigureXYChart(Widget parent); void ConfigureXYOk(void); void ConfigureBarOk(void); void ConfigurePieOk(void); void ConfigureXYReset(void); void ConfigureBarReset(void); void ConfigurePieReset(void); /* * This is used in two places. */ #define CopyRightString \ _( \ "\nGNU Oleo is free software, you are welcome to\n" \ "distribute copies of it. See the file COPYING for the\n" \ "conditions.\n\n" \ "GNU Oleo comes with ABSOLUTELY NO WARRANTY." \ ) /* * Conditionally (only when the user wants it) print debugging info */ void Debug(char *src, char *fmt, ...) { static char *srclist = NULL; va_list ap; int printit = 0; if (! srclist) srclist = getenv("DEBUGSOURCES"); if (srclist && strstr(src, srclist)) printit = 1; if (printit) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } } void MessageAppend(Boolean beep, char *fmt, ...) { XmTextPosition pos; int i; va_list ap; char s[256]; if (fmt == NULL) return; va_start(ap, fmt); vsprintf(s, fmt, ap); va_end(ap); if (msgtext == NULL) { if (Global->MotifGlobal->early_msg_text == NULL) { Global->MotifGlobal->early_msg_text = strdup(s); } else { int l = strlen(Global->MotifGlobal->early_msg_text) + strlen(s) + 1; char *x = malloc(l); strcpy(x, Global->MotifGlobal->early_msg_text); strcat(x, s); free(Global->MotifGlobal->early_msg_text); Global->MotifGlobal->early_msg_text = x; } return; } if ((i = strlen(s)) == 0) return; pos = XmTextGetLastPosition(msgtext); XmTextInsert(msgtext, pos, s); if (s[i-1] != '\n') { pos = XmTextGetLastPosition(msgtext); XmTextInsert(msgtext, pos, "\n"); } XmTextShowPosition(msgtext, XmTextGetLastPosition(msgtext)); if (beep) XBell(XtDisplay(msgtext), 30); } /* * This just prints a message saying this functionality hasn't been * implemented yet. */ void none(Widget w, XtPointer client, XtPointer call) { XmString xms; char *s = NULL; MotifSelectGlobal(w); XtVaGetValues(w, XmNlabelString, &xms, NULL); if (XmStringGetLtoR(xms, XmFONTLIST_DEFAULT_TAG, &s)) { MessageAppend(False, "%s: not implemented yet\n", s); XtFree(s); } XmStringFree(xms); } void PrintDebug(Widget w, XtPointer client, XtPointer call) { int i, j; for (i=1; i<6; i++) { fprintf(stderr, "[%d]\t", i); for (j=1; j<6; j++) { fprintf(stderr, "%s\t", cell_value_string(i, j, True)); } fprintf(stderr, "\n"); } } /**************************************************************** * * * Range Selection Support * * * ****************************************************************/ void FocusCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); ActiveRangeSelectionWidget = w; } void LoseFocusCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); #if 0 if (ActiveRangeSelectionWidget == w) ActiveRangeSelectionWidget = NULL; #endif } void SelectCellCB(Widget w, XtPointer client, XtPointer call) { char *s; XbaeMatrixSelectCellCallbackStruct *cbp = (XbaeMatrixSelectCellCallbackStruct *)call; int i, j; MotifSelectGlobal(w); #if 0 fprintf(stderr, "SelectCell(%s, %d %d)\n", cbp->params[0], cbp->row, cbp->column); #endif if (Global->MotifGlobal->selectedcells == NULL) { /* * There's a memory overrun here somewhere. * Working around it by allocating a couple of extra bytes. */ Global->MotifGlobal->selectedcells = (Boolean **)XtMalloc(AppRes.rows * sizeof(Boolean *)); for (i=0; iMotifGlobal->selectedcells[i] = (Boolean *) XtCalloc(10 + AppRes.columns, sizeof(Boolean)); } if (cbp->num_params >= 1 && strcmp(cbp->params[0], "start") == 0) { selection_range.lr = cbp->row + 1; selection_range.lc = cbp->column + 1; for (i=0; iMotifGlobal->selectedcells[i][j] = False; XtVaSetValues(mat, XmNselectedCells, Global->MotifGlobal->selectedcells, NULL); } else if (cbp->num_params >= 1 && strcmp(cbp->params[0], "end") == 0) { selection_range.hr = cbp->row + 1; selection_range.hc = cbp->column + 1; Global->MotifGlobal->newcall = True; if (ActiveRangeSelectionWidget && XmIsTextField(ActiveRangeSelectionWidget)) { s = range_name(&selection_range); XmTextFieldSetString(ActiveRangeSelectionWidget, s); } } else if (cbp->num_params >= 1 && strcmp(cbp->params[0], "move") == 0) { /* * Need to figure out which call is the first in a selection. */ if (Global->MotifGlobal->newcall) { #if 0 fprintf(stderr, "SelectCellCB(move): first call\n"); #endif /* First call, take the position from the currently selected cell */ selection_range.lr = curow; selection_range.lc = cucol; for (i=0; iMotifGlobal->selectedcells[i][j] = False; XtVaSetValues(mat, XmNselectedCells, Global->MotifGlobal->selectedcells, NULL); } else { #if 0 fprintf(stderr, "SelectCellCB(move): another call\n"); #endif /* Motion : change selected area */ selection_range.hr = cbp->row + 1; selection_range.hc = cbp->column + 1; for (i=selection_range.lr-1; i<=cbp->row; i++) for (j=selection_range.lc-1; j<=cbp->column; j++) Global->MotifGlobal->selectedcells[i][j] = True; XtVaSetValues(mat, XmNselectedCells, Global->MotifGlobal->selectedcells, NULL); if (ActiveRangeSelectionWidget && XmIsTextField(ActiveRangeSelectionWidget)) { s = range_name(&selection_range); XmTextFieldSetString(ActiveRangeSelectionWidget, s); } } Global->MotifGlobal->newcall = False; } } void RegisterRangeSelector(Widget w) { XtAddCallback(w, XmNfocusCallback, FocusCB, NULL); XtAddCallback(w, XmNlosingFocusCallback, LoseFocusCB, NULL); } /**************************************************************** * * * Generic Helper Functions * * * ****************************************************************/ void RegisterWMClose(Widget w) { Atom delete_atom; delete_atom = XmInternAtom(XtDisplay(w), "WM_DELETE_WINDOW", False); XmAddWMProtocols(w, &delete_atom, 1); XmSetWMProtocolHooks(w, delete_atom, (XtCallbackProc)DestroyToplevel, (XtPointer)1, (XtCallbackProc)0, (XtPointer)0); } void PopDownHelpCB(Widget widget, XtPointer client, XtPointer call) { XtPopdown((Widget)client); } void MotifUpdateDisplay() { XbaeMatrixRefresh(mat); /* refresh */ FixA0(); /* * Apparently the refresh above doesn't refresh the cell whose * formula we just changed, and which therefore almost certainly * needs an update. XbaeMatrixRefreshCell also doesn't work. * This does : */ XbaeMatrixSetCell(mat, curow - 1, cucol - 1, cell_value_string(curow, cucol, True)); } /**************************************************************** * * * Graphs * * * ****************************************************************/ struct ConfigureWidgets { Widget x, a, b, c, d, e, f, g, h, i, sa, sb, sc, sd, se, sf, sg, sh, si, ta, tb, tc, td, te, tf, tg, th, ti, xlog, ylog, title, xtitle, ytitle; }; static void sciplot_thunk(void *p, CELL *cp, CELLREF r, CELLREF c) { char * str = (char *)char_to_q_char (print_cell (cp)); MessageAppend(False, "SciPlotThunk(r %d c %d) %s", r, c, print_cell(find_cell(r, c))); } void UpdateGraph() { #ifdef HAVE_SciPlot_H int i, ii, len, xx, xa, lst; int xlog, ylog; double *vx, *va; struct rng rngx, rnga; char *s, *t; extern struct rng graph_get_data(int); enum graph_pair_ordering order = graph_rows_hz; xlog = graph_get_logness('x'); ylog = graph_get_logness('y'); XtVaSetValues(plot, XtNchartType, XtCARTESIAN, XtNxLabel, graph_get_axis_title('x'), XtNyLabel, graph_get_axis_title('y'), XtNxLog, xlog, XtNyLog, ylog, NULL); rngx = graph_get_data(0); rnga = graph_get_data(1); len = rngx.hr - rngx.lr + 1; vx = (double *)XtCalloc(len, sizeof(double)); va = (double *)XtCalloc(len, sizeof(double)); /* FIX ME */ /* This code is wrong: only works for vertical set of data */ for (ii=0, i=rngx.lr; i<=rngx.hr; i++, ii++) { s = cell_value_string(i, rngx.lc, True); vx[ii] = 0.0; sscanf(s, "%lf", &vx[ii]); s = cell_value_string(i, rnga.lc, True); va[ii] = 0.0; sscanf(s, "%lf", &va[ii]); } /* Start test for_pairs_in() */ for_pairs_in(&rngx, order, (fpi_thunk)sciplot_thunk, NULL); for_pairs_in(&rnga, order, (fpi_thunk)sciplot_thunk, NULL); /* End test for_pairs_in() */ lst = SciPlotListCreateDouble(plot, 10, vx, va, graph_get_data_title(0)); #if 1 { /* Colour test */ int fg, bg, lc, pc; bg = SciPlotAllocNamedColor(plot, "seagreen"); fg = SciPlotAllocNamedColor(plot, "yellow"); lc = SciPlotAllocNamedColor(plot, "orange"); pc = SciPlotAllocNamedColor(plot, "light blue"); SciPlotListSetStyle(plot, lst, pc, XtMARKER_CIRCLE, lc, XtLINE_DOTTED); SciPlotSetForegroundColor(plot, fg); SciPlotSetBackgroundColor(plot, bg); } #else SciPlotListSetStyle(plot, lst, 1, XtMARKER_CIRCLE, 1, XtLINE_DOTTED); #endif s = graph_get_title(); if (s && strlen(s)) { XtVaSetValues(plot, XtNplotTitle, s, NULL); } XtFree((XtPointer)vx); XtFree((XtPointer)va); SciPlotSetXAutoScale(plot); SciPlotSetYAutoScale(plot); SciPlotUpdate(plot); #endif } void CreateGraph(Widget w, XtPointer client, XtPointer call) { Widget f, sw, sep, ok; int i; MotifSelectGlobal(w); if (gs) return; gs = XtVaCreatePopupShell("graphShell", topLevelShellWidgetClass, toplevel, NULL); f = XtVaCreateManagedWidget("form", xmFormWidgetClass, gs, NULL); #ifdef HAVE_SciPlot_H sw = XtVaCreateManagedWidget("scroll", xmScrolledWindowWidgetClass, f, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftOffset, 10, XmNrightOffset, 10, NULL); plot = XtVaCreateManagedWidget("plot", sciplotWidgetClass, sw, XmNmarginWidth, 20, XmNmarginHeight, 20, XmNwidth, 600, XmNheight, 500, NULL); #else /* Fallback if we don't have SciPlot */ sw = plot = NULL; #endif sep = XtVaCreateManagedWidget("separator", xmSeparatorGadgetClass, f, XmNorientation, XmHORIZONTAL, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, sw, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightOffset, 10, NULL); ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, f, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, sep, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightOffset, 10, NULL); XtAddCallback(ok, XmNactivateCallback, PopDownHelpCB, gs); UpdateGraph(); } /* * Pop up a window with a graph (from SciPlot). */ #ifdef HAVE_SciPlot_H void ShowGraph(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); CreateGraph(w, client, call); XtPopup(gs, XtGrabNone); } /* * Needs to figure out to which file/printer to print, depending on * the callback data passed from the dialog. */ void ReallyPrintGraph(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); if (gs == NULL) CreateGraph(w, client, call); else UpdateGraph(); if (plot) SciPlotPSCreateColor(plot, "plot.ps"); } /* * FIX ME * This must first pop up a window asking whether to print to a file * or a printer. Only after confirmation must ReallyPrintGraph be * called. */ void PrintGraph(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); ReallyPrintGraph(w, client, call); } #endif /* * Show panel of print options */ void PrintOptionsOk(Widget w, XtPointer client, XtPointer call) { int scale; float f; MotifSelectGlobal(w); XtUnmanageChild(optionsDialog); if (Global->MotifGlobal->ZoomScale) { XtVaGetValues(Global->MotifGlobal->ZoomScale, XmNvalue, &scale, NULL); f = scale; } else f = 100.0; f = f / 100.0; Global->zoom = f; MessageAppend(False, "Set zoom to %2.0f%%", 100 * Global->zoom); } void PrintOptionsReset(Widget w) { float f = Global->zoom * 100.0; int s = f; if (Global->MotifGlobal->ZoomScale) { XtVaSetValues(Global->MotifGlobal->ZoomScale, XmNvalue, s, NULL); } } void PrintOptionsCB(Widget w, XtPointer client, XtPointer call) { Widget ok, cancel, help, t, rc, nb, b, cb, menu, f; XmString xms; Arg al[5]; int ac; MotifSelectGlobal(w); if (! optionsDialog) { ac = 0; XtSetArg(al[ac], XmNautoUnmanage, False); ac++; optionsDialog = XmCreateTemplateDialog(mw, "configureGraph", al, ac); #if XmVERSION > 1 nb = XmCreateNotebook(optionsDialog, "printOptionsNotebook", NULL, 0); XtManageChild(nb); /* What to show */ rc = XtVaCreateManagedWidget("showRC", xmRowColumnWidgetClass, nb, NULL); t = XtVaCreateManagedWidget("showLabels", xmToggleButtonGadgetClass, rc, NULL); t = XtVaCreateManagedWidget("showBorders", xmToggleButtonGadgetClass, rc, NULL); t = XtVaCreateManagedWidget("showRaster", xmToggleButtonGadgetClass, rc, NULL); (void)XtVaCreateManagedWidget("showLabel", xmPushButtonWidgetClass, nb, XmNnotebookChildType, XmMAJOR_TAB, NULL); /* Choose a scale for the print */ f = XtVaCreateManagedWidget("scaleForm", xmFormWidgetClass, nb, NULL); rc = XtVaCreateManagedWidget("scaleRC", xmRowColumnWidgetClass, f, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, NULL); menu = XmCreatePulldownMenu(rc, "optionMenu", NULL, 0); ac = 0; XtSetArg(al[ac], XmNsubMenuId, menu); ac++; xms = XmStringCreateSimple(_("Fit Print Area")); XtSetArg(al[ac], XmNlabelString, xms); ac++; cb = XmCreateOptionMenu(rc, "optionCB", al, ac); XtManageChild(cb); XmStringFree(xms); b = XtVaCreateManagedWidget("PrintScaleZoom", xmPushButtonGadgetClass, menu, NULL); b = XtVaCreateManagedWidget("PrintScaleAsIs", xmPushButtonGadgetClass, menu, NULL); b = XtVaCreateManagedWidget("PrintScaleColumnsOnOne", xmPushButtonGadgetClass, menu, NULL); b = XtVaCreateManagedWidget("PrintScaleRowsOnOne", xmPushButtonGadgetClass, menu, NULL); b = XtVaCreateManagedWidget("PrintScaleAllOnOne", xmPushButtonGadgetClass, menu, NULL); Global->MotifGlobal->ZoomScale = XtVaCreateManagedWidget("PrintZoomScale", xmScaleWidgetClass, f, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, rc, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNorientation, XmHORIZONTAL, XmNminimum, 10, XmNmaximum, 400, XmNshowValue, True, NULL); (void)XtVaCreateManagedWidget("scaleLabel", xmPushButtonWidgetClass, nb, XmNnotebookChildType, XmMAJOR_TAB, NULL); #endif /* Buttons */ ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, optionsDialog, NULL); cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass, optionsDialog, NULL); help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass, optionsDialog, NULL); XtAddCallback(ok, XmNactivateCallback, PrintOptionsOk, optionsDialog); XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, optionsDialog); /* FIX ME need something to call the help system */ } PrintOptionsReset(optionsDialog); XtManageChild(optionsDialog); } void ConversionError(char *s, char *t) { char *r = XtMalloc(strlen(s) + strlen(t) + 100); sprintf(r, _("Conversion error: cannot convert '%s' to a %s\n"), s, t); MessageAppend(True, r); XtFree(r); } #ifdef HAVE_LIBPLOT /* * Create a widget tree to configure a graph with. * The result is a widget that isn't managed yet. * (So you can put it in a dialog). * * Information that's present in traditional oleo graphs : * - general : * X Axis Title, Range * Y Axis Title, Range * Logarithmic axes * - per data set : * Data Set Name * Style (Linespoints, lines) */ Widget CreateConfigureGraph(Widget parent) { Widget toprc, frame, w, rc, cap; struct ConfigureWidgets *cw; MotifSelectGlobal(parent); cw = (struct ConfigureWidgets *)XtMalloc( sizeof(struct ConfigureWidgets)); /* * We need to set the userdata on the toplevel widget here. */ toprc = XtVaCreateWidget("configureGraphRC", xmRowColumnWidgetClass, parent, XmNuserData, cw, NULL); frame = XtVaCreateManagedWidget("dataFrame", xmFrameWidgetClass, toprc, NULL); rc = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, frame, XmNnumColumns, 4, XmNorientation, XmVERTICAL, XmNpacking, XmPACK_COLUMN, NULL); XtVaCreateManagedWidget("l0", xmLabelGadgetClass, rc, NULL); XtVaCreateManagedWidget("l1", xmLabelGadgetClass, rc, NULL); XtVaCreateManagedWidget("l2", xmLabelGadgetClass, rc, NULL); XtVaCreateManagedWidget("l3", xmLabelGadgetClass, rc, NULL); XtVaCreateManagedWidget("l4", xmLabelGadgetClass, rc, NULL); XtVaCreateManagedWidget("l5", xmLabelGadgetClass, rc, NULL); XtVaCreateManagedWidget("r0", xmLabelGadgetClass, rc, NULL); cw->x = XtVaCreateManagedWidget("r1", xmTextFieldWidgetClass, rc, NULL); RegisterRangeSelector(cw->x); cw->a = XtVaCreateManagedWidget("r2", xmTextFieldWidgetClass, rc, NULL); RegisterRangeSelector(cw->a); cw->b = XtVaCreateManagedWidget("r3", xmTextFieldWidgetClass, rc, NULL); RegisterRangeSelector(cw->b); cw->c = XtVaCreateManagedWidget("r4", xmTextFieldWidgetClass, rc, NULL); RegisterRangeSelector(cw->c); cw->d = XtVaCreateManagedWidget("r5", xmTextFieldWidgetClass, rc, NULL); RegisterRangeSelector(cw->d); XtVaCreateManagedWidget("s0", xmLabelGadgetClass, rc, NULL); cw->sa = XtVaCreateManagedWidget("s1", xmToggleButtonGadgetClass, rc, NULL); cw->sb = XtVaCreateManagedWidget("s2", xmToggleButtonGadgetClass, rc, NULL); cw->sc = XtVaCreateManagedWidget("s3", xmToggleButtonGadgetClass, rc, NULL); cw->sd = XtVaCreateManagedWidget("s4", xmToggleButtonGadgetClass, rc, NULL); cw->se = XtVaCreateManagedWidget("s5", xmToggleButtonGadgetClass, rc, NULL); XtVaCreateManagedWidget("t0", xmLabelGadgetClass, rc, NULL); cw->ta = XtVaCreateManagedWidget("t1", xmTextFieldWidgetClass, rc, NULL); cw->tb = XtVaCreateManagedWidget("t2", xmTextFieldWidgetClass, rc, NULL); cw->tc = XtVaCreateManagedWidget("t3", xmTextFieldWidgetClass, rc, NULL); cw->td = XtVaCreateManagedWidget("t4", xmTextFieldWidgetClass, rc, NULL); cw->te = XtVaCreateManagedWidget("t5", xmTextFieldWidgetClass, rc, NULL); frame = XtVaCreateManagedWidget("dataFrame", xmFrameWidgetClass, toprc, NULL); rc = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, frame, NULL); XtVaCreateManagedWidget("xl", xmLabelGadgetClass, rc, NULL); cw->xtitle = XtVaCreateManagedWidget("xt", xmTextFieldWidgetClass, rc, NULL); cw->xlog = XtVaCreateManagedWidget("xlog", xmToggleButtonGadgetClass, rc, NULL); XtVaCreateManagedWidget("yl", xmLabelGadgetClass, rc, NULL); cw->ytitle = XtVaCreateManagedWidget("yt", xmTextFieldWidgetClass, rc, NULL); cw->ylog = XtVaCreateManagedWidget("ylog", xmToggleButtonGadgetClass, rc, NULL); cw->title = XtVaCreateManagedWidget("title", xmTextFieldWidgetClass, rc, NULL); return toprc; } /* * Ok handler * This reads everything from the widgets in the dialog and copies * the information into variables. */ void ConfigureGraphOk(Widget w, XtPointer client, XtPointer call) { Widget f = (Widget)client; struct ConfigureWidgets *cw = NULL; char *s, *p; struct rng rngx; int r; MotifSelectGlobal(w); /* We should only pop down if everything was read correctly. * XtUnmanageChild(configureGraph); */ Global->return_from_error = 1; Global->had_error = 0; XtVaGetValues(f, XmNuserData, &cw, NULL); if (cw == NULL) { MessageAppend(True, _("Cannot find XmNuserData\n")); XtUnmanageChild(configureGraph); Global->return_from_error = 0; return; } /* Plot title */ s = XmTextFieldGetString(cw->title); graph_set_title(s); #ifdef FREE_TF_STRING XtFree(s); #endif /* X Axis */ s = XmTextFieldGetString(cw->xtitle); graph_set_axis_title('x', s); #ifdef FREE_TF_STRING XtFree(s); #endif graph_set_logness('x', 1, XmToggleButtonGadgetGetState(cw->xlog)); /* Y Axis */ s = XmTextFieldGetString(cw->ytitle); graph_set_axis_title('y', s); #ifdef FREE_TF_STRING XtFree(s); #endif graph_set_logness('y', 1, XmToggleButtonGadgetGetState(cw->ylog)); s = XmTextFieldGetString(cw->ta); graph_set_data_title(0, s); #ifdef FREE_TF_STRING XtFree(s); #endif /* Data 1 */ p = s = XmTextFieldGetString(cw->x); if (strlen(s)) { if ((r = parse_cell_or_range(&p, &rngx)) == 0) ConversionError(s, _("range")); else if (r & RANGE) { graph_set_data(0, &rngx); } else { rngx.hr = rngx.lr; rngx.hc = rngx.lc; graph_set_data(0, &rngx); } #ifdef FREE_TF_STRING XtFree(s); #endif } s = XmTextFieldGetString(cw->tb); graph_set_data_title(1, s); #ifdef FREE_TF_STRING XtFree(s); #endif /* Data 2 */ p = s = XmTextFieldGetString(cw->a); if (strlen(s)) { if ((r = parse_cell_or_range(&p, &rngx)) == 0) ConversionError(s, _("range")); else if (r & RANGE) { graph_set_data(1, &rngx); } else { rngx.hr = rngx.lr; rngx.hc = rngx.lc; graph_set_data(1, &rngx); } #ifdef FREE_TF_STRING XtFree(s); #endif } s = XmTextFieldGetString(cw->tc); graph_set_data_title(2, s); #ifdef FREE_TF_STRING XtFree(s); #endif /* Data 3 */ p = s = XmTextFieldGetString(cw->b); if (strlen(s)) { if ((r = parse_cell_or_range(&p, &rngx)) == 0) ConversionError(s, _("range")); else if (r & RANGE) { graph_set_data(2, &rngx); } else { rngx.hr = rngx.lr; rngx.hc = rngx.lc; graph_set_data(2, &rngx); } #ifdef FREE_TF_STRING XtFree(s); #endif } s = XmTextFieldGetString(cw->td); graph_set_data_title(3, s); #ifdef FREE_TF_STRING XtFree(s); #endif p = s = XmTextFieldGetString(cw->c); if (strlen(s)) { if ((r = parse_cell_or_range(&p, &rngx)) == 0) ConversionError(s, _("range")); else if (r & RANGE) { graph_set_data(3, &rngx); } else { rngx.hr = rngx.lr; rngx.hc = rngx.lc; graph_set_data(3, &rngx); } MessageAppend(False, s); #ifdef FREE_TF_STRING XtFree(s); #endif } p = s = XmTextFieldGetString(cw->d); if (strlen(s)) { if ((r = parse_cell_or_range(&p, &rngx)) == 0) ConversionError(s, _("range")); else if (r & RANGE) { graph_set_data(4, &rngx); } else { rngx.hr = rngx.lr; rngx.hc = rngx.lc; graph_set_data(4, &rngx); } MessageAppend(False, s); #ifdef FREE_TF_STRING XtFree(s); #endif } ConfigureXYOk(); ConfigurePieOk(); ConfigureBarOk(); /* Pop down */ if (Global->had_error == 0) XtUnmanageChild(configureGraph); Global->return_from_error = 0; } /* * Revert configure graph fields to their current internal values. * This is needed for popping up the dialog after it's been changed by * the user but he's hit Cancel. * Or for values read from a file. (new to 1.6.14) */ void ConfigureGraphReset(Widget f) { struct ConfigureWidgets *cw = NULL; struct rng r; char *s; extern struct rng graph_get_data(int); XtVaGetValues(f, XmNuserData, &cw, NULL); if (cw == NULL) { MessageAppend(True, _("Cannot find XmNuserData\n")); return; } #if XmVERSION > 1 XtVaSetValues(ConfigureGraphNotebook, XmNcurrentPageNumber, 1, NULL); #endif r = graph_get_data(0); s = range_name(&r); XmTextFieldSetString(cw->x, s); r = graph_get_data(1); s = range_name(&r); XmTextFieldSetString(cw->a, s); r = graph_get_data(2); s = range_name(&r); XmTextFieldSetString(cw->b, s); r = graph_get_data(3); s = range_name(&r); XmTextFieldSetString(cw->c, s); r = graph_get_data(4); s = range_name(&r); XmTextFieldSetString(cw->d, s); s = graph_get_title(); XmTextFieldSetString(cw->title, s); s = graph_get_axis_title('x'); XmTextFieldSetString(cw->xtitle, s); s = graph_get_axis_title('y'); XmTextFieldSetString(cw->ytitle, s); s = graph_get_data_title(0); XmTextFieldSetString(cw->ta, s); s = graph_get_data_title(1); XmTextFieldSetString(cw->tb, s); s = graph_get_data_title(2); XmTextFieldSetString(cw->tc, s); s = graph_get_data_title(3); XmTextFieldSetString(cw->td, s); s = graph_get_data_title(4); XmTextFieldSetString(cw->te, s); ConfigureXYReset(); ConfigurePieReset(); ConfigureBarReset(); } /* * Pop up the dialog for configuring graphs. * If necessary, create the widgets first. */ void ConfigureGraph(Widget w, XtPointer client, XtPointer call) { Widget ok, cancel, help, p, fr; int ac; Arg al[5]; MotifSelectGlobal(w); if (! configureGraph) { ac = 0; XtSetArg(al[ac], XmNautoUnmanage, False); ac++; configureGraph = XmCreateTemplateDialog(mw, "configureGraph", al, ac); #if XmVERSION > 1 ConfigureGraphNotebook = XmCreateNotebook(configureGraph, "configureGraphNotebook", NULL, 0); XtManageChild(ConfigureGraphNotebook); /* The data */ ConfigureGraphInside = CreateConfigureGraph(ConfigureGraphNotebook); XtManageChild(ConfigureGraphInside); p = XtVaCreateManagedWidget("datatab", xmPushButtonWidgetClass, ConfigureGraphNotebook, XmNnotebookChildType, XmMAJOR_TAB, NULL); /* Pie Chart specific stuff */ fr = ConfigurePieChart(ConfigureGraphNotebook); XtManageChild(fr); p = XtVaCreateManagedWidget("PieTab", xmPushButtonWidgetClass, ConfigureGraphNotebook, XmNnotebookChildType, XmMAJOR_TAB, NULL); /* XY Chart specific stuff */ fr = ConfigureXYChart(ConfigureGraphNotebook); XtManageChild(fr); p = XtVaCreateManagedWidget("XYTab", xmPushButtonWidgetClass, ConfigureGraphNotebook, XmNnotebookChildType, XmMAJOR_TAB, NULL); /* Bar Chart specific stuff */ fr = ConfigureBarChart(ConfigureGraphNotebook); XtManageChild(fr); p = XtVaCreateManagedWidget("BarTab", xmPushButtonWidgetClass, ConfigureGraphNotebook, XmNnotebookChildType, XmMAJOR_TAB, NULL); #endif /* Buttons */ ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, configureGraph, NULL); cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass, configureGraph, NULL); help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass, configureGraph, NULL); XtAddCallback(ok, XmNactivateCallback, ConfigureGraphOk, ConfigureGraphInside); XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, configureGraph); /* FIX ME need something to call the help system */ } ConfigureGraphReset(ConfigureGraphInside); XtManageChild(configureGraph); } #endif /* * Plotutils */ #ifndef HAVE_LIBPLOT void NoPlotutils(Widget w, XtPointer client, XtPointer call) { XmString xms; char *s = NULL; MotifSelectGlobal(w); XtVaGetValues(w, XmNlabelString, &xms, NULL); if (XmStringGetLtoR(xms, XmFONTLIST_DEFAULT_TAG, &s)) { MessageAppend(False, "%s: GNU Plotutils not linked in\n", s); XtFree(s); } XmStringFree(xms); } #endif /* * RedrawPlotutilsWindow is called when the plotutils widget needs * a refresh, which may just be when it's scrolling. */ static void RedrawPlotutilsWindow(Widget w, XtPointer client, XtPointer call) { void (*f)(char *, FILE *) = client; MotifSelectGlobal(w); (*f)("Xdrawable", stdout); } /* * Show a GNU Plotutils chart in a Motif widget. * * The client parameter is the function (from plot.c) which will * handle the plotting. We pass it to RedrawPlotutilsWindow() too. */ void PuShowChart(Widget w, XtPointer client, XtPointer call) { #ifdef HAVE_LIBPLOT static Window window; Widget dlg, d, cancel, help, sw; Arg al[5]; int ac; void (*f)(char *, FILE *) = client; MotifSelectGlobal(w); ac = 0; XtSetArg(al[ac], XmNautoUnmanage, False); ac++; dlg = XmCreateTemplateDialog(toplevel, "printDialog", al, ac); ac = 0; #if 0 XtSetArg(al[ac], XmNwidth, 500); ac++; XtSetArg(al[ac], XmNheight, 500); ac++; #endif XtSetArg(al[ac], XmNwidth, Global->PlotGlobal->img_width + 100); ac++; XtSetArg(al[ac], XmNheight, Global->PlotGlobal->img_height + 100); ac++; XtSetArg(al[ac], XmNscrollingPolicy, XmAUTOMATIC); ac++; sw = XmCreateScrolledWindow(dlg, "scroll", al, ac); XtManageChild(sw); ac = 0; XtSetArg(al[ac], XmNwidth, Global->PlotGlobal->img_width); ac++; XtSetArg(al[ac], XmNheight, Global->PlotGlobal->img_height); ac++; d = XmCreateDrawingArea(sw, "DrawingArea", al, ac); XtManageChild(d); XtAddCallback(d, XmNexposeCallback, RedrawPlotutilsWindow, f); XtManageChild(dlg); window = XtWindow(d); if (window == 0) { MessageAppend(True, "PuShowChart: 0 window\n"); return; } PuX(XtDisplayOfObject(w), window); PlotInit(); cancel = XtVaCreateManagedWidget("dismiss", xmPushButtonGadgetClass, dlg, NULL); XtAddCallback(cancel, XmNactivateCallback, DestroyTemplate, dlg); help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass, dlg, NULL); XtAddCallback(help, XmNactivateCallback, helpUsingCB, (XtPointer)"#HelpPlotting"); (*f)("Xdrawable", stdout); #else NoPlotutils(w, client, call); #endif } /* * Printing * need to pop up a dialog to select a file and a GNU PlotUtils plotter * then actually doit */ void PuSelectPlotter(Widget w, XtPointer client, XtPointer call) { XmString xms; char *p; int i; MotifSelectGlobal(w); PuPlotter = (int)client; plotutils_set_device(PuPlotter); for (i=0; PlotutilsDeviceArray[i].pus; i++) if (PlotutilsDeviceArray[i].t == PuPlotter) break; #if 0 fprintf(stderr, "PuSelectPlotter(%s)\n", PlotutilsDeviceArray[i].desc); #endif p = malloc(strlen(PlotutilsDeviceArray[i].ext) + 8); strcpy(p, "*."); strcat(p, PlotutilsDeviceArray[i].ext); xms = XmStringCreateSimple(p); free(p); XtVaSetValues(pufsd, XmNpattern, xms, NULL); XmStringFree(xms); } Widget CreatePlotterOption(Widget parent, XtCallbackProc f) { Arg al[10]; int ac = 0, r, i; XmString xms; Widget cb, menu, b; menu = XmCreatePulldownMenu(parent, "optionMenu", NULL, 0); ac = 0; XtSetArg(al[ac], XmNsubMenuId, menu); ac++; xms = XmStringCreateSimple(_("Plotter Type")); XtSetArg(al[ac], XmNlabelString, xms); ac++; cb = XmCreateOptionMenu(parent, "optionCB", al, ac); XtManageChild(cb); XmStringFree(xms); for (i=0; PlotutilsDeviceArray[i].pus; i++) { b = XtVaCreateManagedWidget(PlotutilsDeviceArray[i].pus, xmPushButtonGadgetClass, menu, NULL); XtAddCallback(b, XmNactivateCallback, f, (XtPointer)PlotutilsDeviceArray[i].t); } return menu; } void PuPrintOk(Widget w, XtPointer client, XtPointer call) { #ifdef HAVE_LIBPLOT XmFileSelectionBoxCallbackStruct *cbp = (XmFileSelectionBoxCallbackStruct *)call; char *fn; MotifSelectGlobal(w); if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &fn)) { /* FIX ME */ return; } plotutils_set_filename(fn); graph_plot(); #endif } void PuPrintDialog(Widget w, XtPointer client, XtPointer call) { Arg al[10]; int ac = 0; XmString xms; Widget cb, menu, b; MotifSelectGlobal(w); ac = 0; XtSetArg(al[ac], XmNautoUnmanage, True); ac++; xms = XmStringCreateSimple(_("*.oleo")); XtSetArg(al[ac], XmNpattern, xms); ac++; pufsd = XmCreateFileSelectionDialog(toplevel, "puselectfile", al, ac); XtDestroyWidget( XmFileSelectionBoxGetChild(pufsd, XmDIALOG_HELP_BUTTON)); XmStringFree(xms); XtAddCallback(pufsd, XmNokCallback, PuPrintOk, NULL); /* Option menu */ menu = CreatePlotterOption(pufsd, PuSelectPlotter); } void PuPrint(Widget w, XtPointer client, XtPointer call) { #ifdef HAVE_LIBPLOT enum graph_type gt = (enum graph_type)client; MotifSelectGlobal(w); plotutils_set_graph_type(gt); if (! pufsd) PuPrintDialog(w, client, call); XtManageChild(pufsd); #endif } #ifdef HAVE_LIBPLOT static void TickTypeCB(Widget w, XtPointer client, XtPointer call) { int n = (int)client; int axis = n / 256; int val = n % 256; tick_type_e v = (tick_type_e)val; Widget tw; MotifSelectGlobal(w); if (axis == 0) { Global->MotifGlobal->xtick = val; tw = Global->MotifGlobal->xtickfmt; } else { Global->MotifGlobal->ytick = val; tw = Global->MotifGlobal->ytickfmt; } switch (v) { SP_TICK_DEFAULT: SP_TICK_NONE: #if 0 fprintf(stderr, "TickTypeCB(axis %d type %d) -> insensitive \n", axis, val); #endif XmTextFieldSetEditable(tw, False); break; SP_TICK_PRINTF: SP_TICK_STRFTIME: #if 0 fprintf(stderr, "TickTypeCB(axis %d type %d) -> sensitive \n", axis, val); #endif XmTextFieldSetEditable(tw, True); break; default: {} #if 0 fprintf(stderr, "Huh ? TickTypeCB(axis %d type %d) -> sensitive \n", axis, val); #endif } #if 0 fprintf(stderr, "SP_TICK_DEFAULT %d\n", SP_TICK_DEFAULT); fprintf(stderr, "SP_TICK_NONE %d\n", SP_TICK_NONE); fprintf(stderr, "SP_TICK_PRINTF %d\n", SP_TICK_PRINTF); fprintf(stderr, "SP_TICK_STRFTIME %d\n", SP_TICK_STRFTIME); #endif } /* * A piece of dialog for configuring XY chars * Needs to be managed by the caller. */ Widget ConfigureXYChart(Widget parent) { Widget frame, form, w, te, l, t; Arg al[10]; int ac; XmString xms; MotifSelectGlobal(parent); ac = 0; frame = XmCreateFrame(parent, "puselectfile", al, ac); w = XtVaCreateManagedWidget("configureXYChartFrameTitle", xmLabelGadgetClass, frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, NULL); form = XtVaCreateManagedWidget("configureXYChartForm", xmFormWidgetClass, frame, NULL); /* X Axis */ XYxAutoToggle = t = XtVaCreateManagedWidget("xAutoToggle", xmToggleButtonGadgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL); l = XtVaCreateManagedWidget("xMinLabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, t, XmNleftOffset, 10, NULL); XYxMinText = te = XtVaCreateManagedWidget("xMinText", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, l, XmNleftOffset, 10, NULL); l = XtVaCreateManagedWidget("xMaxLabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, te, XmNleftOffset, 10, NULL); XYxMaxText = te = XtVaCreateManagedWidget("xMaxText", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, l, XmNleftOffset, 10, NULL); /* Y Axis */ XYyAutoToggle = t = XtVaCreateManagedWidget("yAutoToggle", xmToggleButtonGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, te, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL); l = XtVaCreateManagedWidget("yMinLabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopOffset, 0, XmNtopWidget, t, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, t, XmNleftOffset, 10, NULL); XYyMinText = te = XtVaCreateManagedWidget("yMinText", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopOffset, 0, XmNtopWidget, t, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, l, XmNleftOffset, 10, NULL); l = XtVaCreateManagedWidget("yMaxLabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopOffset, 0, XmNtopWidget, t, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, te, XmNleftOffset, 10, NULL); XYyMaxText = te = XtVaCreateManagedWidget("yMaxText", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopOffset, 0, XmNtopWidget, t, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, l, XmNleftOffset, 10, NULL); /* Line type */ /* Lines to offscreen data points */ lineToOffscreen = XtVaCreateManagedWidget("lineToOffscreen", xmToggleButtonGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, te, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL); /* Axis tick labels */ Global->MotifGlobal->XLogToggle = XtVaCreateManagedWidget("xLogToggle", xmToggleButtonGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, lineToOffscreen, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL); Global->MotifGlobal->xticklblmenu = XmCreatePulldownMenu(form, "xticklblmenu", NULL, 0); ac=0; XtSetArg(al[ac], XmNsubMenuId, Global->MotifGlobal->xticklblmenu); ac++; xms = XmStringCreateSimple(_("X Axis Tick Label Type")); XtSetArg(al[ac], XmNlabelString, xms); ac++; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNtopWidget, lineToOffscreen); ac++; XtSetArg(al[ac], XmNtopOffset, 10); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNleftWidget, Global->MotifGlobal->XLogToggle); ac++; XtSetArg(al[ac], XmNleftOffset, 10); ac++; Global->MotifGlobal->xticklbloption = XmCreateOptionMenu(form, "xticklbloption", al, ac); XtManageChild(Global->MotifGlobal->xticklbloption); w = XtVaCreateManagedWidget("xtickdefault", xmPushButtonWidgetClass, Global->MotifGlobal->xticklblmenu, NULL); Global->MotifGlobal->ticktype_w[0][SP_TICK_DEFAULT] = w; XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x000 | SP_TICK_DEFAULT)); w = XtVaCreateManagedWidget("xticknone", xmPushButtonWidgetClass, Global->MotifGlobal->xticklblmenu, NULL); Global->MotifGlobal->ticktype_w[0][SP_TICK_NONE] = w; XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x000 | SP_TICK_NONE)); w = XtVaCreateManagedWidget("xtickprintf", xmPushButtonWidgetClass, Global->MotifGlobal->xticklblmenu, NULL); Global->MotifGlobal->ticktype_w[0][SP_TICK_PRINTF] = w; XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x000 | SP_TICK_PRINTF)); w = XtVaCreateManagedWidget("xtickstrftime", xmPushButtonWidgetClass, Global->MotifGlobal->xticklblmenu, NULL); Global->MotifGlobal->ticktype_w[0][SP_TICK_STRFTIME] = w; XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x000 | SP_TICK_STRFTIME)); Global->MotifGlobal->xtickfmt = XtVaCreateManagedWidget("xtickfmt", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, lineToOffscreen, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, Global->MotifGlobal->xticklbloption, XmNleftOffset, 10, NULL); Global->MotifGlobal->YLogToggle = XtVaCreateManagedWidget("yLogToggle", xmToggleButtonGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, Global->MotifGlobal->XLogToggle, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL); Global->MotifGlobal->yticklblmenu = XmCreatePulldownMenu(form, "yticklblmenu", NULL, 0); ac=0; XtSetArg(al[ac], XmNsubMenuId, Global->MotifGlobal->yticklblmenu); ac++; xms = XmStringCreateSimple(_("Y Axis Tick Label Type")); XtSetArg(al[ac], XmNlabelString, xms); ac++; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNtopWidget, Global->MotifGlobal->xtickfmt); ac++; XtSetArg(al[ac], XmNtopOffset, 10); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNleftWidget, Global->MotifGlobal->YLogToggle); ac++; XtSetArg(al[ac], XmNleftOffset, 10); ac++; Global->MotifGlobal->yticklbloption = XmCreateOptionMenu(form, "yticklbloption", al, ac); XtManageChild(Global->MotifGlobal->yticklbloption); w = XtVaCreateManagedWidget("ytickdefault", xmPushButtonWidgetClass, Global->MotifGlobal->yticklblmenu, NULL); Global->MotifGlobal->ticktype_w[1][SP_TICK_DEFAULT] = w; XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x100 | SP_TICK_DEFAULT)); w = XtVaCreateManagedWidget("yticknone", xmPushButtonWidgetClass, Global->MotifGlobal->yticklblmenu, NULL); Global->MotifGlobal->ticktype_w[1][SP_TICK_NONE] = w; XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x100 | SP_TICK_NONE)); w = XtVaCreateManagedWidget("ytickprintf", xmPushButtonWidgetClass, Global->MotifGlobal->yticklblmenu, NULL); Global->MotifGlobal->ticktype_w[1][SP_TICK_PRINTF] = w; XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x100 | SP_TICK_PRINTF)); w = XtVaCreateManagedWidget("ytickstrftime", xmPushButtonWidgetClass, Global->MotifGlobal->yticklblmenu, NULL); Global->MotifGlobal->ticktype_w[1][SP_TICK_STRFTIME] = w; XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x100 | SP_TICK_STRFTIME)); Global->MotifGlobal->ytickfmt = XtVaCreateManagedWidget("ytickfmt", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, Global->MotifGlobal->XLogToggle, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, Global->MotifGlobal->xticklbloption, XmNleftOffset, 10, NULL); return frame; } void ConfigureXYOk(void) { char *s; int b; s = XmTextFieldGetString(XYxMinText); graph_set_axis_lo('x', s); s = XmTextFieldGetString(XYxMaxText); graph_set_axis_hi('x', s); s = XmTextFieldGetString(XYyMinText); graph_set_axis_lo('y', s); s = XmTextFieldGetString(XYyMaxText); graph_set_axis_hi('y', s); graph_set_axis_auto(0, XmToggleButtonGadgetGetState(XYxAutoToggle)); graph_set_axis_auto(1, XmToggleButtonGadgetGetState(XYyAutoToggle)); graph_set_linetooffscreen(XmToggleButtonGadgetGetState(lineToOffscreen)); graph_set_axis_ticks(0, /* tick label type */ Global->MotifGlobal->xtick, /* format string */ XmTextFieldGetString(Global->MotifGlobal->xtickfmt)); graph_set_axis_ticks(1, /* tick label type */ Global->MotifGlobal->ytick, /* format string */ XmTextFieldGetString(Global->MotifGlobal->ytickfmt)); /* FIX ME treat these */ b = XmToggleButtonGadgetGetState(Global->MotifGlobal->YLogToggle); b = XmToggleButtonGadgetGetState(Global->MotifGlobal->YLogToggle); } static void TextFieldSetFloat(Widget w, float f) { char t[32]; sprintf(t, "%f", f); XmTextFieldSetString(w, t); } void ConfigureXYReset(void) { XmToggleButtonGadgetSetState(XYxAutoToggle, graph_get_axis_auto(0), False); TextFieldSetFloat(XYxMinText, graph_get_axis_lo(0)); TextFieldSetFloat(XYxMaxText, graph_get_axis_hi(0)); XmToggleButtonGadgetSetState(XYyAutoToggle, graph_get_axis_auto(1), False); TextFieldSetFloat(XYyMinText, graph_get_axis_lo(1)); TextFieldSetFloat(XYyMaxText, graph_get_axis_hi(1)); XmToggleButtonGadgetSetState(lineToOffscreen, graph_get_linetooffscreen(), False); XtVaSetValues(Global->MotifGlobal->xticklbloption, XmNmenuHistory, Global->MotifGlobal->ticktype_w[0][Global->PlotGlobal->ticktype[0]], NULL); XtVaSetValues(Global->MotifGlobal->yticklbloption, XmNmenuHistory, Global->MotifGlobal->ticktype_w[1][Global->PlotGlobal->ticktype[1]], NULL); XmTextFieldSetString(Global->MotifGlobal->xtickfmt, graph_get_axis_tickformat(0)); XmTextFieldSetString(Global->MotifGlobal->ytickfmt, graph_get_axis_tickformat(1)); } Widget ConfigurePieChart(Widget parent) { Widget frame, form, w, te, l, t; Arg al[10]; int ac; ac = 0; frame = XmCreateFrame(parent, "configurePieChartFrame", al, ac); w = XtVaCreateManagedWidget("configurePieChartFrameTitle", xmLabelGadgetClass, frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, NULL); form = XtVaCreateManagedWidget("configurePieChartForm", xmFormWidgetClass, frame, NULL); t = XtVaCreateManagedWidget("pie3d", xmToggleButtonGadgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL); return frame; } void ConfigurePieOk(void) { } void ConfigurePieReset(void) { } Widget ConfigureBarChart(Widget parent) { Widget frame, form, w, te, l, t; Arg al[10]; int ac; ac = 0; frame = XmCreateFrame(parent, "configureBarChartFrame", al, ac); w = XtVaCreateManagedWidget("configureBarChartFrameTitle", xmLabelGadgetClass, frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, NULL); form = XtVaCreateManagedWidget("configureBarChartForm", xmFormWidgetClass, frame, NULL); t = XtVaCreateManagedWidget("stackToggle", xmToggleButtonGadgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL); return frame; } void ConfigureBarOk(void) { } void ConfigureBarReset(void) { } #endif /* * Print */ struct PrintWidgets { Widget rangeTF, fileTF, printerTF, programTF; Widget PrinterToggle, FileToggle, ProgramToggle; } PrintWidgets; /* * Print the spreadsheet */ void ReallyPrintCB(Widget w, XtPointer client, XtPointer call) { /* FIX ME * This is simplistic, we need to print to either a file, * selected by the user from a dialog, or to a printer, * also selected by the user. */ FILE *fp = NULL; struct rng rng; char *fn = NULL, *s, *p, *pr = NULL; int r; MotifSelectGlobal(w); XtUnmanageChild(PrintDialog); if (XmToggleButtonGadgetGetState(PrintWidgets.PrinterToggle)) { char cmd[64]; pr = XmTextFieldGetString(PrintWidgets.printerTF); if (pr && strlen(pr)) { sprintf(cmd, "lpr -P%s", pr); } else if (strlen(AppRes.printer)) { sprintf(cmd, "lpr -P%s", AppRes.printer); pr = AppRes.printer; } else { sprintf(cmd, "lpr"); pr = "[default printer]"; } fp = popen(cmd, "w"); if (fp == NULL) { MessageAppend(True, "Couldn't print to printer %s\n", AppRes.printer); return; } } else if (XmToggleButtonGadgetGetState(PrintWidgets.FileToggle)) { fn = XmTextFieldGetString(PrintWidgets.fileTF); if (fn) fp = fopen(fn, "w"); if (! fp) { MessageAppend(True, "Couldn't write to file %s\n", fn); #ifdef FREE_TF_STRING XtFree(fn); #endif return; } } else if (XmToggleButtonGadgetGetState(PrintWidgets.ProgramToggle)) { fp = popen(AppRes.program, "w"); if (fp == NULL) { MessageAppend(True, "Couldn't print to program %s\n", AppRes.program); return; } } else { MessageAppend(True, _("Internal error: can't find what to print to\n")); return; } p = s = XmTextFieldGetString(PrintWidgets.rangeTF); if ((r = parse_cell_or_range(&p, &rng)) == 0) { ConversionError(s, _("range")); /* FIX ME Which range is the complete spreadsheet ? */ rng.lr = 1; rng.lc = 1; rng.hc = 40; rng.hr = 80; } else if (r & RANGE) { ; } else { rng.hr = rng.lr; rng.hc = rng.lc; } #ifdef FREE_TF_STRING XtFree(s); #endif print_region_cmd(&rng, fp); if (XmToggleButtonGadgetGetState(PrintWidgets.FileToggle)) fclose(fp); else pclose(fp); if (Global->zoom < 0.90 || Global->zoom > 1.1) { int z = Global->zoom * 100; if (fn) MessageAppend(False, "Printed %s to file %s, at %d percent size\n", range_name(&rng), fn, z); else MessageAppend(False, "Printed %s to printer %s, at %d percent size\n", range_name(&rng), pr, z); } else if (fn) { MessageAppend(False, "Printed %s to file %s\n", range_name(&rng), fn); } else { MessageAppend(False, "Printed %s to printer %s\n", range_name(&rng), pr); } #ifdef FREE_TF_STRING XtFree(fn); #endif } static void MotifSetPrintType(Widget w, XtPointer client, XtPointer call) { char *s = (char *)client; MotifSelectGlobal(w); MessageAppend(False, "Set printer type to %s\n", s); PrintSetType(s); } static void MotifSetPrintPage(Widget w, XtPointer client, XtPointer call) { int i = (int) client; MotifSelectGlobal(w); MessageAppend(False, "Set page format to %s\n", PrintGetPageName(i)); PrintSetPage(PrintGetPageName(i)); } /* * Select a file to print into */ void PrintBrowseFileCBOk(Widget w, XtPointer client, XtPointer call) { char *fn; XmFileSelectionBoxCallbackStruct *cbp = (XmFileSelectionBoxCallbackStruct *)call; MotifSelectGlobal(w); if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &fn)) return; XmTextFieldSetString(PrintWidgets.fileTF, fn); } void PrintBrowseFileCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); if (! pfsd) { XmString xms; Arg al[5]; int ac = 0; xms = XmStringCreateSimple(_("*.out")); XtSetArg(al[ac], XmNpattern, xms); ac++; XtSetArg(al[ac], XmNautoUnmanage, True); ac++; pfsd = XmCreateFileSelectionDialog(toplevel, "selectfile", al, ac); XtDestroyWidget( XmFileSelectionBoxGetChild(pfsd, XmDIALOG_HELP_BUTTON)); XtAddCallback(pfsd, XmNokCallback, PrintBrowseFileCBOk, NULL); XmStringFree(xms); } XtManageChild(pfsd); } void CupsSelectPrinter(Widget w, XtPointer client, XtPointer call) { Widget tf = (Widget)client; MotifSelectGlobal(w); XmTextFieldSetString(tf, XtName(w)); } /* * The print dialog : * - select where to print to (program, printer, file) * - paper size * - print range */ Widget MotifCreatePrintDialog(Widget s) { Widget form, menu, cb, w, frame, radio, form2, cb1, cupsmenu, cupsOption; int npages, i, ac, nprinters; Arg al[5]; XmString xms; int defaultprint = 0; char **printers; MotifSelectGlobal(s); ac = 0; form = XmCreateForm(s, "printForm", al, ac); /* Check value of resource */ #ifdef HAVE_STRCASECMP if (strcasecmp(AppRes.defaultPrintTo, "printer") != 0 && strcasecmp(AppRes.defaultPrintTo, "program") != 0 && strcasecmp(AppRes.defaultPrintTo, "file") != 0) #else if (strcmp(AppRes.defaultPrintTo, "printer") != 0 && strcmp(AppRes.defaultPrintTo, "program") != 0 && strcmp(AppRes.defaultPrintTo, "file") != 0) #endif { defaultprint = 1; MessageAppend(True, _("Value of defaultPrintTo resource is invalid, " "should be one of %s, %s, or %s\n"), "printer", "file", "program"); } /* Destination */ frame = XtVaCreateManagedWidget("printDestinationFrame", xmFrameWidgetClass, form, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNtopOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, NULL); w = XtVaCreateManagedWidget("printDestinationFrameTitle", xmLabelGadgetClass, frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, NULL); radio = XtVaCreateManagedWidget("printDestinationRadio", xmRowColumnWidgetClass, frame, XmNradioBehavior, True, XmNradioAlwaysOne, True, XmNnumColumns, 3, XmNorientation, XmHORIZONTAL, NULL); PrintWidgets.PrinterToggle = w = XtVaCreateManagedWidget("printer", xmToggleButtonGadgetClass, radio, NULL); #ifdef HAVE_STRCASECMP if (strcasecmp(AppRes.defaultPrintTo, "printer") == 0 || defaultprint) #else if (strcmp(AppRes.defaultPrintTo, "printer") == 0 || defaultprint) #endif XmToggleButtonGadgetSetState(w, True, False); PrintWidgets.printerTF = w = XtVaCreateManagedWidget("printerTF", xmTextFieldWidgetClass, radio, NULL); XmTextFieldSetString(w, AppRes.printer); /* * Build an option menu with a list of known printers. * * We can do this if we have CUPS (www.cups.org), otherwise * make the damned thing insensitive. */ cupsmenu = XmCreatePulldownMenu(radio, "cupsMenu", NULL, 0); ac=0; XtSetArg(al[ac], XmNsubMenuId, cupsmenu); ac++; xms = XmStringCreateSimple(_("Select Printer")); XtSetArg(al[ac], XmNlabelString, xms); ac++; cupsOption = XmCreateOptionMenu(radio, "printerOption", al, ac); XtManageChild(cupsOption); #ifndef HAVE_LIBCUPS XtSetSensitive(cupsOption, False); #endif XmStringFree(xms); #ifdef HAVE_LIBCUPS printers = NULL; nprinters = cupsGetPrinters(&printers); for (i=0; i < nprinters; i++) { Widget b; b = XtVaCreateManagedWidget(printers[i], xmPushButtonGadgetClass, cupsmenu, NULL); XtAddCallback(b, XmNactivateCallback, CupsSelectPrinter, (XtPointer)PrintWidgets.printerTF); if (i == 0) XtVaSetValues(cupsOption, XmNmenuHistory, b, NULL); } if (nprinters == 0) { w = XtVaCreateManagedWidget("No printers available from CUPS", xmPushButtonGadgetClass, cupsmenu, NULL); XtAddCallback(w, XmNactivateCallback, CupsSelectPrinter, (XtPointer)PrintWidgets.printerTF); } #endif PrintWidgets.FileToggle = w = XtVaCreateManagedWidget("file", xmToggleButtonGadgetClass, radio, NULL); #ifdef HAVE_STRCASECMP if (strcasecmp(AppRes.defaultPrintTo, "file") == 0) #else if (strcmp(AppRes.defaultPrintTo, "file") == 0) #endif XmToggleButtonGadgetSetState(w, True, False); PrintWidgets.fileTF = w = XtVaCreateManagedWidget("fileTF", xmTextFieldWidgetClass, radio, NULL); w = XtVaCreateManagedWidget("fileTFBrowse", xmPushButtonGadgetClass, radio, NULL); XtAddCallback(w, XmNactivateCallback, PrintBrowseFileCB, NULL); PrintWidgets.ProgramToggle = w = XtVaCreateManagedWidget("program", xmToggleButtonGadgetClass, radio, NULL); #ifdef HAVE_STRCASECMP if (strcasecmp(AppRes.defaultPrintTo, "program") == 0) #else if (strcmp(AppRes.defaultPrintTo, "program") == 0) #endif XmToggleButtonGadgetSetState(w, True, False); PrintWidgets.programTF = w = XtVaCreateManagedWidget("programTF", xmTextFieldWidgetClass, radio, NULL); XmTextFieldSetString(w, AppRes.program); /* Paper */ w = frame; frame = XtVaCreateManagedWidget("printPaperFrame", xmFrameWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, w, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, NULL); form2 = XtVaCreateManagedWidget("printPaperForm", xmFormWidgetClass, frame, NULL); w = XtVaCreateManagedWidget("printPaperFrameTitle", xmLabelGadgetClass, form2, XmNchildType, XmFRAME_TITLE_CHILD, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, NULL); menu = XmCreatePulldownMenu(form2, "optionMenu", NULL, 0); ac = 0; XtSetArg(al[ac], XmNsubMenuId, menu); ac++; xms = XmStringCreateSimple(_("Paper Format")); XtSetArg(al[ac], XmNlabelString, xms); ac++; cb1 = cb = XmCreateOptionMenu(form2, "optionCB", al, ac); XtManageChild(cb); XmStringFree(xms); npages = PrintGetNumPageSizes(); for (i=0; idoit = True; /* * Check whether this cell has a formula. * Don't change the value if it does. */ if ((cp = find_cell (curow, cucol)) && cp->cell_formula) { Debug(__FILE__, "LeaveCell(%d,%d) has a formula !!\n", cbp->row, cbp->column, cbp->value); return; } Debug(__FILE__, "LeaveCell(%d,%d,%s)\n", cbp->row, cbp->column, cbp->value); /* * Have oleo put the new cell content in place. * * This supposedly returns NULL when all is well, otherwise * an error message. */ r = new_value(cbp->row + 1, cbp->column + 1, cbp->value); if (r) { MessageAppend(True, r); cbp->doit = False; /* veto */ } else { Global->modified = 1; recalculate(1); if (! cp) cp = find_cell (curow, cucol); if (cp && cp->cell_formula) { UpdateStatus(); #if 0 XbaeMatrixRefreshCell(mat, curow - 1, cucol - 1); #endif /* * This veto prevents Xbae from displaying the formula * again. By preventing this, it'll display what we * just put in there: the result of formula evaluation. * * Oh boy. */ cbp->doit = False; /* veto */ } MotifUpdateDisplay(); } } /* * Yuck. Apparently oleo doesn't have an API to change cells. * I seem to have to call goto_region, *and* set curow/cucol. */ void EnterCell(Widget w, XtPointer client, XtPointer call) { struct rng r; CELL *cp; XbaeMatrixEnterCellCallbackStruct *cbp = (XbaeMatrixEnterCellCallbackStruct *)call; char *dec; MotifSelectGlobal(w); Debug(__FILE__, "EnterCell (%d, %d)\n", cbp->row, cbp->column); /* Tell oleo to move */ curow = cbp->row + 1; cucol = cbp->column + 1; r.lr = r.hr = cbp->row + 1; r.hc = r.lc = cbp->column + 1; goto_region(&r); /* Change Formula editor */ #if 1 if (cp = find_cell (curow, cucol)) { dec = decomp (curow, cucol, cp); XmTextFieldSetString(formulatf, dec); } else { XmTextFieldSetString(formulatf, ""); } #else if ((cp = find_cell (curow, cucol)) && cp->cell_formula) { dec = decomp (curow, cucol, cp); XmTextFieldSetString(formulatf, dec); } else { XmTextFieldSetString(formulatf, ""); } #endif } void ModifyVerify(Widget w, XtPointer client, XtPointer call) { XbaeMatrixModifyVerifyCallbackStruct *cbp = (XbaeMatrixModifyVerifyCallbackStruct *)call; MotifSelectGlobal(w); Debug(__FILE__, "ModifyVerify(%d,%d) '%s'\n", cbp->row, cbp->column, cbp->prev_text); } void WriteCell(Widget w, XtPointer client, XtPointer call) { XbaeMatrixWriteCellCallbackStruct *cbp = (XbaeMatrixWriteCellCallbackStruct *)call; MotifSelectGlobal(w); Debug(__FILE__, "WriteCell(%d, %d, %s)\n", cbp->row, cbp->column, cbp->string); } void DrawCell(Widget w, XtPointer client, XtPointer call) { /* This needs to be called otherwise WriteCell won't work. */ XbaeMatrixDrawCellCallbackStruct *cbp = (XbaeMatrixDrawCellCallbackStruct *)call; MotifSelectGlobal(w); cbp->type = XbaeString; #if 1 cbp->string = cell_value_string(cbp->row + 1, cbp->column + 1, True); #else if (curow == cbp->row + 1 && cucol == cbp->column + 1) { cbp->string = cell_value_string(cbp->row + 1, cbp->column + 1, True); } else { cbp->string = print_cell(find_cell(cbp->row + 1, cbp->column + 1)); } #endif #if 0 if (cbp->string && strlen(cbp->string)) fprintf(stderr, "OleoDrawCell(%d,%d) -> [%s]\n", cbp->row, cbp->column, cbp->string); #endif #ifdef VERBOSE Debug(__FILE__, "DrawCell(%d, %d, %s)\n", cbp->row, cbp->column, cbp->string); #endif } void FormulaCB(Widget w, XtPointer client, XtPointer call) { char *s, *r; MotifSelectGlobal(w); s = XmTextFieldGetString(w); Debug(__FILE__, "FormulaCB(%s) -> %d,%d\n", s, curow, cucol); r = new_value(curow, cucol, s); if (r) { MessageAppend(True, r); } else Global->modified = 1; #ifdef FREE_TF_STRING XtFree(s); #endif recalculate(1); /* 1 is recalculate all */ MotifUpdateDisplay(); /* refresh */ } #ifdef XmNresizeRowCallback void ResizeRowCB(Widget w, XtPointer client, XtPointer call) { XbaeMatrixResizeRowCallbackStruct *cbp = (XbaeMatrixResizeRowCallbackStruct *)call; fprintf(stderr, "Resize row %d to height %d\n", cbp->which, cbp->row_heights[cbp->which]); } #endif void ResizeColumnCB(Widget w, XtPointer client, XtPointer call) { XbaeMatrixResizeColumnCallbackStruct *cbp = (XbaeMatrixResizeColumnCallbackStruct *)call; struct rng rng; char wid[20]; MotifSelectGlobal(w); /* Set a range which is a column */ rng.lr = 0; rng.hr = -1; rng.lc = rng.hc = cbp->which + 1; #if 0 fprintf(stderr, "Resize column %d to %d, using range %s\n", cbp->which, cbp->column_widths[cbp->which], range_name(&rng)); #endif sprintf(wid, "%d", cbp->column_widths[cbp->which]); set_region_width(&rng, wid); } /**************************************************************** * * * File interaction * * * ****************************************************************/ void MotifSetWindowName(const char *s) { char *t; t = XtMalloc(strlen(s) + 32); /* enough */ sprintf(t, _("[Oleo: %s]"), s); XtVaSetValues(toplevel, XmNtitle, t, NULL); XtVaSetValues(toplevel, XmNiconName, t, NULL); XtFree(t); } void FileFormatCB(Widget w, XtPointer client, XtPointer call) { char *f = (char *)client, *p; XmString xms; MotifSelectGlobal(w); p = file_get_pattern(f); if (p == NULL) p = f; strcpy(Global->MotifGlobal->fileformat, f); strcpy(Global->MotifGlobal->pattern, "*."); strcat(Global->MotifGlobal->pattern, p); xms = XmStringCreateSimple(Global->MotifGlobal->pattern); XtVaSetValues(fsd, XmNpattern, xms, NULL); XmStringFree(xms); } void ReallyLoadCB(Widget w, XtPointer client, XtPointer call) { XmFileSelectionBoxCallbackStruct *cbp = (XmFileSelectionBoxCallbackStruct *)call; FILE *fp; char *s; MotifSelectGlobal(w); if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &s)) { /* handle error */ return; } if (Global->modified) { /* Handle unsaved changes */ } /* From here it's irreversible */ ResetColumnWidths(); XbaeMatrixCancelEdit(mat, True); fp = fopen(s, "r"); if (fp == NULL) { /* handle error */ XtFree(s); return; } FileSetCurrentFileName(s); read_file_generic(fp, 0, Global->MotifGlobal->fileformat, s); if (fclose(fp) != 0) { /* handle error */ XtFree(s); return; } FixA0(); /* Force calculate */ recalculate(1); /* 1 is all */ /* Force redisplay */ MotifUpdateDisplay(); /* Set the widget as well as the spreadsheet to a default state. */ Global->modified = 0; curow = cucol = 1; XbaeMatrixEditCell(mat, 0, 0); MotifSetWindowName(s); MessageAppend(False, _("Read file '%s'\n"), s); XtFree(s); } void DefaultFileResetCB(Widget w, XtPointer client, XtPointer call) { Widget menu, x; char format[32], *f, *p; XmString xms; MotifSelectGlobal(w); f = file_get_default_format(); strcpy(format, "*."); strcat(format, f ? f : "oleo"); x = XtNameToWidget(fsd, format); menu = XtNameToWidget(fsd, "*optionCB"); XtVaSetValues(menu, XmNmenuHistory, x, NULL); p = file_get_pattern(f ? f : "oleo"); strcpy(format, "*."); strcat(format, p); xms = XmStringCreateSimple(format); XtVaSetValues(fsd, XmNpattern, xms, NULL); XmStringFree(xms); } void CreateFSD() { Arg al[10]; int ac = 0; XmString xms; Widget cb, menu, b; ac = 0; XtSetArg(al[ac], XmNautoUnmanage, True); ac++; xms = XmStringCreateSimple(_("*.oleo")); XtSetArg(al[ac], XmNpattern, xms); ac++; fsd = XmCreateFileSelectionDialog(toplevel, "selectfile", al, ac); XtDestroyWidget( XmFileSelectionBoxGetChild(fsd, XmDIALOG_HELP_BUTTON)); XmStringFree(xms); /* Option menu */ menu = CreateFileFormatOption(fsd, FileFormatCB); XtAddCallback(XtParent(fsd), XmNpopupCallback, DefaultFileResetCB, (XtPointer)menu); } void PopupLoad(void) { Arg al[10]; int ac = 0; if (fsd == NULL) CreateFSD(); XtRemoveAllCallbacks(fsd, XmNokCallback); XtAddCallback(fsd, XmNokCallback, ReallyLoadCB, NULL); ac = 0; XtSetArg(al[ac], XmNtitle, _("Choose a file to load")); ac++; XtSetValues(fsd, al, ac); XtManageChild(fsd); } void LoadCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); PopupLoad(); } void NewCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); /* FIX ME Open a new window */ none(w, client, call); } void DestroyToplevel(Widget w, XtPointer client, XtPointer call) { #if 0 fprintf(stderr, "In DestroyToplevel()\n"); #endif /* * Calling this solves all the issues... */ QuitCB(w, client, call); } /* * MDI : Experimental code to open a second window. */ void OpenNewCB(Widget w, XtPointer client, XtPointer call) { Widget m; Display *d = XtDisplayOfObject(w); XtAppContext appc = Global->MotifGlobal->app_c; MdiOpen(); /* Now we've got another Global pointer */ Global->MotifGlobal->app_c = appc; toplevel = XtVaAppCreateShell(PACKAGE, PACKAGE, topLevelShellWidgetClass, d, NULL); RegisterWMClose(toplevel); XtVaSetValues(toplevel, XmNdeleteResponse, XmDO_NOTHING, NULL); /* FIX ME do we need to do this again ?? */ XtVaGetApplicationResources(toplevel, &AppRes, resources, num_resources, NULL); /* Without this we have NULL in cwin. */ io_init_windows(AppRes.rows, AppRes.columns, 1, 2, 1, 1, 1, 1); m = GscBuildMainWindow(toplevel); XtManageChild(m); XtRealizeWidget(toplevel); PopupLoad(); } void OpenCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); /* * FIX ME * * Figure out when to open a new window : * - when this window has been modified * - when this window has an open file */ if (Global->modified || MdiHasFile()) OpenNewCB(w, client, call); else LoadCB(w, client, call); } void ReallyCloseCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); /* * Destroying the widget tree should take care of calling * MdiClose(), and therefore also of closing the Global * structure. * When MdiClose notices this is the last window, it'll also * exit the application. */ XtDestroyWidget(toplevel); } void CloseCB(Widget w, XtPointer client, XtPointer call) { Arg al[3]; int ac; Widget md; MotifSelectGlobal(w); if (Global->modified && !option_filter) { XmString xms = XmStringCreateLtoR( _("There are unsaved changes.\n" "Do you want to quit anyway ?"), XmFONTLIST_DEFAULT_TAG); ac = 0; /* Application resource for message allow i18n */ XtSetArg(al[ac], XmNmessageString, xms); ac++; md = XmCreateQuestionDialog(toplevel, "quitMB", al, ac); XtAddCallback(md, XmNokCallback, ReallyCloseCB, NULL); XtDestroyWidget(XmMessageBoxGetChild(md, XmDIALOG_HELP_BUTTON)); XtManageChild(md); XmStringFree(xms); return; } /* No dialog - just close */ XtDestroyWidget(toplevel); } FILE *OleoOpenForWrite(const char *s) { FILE *fp; int len; char *fn; if (access(s, R_OK) == 0) { /* Maybe replace it ? */ len = strlen(s) + 2 + strlen(".old"); fn = malloc(len); strcpy(fn, s); strcat(fn, ".old"); unlink(fn); if (rename(s, fn) < 0) { MessageAppend(True, _("OleoOpenForWrite: can't move %s to %s"), s, fn); free(fn); return NULL; } free(fn); } fp = fopen(s, "w"); if (fp == NULL) { /* handle error */ MessageAppend(True, _("OleoOpenForWrite: couldn't open file '%s' for write"), s); return NULL; } return fp; } void ReallySave(const char *s) { FILE *fp; fp = OleoOpenForWrite(s); if (fp == NULL) { /* handle error */ MessageAppend(True, _("ReallySaveCB(%s): couldn't open file for writing"), s); return; } write_file_generic(fp, 0, Global->MotifGlobal->fileformat); if (fclose(fp) != 0) { /* handle error */ MessageAppend(True, _("ReallySaveCB: file close failed")); return; } Global->modified = 0; MessageAppend(False, _("Saved file '%s'\n"), s); MotifSetWindowName(s); } void ReallySaveCB(Widget w, XtPointer client, XtPointer call) { XmFileSelectionBoxCallbackStruct *cbp = (XmFileSelectionBoxCallbackStruct *)call; char *s, *t; MotifSelectGlobal(w); if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &s)) { /* handle error */ MessageAppend(True, _("ReallySaveCB: couldn't figure out file to save into")); return; } ReallySave(s); XtFree(s); } /* * Called from the menu system. * Always pop up a FileSB. */ void SaveAsCB(Widget w, XtPointer client, XtPointer call) { Arg al[10]; int ac = 0; MotifSelectGlobal(w); if (fsd == NULL) CreateFSD(); XtRemoveAllCallbacks(fsd, XmNokCallback); XtAddCallback(fsd, XmNokCallback, ReallySaveCB, NULL); ac = 0; XtSetArg(al[ac], XmNtitle, _("Choose a file to save in")); ac++; XtSetValues(fsd, al, ac); XtManageChild(fsd); } /* * Called from the menu system. * If we don't have a current file, call SaveAs. */ void SaveCB(Widget w, XtPointer client, XtPointer call) { char *s; MotifSelectGlobal(w); if (s = FileGetCurrentFileName()) { ReallySave(s); return; } SaveAsCB(w, client, call); } /**************************************************************** * * * Build Help Widgets * * * ****************************************************************/ #ifdef HAVE_XmHTML_H static void anchorCB(Widget widget, XtPointer client, XtPointer call) { XmHTMLAnchorCallbackStruct *cbs = (XmHTMLAnchorCallbackStruct *) call; char *anchor; MotifSelectGlobal(w); #if 0 fprintf(stderr, "AnchorCB(%s)\n", cbs->href); #endif cbs->doit = True; cbs->visited = True; anchor = strchr(cbs->href, '#'); XmHTMLAnchorScrollToName(Html, anchor); } static void HelpBuildWindow(void) { Widget f, sep, ok; if (! Html) { hd = XtVaCreatePopupShell("helpShell", topLevelShellWidgetClass, toplevel, XmNdeleteResponse, XmUNMAP, NULL); f = XtVaCreateManagedWidget("form", xmFormWidgetClass, hd, NULL); ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, f, XmNtopAttachment, XmATTACH_NONE, XmNtopOffset, 10, XmNtopWidget, sep, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightOffset, 10, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, NULL); XtAddCallback(ok, XmNactivateCallback, PopDownHelpCB, hd); sep = XtVaCreateManagedWidget("separator", xmSeparatorGadgetClass, f, XmNorientation, XmHORIZONTAL, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightOffset, 10, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomOffset, 10, XmNbottomWidget, ok, NULL); Html = XtVaCreateManagedWidget("html", xmHTMLWidgetClass, f, XmNmarginWidth, 20, XmNmarginHeight, 20, XmNwidth, 600, XmNheight, 500, XmNenableBadHTMLWarnings, XmHTML_NONE, XmNscrollBarDisplayPolicy, XmSTATIC, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightOffset, 10, XmNtopOffset, 10, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomOffset, 10, XmNbottomWidget, sep, NULL); XtAddCallback(Html, XmNactivateCallback, (XtCallbackProc)anchorCB, NULL); } } #endif /* * Load a file into the help window. * This probably needs to look at the language. */ #define HELP_FILE_LENGTH 200000 #ifndef HTMLDIR #define HTMLDIR "/usr/local/share/oleo" #endif static void HelpLoadFile(char *fn, char *anchor) { #ifdef HAVE_XmHTML_H char *buffer = XtMalloc(HELP_FILE_LENGTH); FILE *fp = fopen("oleo.html", "r"); char *n; if (fn == NULL) { XmHTMLTextSetString(Html, _("" "Can't find the requested help file\n" "")); return; } n = XtMalloc(256); fp = fopen(fn, "r"); if (fp == NULL) { sprintf(n, "%s/%s/%s", HTMLDIR, getenv("LANGUAGE") != NULL ? getenv("LANGUAGE") : "", fn); fp = fopen(n, "r"); } if (fp == NULL) { sprintf(n, "%s/%s/%s", HTMLDIR, getenv("LANG") != NULL ? getenv("LANG") : "", fn); fp = fopen(n, "r"); } if (fp == NULL) { sprintf(n, "%s/%s", HTMLDIR, fn); fp = fopen(n, "r"); } if (fp) { fread(buffer, 1, HELP_FILE_LENGTH, fp); fclose(fp); XmHTMLTextSetString(Html, buffer); } else { XmHTMLTextSetString(Html, _("" "Can't find the requested help file\n" "")); return; } XtFree(buffer); if (anchor) MessageAppend(False, _("Help requested on '%s'"), anchor); else MessageAppend(False, _("Help requested on using Oleo")); if (anchor) XmHTMLAnchorScrollToName(Html, anchor); XtFree(n); #endif } void helpUsingCB(Widget w, XtPointer client, XtPointer call) { #ifdef HAVE_XmHTML_H MotifSelectGlobal(w); HelpBuildWindow(); HelpLoadFile("oleo.html", client); XtPopup(hd, XtGrabNone); XtManageChild(XtParent(Html)); /* LessTif only, harmless otherwise */ #endif } void helpAboutCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); /* FIX ME */ versionCB(w, client, call); } void helpVersionCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); /* FIX ME */ versionCB(w, client, call); } void MotifUpdateWidth(int col, int wid) { if (Global->MotifGlobal == 0) return; if (! columnwidths) ResetColumnWidths(); columnwidths[col - 1] = wid; if (mat) XtVaSetValues(mat, XmNcolumnWidths, columnwidths, NULL); } void ResetColumnWidths(void) { int i; if (Global->MotifGlobal == 0) return; columnwidths = (short *)XtCalloc(AppRes.columns, sizeof(short)); for (i=0; ia0 ? "%d" : "R%d", i + 1); rowlabels[i] = XtNewString(tmp); } for (i=0; ia0) columnlabels[i] = XtNewString(col_to_str(i+1)); else { sprintf(tmp, "C%d", i + 1); columnlabels[i] = XtNewString(tmp); } columnmaxlengths[i] = 64000; } } void ChangeRowColumnLabels(void) { int i; char tmp[10]; for (i=0; ia0 ? "%d" : "R%d", i + 1); XtFree(rowlabels[i]); rowlabels[i] = XtNewString(tmp); } for (i=0; ia0) columnlabels[i] = XtNewString(col_to_str(i+1)); else { sprintf(tmp, "C%d", i + 1); columnlabels[i] = XtNewString(tmp); } columnmaxlengths[i] = 64000; } } /**************************************************************** * * * Some option settings * * * ****************************************************************/ static void FixA0() { if (Global->MotifGlobal->havea0 == Global->a0) return; Global->MotifGlobal->havea0 = Global->a0; /* Update matrix */ ChangeRowColumnLabels(); XtVaSetValues(mat, XmNrowLabels, rowlabels, XmNcolumnLabels, columnlabels, NULL); } void ToggleA0(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); if (Global->a0) Global->a0 = 0; else Global->a0 = 1; FixA0(); } /**************************************************************** * * * Edit Menu * * * ****************************************************************/ void UndoCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); none(w, client, call); } void EditInsertCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); /* FIX ME */ /* Need to figure out whether to insert row or column */ /* Need to figure out how many rows/columns to treat */ insert_row(1); /* Also need to clear the current cell */ MotifUpdateDisplay(); } void EditDeleteCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); /* FIX ME */ /* Need to figure out whether to delete row or column */ /* Need to figure out how many rows/columns to treat */ delete_row(1); /* Also need to clear the current cell */ MotifUpdateDisplay(); } void EditRecalculateCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); recalculate(1); MotifUpdateDisplay(); } /**************************************************************** * * * Copy/Paste stuff * * * ****************************************************************/ /* * This, and the other copy/paste functions, must act as follows : * - a region is assumed to be selected in the spreadsheet * - the region is converted into more than one selections (only on * request though) : text, value/formula group, ... * - copying to/from the X selection mechanism * - conversion in the other way (preferably the value/formula group, * otherwise text, which can come from other sources as well... ) * * Note that this bypasses the existing oleo copy/paste mechanism. */ void CopyCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); none(w, client, call); } void CutCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); none(w, client, call); } void PasteCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); none(w, client, call); } /**************************************************************** * * * Oleo move/copy functionality * * * ****************************************************************/ void CreateCopyDialog(char *t, void (*cb)(Widget, XtPointer, XtPointer)) { Widget w, rc, cap; Arg al[3]; int ac; XmString ok, cancel; if (copyDialog == NULL) { ac = 0; ok = XmStringCreateSimple(_("OK")); cancel = XmStringCreateSimple(_("Cancel")); XtSetArg(al[ac], XmNokLabelString, ok); ac++; XtSetArg(al[ac], XmNcancelLabelString, cancel); ac++; XtSetArg(al[ac], XmNautoUnmanage, False); ac++; copyDialog = XmCreateTemplateDialog(toplevel, "copyDialog", al, ac); XmStringFree(ok); XmStringFree(cancel); rc = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, copyDialog, NULL); cap = XtVaCreateManagedWidget("cap1", xbaeCaptionWidgetClass, rc, NULL); w = XtVaCreateManagedWidget("r1", xmTextFieldWidgetClass, cap, NULL); RegisterRangeSelector(w); cap = XtVaCreateManagedWidget("cap2", xbaeCaptionWidgetClass, rc, NULL); w = XtVaCreateManagedWidget("r2", xmTextFieldWidgetClass, cap, NULL); RegisterRangeSelector(w); } XtRemoveAllCallbacks(copyDialog, XmNokCallback); XtAddCallback(copyDialog, XmNokCallback, cb, NULL); XtAddCallback(copyDialog, XmNcancelCallback, CancelTemplate, copyDialog); XtVaSetValues(XtParent(copyDialog), XmNtitle, t, NULL); } void ReallyCopyRegionCB(Widget w, XtPointer client, XtPointer call) { Widget ft, tt; char *f, *t, *p; struct rng from, to; int r; MotifSelectGlobal(w); ft = XtNameToWidget(copyDialog, "*r1"); tt = XtNameToWidget(copyDialog, "*r2"); f = XmTextFieldGetString(ft); t = XmTextFieldGetString(tt); p = f; if ((r = parse_cell_or_range(&p, &from)) == 0) ConversionError(f, _("range")); else if ((r & RANGE) == 0) { /* It's a cell address, not a range */ from.hr = from.lr; from.hc = from.lc; } p = t; if ((r = parse_cell_or_range(&p, &to)) == 0) ConversionError(t, _("range")); else if ((r & RANGE) == 0) { /* It's a cell address, not a range */ to.hr = to.lr; to.hc = to.lc; } copy_region(&from, &to); Global->modified = 1; recalculate(1); MotifUpdateDisplay(); #if 0 XtFree(f); XtFree(t); #endif } void ReallyMoveCB(Widget w, XtPointer client, XtPointer call) { Widget ft, tt; char *f, *t, *p; struct rng from, to; int r; MotifSelectGlobal(w); ft = XtNameToWidget(copyDialog, "*r1"); tt = XtNameToWidget(copyDialog, "*r2"); f = XmTextFieldGetString(ft); t = XmTextFieldGetString(tt); MessageAppend(False, "ReallyMoveCB (%s -> %s)!!\n", f, t); p = f; if ((r = parse_cell_or_range(&p, &from)) == 0) ConversionError(f, _("range")); else if ((r & RANGE) == 0) { /* It's a cell address, not a range */ from.hr = from.lr; from.hc = from.lc; } p = t; if ((r = parse_cell_or_range(&p, &to)) == 0) ConversionError(t, _("range")); else if ((r & RANGE) == 0) { /* It's a cell address, not a range */ to.hr = to.lr; to.hc = to.lc; } move_region(&from, &to); Global->modified = 1; recalculate(1); MotifUpdateDisplay(); #if 0 XtFree(f); XtFree(t); #endif } void ReallyCopyValuesCB(Widget w, XtPointer client, XtPointer call) { Widget ft, tt; char *f, *t, *p; struct rng from, to; int r; MotifSelectGlobal(w); ft = XtNameToWidget(copyDialog, "*r1"); tt = XtNameToWidget(copyDialog, "*r2"); f = XmTextFieldGetString(ft); t = XmTextFieldGetString(tt); p = f; if ((r = parse_cell_or_range(&p, &from)) == 0) ConversionError(f, _("range")); else if ((r & RANGE) == 0) { /* It's a cell address, not a range */ from.hr = from.lr; from.hc = from.lc; } p = t; if ((r = parse_cell_or_range(&p, &to)) == 0) ConversionError(t, _("range")); else if ((r & RANGE) == 0) { /* It's a cell address, not a range */ to.hr = to.lr; to.hc = to.lc; } copy_values_region(&from, &to); Global->modified = 1; recalculate(1); MotifUpdateDisplay(); #if 0 XtFree(f); XtFree(t); #endif } void CopyRegionCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); CreateCopyDialog(_("Copy a region"), ReallyCopyRegionCB); XtManageChild(copyDialog); } void CopyValuesCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); CreateCopyDialog(_("Copy Values"), ReallyCopyValuesCB); XtManageChild(copyDialog); } void MoveCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); CreateCopyDialog(_("Move"), ReallyMoveCB); XtManageChild(copyDialog); } void MarkCellCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); } void MarkRegionCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); } void MarkFromDialogCB(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); } /**************************************************************** * * * Formats Dialog * * * ****************************************************************/ static int formats_list[] = { /* 0 */ FMT_DEF, /* 1 */ FMT_HID, /* 2 */ FMT_GPH, /* 3 */ FMT_GEN, /* 4 */ FMT_DOL, /* 5 */ FMT_CMA, /* 6 */ FMT_PCT, /* 7 */ FMT_DEF, /* 8 */ FMT_DEF, /* 9 */ FMT_FXT, /* 10 */ FMT_DEF, /* 11 */ FMT_DATE, /* 12 */ FMT_DEF, /* 13 */ FMT_DEF, /* 14 */ FMT_DEF, /* 15 */ FMT_DEF, /* 16 */ FMT_DEF }; /* * This is ugly. * * Yeah gets called whenever the user manipulates the option menu. * The OK callback only has to figure out what got selected last * (from the global variable) and do its thing. * A cleaner but harder solution would have to figure out which * button is currently selected and translate that into a format. */ void Yeah(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); Global->MotifGlobal->fmt = formats_list[(int) client]; #if 0 fprintf(stderr, "Yeah %d->%d\n", (int)client, Global->MotifGlobal->fmt); #endif } int date_format; void MotifDateFormat(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); date_format = (int) client; } void CreateFormatsDialog(Widget p) { Widget frame, f, tf, l; XmString xms, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; extern char *date_formats[]; Widget menu, cb; Arg al[5]; int ac, i; frame = XtVaCreateManagedWidget("formatsFrame", xmFrameWidgetClass, p, NULL); l = XtVaCreateManagedWidget("formatsFrameTitle", xmLabelGadgetClass, frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, NULL); f = XtVaCreateManagedWidget("formatsForm", xmFormWidgetClass, frame, NULL); l = XtVaCreateManagedWidget("formatsL", xmLabelGadgetClass, f, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNtopOffset, 10, NULL); tf = XtVaCreateManagedWidget("formatsTf", xmTextFieldWidgetClass, f, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, l, XmNleftOffset, 10, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, NULL); RegisterRangeSelector(tf); xms = XmStringCreateSimple(_("Formats :")); x0 = XmStringCreateSimple(_("Default")); /* FMT_DEF */ x1 = XmStringCreateSimple(_("Hidden")); /* FMT_HID */ x2 = XmStringCreateSimple(_("Graph")); /* FMT_GPH */ x3 = XmStringCreateSimple(_("General")); /* FMT_GEN */ x4 = XmStringCreateSimple(_("Dollar")); /* FMT_DOL */ x5 = XmStringCreateSimple(_("Comma")); /* FMT_CMA */ x6 = XmStringCreateSimple(_("Percent")); /* FMT_PCT */ x7 = XmStringCreateSimple(_("Integer")); x8 = XmStringCreateSimple(_("Decimal")); x9 = XmStringCreateSimple(_("Fixed")); x10 = XmStringCreateSimple(_("Exponent")); x11 = XmStringCreateSimple(_("Date")); /* FMT_DATE */ x12 = XmStringCreateSimple(_("User-1")); x13 = XmStringCreateSimple(_("User-2")); x14 = XmStringCreateSimple(_("User-3")); x15 = XmStringCreateSimple(_("User-4")); w = XmVaCreateSimpleOptionMenu(f, "formatsOption", xms, /* mnemonic ? */0, /* initial selection */ 0, /* callback */ Yeah, /* Type, LabelString, Mnemonic, Accelerator, AcceleratorText */ XmVaPUSHBUTTON, x0, 'D', NULL, NULL, XmVaPUSHBUTTON, x1, 'P', NULL, NULL, XmVaPUSHBUTTON, x2, ' ', NULL, NULL, XmVaPUSHBUTTON, x3, ' ', NULL, NULL, XmVaPUSHBUTTON, x4, ' ', NULL, NULL, XmVaPUSHBUTTON, x5, ' ', NULL, NULL, XmVaPUSHBUTTON, x6, ' ', NULL, NULL, XmVaPUSHBUTTON, x7, ' ', NULL, NULL, XmVaPUSHBUTTON, x8, ' ', NULL, NULL, XmVaPUSHBUTTON, x9, ' ', NULL, NULL, XmVaPUSHBUTTON, x10, ' ', NULL, NULL, XmVaPUSHBUTTON, x11, ' ', NULL, NULL, XmVaPUSHBUTTON, x12, ' ', NULL, NULL, XmVaPUSHBUTTON, x13, ' ', NULL, NULL, XmVaPUSHBUTTON, x14, ' ', NULL, NULL, XmVaPUSHBUTTON, x15, ' ', NULL, NULL, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, tf, XmNtopOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, NULL); XtManageChild(w); XmStringFree(xms); XmStringFree(x0); XmStringFree(x1); XmStringFree(x2); XmStringFree(x3); XmStringFree(x4); XmStringFree(x5); XmStringFree(x6); XmStringFree(x7); XmStringFree(x8); XmStringFree(x9); XmStringFree(x10); XmStringFree(x11); XmStringFree(x12); XmStringFree(x13); XmStringFree(x14); XmStringFree(x15); /* Precision */ l = XtVaCreateManagedWidget("precisionL", xmLabelGadgetClass, f, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, w, NULL); tf = XtVaCreateManagedWidget("precisionTf", xmTextFieldWidgetClass, f, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, w, XmNtopOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, l, XmNleftOffset, 10, NULL); /* A dialog for date formats */ menu = XmCreatePulldownMenu(f, "optionMenu", NULL, 0); ac = 0; XtSetArg(al[ac], XmNsubMenuId, menu); ac++; xms = XmStringCreateSimple(_("Date Format")); XtSetArg(al[ac], XmNlabelString, xms); ac++; cb = XmCreateOptionMenu(f, "optionCB", al, ac); XtVaSetValues(cb, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, tf, XmNtopOffset, 10, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 10, NULL); XtManageChild(cb); XmStringFree(xms); for (i=0; date_formats[i]; i++) { ac = 0; xms = XmStringCreateSimple(date_formats[i]); XtSetArg(al[ac], XmNlabelString, xms); ac++; w = XmCreatePushButtonGadget(menu, "button", al, ac); if (i == 0) XtVaSetValues(menu, XmNmenuHistory, w, NULL); XtAddCallback(w, XmNactivateCallback, MotifDateFormat, (XtPointer)i); XmStringFree(xms); XtManageChild(w); } } /* * Set formats both on cells/ranges and as default. * client_data = 1 means set the default. */ void FormatsDialogOk(Widget w, XtPointer client, XtPointer call) { struct rng rng; Widget om, b = NULL, tf, pr; char *p, *s = NULL, *prec = NULL; int r, precision; MotifSelectGlobal(w); XtUnmanageChild(FormatD); om = XtNameToWidget(FormatD, "*formatsFrame*formatsOption*formatsOption"); tf = XtNameToWidget(FormatD, "*formatsFrame*formatsTf"); pr = XtNameToWidget(FormatD, "*formatsFrame*precisionTf"); if (om) XtVaGetValues(om, XmNmenuHistory, &b, NULL); if (tf) p = s = XmTextFieldGetString(tf); if (pr) { prec = XmTextFieldGetString(pr); if (prec) precision = atoi(prec); } /* date */ if (Global->MotifGlobal->fmt == FMT_DATE) precision = date_format; if (client) { /* Set default */ default_fmt = Global->MotifGlobal->fmt; default_prc = precision; MessageAppend(False, "Set Default Format %d, precision %d\n", default_fmt, default_prc); recalculate(1); MotifUpdateDisplay(); } else { if (p) { if ((r = parse_cell_or_range(&p, &rng)) == 0) ConversionError(s, _("range")); else if (r & RANGE) { MessageAppend(False, "FormatRegion %s\n", range_name(&rng)); format_region(&rng, Global->MotifGlobal->fmt, -1); precision_region(&rng, precision); recalculate(1); MotifUpdateDisplay(); } else { rng.hr = rng.lr; rng.hc = rng.lc; format_region(&rng, Global->MotifGlobal->fmt, -1); precision_region(&rng, precision); recalculate(1); MotifUpdateDisplay(); } } } #ifdef FREE_TF_STRING XtFree(s); XtFree(prec); #endif } void FormatsDialogReset(Widget d) { } void FormatsDialog(Widget w, XtPointer client, XtPointer call) { Widget ok, cancel, help, tf; int c = (int)client, ac; Arg al[5]; MotifSelectGlobal(w); if (! FormatD) { ac = 0; XtSetArg(al[ac], XmNautoUnmanage, False); ac++; FormatD = XmCreateTemplateDialog(mw, "formatsDialog", al, ac); CreateFormatsDialog(FormatD); ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, FormatD, NULL); cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass, FormatD, NULL); help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass, FormatD, NULL); XtAddCallback(ok, XmNactivateCallback, FormatsDialogOk, (XtPointer)client); /* Whether or not it's a default setting */ XtAddCallback(help, XmNactivateCallback, helpUsingCB, (XtPointer)"#HelpFormats"); XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, FormatD); } tf = XtNameToWidget(FormatD, "*formatsFrame*formatsTf"); if (tf) XtSetSensitive(tf, 1 - c); FormatsDialogReset(FormatD); XtManageChild(FormatD); } /**************************************************************** * * * Generic Dialog Support * * * ****************************************************************/ /* * Walk up widget tree until a shell is found. * The previous widget is the one returned. */ static Widget FindDialog(Widget w) { Widget p, q; p = q = w; for (p=q=w; q=p, p=XtParent(p); p != NULL && q != NULL & !XmIsDialogShell(p)) ; return q; } /**************************************************************** * * * User Preferences * * * ****************************************************************/ void UserPreferencesOk(Widget w, XtPointer client, XtPointer call) { Widget mft, ft, etf; char *mf, f; XmFontList fl; XmFontListEntry fle; XFontSet fs; char m1[2][80], **missing = (char **)&m1[0]; char m2[80], *def = &m2[0]; int nmissing = 0; Display *d = XtDisplayOfObject(w); MotifSelectGlobal(w); XtUnmanageChild(UserPref); mft = XtNameToWidget(UserPref, "*matrixfonttf"); ft = XtNameToWidget(UserPref, "*fonttf"); etf = XtNameToWidget(UserPref, "*encodingTf"); if (ft == NULL || mft == NULL || etf == NULL) return; /* Huh ?? */ mf = XmTextFieldGetString(mft); /* set preferences now */ fs = XCreateFontSet(d, mf, &missing, &nmissing, &def); if (fs != NULL) { fle = XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG, XmFONT_IS_FONTSET, fs); fl = XmFontListAppendEntry(NULL, fle); XtVaSetValues(mat, XmNfontList, fl, NULL); /* FIX ME potential leak : can we free fl, fle, fs yet ? */ OleoSetEncoding(XmTextFieldGetString(etf)); } XtFree(mf); } void UserPreferencesReset(Widget w) { Widget e = XtNameToWidget(w, "*encodingTf"); if (e) XmTextFieldSetString(e, OleoGetEncoding()); } #ifdef HAVE_XLT_FONTCHOOSER #include #endif static void ChooseFont(Widget w, XtPointer client, XtPointer call) { #ifdef HAVE_XLT_FONTCHOOSER char *s; Widget tf; MotifSelectGlobal(w); XtVaGetValues(w, XltNfontName, &s, NULL); fprintf(stderr, "Selected font '%s'\n", s); tf = XtNameToWidget(UserPref, "*matrixfonttf"); if (tf) XmTextFieldSetString(tf, s); #endif } void FontChooserCB(Widget w, XtPointer client, XtPointer call) { #ifdef HAVE_XLT_FONTCHOOSER Widget tf = (Widget)client, fc; Arg al[5]; int ac; MotifSelectGlobal(w); ac = 0; fc = XltCreateFontChooserDialog(toplevel, "font chooser", al, ac); XtManageChild(fc); XtAddCallback(fc, XmNokCallback, ChooseFont, NULL); #endif } void CreateUserPreferences(Widget parent) { Widget form, l, t, b; form = XtVaCreateManagedWidget("form", xmFormWidgetClass, parent, NULL); XtManageChild(form); l = XtVaCreateManagedWidget("matrixfontlabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_NONE, NULL); t = XtVaCreateManagedWidget("matrixfonttf", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftOffset, 10, XmNleftWidget, l, XmNrightAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_NONE, NULL); b = XtVaCreateManagedWidget("matrixfontbutton", xmPushButtonGadgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftOffset, 10, XmNleftWidget, t, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, NULL); XtAddCallback(b, XmNactivateCallback, FontChooserCB, (XtPointer)t); l = XtVaCreateManagedWidget("fontlabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, t, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, t, XmNrightOffset, 10, XmNbottomAttachment, XmATTACH_NONE, NULL); t = XtVaCreateManagedWidget("fonttf", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, t, XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET, XmNrightWidget, t, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, t, NULL); b = XtVaCreateManagedWidget("fontbutton", xmPushButtonGadgetClass, form, XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, XmNtopOffset, 0, XmNtopWidget, t, XmNleftAttachment, XmATTACH_WIDGET, XmNleftOffset, 10, XmNleftWidget, t, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, NULL); XtAddCallback(b, XmNactivateCallback, FontChooserCB, (XtPointer)t); l = XtVaCreateManagedWidget("encodingLabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, t, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, t, XmNrightOffset, 10, XmNbottomAttachment, XmATTACH_NONE, NULL); t = XtVaCreateManagedWidget("encodingTf", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, t, XmNbottomAttachment, XmATTACH_NONE, XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET, XmNrightWidget, t, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, t, NULL); } void DoUserPreferences(Widget w, XtPointer client, XtPointer call) { Widget ok, cancel, help, tf; int c = (int)client, ac; Arg al[5]; MotifSelectGlobal(w); if (! UserPref) { ac = 0; XtSetArg(al[ac], XmNautoUnmanage, False); ac++; UserPref = XmCreateTemplateDialog(mw, "UserPreferences", al, ac); CreateUserPreferences(UserPref); ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, UserPref, NULL); cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass, UserPref, NULL); help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass, UserPref, NULL); XtAddCallback(ok, XmNactivateCallback, UserPreferencesOk, NULL); XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, UserPref); XtAddCallback(help, XmNactivateCallback, helpUsingCB, (XtPointer)"#HelpUserPreferences"); } UserPreferencesReset(UserPref); XtManageChild(UserPref); } void SaveUserPreferences(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); save_preferences(); } /**************************************************************** * * * Database Interaction * * * ****************************************************************/ void DoMySQLRead(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); none(w, client, call); } void DoMySQLWrite(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); none(w, client, call); } void DoXbaseRead(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); none(w, client, call); } void DoXbaseWrite(Widget w, XtPointer client, XtPointer call) { MotifSelectGlobal(w); none(w, client, call); } void MySQLDialogOk(Widget w, XtPointer client, XtPointer call) { Widget d = FindDialog(w), dbhosttf = XtNameToWidget(d, "*dbhosttf"), dbnametf = XtNameToWidget(d, "*dbnametf"), dbusertf = XtNameToWidget(d, "*dbusertf"); char *h, *n, *u; MotifSelectGlobal(w); XtUnmanageChild(MySQLDialog); if (dbhosttf == NULL || dbnametf == NULL) return; h = XmTextFieldGetString(dbhosttf); DatabaseSetHost(h); n = XmTextFieldGetString(dbnametf); DatabaseSetName(n); u = XmTextFieldGetString(dbusertf); DatabaseSetUser(u); MessageAppend(False, "Database host %s name %s user %s", h, n, u); XtFree(h); XtFree(n); XtFree(u); } void ConfigureMySQLDialogReset(Widget w) { Widget d = FindDialog(w), dbhosttf = XtNameToWidget(d, "*dbhosttf"), dbnametf = XtNameToWidget(d, "*dbnametf"), dbusertf = XtNameToWidget(d, "*dbusertf"); if (dbhosttf == NULL || dbnametf == NULL) return; XmTextFieldSetString(dbhosttf, DatabaseGetHost()); XmTextFieldSetString(dbnametf, DatabaseGetName()); XmTextFieldSetString(dbusertf, DatabaseGetUser()); } void CreateConfigureMySQLDialog(Widget parent) { Widget form, l, t; form = XtVaCreateManagedWidget("form", xmFormWidgetClass, parent, NULL); XtManageChild(form); l = XtVaCreateManagedWidget("dbhostlabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_NONE, NULL); t = XtVaCreateManagedWidget("dbhosttf", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftOffset, 10, XmNleftWidget, l, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNbottomAttachment, XmATTACH_NONE, NULL); l = XtVaCreateManagedWidget("dbnamelabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, t, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_NONE, NULL); t = XtVaCreateManagedWidget("dbnametf", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, t, XmNleftAttachment, XmATTACH_WIDGET, XmNleftOffset, 10, XmNleftWidget, l, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNbottomAttachment, XmATTACH_NONE, NULL); l = XtVaCreateManagedWidget("dbuserlabel", xmLabelGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, t, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 10, XmNrightAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_NONE, NULL); t = XtVaCreateManagedWidget("dbusertf", xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopOffset, 10, XmNtopWidget, t, XmNleftAttachment, XmATTACH_WIDGET, XmNleftOffset, 10, XmNleftWidget, l, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 10, XmNbottomAttachment, XmATTACH_NONE, NULL); } void ConfigureMySQL(Widget w, XtPointer client, XtPointer call) { Widget ok, cancel, help, tf; int c = (int)client, ac; Arg al[5]; MotifSelectGlobal(w); if (! MySQLDialog) { ac = 0; XtSetArg(al[ac], XmNautoUnmanage, False); ac++; MySQLDialog = XmCreateTemplateDialog(mw, "mySQLDialog", al, ac); CreateConfigureMySQLDialog(MySQLDialog); ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, MySQLDialog, NULL); cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass, MySQLDialog, NULL); help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass, MySQLDialog, NULL); XtAddCallback(ok, XmNactivateCallback, MySQLDialogOk, NULL); XtAddCallback(help, XmNactivateCallback, helpUsingCB, (XtPointer)"#HelpMySQL"); XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, MySQLDialog); } ConfigureMySQLDialogReset(MySQLDialog); XtManageChild(MySQLDialog); } void ExecuteCommandOk(Widget w, XtPointer client, XtPointer call) { XmSelectionBoxCallbackStruct *cbp = (XmSelectionBoxCallbackStruct *)call; String s; MotifSelectGlobal(w); if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &s)) { MessageAppend(True, "Couldn't convert XmString into string\n"); return; } MessageAppend(False, "Executing command '%s'\n", s); execute_command(s); XtFree(s); } void ExecuteCommandCB(Widget w, XtPointer client, XtPointer call) { int ac; Arg al[5]; MotifSelectGlobal(w); if (! ExecuteCommandDialog) { ac = 0; XtSetArg(al[ac], XmNautoUnmanage, False); ac++; ExecuteCommandDialog = XmCreatePromptDialog(mw, "executeCommandDialog", al, ac); XtAddCallback(ExecuteCommandDialog, XmNokCallback, ExecuteCommandOk, NULL); XtAddCallback(ExecuteCommandDialog, XmNhelpCallback, helpUsingCB, (XtPointer)"#HelpExecuteCommand"); XtAddCallback(ExecuteCommandDialog, XmNcancelCallback, CancelTemplate, (XtPointer)ExecuteCommandDialog); } XtManageChild(ExecuteCommandDialog); } /**************************************************************** * * * Build Motif GUI * * * ****************************************************************/ /* * Build a splash screen */ Widget GscBuildSplash(Widget parent) { Arg al[10]; int ac; Pixel bg, fg; Display *dpy = XtDisplay(parent); int depth; Widget sh, rc, iconlabel, textlabel, form; XmString x1, x2, xms; #ifdef HAVE_LIBXPM XpmAttributes attrib; Pixmap mask; #endif sh = XtVaCreatePopupShell("splashShell", xmMenuShellWidgetClass, parent, #if 0 XmNallowShellResize, False, #endif XmNx, 300, XmNy, 300, XmNwidth, 100, XmNheight, 100, NULL); /* MenuShell wants an RC child */ rc = XtVaCreateManagedWidget("splash", xmRowColumnWidgetClass, sh, NULL); form = XtVaCreateWidget("form", xmFormWidgetClass, rc, NULL); ac = 0; #ifdef HAVE_LIBXPM attrib.closeness = 256; attrib.valuemask = 0; attrib.valuemask |= XpmCloseness; ac = XpmCreatePixmapFromData(XtDisplay(rc), XRootWindowOfScreen(XtScreen(rc)), oleo_icon, &Global->MotifGlobal->oleo_icon_pm, &mask, &attrib); if ( ac < 0 ) { fprintf ( stderr, "GBSplash: XpmCreatePixmapFromData failed. "); switch ( ac ) { case -1: fprintf ( stderr, "XpmOpenFailed failed\n" ); XpmFreeAttributes(&attrib); goto skip_xpm_icon; break; case -2: fprintf ( stderr, "XpmFileInvalid\n" ); XpmFreeAttributes(&attrib); goto skip_xpm_icon; break; case -3: fprintf ( stderr, "XpmNoMemory\n" ); goto skip_xpm_icon; XpmFreeAttributes(&attrib); break; case -4: while ( attrib.closeness <= 10000 ) { attrib.closeness += 256; ac = XpmCreatePixmapFromData(XtDisplay(rc), XRootWindowOfScreen(XtScreen(rc)), oleo_icon, &Global->MotifGlobal->oleo_icon_pm, &mask, &attrib); if ( ac == -4 ) continue; if ( ac >= 0 ) break; if ( ac == -1 || ac == -2 || ac == -3 ) { fprintf ( stderr, "secondary error %d\n", ac ); XpmFreeAttributes(&attrib); goto skip_xpm_icon; } } /* while ( attrib.closeness <= 10000 ) */ if ( attrib.closeness > 10000 ) { fprintf ( stderr, "giving up, can't get close colors\n" ); XpmFreeAttributes(&attrib); goto skip_xpm_icon; } else fprintf ( stderr, "\n" ); break; default: break; } /* switch (ac) */ } /* if ( ac < 0 ) */ ac = 0; XpmFreeAttributes(&attrib); XtSetArg(al[ac], XmNlabelPixmap, Global->MotifGlobal->oleo_icon_pm); ac++; XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++; XtSetArg(al[ac], XmNshadowThickness, 0); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNleftOffset, 0); ac++; XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNtopOffset, 0); ac++; iconlabel = XmCreatePushButtonGadget(form, "iconsplash", al, ac); XtManageChild(iconlabel); XtAddCallback(iconlabel, XmNactivateCallback, PopDownSplash, NULL); #endif skip_xpm_icon: /* XpmCreatePixmapFromData call failed -- skip it */ ac = 0; x1 = XmStringCreateLtoR(GNU_PACKAGE " " VERSION "\n", "large"); x2 = XmStringCreateLtoR(CopyRightString, "small"); xms = XmStringConcat(x1, x2); XtSetArg(al[ac], XmNlabelString, xms); ac++; XtSetArg(al[ac], XmNlabelType, XmSTRING); ac++; XtSetArg(al[ac], XmNshadowThickness, 0); ac++; #ifdef HAVE_LIBXPM XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNleftWidget, iconlabel); ac++; #else XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; #endif XtSetArg(al[ac], XmNleftOffset, 0); ac++; XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNrightOffset, 0); ac++; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNtopOffset, 0); ac++; textlabel = XmCreatePushButtonGadget(form, "textsplash", al, ac); XtManageChild(textlabel); XtAddCallback(textlabel, XmNactivateCallback, PopDownSplash, NULL); XmStringFree(x1); XmStringFree(x2); XmStringFree(xms); XtManageChild(form); return sh; } void Traverse() { if (! XmProcessTraversal(mat, XmTRAVERSE_CURRENT)) { fprintf(stderr, _("XmProcessTraversal failed\n")); } } /* * Create the main widget tree. */ Widget GscBuildMainWindow(Widget parent) { int i; /* * Structure */ mw = XmCreateMainWindow(parent, "mw", NULL, 0); XtManageChild(mw); mb = XmCreateMenuBar(mw, "menubar", NULL, 0); XtManageChild(mb); filemenu = XmCreatePulldownMenu(mb, "filemenu", NULL, 0); XtManageChild(filemenu); XtVaCreateManagedWidget("filecascade", xmCascadeButtonGadgetClass, mb, XmNsubMenuId, filemenu, NULL); editmenu = XmCreatePulldownMenu(mb, "editmenu", NULL, 0); XtManageChild(editmenu); XtVaCreateManagedWidget("editcascade", xmCascadeButtonGadgetClass, mb, XmNsubMenuId, editmenu, NULL); stylemenu = XmCreatePulldownMenu(mb, "stylemenu", NULL, 0); XtManageChild(stylemenu); XtVaCreateManagedWidget("stylecascade", xmCascadeButtonGadgetClass, mb, XmNsubMenuId, stylemenu, NULL); optionsmenu = XmCreatePulldownMenu(mb, "optionsmenu", NULL, 0); XtManageChild(optionsmenu); XtVaCreateManagedWidget("optionscascade", xmCascadeButtonGadgetClass, mb, XmNsubMenuId, optionsmenu, NULL); graphmenu = XmCreatePulldownMenu(mb, "graphmenu", NULL, 0); XtManageChild(graphmenu); XtVaCreateManagedWidget("graphcascade", xmCascadeButtonGadgetClass, mb, XmNsubMenuId, graphmenu, NULL); helpmenu = XmCreatePulldownMenu(mb, "helpmenu", NULL, 0); XtManageChild(helpmenu); w = XtVaCreateManagedWidget("helpcascade", xmCascadeButtonGadgetClass, mb, XmNsubMenuId, helpmenu, NULL); XtVaSetValues(mb, XmNmenuHelpWidget, w, NULL); /* * Row- and column labels */ if (! columnwidths) ResetColumnWidths(); SetRowColumnLabels(); /* * The main thing : BaeMatrix * * A couple of application resources determine how big the matrix * should be made. * FIX ME. */ mat = XtVaCreateManagedWidget("bae", xbaeMatrixWidgetClass, mw, XmNrowLabels, rowlabels, XmNcolumnLabels, columnlabels, XmNcolumnWidths, columnwidths, XmNcolumnMaxLengths, columnmaxlengths, XmNrows, AppRes.rows, XmNcolumns, AppRes.columns, NULL); XtAddCallback(mat, XmNleaveCellCallback, LeaveCell, NULL); XtAddCallback(mat, XmNenterCellCallback, EnterCell, NULL); XtAddCallback(mat, XmNmodifyVerifyCallback, ModifyVerify, NULL); XtAddCallback(mat, XmNdrawCellCallback, DrawCell, NULL); XtAddCallback(mat, XmNwriteCellCallback, WriteCell, NULL); XtAddCallback(mat, XmNselectCellCallback, SelectCellCB, NULL); XtAddCallback(mat, XmNresizeColumnCallback, ResizeColumnCB, NULL); #ifdef XmNresizeRowCallback XtAddCallback(mat, XmNresizeRowCallback, ResizeRowCB, NULL); #endif /* * We're building a small combo of two widgets which will represent * one area in the MainWindow : a status area, and a formula editor. */ w = XtVaCreateManagedWidget("statusformula", xmFormWidgetClass, mw, NULL); statustf = XtVaCreateManagedWidget("status", xmTextFieldWidgetClass, w, XmNeditable, False, XmNblinkRate, 0, NULL); formulatf = XtVaCreateManagedWidget("formula", xmTextFieldWidgetClass, w, XmNleftWidget, statustf, XmNleftOffset, 5, XmNleftAttachment, XmATTACH_WIDGET, NULL); XtAddCallback(formulatf, XmNactivateCallback, FormulaCB, 0); /* * Oleo error messages */ msgtext = XmCreateScrolledText(mw, "messages", NULL, 0); XtVaSetValues(mw, XmNmessageWindow, XtParent(msgtext), XmNcommandWindow, w, NULL); XtManageChild(msgtext); if (Global->MotifGlobal->early_msg_text) { XmTextSetString(msgtext, Global->MotifGlobal->early_msg_text); free(Global->MotifGlobal->early_msg_text); Global->MotifGlobal->early_msg_text = NULL; XmTextShowPosition(msgtext, XmTextGetLastPosition(msgtext)); XBell(XtDisplay(msgtext), 30); } /* * Menu system contents : * File Menu. */ w = XtVaCreateManagedWidget("new", xmPushButtonGadgetClass, filemenu, NULL); XtAddCallback(w, XmNactivateCallback, NewCB, NULL); w = XtVaCreateManagedWidget("open", xmPushButtonGadgetClass, filemenu, NULL); XtAddCallback(w, XmNactivateCallback, OpenCB, NULL); w = XtVaCreateManagedWidget("save", xmPushButtonGadgetClass, filemenu, NULL); XtAddCallback(w, XmNactivateCallback, SaveCB, NULL); w = XtVaCreateManagedWidget("saveas", xmPushButtonGadgetClass, filemenu, NULL); XtAddCallback(w, XmNactivateCallback, SaveAsCB, NULL); w = XtVaCreateManagedWidget("close", xmPushButtonGadgetClass, filemenu, NULL); XtAddCallback(w, XmNactivateCallback, CloseCB, NULL); w = XtVaCreateManagedWidget("print", xmPushButtonGadgetClass, filemenu, NULL); XtAddCallback(w, XmNactivateCallback, printCB, NULL); w = XtVaCreateManagedWidget("quit", xmPushButtonGadgetClass, filemenu, NULL); XtAddCallback(w, XmNactivateCallback, QuitCB, NULL); /* * Edit Menu. */ w = XtVaCreateManagedWidget("undo", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, UndoCB, NULL); XtVaCreateManagedWidget("sep1", xmSeparatorGadgetClass, editmenu, NULL); w = XtVaCreateManagedWidget("copy", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, CopyCB, NULL); w = XtVaCreateManagedWidget("cut", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, CutCB, NULL); w = XtVaCreateManagedWidget("paste", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, PasteCB, NULL); XtVaCreateManagedWidget("sep2", xmSeparatorGadgetClass, editmenu, NULL); w = XtVaCreateManagedWidget("sort", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); w = XtVaCreateManagedWidget("copyvalues", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, CopyValuesCB, NULL); w = XtVaCreateManagedWidget("copyregion", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, CopyRegionCB, NULL); w = XtVaCreateManagedWidget("move", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, MoveCB, NULL); XtVaCreateManagedWidget("sep3", xmSeparatorGadgetClass, editmenu, NULL); w = XtVaCreateManagedWidget("insert", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, EditInsertCB, NULL); w = XtVaCreateManagedWidget("delete", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, EditDeleteCB, NULL); XtVaCreateManagedWidget("sep4", xmSeparatorGadgetClass, editmenu, NULL); w = XtVaCreateManagedWidget("recalculate", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, EditRecalculateCB, NULL); XtVaCreateManagedWidget("sep5", xmSeparatorGadgetClass, editmenu, NULL); w = XtVaCreateManagedWidget("setregion", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); w = XtVaCreateManagedWidget("markcell", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, MarkCellCB, NULL); w = XtVaCreateManagedWidget("markregion", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, MarkRegionCB, NULL); w = XtVaCreateManagedWidget("setmark", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, MarkFromDialogCB, NULL); w = XtVaCreateManagedWidget("gotocell", xmPushButtonGadgetClass, editmenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); /* * Style Menu. */ w = XtVaCreateManagedWidget("format", xmPushButtonGadgetClass, stylemenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); w = XtVaCreateManagedWidget("alignment", xmPushButtonGadgetClass, stylemenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); w = XtVaCreateManagedWidget("font", xmPushButtonGadgetClass, stylemenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); XtVaCreateManagedWidget("sep1", xmSeparatorGadgetClass, stylemenu, NULL); w = XtVaCreateManagedWidget("width", xmPushButtonGadgetClass, stylemenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); w = XtVaCreateManagedWidget("height", xmPushButtonGadgetClass, stylemenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); XtVaCreateManagedWidget("sep2", xmSeparatorGadgetClass, stylemenu, NULL); w = XtVaCreateManagedWidget("protection", xmPushButtonGadgetClass, stylemenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); /* * Graph Menu. */ w = XtVaCreateManagedWidget("define", xmPushButtonGadgetClass, graphmenu, NULL); #ifdef HAVE_LIBPLOT XtAddCallback(w, XmNactivateCallback, ConfigureGraph, NULL); #else XtAddCallback(w, XmNactivateCallback, NoPlotutils, NULL); #endif #ifdef HAVE_SciPlot_H w = XtVaCreateManagedWidget("show", xmPushButtonGadgetClass, graphmenu, NULL); XtAddCallback(w, XmNactivateCallback, ShowGraph, NULL); w = XtVaCreateManagedWidget("print", xmPushButtonGadgetClass, graphmenu, NULL); XtAddCallback(w, XmNactivateCallback, PrintGraph, NULL); #endif #ifdef HAVE_LIBPLOT /* GNU Plotutils */ w = XtVaCreateManagedWidget("pulabel", xmLabelGadgetClass, graphmenu, NULL); w = XtVaCreateManagedWidget("pushowpie", xmPushButtonGadgetClass, graphmenu, NULL); XtAddCallback(w, XmNactivateCallback, PuShowChart, PuPieChart); w = XtVaCreateManagedWidget("pushowbar", xmPushButtonGadgetClass, graphmenu, NULL); XtAddCallback(w, XmNactivateCallback, PuShowChart, PuBarChart); w = XtVaCreateManagedWidget("pushowxy", xmPushButtonGadgetClass, graphmenu, NULL); XtAddCallback(w, XmNactivateCallback, PuShowChart, PuXYChart); w = XtVaCreateManagedWidget("puprintpie", xmPushButtonGadgetClass, graphmenu, NULL); XtAddCallback(w, XmNactivateCallback, PuPrint, (XtPointer)GRAPH_PIE); w = XtVaCreateManagedWidget("puprintbar", xmPushButtonGadgetClass, graphmenu, NULL); XtAddCallback(w, XmNactivateCallback, PuPrint, (XtPointer)GRAPH_BAR); w = XtVaCreateManagedWidget("puprintxy", xmPushButtonGadgetClass, graphmenu, NULL); XtAddCallback(w, XmNactivateCallback, PuPrint, (XtPointer)GRAPH_XY); #endif /* * Options Menu. */ w = XtVaCreateManagedWidget("a0", xmToggleButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNvalueChangedCallback, ToggleA0, NULL); XmToggleButtonGadgetSetState(w, Global->a0, False); w = XtVaCreateManagedWidget("edges", xmToggleButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNvalueChangedCallback, none, NULL); XmToggleButtonGadgetSetState(w, cwin->flags & WIN_EDGES, False); w = XtVaCreateManagedWidget("autorecalc", xmToggleButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNvalueChangedCallback, none, NULL); XmToggleButtonGadgetSetState(w, Global->auto_recalc, False); w = XtVaCreateManagedWidget("loadhooks", xmToggleButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNvalueChangedCallback, none, NULL); XmToggleButtonGadgetSetState(w, UserPreferences.run_load_hooks, False); w = XtVaCreateManagedWidget("statusline", xmToggleButtonGadgetClass, optionsmenu, NULL); XmToggleButtonGadgetSetState(w, Global->a0, False); XtAddCallback(w, XmNvalueChangedCallback, none, NULL); w = XtVaCreateManagedWidget("backup", xmToggleButtonGadgetClass, optionsmenu, NULL); XmToggleButtonGadgetSetState(w, __make_backups, False); XtAddCallback(w, XmNvalueChangedCallback, none, NULL); w = XtVaCreateManagedWidget("backupcopy", xmToggleButtonGadgetClass, optionsmenu, NULL); XmToggleButtonGadgetSetState(w, __backup_by_copying, False); XtAddCallback(w, XmNvalueChangedCallback, none, NULL); XtVaCreateManagedWidget("sep1", xmSeparatorGadgetClass, optionsmenu, NULL); w = XtVaCreateManagedWidget("formats", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, FormatsDialog, NULL); w = XtVaCreateManagedWidget("defaultformat", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, FormatsDialog, (XtPointer) 1); w = XtVaCreateManagedWidget("printoptions", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, PrintOptionsCB, NULL); w = XtVaCreateManagedWidget("defaultfileformat", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, DefaultFileCB, NULL); XtVaCreateManagedWidget("sep2", xmSeparatorGadgetClass, optionsmenu, NULL); w = XtVaCreateManagedWidget("setvariable", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); w = XtVaCreateManagedWidget("showvariable", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); w = XtVaCreateManagedWidget("listvariables", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); w = XtVaCreateManagedWidget("showoptions", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, none, NULL); XtVaCreateManagedWidget("sep3", xmSeparatorGadgetClass, optionsmenu, NULL); w = XtVaCreateManagedWidget("userpreferences", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, DoUserPreferences, NULL); w = XtVaCreateManagedWidget("saveuserpreferences", xmPushButtonGadgetClass, optionsmenu, NULL); XtAddCallback(w, XmNactivateCallback, SaveUserPreferences, NULL); /* * Database Access */ dbmenu = XmCreatePulldownMenu(mb, "dbmenu", NULL, 0); XtManageChild(dbmenu); w = XtVaCreateManagedWidget("dbcascade", xmCascadeButtonGadgetClass, mb, XmNsubMenuId, dbmenu, NULL); #ifdef HAVE_LIBMYSQLCLIENT w = XtVaCreateManagedWidget("configuremysql", xmPushButtonGadgetClass, dbmenu, NULL); XtAddCallback(w, XmNactivateCallback, ConfigureMySQL, NULL); w = XtVaCreateManagedWidget("readmysql", xmPushButtonGadgetClass, dbmenu, NULL); XtAddCallback(w, XmNactivateCallback, DoMySQLRead, NULL); w = XtVaCreateManagedWidget("writemysql", xmPushButtonGadgetClass, dbmenu, NULL); XtAddCallback(w, XmNactivateCallback, DoMySQLWrite, NULL); #endif #if defined(HAVE_LIBMYSQLCLIENT) && defined(HAVE_LIBXBASE) w = XtVaCreateManagedWidget("sep", xmSeparatorGadgetClass, dbmenu, NULL); #endif #if (! defined(HAVE_LIBMYSQLCLIENT)) && (! defined(HAVE_LIBXBASE)) /* This only happens if no db linked in */ w = XtVaCreateManagedWidget("nodbms", xmLabelGadgetClass, dbmenu, NULL); #endif #ifdef HAVE_LIBXBASE w = XtVaCreateManagedWidget("readxbase", xmPushButtonGadgetClass, dbmenu, NULL); XtAddCallback(w, XmNactivateCallback, DoXbaseRead, NULL); w = XtVaCreateManagedWidget("writexbase", xmPushButtonGadgetClass, dbmenu, NULL); XtAddCallback(w, XmNactivateCallback, DoXbaseWrite, NULL); #endif /* * Add test code here */ #ifdef HAVE_TEST testmenu = XmCreatePulldownMenu(mb, "testmenu", NULL, 0); XtManageChild(testmenu); w = XtVaCreateManagedWidget("testcascade", xmCascadeButtonGadgetClass, mb, XmNsubMenuId, testmenu, NULL); w = XtVaCreateManagedWidget("Traverse", xmPushButtonGadgetClass, testmenu, NULL); XtAddCallback(w, XmNactivateCallback, Traverse, NULL); w = XtVaCreateManagedWidget("OpenNew", xmPushButtonGadgetClass, testmenu, NULL); XtAddCallback(w, XmNactivateCallback, OpenNewCB, NULL); w = XtVaCreateManagedWidget("ExecuteCommand", xmPushButtonGadgetClass, testmenu, NULL); XtAddCallback(w, XmNactivateCallback, ExecuteCommandCB, NULL); #endif /* HAVE_TEST */ /* * Help Menu. */ w = XtVaCreateManagedWidget("about", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpAboutCB, NULL); w = XtVaCreateManagedWidget("version", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpVersionCB, NULL); w = XtVaCreateManagedWidget("using", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, NULL); XtVaCreateManagedWidget("sep1", xmSeparatorGadgetClass, helpmenu, NULL); w = XtVaCreateManagedWidget("math", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpMathFunctions"); w = XtVaCreateManagedWidget("trig", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpTrigonometricFunctions"); w = XtVaCreateManagedWidget("stats", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpStatisticalFunctions"); w = XtVaCreateManagedWidget("bool", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpBooleanFunctions"); w = XtVaCreateManagedWidget("string", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpStringFunctions"); w = XtVaCreateManagedWidget("struct", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpStructuralFunctions"); w = XtVaCreateManagedWidget("search", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpSearchFunctions"); w = XtVaCreateManagedWidget("bus", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpBusinessFunctions"); w = XtVaCreateManagedWidget("date", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpDateFunctions"); XtVaCreateManagedWidget("sep2", xmSeparatorGadgetClass, helpmenu, NULL); w = XtVaCreateManagedWidget("expr", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpExpressions"); w = XtVaCreateManagedWidget("error", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpErrorValues"); w = XtVaCreateManagedWidget("format", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, NULL); w = XtVaCreateManagedWidget("option", xmPushButtonGadgetClass, helpmenu, NULL); XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpOptions"); return mw; } static void xio_redraw_input_cursor (int on) { #ifdef VERBOSE Debug(__FILE__, "xio_redraw_input_cursor\n"); #endif } static void xio_cellize_cursor (void) { #ifdef VERBOSE Debug(__FILE__, "xio_cellize_cursor\n"); #endif xio_redraw_input_cursor (0); } static void xio_inputize_cursor (void) { #ifdef VERBOSE Debug(__FILE__, "xio_inputize_cursor\n"); #endif xio_redraw_input_cursor (1); } /* This redraws the input area without recomputing anything. */ static void xio_redraw_input (void) { #ifdef VERBOSE Debug(__FILE__, "xio_redraw_input\n"); #endif } static void xio_fix_input (void) { #ifdef VERBOSE Debug(__FILE__, "xio_fix_input\n"); #endif } static void xio_move_cursor (void) { #ifdef VERBOSE Debug(__FILE__, "xio_move_cursor\n"); #endif } static void xio_erase (int len) { #ifdef VERBOSE Debug(__FILE__, "xio_erase\n"); #endif } static void xio_insert (int len) { #ifdef VERBOSE Debug(__FILE__, "xio_insert\n"); #endif } static void xio_over (char * str, int len) { #ifdef VERBOSE Debug(__FILE__, "xio_over\n"); #endif } static void xio_scan_for_input (int blockp) { } static int xio_input_avail (void) { } static void xio_wait_for_input (void) { #ifdef VERBOSE Debug(__FILE__, "xio_wait_for_input ...\n"); #endif } static int xio_read_kbd (char *buffer, int size) { int amt_read = size < Global->MotifGlobal->chars_buffered ? size : Global->MotifGlobal->chars_buffered; #ifdef VERBOSE Debug(__FILE__, "xio_read_kbd ...\n"); #endif if (amt_read) bcopy (Global->MotifGlobal->input_buf, (char *) buffer, amt_read); Global->MotifGlobal->chars_buffered -= amt_read; if (Global->MotifGlobal->chars_buffered) bcopy ((char *) Global->MotifGlobal->input_buf + amt_read, (char *) Global->MotifGlobal->input_buf, Global->MotifGlobal->chars_buffered); return amt_read; } static void xio_nodelay (int delayp) { #ifdef VERBOSE Debug(__FILE__, "xio_nodelay ...\n"); #endif } static int xio_getch (void) { #ifdef VERBOSE Debug(__FILE__, "xio_getch ...\n"); #endif return 0; } static void xio_clear_input_before (void) { #ifdef VERBOSE Debug(__FILE__, "xio_clear_input_before\n"); #endif } static void xio_clear_input_after (void) { #ifdef VERBOSE Debug(__FILE__, "xio_clear_input_after\n"); #endif } static void UpdateStatus(void) { CELL *cp; char buf[1024]; char *ptr, *pos = buf, *dec; if (!user_status) { Debug(__FILE__, "UpdateStatus: no user_status\n"); return; } if (mkrow != NON_ROW) { struct rng r; *pos++ = '*'; set_rng (&r, curow, cucol, mkrow, mkcol); ptr = range_name (&r); } else ptr = cell_name (curow, cucol); strcpy(buf, ptr); /* Put formula in its own widget */ if ((cp = find_cell (curow, cucol)) && cp->cell_formula) { dec = decomp (curow, cucol, cp); if (formulatf) XmTextFieldSetString(formulatf, dec); } /* Value */ ptr = cell_value_string (curow, cucol, True); if (ptr) { strcat(buf, " ["); strcat(buf, ptr); strcat(buf, "]"); } if (statustf) XmTextFieldSetString(statustf, buf); } /* * Copy the spreadsheet values into Xbae * Then do an event loop until there are no more input events. */ static void xio_update_status (void) { XEvent ev; UpdateStatus(); #ifdef VERBOSEx Debug(__FILE__, "xio_update_status(%d,%d)...", curow, cucol); #endif while (XtAppPending(app)) { XtAppNextEvent(app, &ev); (void) XtDispatchEvent(&ev); } #ifdef VERBOSEx Debug(__FILE__, " done\n"); #endif } static int xio_get_chr (char *prompt) { #ifdef VERBOSE Debug(__FILE__, "xio_get_chr(%s)\n", prompt); #endif MessageAppend(True, prompt); return io_getch (); } static void xio_pr_cell_win (struct window *win, CELLREF r, CELLREF c, CELL *cp) { #ifdef VERBOSEx Debug(__FILE__, "xio_pr_cell_win\n"); #endif } static void xio_repaint_win (struct window *win) { #ifdef VERBOSEx Debug(__FILE__, "xio_repaint_win\n"); #endif } static void xio_repaint (void) { #ifdef VERBOSEx Debug(__FILE__, "xio_repaint\n"); #endif } static void xio_hide_cell_cursor (void) { #ifdef VERBOSEx Debug(__FILE__, "xio_hide_cell_cursor\n"); #endif } static void xio_display_cell_cursor (void) { #ifdef VERBOSEx Debug(__FILE__, "xio_display_cell_cursor\n"); #endif } /* Refresh the existing image. */ static void xio_redisp (void) { #ifdef VERBOSE Debug(__FILE__, "xio_redisp\n"); #endif } extern void xio_close_display(int e) { #ifdef VERBOSE Debug(__FILE__, "xio_close_display\n"); #endif if (toplevel && XtDisplay(toplevel)) { XtDestroyWidget(toplevel); } toplevel = NULL; } static void xio_flush (void) { #if 0 XFlush (theDisplay); #endif } static void xio_bell (void) { #if 0 XBell (XtDisplay(toplevel), 30); XFlush (XtDisplay(toplevel)); #endif } extern void xio_open_display (void) { #ifdef VERBOSE Debug(__FILE__, "xio_open_display\n"); #endif } int io_col_to_input_pos (int c) { #if 1 Debug(__FILE__, "io_col_to_input_pos\n"); return 0; #else struct input_view * iv = &thePort->input_view; char * prompt = (iv->expanded_keymap_prompt ? iv->expanded_keymap_prompt : (iv->prompt ? iv->prompt : "")); int prompt_wid = iv->prompt_metric (prompt, strlen(prompt)); c -= prompt_wid; { int cpos; int max = iv->visibility_end - iv->visibility_begin + 1; for (cpos = 1; cpos <= max; ++cpos) if (iv->input_metric (iv->input_area->buf + iv->visibility_begin, cpos) >= c) break; return iv->visibility_begin + cpos - 1; } #endif } void set_x_default_point_size (int l) { /* If the display is not open (ie, we're running on a non x screen, */ /* silently return - allows stuff in startup file to work right.PGA */ if (!toplevel) return; } void xio_command_loop (int i) { XtAppMainLoop(app); } void PopDownSplash() { if (SplashShell) XtDestroyWidget(SplashShell); SplashShell = 0; } void MotifGlobalInitialize(void) { if (Global->MotifGlobal) return; Global->MotifGlobal = (struct MotifGlobalType *)XtMalloc(sizeof(struct MotifGlobalType)); memset(Global->MotifGlobal, 0, sizeof(struct MotifGlobalType)); Global->MotifGlobal->input_buf_allocated = 1024; strcpy(Global->MotifGlobal->fileformat, "oleo"); Global->MotifGlobal->havea0 = -1; Global->MotifGlobal->selectedcells = NULL; Global->MotifGlobal->newcall = True; Global->MotifGlobal->needrecalculate = False; } void motif_init(int *argc, char **argv) { Display *dpy; MotifGlobalInitialize(); io_command_loop = xio_command_loop; io_open_display = xio_open_display; io_redisp = xio_redisp; io_repaint = xio_repaint; io_repaint_win = xio_repaint_win; io_close_display = xio_close_display; io_input_avail = xio_input_avail; io_scan_for_input = xio_scan_for_input; io_wait_for_input = xio_wait_for_input; io_read_kbd = xio_read_kbd; io_nodelay = xio_nodelay; io_getch = xio_getch; io_bell = xio_bell; io_get_chr = xio_get_chr; io_update_status = xio_update_status; io_fix_input = xio_fix_input; io_move_cursor = xio_move_cursor; io_erase = xio_erase; io_insert = xio_insert; io_over = xio_over; io_flush = xio_flush; io_clear_input_before = xio_clear_input_before; io_clear_input_after = xio_clear_input_after; io_pr_cell_win = xio_pr_cell_win; io_hide_cell_cursor = xio_hide_cell_cursor; io_display_cell_cursor = xio_display_cell_cursor; io_cellize_cursor = xio_cellize_cursor; io_inputize_cursor = xio_inputize_cursor; /* * XAPPLRESDIR is a variable that can be set to determine * where to find an application resource file. * If it isn't defined yet, let's define one so the odds are * good for finding our (i18n) application resources. */ #ifndef APPLRESDIR #define APPLRESDIR HTMLDIR #endif if (getenv("XAPPLRESDIR") == NULL) { #ifdef HAVE_PUTENV putenv("XAPPLRESDIR=" APPLRESDIR); #endif } /* * Open a connection to the display and create a toplevel shell widget. */ XtToolkitInitialize(); app = XtCreateApplicationContext(); XtAppSetFallbackResources(app, fallback); dpy = XtOpenDisplay(app, NULL, PACKAGE, PACKAGE, /* options */ NULL, 0, /* command line */ argc, argv); toplevel = XtVaAppCreateShell(PACKAGE, PACKAGE, topLevelShellWidgetClass, dpy, NULL); RegisterWMClose(toplevel); XtVaSetValues(toplevel, XmNdeleteResponse, XmDO_NOTHING, NULL); /* * Add converter for tearoffs. */ #if XmVersion >= 1002 XmRepTypeInstallTearOffModelConverter(); #endif XtVaGetApplicationResources(toplevel, &AppRes, resources, num_resources, NULL); if (AppRes.show_version > 0) { long t = AppRes.show_version; SplashShell = GscBuildSplash(toplevel); XtPopup(SplashShell, XtGrabNone); /* Splash remains on screen for configurable time (milliseconds) */ XtAppAddTimeOut(app, t, PopDownSplash, 0); } /* Without this we have NULL in cwin. */ io_init_windows(AppRes.rows, AppRes.columns, 1, 2, 1, 1, 1, 1); } void RaiseSplash() { /* This needs to be triggered by a timeout because otherwise it won't work */ if (SplashShell) XRaiseWindow(XtDisplay(SplashShell), XtWindow(SplashShell)); } void motif_build_gui(void) { RegisterWMClose(toplevel); XtVaSetValues(toplevel, XmNdeleteResponse, XmDO_NOTHING, NULL); w = GscBuildMainWindow(toplevel); XtManageChild(w); XtRealizeWidget(toplevel); #ifdef HAVE_LIBXPM XtVaSetValues(toplevel, XmNiconPixmap, Global->MotifGlobal->oleo_icon_pm, NULL); #endif if (AppRes.show_version > 0) { /* 30ms is an arbitrary short value. 1 probably works as well. */ XtAppAddTimeOut(app, 30L, RaiseSplash, 0); } if (! XmProcessTraversal(mat, XmTRAVERSE_CURRENT)) { fprintf(stderr, _("XmProcessTraversal failed\n")); } if (Global->MotifGlobal->needrecalculate) { recalculate(1); } } void ReallyQuit(Widget w, XtPointer client, XtPointer call) { kill_oleo(); } void QuitCB(Widget w, XtPointer client, XtPointer call) { Widget md; Arg al[4]; int ac; MotifSelectGlobal(w); /* FIX ME this should work on all open files */ MdiQuit(); if (Global->modified && !option_filter) { XmString xms = XmStringCreateLtoR( _("There are unsaved changes.\n" "Do you want to quit anyway ?"), XmFONTLIST_DEFAULT_TAG); ac = 0; /* Application resource for message allow i18n */ XtSetArg(al[ac], XmNmessageString, xms); ac++; md = XmCreateQuestionDialog(toplevel, "quitMB", al, ac); XtAddCallback(md, XmNokCallback, ReallyQuit, NULL); XtDestroyWidget(XmMessageBoxGetChild(md, XmDIALOG_HELP_BUTTON)); XtManageChild(md); XmStringFree(xms); return; } kill_oleo(); } static char *gpl_string = #include "gpl.h" ; void gplCB(Widget w, XtPointer client, XtPointer call) { Widget x, t, p; Arg al[4]; int ac; MotifSelectGlobal(w); ac = 0; XtSetArg(al[ac], XmNautoUnmanage, False); ac++; x = XmCreateTemplateDialog(toplevel, "versionD", al, ac); ac = 0; XtSetArg(al[ac], XmNeditable, False); ac++; t = XmCreateScrolledText(x, "gpl", al, ac); XtManageChild(t); XmTextSetString(t, gpl_string); ac = 0; p = XmCreatePushButtonGadget(x, "ok", al, ac); XtManageChild(p); XtAddCallback(p, XmNactivateCallback, DestroyTemplate, x); XtManageChild(x); } void versionCB(Widget w, XtPointer client, XtPointer call) { Widget x; XmString xms, xms1, xms2; Arg al[2]; int ac; char xbae[64]; MotifSelectGlobal(w); xms1 = XmStringCreateLtoR(GNU_PACKAGE " " VERSION, XmFONTLIST_DEFAULT_TAG); xms2 = XmStringCreateLtoR(CopyRightString, XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); /* Now add info about libraries used */ xms1 = xms; xms2 = XmStringCreateLtoR("\n\nLibraries used :", XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); xms1 = xms; xms2 = XmStringCreateLtoR("\n " XmVERSION_STRING, XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); #if XbaeVersion > 40800 sprintf(xbae, "\n %s", XbaeGetVersionTxt()); #else sprintf(xbae, "\n Xbae %d", XbaeVersion); #endif xms1 = xms; xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); #ifdef HAVE_XmHTML_H xms1 = xms; xms2 = XmStringCreateLtoR("\n " XmHTMLVERSION_STRING, XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); #endif #ifdef HAVE_SciPlot_H sprintf(xbae, "\n SciPlot %f", _SCIPLOT_WIDGET_VERSION); xms1 = xms; xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); #endif #ifdef HAVE_LIBMYSQLCLIENT sprintf(xbae, "\n MySQL %s", MYSQL_SERVER_VERSION); xms1 = xms; xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); #endif #ifdef HAVE_LIBCUPS sprintf(xbae, "\n CUPS %f", CUPS_VERSION); xms1 = xms; xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); #endif #ifdef HAVE_LIBPLOT #if defined(PL_LIBPLOT_VER_STRING) sprintf(xbae, "\n GNU PlotUtils (libplot version %s)", PL_LIBPLOT_VER_STRING); #else sprintf(xbae, "\n GNU PlotUtils (libplot version %s)", LIBPLOT_VERSION); #endif xms1 = xms; xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); #endif #if defined(HAVE_LIBXDB) { extern char *oleoXdbVersion(); char *v = oleoXdbVersion(); if (v) { sprintf(xbae, "\n XBase library version %s", v); xms1 = xms; xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG); xms = XmStringConcat(xms1, xms2); XmStringFree(xms1); XmStringFree(xms2); } } #endif ac = 0; XtSetArg(al[0], XmNmessageString, xms); ac++; x = XmCreateMessageDialog(toplevel, "versionD", al, ac); XtAddCallback(x, XmNhelpCallback, gplCB, NULL); XmStringFree(xms); XtManageChild(x); } /* * These are necessary from io-x11.c */ void get_x11_args (int * argc_p, char ** argv) { } void x11_graphics(void) { } void motif_main_loop(void) { XtAppMainLoop(app); } /* * */ static void MotifSelectGlobal(Widget w) { Widget p; for (p=w; XtParent(p); p=XtParent(p)) ; MdiSelectGlobal(offsetof(struct OleoGlobal, MotifGlobal), offsetof(struct MotifGlobalType, toplevel_w), p); } void ActivateCellWidget(Widget w, XtPointer client, XtPointer call) { char *cell_name = (char *)client; execute_command(cell_name); } void MotifButton(int r, int c, char *lbl, char *cmd) { Widget button; char *command; if (mat == 0) { Global->MotifGlobal->needrecalculate = True; return; } #if XbaeVersion > 4007 if (XbaeMatrixGetCellWidget(mat, r-1, c-1) == NULL) { button = XtVaCreateManagedWidget(lbl, xmPushButtonWidgetClass, mat, NULL); XbaeMatrixSetCellWidget(mat, r-1, c-1, button); command = strdup(cmd); XtAddCallback(button, XmNactivateCallback, ActivateCellWidget, (XtPointer)command); fprintf(stderr, "MotifButton(%d,%d,%s,%s)\n", r-1, c-1, lbl, command); } #endif }