1 #define	HAVE_TEST
2 /*
3  *  $Id: io-motif.c,v 1.66 2001/03/09 11:33:29 danny Exp $
4  *
5  *  This file is part of Oleo, the GNU spreadsheet.
6  *
7  *  Copyright � 1998-2000 by the Free Software Foundation, Inc.
8  *  Written by Danny Backx <danny@gnu.org>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24 
25 static char rcsid[] = "$Id: io-motif.c,v 1.66 2001/03/09 11:33:29 danny Exp $";
26 
27 #ifdef	HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #ifdef	WITH_DMALLOC
32 #include <dmalloc.h>
33 #endif
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <ctype.h>
39 #include <sys/param.h>
40 #include <stdarg.h>
41 
42 #ifdef	HAVE_LOCALE_H
43 #include <locale.h>
44 #endif
45 #include <libintl.h>
46 
47 #include <X11/Intrinsic.h>
48 #include <X11/Shell.h>
49 
50 #include <Xm/XmAll.h>
51 #include <Xbae/Matrix.h>
52 #include <Xbae/Caption.h>
53 
54 #ifdef	HAVE_XLT
55 #include <Xlt/SciPlot.h>
56 #ifndef HAVE_SciPlot_H
57 #define	HAVE_SciPlot_H
58 #endif
59 #else
60 #ifdef	HAVE_SciPlot_H
61 #include <SciPlot/SciPlot.h>
62 #endif
63 #endif
64 
65 #ifdef	HAVE_LIBXPM
66 #include <X11/xpm.h>
67 #include "oleo_icon.xpm"
68 #endif
69 
70 #include "global.h"
71 
72 #ifdef	HAVE_LIBPLOT
73 #include <plot.h>
74 #include "sciplot.h"
75 #endif
76 #include "oleo_plot.h"
77 
78 #ifdef	HAVE_LIBMYSQLCLIENT
79 #include <mysql/mysql_version.h>
80 #endif
81 #include "oleosql.h"
82 
83 #ifdef	HAVE_LIBCUPS
84 #include <cups/cups.h>
85 #endif
86 
87 #include "utils.h"
88 #include "io-generic.h"
89 #include "io-edit.h"
90 #include "io-utils.h"
91 #include "io-term.h"
92 #include "cmd.h"
93 #include "window.h"
94 #include "line.h"
95 #include "font.h"
96 #include "lists.h"
97 #include "ir.h"
98 #include "display.h"
99 #include "io-abstract.h"
100 #include "regions.h"
101 #include "input.h"
102 #include "info.h"
103 #include "eval.h"
104 #include "basic.h"
105 #include "graph.h"
106 #include "print.h"
107 #include "mdi.h"
108 #include "userpref.h"
109 
110 #include "io-motif.h"		/* To get warnings when inconsistent */
111 
112 #ifdef	HAVE_XmHTML_H
113 #include <XmHTML/XmHTML.h>
114 #endif
115 
116 static Widget	w;
117 
118 /* Fallback resources, application resources */
119 extern char *fallback[];
120 #include "appres.h"
121 
122 GnuSheetAppres	AppRes;
123 
124 /* Forward declarations */
125 void CancelTemplate(Widget w, XtPointer client, XtPointer call);
126 void DestroyTemplate(Widget w, XtPointer client, XtPointer call);
127 static void FixA0();
128 static void PopDownSplash();
129 static void UpdateStatus(void);
130 void helpUsingCB(Widget w, XtPointer client, XtPointer call);
131 static void MotifSelectGlobal(Widget);
132 Widget GscBuildMainWindow(Widget parent);
133 void DestroyToplevel(Widget w, XtPointer client, XtPointer call);
134 
135 Widget ConfigureBarChart(Widget parent);
136 Widget ConfigurePieChart(Widget parent);
137 Widget ConfigureXYChart(Widget parent);
138 void ConfigureXYOk(void);
139 void ConfigureBarOk(void);
140 void ConfigurePieOk(void);
141 void ConfigureXYReset(void);
142 void ConfigureBarReset(void);
143 void ConfigurePieReset(void);
144 
145 /*
146  * This is used in two places.
147  */
148 #define	CopyRightString							\
149 	_(								\
150 	"\nGNU Oleo is free software, you are welcome to\n"		\
151 	"distribute copies of it. See the file COPYING for the\n"	\
152 	"conditions.\n\n"						\
153 	"GNU Oleo comes with ABSOLUTELY NO WARRANTY."			\
154 	)
155 
156 /*
157  * Conditionally (only when the user wants it) print debugging info
158  */
Debug(char * src,char * fmt,...)159 void Debug(char *src, char *fmt, ...)
160 {
161 	static char	*srclist = NULL;
162 	va_list	ap;
163 	int		printit = 0;
164 
165 	if (! srclist)
166 		srclist = getenv("DEBUGSOURCES");
167 
168 	if (srclist && strstr(src, srclist))
169 		printit = 1;
170 
171 	if (printit) {
172 		va_start(ap, fmt);
173 		vfprintf(stderr, fmt, ap);
174 		va_end(ap);
175 	}
176 }
177 
MessageAppend(Boolean beep,char * fmt,...)178 void MessageAppend(Boolean beep, char *fmt, ...)
179 {
180 	XmTextPosition	pos;
181 	int		i;
182 	va_list		ap;
183 	char		s[256];
184 
185 	if (fmt == NULL)
186 		return;
187 
188 	va_start(ap, fmt);
189 	vsprintf(s, fmt, ap);
190 	va_end(ap);
191 
192 	if (msgtext == NULL) {
193 		if (Global->MotifGlobal->early_msg_text == NULL) {
194 			Global->MotifGlobal->early_msg_text = strdup(s);
195 		} else {
196 			int l = strlen(Global->MotifGlobal->early_msg_text) + strlen(s) + 1;
197 			char *x = malloc(l);
198 			strcpy(x, Global->MotifGlobal->early_msg_text);
199 			strcat(x, s);
200 			free(Global->MotifGlobal->early_msg_text);
201 			Global->MotifGlobal->early_msg_text = x;
202 		}
203 		return;
204 	}
205 
206 	if ((i = strlen(s)) == 0)
207 		return;
208 
209 	pos = XmTextGetLastPosition(msgtext);
210 	XmTextInsert(msgtext, pos, s);
211 
212 	if (s[i-1] != '\n') {
213 		pos = XmTextGetLastPosition(msgtext);
214 		XmTextInsert(msgtext, pos, "\n");
215 	}
216 
217 	XmTextShowPosition(msgtext, XmTextGetLastPosition(msgtext));
218 
219 	if (beep)
220 		XBell(XtDisplay(msgtext), 30);
221 }
222 
223 /*
224  * This just prints a message saying this functionality hasn't been
225  * implemented yet.
226  */
none(Widget w,XtPointer client,XtPointer call)227 void none(Widget w, XtPointer client, XtPointer call)
228 {
229 	XmString	xms;
230 	char		*s = NULL;
231 
232 	MotifSelectGlobal(w);
233 
234 	XtVaGetValues(w, XmNlabelString, &xms, NULL);
235 	if (XmStringGetLtoR(xms, XmFONTLIST_DEFAULT_TAG, &s)) {
236 		MessageAppend(False, "%s: not implemented yet\n", s);
237 		XtFree(s);
238 	}
239 	XmStringFree(xms);
240 }
241 
PrintDebug(Widget w,XtPointer client,XtPointer call)242 void PrintDebug(Widget w, XtPointer client, XtPointer call)
243 {
244 	int	i, j;
245 
246 	for (i=1; i<6; i++) {
247 		fprintf(stderr, "[%d]\t", i);
248 		for (j=1; j<6; j++) {
249 			fprintf(stderr, "%s\t", cell_value_string(i, j, True));
250 		}
251 		fprintf(stderr, "\n");
252 	}
253 }
254 
255 /****************************************************************
256  *								*
257  *		Range Selection Support				*
258  *								*
259  ****************************************************************/
260 
FocusCB(Widget w,XtPointer client,XtPointer call)261 void FocusCB(Widget w, XtPointer client, XtPointer call)
262 {
263 	MotifSelectGlobal(w);
264 
265 	ActiveRangeSelectionWidget = w;
266 }
267 
LoseFocusCB(Widget w,XtPointer client,XtPointer call)268 void LoseFocusCB(Widget w, XtPointer client, XtPointer call)
269 {
270 	MotifSelectGlobal(w);
271 
272 #if 0
273 	if (ActiveRangeSelectionWidget == w)
274 		ActiveRangeSelectionWidget = NULL;
275 #endif
276 }
277 
SelectCellCB(Widget w,XtPointer client,XtPointer call)278 void SelectCellCB(Widget w, XtPointer client, XtPointer call)
279 {
280 	char	*s;
281 	XbaeMatrixSelectCellCallbackStruct *cbp =
282 		(XbaeMatrixSelectCellCallbackStruct *)call;
283 	int		i, j;
284 
285 	MotifSelectGlobal(w);
286 
287 #if 0
288 	fprintf(stderr, "SelectCell(%s, %d %d)\n",
289 		cbp->params[0], cbp->row, cbp->column);
290 #endif
291 
292 	if (Global->MotifGlobal->selectedcells == NULL) {
293 		/*
294 		 * There's a memory overrun here somewhere.
295 		 * Working around it by allocating a couple of extra bytes.
296 		 */
297 		Global->MotifGlobal->selectedcells = (Boolean **)XtMalloc(AppRes.rows *
298 				sizeof(Boolean *));
299 		for (i=0; i<AppRes.rows; i++)
300 			Global->MotifGlobal->selectedcells[i] = (Boolean *)
301 				XtCalloc(10 + AppRes.columns, sizeof(Boolean));
302 	}
303 
304 	if (cbp->num_params >= 1 && strcmp(cbp->params[0], "start") == 0) {
305 		selection_range.lr = cbp->row + 1;
306 		selection_range.lc = cbp->column + 1;
307 
308 		for (i=0; i<AppRes.rows; i++)
309 		    for (j=0; j<=AppRes.columns; j++)
310 			Global->MotifGlobal->selectedcells[i][j] = False;
311 
312 		XtVaSetValues(mat, XmNselectedCells, Global->MotifGlobal->selectedcells, NULL);
313 	} else if (cbp->num_params >= 1 && strcmp(cbp->params[0], "end") == 0) {
314 		selection_range.hr = cbp->row + 1;
315 		selection_range.hc = cbp->column + 1;
316 
317 		Global->MotifGlobal->newcall = True;
318 
319 		if (ActiveRangeSelectionWidget &&
320 				XmIsTextField(ActiveRangeSelectionWidget)) {
321 			s = range_name(&selection_range);
322 			XmTextFieldSetString(ActiveRangeSelectionWidget, s);
323 		}
324 	} else if (cbp->num_params >= 1 && strcmp(cbp->params[0], "move") == 0) {
325 		/*
326 		 * Need to figure out which call is the first in a selection.
327 		 */
328 
329 		if (Global->MotifGlobal->newcall) {
330 #if 0
331 			fprintf(stderr, "SelectCellCB(move): first call\n");
332 #endif
333 			/* First call, take the position from the currently selected cell */
334 			selection_range.lr = curow;
335 			selection_range.lc = cucol;
336 
337 			for (i=0; i<AppRes.rows; i++)
338 			    for (j=0; j<=AppRes.columns; j++)
339 				Global->MotifGlobal->selectedcells[i][j] = False;
340 
341 			XtVaSetValues(mat, XmNselectedCells, Global->MotifGlobal->selectedcells, NULL);
342 		} else {
343 #if 0
344 			fprintf(stderr, "SelectCellCB(move): another call\n");
345 #endif
346 			/* Motion : change selected area */
347 			selection_range.hr = cbp->row + 1;
348 			selection_range.hc = cbp->column + 1;
349 
350 			for (i=selection_range.lr-1; i<=cbp->row; i++)
351 			    for (j=selection_range.lc-1; j<=cbp->column; j++)
352 				Global->MotifGlobal->selectedcells[i][j] = True;
353 
354 			XtVaSetValues(mat, XmNselectedCells, Global->MotifGlobal->selectedcells, NULL);
355 
356 			if (ActiveRangeSelectionWidget &&
357 					XmIsTextField(ActiveRangeSelectionWidget)) {
358 				s = range_name(&selection_range);
359 				XmTextFieldSetString(ActiveRangeSelectionWidget, s);
360 			}
361 		}
362 
363 		Global->MotifGlobal->newcall = False;
364 	}
365 }
366 
RegisterRangeSelector(Widget w)367 void RegisterRangeSelector(Widget w)
368 {
369 	XtAddCallback(w, XmNfocusCallback, FocusCB, NULL);
370 	XtAddCallback(w, XmNlosingFocusCallback, LoseFocusCB, NULL);
371 }
372 
373 /****************************************************************
374  *								*
375  *		Generic Helper Functions			*
376  *								*
377  ****************************************************************/
378 void
RegisterWMClose(Widget w)379 RegisterWMClose(Widget w)
380 {
381         Atom    delete_atom;
382 
383         delete_atom = XmInternAtom(XtDisplay(w), "WM_DELETE_WINDOW", False);
384         XmAddWMProtocols(w, &delete_atom, 1);
385         XmSetWMProtocolHooks(w, delete_atom,
386 		(XtCallbackProc)DestroyToplevel, (XtPointer)1,
387                 (XtCallbackProc)0, (XtPointer)0);
388 }
389 
390 void
PopDownHelpCB(Widget widget,XtPointer client,XtPointer call)391 PopDownHelpCB(Widget widget, XtPointer client, XtPointer call)
392 {
393 	XtPopdown((Widget)client);
394 }
395 
MotifUpdateDisplay()396 void MotifUpdateDisplay()
397 {
398         XbaeMatrixRefresh(mat); /* refresh */
399 
400 	FixA0();
401 
402         /*
403          * Apparently the refresh above doesn't refresh the cell whose
404          * formula we just changed, and which therefore almost certainly
405          * needs an update. XbaeMatrixRefreshCell also doesn't work.
406          * This does :
407          */
408         XbaeMatrixSetCell(mat, curow - 1, cucol - 1,
409                 cell_value_string(curow, cucol, True));
410 }
411 
412 /****************************************************************
413  *								*
414  *			Graphs					*
415  *								*
416  ****************************************************************/
417 struct ConfigureWidgets {
418 	Widget	x,
419 		a, b, c, d, e, f, g, h, i,
420 		sa, sb, sc, sd, se, sf, sg, sh, si,
421 		ta, tb, tc, td, te, tf, tg, th, ti,
422 		xlog, ylog,
423 		title, xtitle, ytitle;
424 };
425 
426 static void
sciplot_thunk(void * p,CELL * cp,CELLREF r,CELLREF c)427 sciplot_thunk(void *p, CELL *cp, CELLREF r, CELLREF c)
428 {
429 	char * str = (char *)char_to_q_char (print_cell (cp));
430 
431 	MessageAppend(False, "SciPlotThunk(r %d c %d) %s",
432 		r, c, print_cell(find_cell(r, c)));
433 }
434 
UpdateGraph()435 void UpdateGraph()
436 {
437 #ifdef	HAVE_SciPlot_H
438 	int			i, ii, len, xx, xa, lst;
439 	int			xlog, ylog;
440 	double			*vx, *va;
441 	struct rng		rngx, rnga;
442 	char			*s, *t;
443 	extern struct rng	graph_get_data(int);
444 	enum graph_pair_ordering order = graph_rows_hz;
445 
446 	xlog = graph_get_logness('x');
447 	ylog = graph_get_logness('y');
448 
449 	XtVaSetValues(plot,
450 			XtNchartType,		XtCARTESIAN,
451 			XtNxLabel,		graph_get_axis_title('x'),
452 			XtNyLabel,		graph_get_axis_title('y'),
453 			XtNxLog,		xlog,
454 			XtNyLog,		ylog,
455 		NULL);
456 
457 
458 	rngx = graph_get_data(0);
459 	rnga = graph_get_data(1);
460 
461 	len = rngx.hr - rngx.lr + 1;
462 
463 	vx = (double *)XtCalloc(len, sizeof(double));
464 	va = (double *)XtCalloc(len, sizeof(double));
465 
466 	/* FIX ME */
467 	/* This code is wrong: only works for vertical set of data */
468 	for (ii=0, i=rngx.lr; i<=rngx.hr; i++, ii++) {
469 		s = cell_value_string(i, rngx.lc, True);
470 		vx[ii] = 0.0;
471 		sscanf(s, "%lf", &vx[ii]);
472 		s = cell_value_string(i, rnga.lc, True);
473 		va[ii] = 0.0;
474 		sscanf(s, "%lf", &va[ii]);
475 	}
476 
477 /* Start test for_pairs_in() */
478 	for_pairs_in(&rngx, order, (fpi_thunk)sciplot_thunk, NULL);
479 	for_pairs_in(&rnga, order, (fpi_thunk)sciplot_thunk, NULL);
480 /* End test for_pairs_in() */
481 
482 	lst = SciPlotListCreateDouble(plot, 10, vx, va,
483 			graph_get_data_title(0));
484 #if 1
485     {
486 	/* Colour test */
487 
488 	int	fg, bg, lc, pc;
489 
490 	bg = SciPlotAllocNamedColor(plot, "seagreen");
491 	fg = SciPlotAllocNamedColor(plot, "yellow");
492 	lc = SciPlotAllocNamedColor(plot, "orange");
493 	pc = SciPlotAllocNamedColor(plot, "light blue");
494 
495 	SciPlotListSetStyle(plot, lst, pc, XtMARKER_CIRCLE,
496 		lc, XtLINE_DOTTED);
497 	SciPlotSetForegroundColor(plot, fg);
498 	SciPlotSetBackgroundColor(plot, bg);
499     }
500 #else
501 	SciPlotListSetStyle(plot, lst, 1, XtMARKER_CIRCLE,
502 		1, XtLINE_DOTTED);
503 #endif
504 
505 	s = graph_get_title();
506 	if (s && strlen(s)) {
507 		XtVaSetValues(plot, XtNplotTitle, s, NULL);
508 	}
509 
510 	XtFree((XtPointer)vx);
511 	XtFree((XtPointer)va);
512 
513 	SciPlotSetXAutoScale(plot);
514 	SciPlotSetYAutoScale(plot);
515 
516 	SciPlotUpdate(plot);
517 #endif
518 }
519 
CreateGraph(Widget w,XtPointer client,XtPointer call)520 void CreateGraph(Widget w, XtPointer client, XtPointer call)
521 {
522 	Widget	f, sw, sep, ok;
523 	int	i;
524 
525 	MotifSelectGlobal(w);
526 
527 	if (gs)
528 		return;
529 
530 	gs = XtVaCreatePopupShell("graphShell",
531 		topLevelShellWidgetClass,
532 		toplevel,
533 	NULL);
534 
535 	f = XtVaCreateManagedWidget("form", xmFormWidgetClass, gs,
536 		NULL);
537 
538 #ifdef	HAVE_SciPlot_H
539 	sw = XtVaCreateManagedWidget("scroll",
540 		xmScrolledWindowWidgetClass, f,
541 			XmNtopAttachment,	XmATTACH_FORM,
542 			XmNleftAttachment,	XmATTACH_FORM,
543 			XmNrightAttachment,	XmATTACH_FORM,
544 			XmNtopOffset,		10,
545 			XmNleftOffset,		10,
546 			XmNrightOffset,		10,
547 		NULL);
548 
549 	plot = XtVaCreateManagedWidget("plot",
550 		sciplotWidgetClass, sw,
551 			XmNmarginWidth,		20,
552 			XmNmarginHeight,	20,
553 			XmNwidth,		600,
554 			XmNheight,		500,
555 		NULL);
556 #else
557 	/* Fallback if we don't have SciPlot */
558 	sw = plot = NULL;
559 #endif
560 
561 	sep = XtVaCreateManagedWidget("separator",
562 		xmSeparatorGadgetClass, f,
563 			XmNorientation,		XmHORIZONTAL,
564 			XmNtopAttachment,	XmATTACH_WIDGET,
565 			XmNtopOffset,		10,
566 			XmNtopWidget,		sw,
567 			XmNleftAttachment,	XmATTACH_FORM,
568 			XmNrightAttachment,	XmATTACH_FORM,
569 			XmNleftOffset,		10,
570 			XmNrightOffset,		10,
571 		NULL);
572 
573 	ok = XtVaCreateManagedWidget("ok",
574 		xmPushButtonGadgetClass, f,
575 			XmNtopAttachment,	XmATTACH_WIDGET,
576 			XmNtopOffset,		10,
577 			XmNtopWidget,		sep,
578 			XmNleftAttachment,	XmATTACH_FORM,
579 			XmNrightAttachment,	XmATTACH_FORM,
580 			XmNleftOffset,		10,
581 			XmNrightOffset,		10,
582 		NULL);
583 	XtAddCallback(ok, XmNactivateCallback, PopDownHelpCB, gs);
584 
585 	UpdateGraph();
586 }
587 
588 /*
589  * Pop up a window with a graph (from SciPlot).
590  */
591 #ifdef	HAVE_SciPlot_H
ShowGraph(Widget w,XtPointer client,XtPointer call)592 void ShowGraph(Widget w, XtPointer client, XtPointer call)
593 {
594 	MotifSelectGlobal(w);
595 
596 	CreateGraph(w, client, call);
597 	XtPopup(gs, XtGrabNone);
598 }
599 
600 /*
601  * Needs to figure out to which file/printer to print, depending on
602  * the callback data passed from the dialog.
603  */
ReallyPrintGraph(Widget w,XtPointer client,XtPointer call)604 void ReallyPrintGraph(Widget w, XtPointer client, XtPointer call)
605 {
606 	MotifSelectGlobal(w);
607 
608 	if (gs == NULL)
609 		CreateGraph(w, client, call);
610 	else
611 		UpdateGraph();
612 	if (plot)
613 		SciPlotPSCreateColor(plot, "plot.ps");
614 }
615 
616 /*
617  * FIX ME
618  * This must first pop up a window asking whether to print to a file
619  * or a printer. Only after confirmation must ReallyPrintGraph be
620  * called.
621  */
PrintGraph(Widget w,XtPointer client,XtPointer call)622 void PrintGraph(Widget w, XtPointer client, XtPointer call)
623 {
624 	MotifSelectGlobal(w);
625 
626 	ReallyPrintGraph(w, client, call);
627 }
628 #endif
629 
630 /*
631  * Show panel of print options
632  */
PrintOptionsOk(Widget w,XtPointer client,XtPointer call)633 void PrintOptionsOk(Widget w, XtPointer client, XtPointer call)
634 {
635 	int	scale;
636 	float	f;
637 
638 	MotifSelectGlobal(w);
639 	XtUnmanageChild(optionsDialog);
640 
641 	if (Global->MotifGlobal->ZoomScale) {
642 		XtVaGetValues(Global->MotifGlobal->ZoomScale,
643 				XmNvalue, &scale,
644 			NULL);
645 		f = scale;
646 	} else
647 		f = 100.0;
648 
649 	f = f / 100.0;
650 	Global->zoom = f;
651 
652 	MessageAppend(False, "Set zoom to %2.0f%%", 100 * Global->zoom);
653 }
654 
PrintOptionsReset(Widget w)655 void PrintOptionsReset(Widget w)
656 {
657 	float	f = Global->zoom * 100.0;
658 	int	s = f;
659 
660 	if (Global->MotifGlobal->ZoomScale) {
661 		XtVaSetValues(Global->MotifGlobal->ZoomScale,
662 				XmNvalue,	s,
663 			NULL);
664 	}
665 }
666 
PrintOptionsCB(Widget w,XtPointer client,XtPointer call)667 void PrintOptionsCB(Widget w, XtPointer client, XtPointer call)
668 {
669 	Widget		ok, cancel, help, t, rc, nb, b, cb, menu, f;
670 	XmString	xms;
671 	Arg		al[5];
672 	int		ac;
673 
674 	MotifSelectGlobal(w);
675 
676 	if (! optionsDialog) {
677 		ac = 0;
678 		XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
679 		optionsDialog = XmCreateTemplateDialog(mw, "configureGraph",
680 			al, ac);
681 
682 #if XmVERSION > 1
683 		nb = XmCreateNotebook(optionsDialog,
684 			"printOptionsNotebook",
685 			NULL, 0);
686 		XtManageChild(nb);
687 
688 		/* What to show */
689 		rc = XtVaCreateManagedWidget("showRC", xmRowColumnWidgetClass,
690 			nb, NULL);
691 
692 		t = XtVaCreateManagedWidget("showLabels", xmToggleButtonGadgetClass,
693 				rc,
694 			NULL);
695 		t = XtVaCreateManagedWidget("showBorders", xmToggleButtonGadgetClass,
696 				rc,
697 			NULL);
698 		t = XtVaCreateManagedWidget("showRaster", xmToggleButtonGadgetClass,
699 				rc,
700 			NULL);
701 
702 		(void)XtVaCreateManagedWidget("showLabel", xmPushButtonWidgetClass,
703 				nb,
704 				XmNnotebookChildType, XmMAJOR_TAB,
705 			NULL);
706 
707 		/* Choose a scale for the print */
708 		f = XtVaCreateManagedWidget("scaleForm", xmFormWidgetClass,
709 			nb,
710 			NULL);
711 
712 		rc = XtVaCreateManagedWidget("scaleRC", xmRowColumnWidgetClass,
713 			f,
714 				XmNtopAttachment,	XmATTACH_FORM,
715 				XmNtopOffset,		10,
716 				XmNleftAttachment,	XmATTACH_FORM,
717 			NULL);
718 
719 		menu = XmCreatePulldownMenu(rc, "optionMenu", NULL, 0);
720 		ac = 0;
721 		XtSetArg(al[ac], XmNsubMenuId, menu); ac++;
722 		xms = XmStringCreateSimple(_("Fit Print Area"));
723 		XtSetArg(al[ac], XmNlabelString, xms); ac++;
724 		cb = XmCreateOptionMenu(rc, "optionCB", al, ac);
725 		XtManageChild(cb);
726 		XmStringFree(xms);
727 
728 		b = XtVaCreateManagedWidget("PrintScaleZoom", xmPushButtonGadgetClass,
729 			menu,
730 			NULL);
731 		b = XtVaCreateManagedWidget("PrintScaleAsIs", xmPushButtonGadgetClass,
732 			menu,
733 			NULL);
734 		b = XtVaCreateManagedWidget("PrintScaleColumnsOnOne", xmPushButtonGadgetClass,
735 			menu,
736 			NULL);
737 		b = XtVaCreateManagedWidget("PrintScaleRowsOnOne", xmPushButtonGadgetClass,
738 			menu,
739 			NULL);
740 		b = XtVaCreateManagedWidget("PrintScaleAllOnOne", xmPushButtonGadgetClass,
741 			menu,
742 			NULL);
743 
744 		Global->MotifGlobal->ZoomScale = XtVaCreateManagedWidget("PrintZoomScale",
745 			xmScaleWidgetClass, f,
746 				XmNtopAttachment,	XmATTACH_WIDGET,
747 				XmNtopWidget,		rc,
748 				XmNtopOffset,		10,
749 				XmNleftAttachment,	XmATTACH_FORM,
750 				XmNleftOffset,		10,
751 				XmNrightAttachment,	XmATTACH_FORM,
752 				XmNrightOffset,		10,
753 				XmNorientation,		XmHORIZONTAL,
754 				XmNminimum,		10,
755 				XmNmaximum,		400,
756 				XmNshowValue,		True,
757 			NULL);
758 
759 		(void)XtVaCreateManagedWidget("scaleLabel", xmPushButtonWidgetClass,
760 				nb,
761 				XmNnotebookChildType, XmMAJOR_TAB,
762 			NULL);
763 #endif
764 
765 		/* Buttons */
766 		ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass,
767 			optionsDialog,
768 			NULL);
769 		cancel = XtVaCreateManagedWidget("cancel",
770 			xmPushButtonGadgetClass, optionsDialog,
771 			NULL);
772 		help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass,
773 			optionsDialog,
774 			NULL);
775 
776 		XtAddCallback(ok, XmNactivateCallback, PrintOptionsOk, optionsDialog);
777 		XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, optionsDialog);
778 
779 		/* FIX ME need something to call the help system */
780 	}
781 
782 	PrintOptionsReset(optionsDialog);
783 	XtManageChild(optionsDialog);
784 }
785 
ConversionError(char * s,char * t)786 void ConversionError(char *s, char *t)
787 {
788 	char *r = XtMalloc(strlen(s) + strlen(t) + 100);
789 
790 	sprintf(r,
791 		_("Conversion error: cannot convert '%s' to a %s\n"),
792 		s, t);
793 	MessageAppend(True, r);
794 	XtFree(r);
795 }
796 
797 #ifdef	HAVE_LIBPLOT
798 /*
799  * Create a widget tree to configure a graph with.
800  *	The result is a widget that isn't managed yet.
801  *	(So you can put it in a dialog).
802  *
803  * Information that's present in traditional oleo graphs :
804  * - general :
805  *	X Axis		Title, Range
806  *	Y Axis		Title, Range
807  *	Logarithmic axes
808  * - per data set :
809  *	Data Set Name
810  *	Style		(Linespoints, lines)
811  */
CreateConfigureGraph(Widget parent)812 Widget CreateConfigureGraph(Widget parent)
813 {
814 	Widget	toprc, frame, w, rc, cap;
815 	struct ConfigureWidgets	*cw;
816 
817 	MotifSelectGlobal(parent);
818 
819 	cw = (struct ConfigureWidgets *)XtMalloc(
820 		sizeof(struct ConfigureWidgets));
821 
822 	/*
823 	 * We need to set the userdata on the toplevel widget here.
824 	 */
825 	toprc = XtVaCreateWidget("configureGraphRC", xmRowColumnWidgetClass,
826 		parent,
827 			XmNuserData,	cw,
828 		NULL);
829 
830 	frame = XtVaCreateManagedWidget("dataFrame",
831 		xmFrameWidgetClass, toprc,
832 		NULL);
833 
834 	rc = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, frame,
835 			XmNnumColumns,	4,
836 			XmNorientation,	XmVERTICAL,
837 			XmNpacking,	XmPACK_COLUMN,
838 		NULL);
839 	XtVaCreateManagedWidget("l0", xmLabelGadgetClass, rc,
840 		NULL);
841 	XtVaCreateManagedWidget("l1", xmLabelGadgetClass, rc,
842 		NULL);
843 	XtVaCreateManagedWidget("l2", xmLabelGadgetClass, rc,
844 		NULL);
845 	XtVaCreateManagedWidget("l3", xmLabelGadgetClass, rc,
846 		NULL);
847 	XtVaCreateManagedWidget("l4", xmLabelGadgetClass, rc,
848 		NULL);
849 	XtVaCreateManagedWidget("l5", xmLabelGadgetClass, rc,
850 		NULL);
851 
852 	XtVaCreateManagedWidget("r0", xmLabelGadgetClass, rc,
853 		NULL);
854 	cw->x = XtVaCreateManagedWidget("r1", xmTextFieldWidgetClass, rc,
855 		NULL);
856 	RegisterRangeSelector(cw->x);
857 	cw->a = XtVaCreateManagedWidget("r2", xmTextFieldWidgetClass, rc,
858 		NULL);
859 	RegisterRangeSelector(cw->a);
860 	cw->b = XtVaCreateManagedWidget("r3", xmTextFieldWidgetClass, rc,
861 		NULL);
862 	RegisterRangeSelector(cw->b);
863 	cw->c = XtVaCreateManagedWidget("r4", xmTextFieldWidgetClass, rc,
864 		NULL);
865 	RegisterRangeSelector(cw->c);
866 	cw->d = XtVaCreateManagedWidget("r5", xmTextFieldWidgetClass, rc,
867 		NULL);
868 	RegisterRangeSelector(cw->d);
869 
870 	XtVaCreateManagedWidget("s0", xmLabelGadgetClass, rc,
871 		NULL);
872 	cw->sa = XtVaCreateManagedWidget("s1", xmToggleButtonGadgetClass, rc,
873 		NULL);
874 	cw->sb = XtVaCreateManagedWidget("s2", xmToggleButtonGadgetClass, rc,
875 		NULL);
876 	cw->sc = XtVaCreateManagedWidget("s3", xmToggleButtonGadgetClass, rc,
877 		NULL);
878 	cw->sd = XtVaCreateManagedWidget("s4", xmToggleButtonGadgetClass, rc,
879 		NULL);
880 	cw->se = XtVaCreateManagedWidget("s5", xmToggleButtonGadgetClass, rc,
881 		NULL);
882 
883 	XtVaCreateManagedWidget("t0", xmLabelGadgetClass, rc,
884 		NULL);
885 	cw->ta = XtVaCreateManagedWidget("t1", xmTextFieldWidgetClass, rc,
886 		NULL);
887 	cw->tb = XtVaCreateManagedWidget("t2", xmTextFieldWidgetClass, rc,
888 		NULL);
889 	cw->tc = XtVaCreateManagedWidget("t3", xmTextFieldWidgetClass, rc,
890 		NULL);
891 	cw->td = XtVaCreateManagedWidget("t4", xmTextFieldWidgetClass, rc,
892 		NULL);
893 	cw->te = XtVaCreateManagedWidget("t5", xmTextFieldWidgetClass, rc,
894 		NULL);
895 
896 	frame = XtVaCreateManagedWidget("dataFrame",
897 		xmFrameWidgetClass, toprc,
898 		NULL);
899 	rc = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, frame,
900 		NULL);
901 	XtVaCreateManagedWidget("xl", xmLabelGadgetClass, rc,
902 		NULL);
903 	cw->xtitle = XtVaCreateManagedWidget("xt", xmTextFieldWidgetClass, rc,
904 		NULL);
905 	cw->xlog = XtVaCreateManagedWidget("xlog",
906 		xmToggleButtonGadgetClass, rc,
907 		NULL);
908 	XtVaCreateManagedWidget("yl", xmLabelGadgetClass, rc,
909 		NULL);
910 	cw->ytitle = XtVaCreateManagedWidget("yt", xmTextFieldWidgetClass, rc,
911 		NULL);
912 	cw->ylog = XtVaCreateManagedWidget("ylog",
913 		xmToggleButtonGadgetClass, rc,
914 		NULL);
915 
916 	cw->title = XtVaCreateManagedWidget("title", xmTextFieldWidgetClass, rc,
917 		NULL);
918 
919 	return toprc;
920 }
921 
922 /*
923  * Ok handler
924  *	This reads everything from the widgets in the dialog and copies
925  *	the information into variables.
926  */
ConfigureGraphOk(Widget w,XtPointer client,XtPointer call)927 void ConfigureGraphOk(Widget w, XtPointer client, XtPointer call)
928 {
929 	Widget			f = (Widget)client;
930 	struct ConfigureWidgets	*cw = NULL;
931 	char			*s, *p;
932 	struct rng		rngx;
933 	int			r;
934 
935 	MotifSelectGlobal(w);
936 
937 /* We should only pop down if everything was read correctly.
938  *	XtUnmanageChild(configureGraph);
939  */
940 	Global->return_from_error = 1;
941 	Global->had_error = 0;
942 
943 	XtVaGetValues(f, XmNuserData, &cw, NULL);
944 
945 	if (cw == NULL) {
946 		MessageAppend(True, _("Cannot find XmNuserData\n"));
947 		XtUnmanageChild(configureGraph);
948 		Global->return_from_error = 0;
949 		return;
950 	}
951 
952 /* Plot title */
953 	s = XmTextFieldGetString(cw->title);
954 	graph_set_title(s);
955 #ifdef	FREE_TF_STRING
956 	XtFree(s);
957 #endif
958 
959 /* X Axis */
960 	s = XmTextFieldGetString(cw->xtitle);
961 	graph_set_axis_title('x', s);
962 #ifdef	FREE_TF_STRING
963 	XtFree(s);
964 #endif
965 	graph_set_logness('x', 1, XmToggleButtonGadgetGetState(cw->xlog));
966 
967 /* Y Axis */
968 	s = XmTextFieldGetString(cw->ytitle);
969 	graph_set_axis_title('y', s);
970 #ifdef	FREE_TF_STRING
971 	XtFree(s);
972 #endif
973 	graph_set_logness('y', 1, XmToggleButtonGadgetGetState(cw->ylog));
974 
975 	s = XmTextFieldGetString(cw->ta);
976 	graph_set_data_title(0, s);
977 #ifdef	FREE_TF_STRING
978 	XtFree(s);
979 #endif
980 
981 /* Data 1 */
982 	p = s = XmTextFieldGetString(cw->x);
983 	if (strlen(s)) {
984 		if ((r = parse_cell_or_range(&p, &rngx)) == 0)
985 			ConversionError(s, _("range"));
986 		else if (r & RANGE) {
987 			graph_set_data(0, &rngx);
988 		} else {
989 			rngx.hr = rngx.lr;
990 			rngx.hc = rngx.lc;
991 			graph_set_data(0, &rngx);
992 		}
993 #ifdef	FREE_TF_STRING
994 		XtFree(s);
995 #endif
996 	}
997 
998 	s = XmTextFieldGetString(cw->tb);
999 	graph_set_data_title(1, s);
1000 #ifdef	FREE_TF_STRING
1001 	XtFree(s);
1002 #endif
1003 
1004 /* Data 2 */
1005 	p = s = XmTextFieldGetString(cw->a);
1006 	if (strlen(s)) {
1007 		if ((r = parse_cell_or_range(&p, &rngx)) == 0)
1008 			ConversionError(s, _("range"));
1009 		else if (r & RANGE) {
1010 			graph_set_data(1, &rngx);
1011 		} else {
1012 			rngx.hr = rngx.lr;
1013 			rngx.hc = rngx.lc;
1014 			graph_set_data(1, &rngx);
1015 		}
1016 #ifdef	FREE_TF_STRING
1017 		XtFree(s);
1018 #endif
1019 	}
1020 
1021 	s = XmTextFieldGetString(cw->tc);
1022 	graph_set_data_title(2, s);
1023 #ifdef	FREE_TF_STRING
1024 	XtFree(s);
1025 #endif
1026 
1027 /* Data 3 */
1028 	p = s = XmTextFieldGetString(cw->b);
1029 	if (strlen(s)) {
1030 		if ((r = parse_cell_or_range(&p, &rngx)) == 0)
1031 			ConversionError(s, _("range"));
1032 		else if (r & RANGE) {
1033 			graph_set_data(2, &rngx);
1034 		} else {
1035 			rngx.hr = rngx.lr;
1036 			rngx.hc = rngx.lc;
1037 			graph_set_data(2, &rngx);
1038 		}
1039 #ifdef	FREE_TF_STRING
1040 		XtFree(s);
1041 #endif
1042 	}
1043 
1044 	s = XmTextFieldGetString(cw->td);
1045 	graph_set_data_title(3, s);
1046 #ifdef	FREE_TF_STRING
1047 	XtFree(s);
1048 #endif
1049 
1050 	p = s = XmTextFieldGetString(cw->c);
1051 	if (strlen(s)) {
1052 		if ((r = parse_cell_or_range(&p, &rngx)) == 0)
1053 			ConversionError(s, _("range"));
1054 		else if (r & RANGE) {
1055 			graph_set_data(3, &rngx);
1056 		} else {
1057 			rngx.hr = rngx.lr;
1058 			rngx.hc = rngx.lc;
1059 			graph_set_data(3, &rngx);
1060 		}
1061 		MessageAppend(False, s);
1062 #ifdef	FREE_TF_STRING
1063 		XtFree(s);
1064 #endif
1065 	}
1066 
1067 	p = s = XmTextFieldGetString(cw->d);
1068 	if (strlen(s)) {
1069 		if ((r = parse_cell_or_range(&p, &rngx)) == 0)
1070 			ConversionError(s, _("range"));
1071 		else if (r & RANGE) {
1072 			graph_set_data(4, &rngx);
1073 		} else {
1074 			rngx.hr = rngx.lr;
1075 			rngx.hc = rngx.lc;
1076 			graph_set_data(4, &rngx);
1077 		}
1078 		MessageAppend(False, s);
1079 #ifdef	FREE_TF_STRING
1080 		XtFree(s);
1081 #endif
1082 	}
1083 
1084 	ConfigureXYOk();
1085 	ConfigurePieOk();
1086 	ConfigureBarOk();
1087 
1088 	/* Pop down */
1089 	if (Global->had_error == 0)
1090 		XtUnmanageChild(configureGraph);
1091 
1092 	Global->return_from_error = 0;
1093 }
1094 
1095 /*
1096  * Revert configure graph fields to their current internal values.
1097  *	This is needed for popping up the dialog after it's been changed by
1098  *	the user but he's hit Cancel.
1099  *	Or for values read from a file. (new to 1.6.14)
1100  */
ConfigureGraphReset(Widget f)1101 void ConfigureGraphReset(Widget f)
1102 {
1103 	struct ConfigureWidgets	*cw = NULL;
1104 	struct rng		r;
1105 	char			*s;
1106 	extern struct rng	graph_get_data(int);
1107 
1108 	XtVaGetValues(f, XmNuserData, &cw, NULL);
1109 
1110 	if (cw == NULL) {
1111 		MessageAppend(True, _("Cannot find XmNuserData\n"));
1112 		return;
1113 	}
1114 
1115 #if XmVERSION > 1
1116 	XtVaSetValues(ConfigureGraphNotebook, XmNcurrentPageNumber, 1, NULL);
1117 #endif
1118 
1119 	r = graph_get_data(0);
1120 	s = range_name(&r);
1121 	XmTextFieldSetString(cw->x, s);
1122 
1123 	r = graph_get_data(1);
1124 	s = range_name(&r);
1125 	XmTextFieldSetString(cw->a, s);
1126 
1127 	r = graph_get_data(2);
1128 	s = range_name(&r);
1129 	XmTextFieldSetString(cw->b, s);
1130 
1131 	r = graph_get_data(3);
1132 	s = range_name(&r);
1133 	XmTextFieldSetString(cw->c, s);
1134 
1135 	r = graph_get_data(4);
1136 	s = range_name(&r);
1137 	XmTextFieldSetString(cw->d, s);
1138 
1139 	s = graph_get_title();
1140 	XmTextFieldSetString(cw->title, s);
1141 
1142 	s = graph_get_axis_title('x');
1143 	XmTextFieldSetString(cw->xtitle, s);
1144 
1145 	s = graph_get_axis_title('y');
1146 	XmTextFieldSetString(cw->ytitle, s);
1147 
1148 	s = graph_get_data_title(0);
1149 	XmTextFieldSetString(cw->ta, s);
1150 	s = graph_get_data_title(1);
1151 	XmTextFieldSetString(cw->tb, s);
1152 	s = graph_get_data_title(2);
1153 	XmTextFieldSetString(cw->tc, s);
1154 	s = graph_get_data_title(3);
1155 	XmTextFieldSetString(cw->td, s);
1156 	s = graph_get_data_title(4);
1157 	XmTextFieldSetString(cw->te, s);
1158 
1159 	ConfigureXYReset();
1160 	ConfigurePieReset();
1161 	ConfigureBarReset();
1162 }
1163 
1164 /*
1165  * Pop up the dialog for configuring graphs.
1166  * If necessary, create the widgets first.
1167  */
ConfigureGraph(Widget w,XtPointer client,XtPointer call)1168 void ConfigureGraph(Widget w, XtPointer client, XtPointer call)
1169 {
1170 	Widget		ok, cancel, help, p, fr;
1171 	int		ac;
1172 	Arg		al[5];
1173 
1174 	MotifSelectGlobal(w);
1175 
1176 	if (! configureGraph) {
1177 		ac = 0;
1178 		XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
1179 		configureGraph = XmCreateTemplateDialog(mw, "configureGraph",
1180 			al, ac);
1181 
1182 #if XmVERSION > 1
1183 		ConfigureGraphNotebook = XmCreateNotebook(configureGraph,
1184 			"configureGraphNotebook",
1185 			NULL, 0);
1186 		XtManageChild(ConfigureGraphNotebook);
1187 
1188 		/* The data */
1189 		ConfigureGraphInside = CreateConfigureGraph(ConfigureGraphNotebook);
1190 		XtManageChild(ConfigureGraphInside);
1191 
1192 		p = XtVaCreateManagedWidget("datatab", xmPushButtonWidgetClass,
1193 			ConfigureGraphNotebook,
1194 				XmNnotebookChildType, XmMAJOR_TAB,
1195 			NULL);
1196 
1197 		/* Pie Chart specific stuff */
1198 		fr = ConfigurePieChart(ConfigureGraphNotebook);
1199 		XtManageChild(fr);
1200 
1201 		p = XtVaCreateManagedWidget("PieTab", xmPushButtonWidgetClass,
1202 			ConfigureGraphNotebook,
1203 				XmNnotebookChildType, XmMAJOR_TAB,
1204 			NULL);
1205 
1206 		/* XY Chart specific stuff */
1207 		fr = ConfigureXYChart(ConfigureGraphNotebook);
1208 		XtManageChild(fr);
1209 
1210 		p = XtVaCreateManagedWidget("XYTab", xmPushButtonWidgetClass,
1211 			ConfigureGraphNotebook,
1212 				XmNnotebookChildType, XmMAJOR_TAB,
1213 			NULL);
1214 
1215 		/* Bar Chart specific stuff */
1216 		fr = ConfigureBarChart(ConfigureGraphNotebook);
1217 		XtManageChild(fr);
1218 
1219 		p = XtVaCreateManagedWidget("BarTab", xmPushButtonWidgetClass,
1220 			ConfigureGraphNotebook,
1221 				XmNnotebookChildType, XmMAJOR_TAB,
1222 			NULL);
1223 #endif
1224 
1225 		/* Buttons */
1226 		ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass,
1227 			configureGraph,
1228 			NULL);
1229 		cancel = XtVaCreateManagedWidget("cancel",
1230 			xmPushButtonGadgetClass, configureGraph,
1231 			NULL);
1232 		help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass,
1233 			configureGraph,
1234 			NULL);
1235 
1236 		XtAddCallback(ok, XmNactivateCallback, ConfigureGraphOk, ConfigureGraphInside);
1237 		XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, configureGraph);
1238 
1239 		/* FIX ME need something to call the help system */
1240 	}
1241 
1242 	ConfigureGraphReset(ConfigureGraphInside);
1243 	XtManageChild(configureGraph);
1244 }
1245 #endif
1246 
1247 /*
1248  * Plotutils
1249  */
1250 
1251 #ifndef	HAVE_LIBPLOT
NoPlotutils(Widget w,XtPointer client,XtPointer call)1252 void NoPlotutils(Widget w, XtPointer client, XtPointer call)
1253 {
1254 	XmString	xms;
1255 	char		*s = NULL;
1256 
1257 	MotifSelectGlobal(w);
1258 
1259 	XtVaGetValues(w, XmNlabelString, &xms, NULL);
1260 	if (XmStringGetLtoR(xms, XmFONTLIST_DEFAULT_TAG, &s)) {
1261 		MessageAppend(False, "%s: GNU Plotutils not linked in\n", s);
1262 		XtFree(s);
1263 	}
1264 	XmStringFree(xms);
1265 }
1266 #endif
1267 
1268 /*
1269  * RedrawPlotutilsWindow is called when the plotutils widget needs
1270  * a refresh, which may just be when it's scrolling.
1271  */
RedrawPlotutilsWindow(Widget w,XtPointer client,XtPointer call)1272 static void RedrawPlotutilsWindow(Widget w, XtPointer client, XtPointer call)
1273 {
1274 	void (*f)(char *, FILE *) = client;
1275 
1276 	MotifSelectGlobal(w);
1277 
1278 	(*f)("Xdrawable", stdout);
1279 }
1280 
1281 /*
1282  * Show a GNU Plotutils chart in a Motif widget.
1283  *
1284  * The client parameter is the function (from plot.c) which will
1285  * handle the plotting. We pass it to RedrawPlotutilsWindow() too.
1286  */
PuShowChart(Widget w,XtPointer client,XtPointer call)1287 void PuShowChart(Widget w, XtPointer client, XtPointer call)
1288 {
1289 #ifdef	HAVE_LIBPLOT
1290 	static Window	window;
1291 	Widget		dlg, d, cancel, help, sw;
1292 	Arg		al[5];
1293 	int		ac;
1294 	void (*f)(char *, FILE *) = client;
1295 
1296 	MotifSelectGlobal(w);
1297 
1298 	ac = 0;
1299 	XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
1300 	dlg = XmCreateTemplateDialog(toplevel, "printDialog", al, ac);
1301 
1302 	ac = 0;
1303 #if 0
1304 	XtSetArg(al[ac], XmNwidth, 500); ac++;
1305 	XtSetArg(al[ac], XmNheight, 500); ac++;
1306 #endif
1307 	XtSetArg(al[ac], XmNwidth, Global->PlotGlobal->img_width + 100); ac++;
1308 	XtSetArg(al[ac], XmNheight, Global->PlotGlobal->img_height + 100); ac++;
1309 	XtSetArg(al[ac], XmNscrollingPolicy, XmAUTOMATIC); ac++;
1310 	sw = XmCreateScrolledWindow(dlg, "scroll", al, ac);
1311 	XtManageChild(sw);
1312 
1313 	ac = 0;
1314 	XtSetArg(al[ac], XmNwidth, Global->PlotGlobal->img_width); ac++;
1315 	XtSetArg(al[ac], XmNheight, Global->PlotGlobal->img_height); ac++;
1316 	d = XmCreateDrawingArea(sw, "DrawingArea", al, ac);
1317 	XtManageChild(d);
1318 
1319 	XtAddCallback(d, XmNexposeCallback, RedrawPlotutilsWindow, f);
1320 
1321 	XtManageChild(dlg);
1322 
1323 	window = XtWindow(d);
1324 	if (window == 0) {
1325 		MessageAppend(True, "PuShowChart: 0 window\n");
1326 		return;
1327 	}
1328 
1329 	PuX(XtDisplayOfObject(w), window);
1330 	PlotInit();
1331 
1332 	cancel = XtVaCreateManagedWidget("dismiss", xmPushButtonGadgetClass, dlg, NULL);
1333 	XtAddCallback(cancel, XmNactivateCallback, DestroyTemplate, dlg);
1334 
1335 	help = XtVaCreateManagedWidget("help",
1336 		xmPushButtonGadgetClass, dlg, NULL);
1337 	XtAddCallback(help, XmNactivateCallback, helpUsingCB,
1338 		(XtPointer)"#HelpPlotting");
1339 
1340 	(*f)("Xdrawable", stdout);
1341 #else
1342 	NoPlotutils(w, client, call);
1343 #endif
1344 }
1345 
1346 /*
1347  * Printing
1348  *	need to pop up a dialog to select a file and a GNU PlotUtils plotter
1349  *	then actually doit
1350  */
PuSelectPlotter(Widget w,XtPointer client,XtPointer call)1351 void PuSelectPlotter(Widget w, XtPointer client, XtPointer call)
1352 {
1353 	XmString	xms;
1354 	char		*p;
1355 	int		i;
1356 
1357 	MotifSelectGlobal(w);
1358 
1359 	PuPlotter = (int)client;
1360 
1361 	plotutils_set_device(PuPlotter);
1362 
1363 	for (i=0; PlotutilsDeviceArray[i].pus; i++)
1364 		if (PlotutilsDeviceArray[i].t == PuPlotter)
1365 			break;
1366 
1367 #if 0
1368 	fprintf(stderr, "PuSelectPlotter(%s)\n", PlotutilsDeviceArray[i].desc);
1369 #endif
1370 
1371 	p = malloc(strlen(PlotutilsDeviceArray[i].ext) + 8);
1372 	strcpy(p, "*.");
1373 	strcat(p, PlotutilsDeviceArray[i].ext);
1374 	xms = XmStringCreateSimple(p);
1375 	free(p);
1376 
1377 	XtVaSetValues(pufsd, XmNpattern, xms, NULL);
1378 	XmStringFree(xms);
1379 }
1380 
CreatePlotterOption(Widget parent,XtCallbackProc f)1381 Widget CreatePlotterOption(Widget parent, XtCallbackProc f)
1382 {
1383 	Arg		al[10];
1384 	int		ac = 0, r, i;
1385 	XmString	xms;
1386 	Widget		cb, menu, b;
1387 
1388 	menu = XmCreatePulldownMenu(parent, "optionMenu", NULL, 0);
1389 	ac = 0;
1390 	XtSetArg(al[ac], XmNsubMenuId, menu); ac++;
1391 	xms = XmStringCreateSimple(_("Plotter Type"));
1392 	XtSetArg(al[ac], XmNlabelString, xms); ac++;
1393 	cb = XmCreateOptionMenu(parent, "optionCB", al, ac);
1394 	XtManageChild(cb);
1395 	XmStringFree(xms);
1396 
1397 	for (i=0; PlotutilsDeviceArray[i].pus; i++) {
1398 		b = XtVaCreateManagedWidget(PlotutilsDeviceArray[i].pus, xmPushButtonGadgetClass,
1399 			menu,
1400 			NULL);
1401 		XtAddCallback(b, XmNactivateCallback, f, (XtPointer)PlotutilsDeviceArray[i].t);
1402 	}
1403 
1404 	return menu;
1405 }
1406 
PuPrintOk(Widget w,XtPointer client,XtPointer call)1407 void PuPrintOk(Widget w, XtPointer client, XtPointer call)
1408 {
1409 #ifdef	HAVE_LIBPLOT
1410 	XmFileSelectionBoxCallbackStruct	*cbp = (XmFileSelectionBoxCallbackStruct *)call;
1411 	char					*fn;
1412 
1413 	MotifSelectGlobal(w);
1414 
1415 	if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &fn)) {
1416 		/* FIX ME */
1417 		return;
1418 	}
1419 
1420 	plotutils_set_filename(fn);
1421 	graph_plot();
1422 #endif
1423 }
1424 
PuPrintDialog(Widget w,XtPointer client,XtPointer call)1425 void PuPrintDialog(Widget w, XtPointer client, XtPointer call)
1426 {
1427 	Arg		al[10];
1428 	int		ac = 0;
1429 	XmString	xms;
1430 	Widget		cb, menu, b;
1431 
1432 	MotifSelectGlobal(w);
1433 
1434 	ac = 0;
1435 	XtSetArg(al[ac], XmNautoUnmanage, True); ac++;
1436 	xms = XmStringCreateSimple(_("*.oleo"));
1437 	XtSetArg(al[ac], XmNpattern, xms); ac++;
1438 
1439 	pufsd = XmCreateFileSelectionDialog(toplevel, "puselectfile",
1440 		al, ac);
1441 	XtDestroyWidget(
1442 		XmFileSelectionBoxGetChild(pufsd, XmDIALOG_HELP_BUTTON));
1443 	XmStringFree(xms);
1444 	XtAddCallback(pufsd, XmNokCallback, PuPrintOk, NULL);
1445 
1446 	/* Option menu */
1447 	menu = CreatePlotterOption(pufsd, PuSelectPlotter);
1448 }
1449 
PuPrint(Widget w,XtPointer client,XtPointer call)1450 void PuPrint(Widget w, XtPointer client, XtPointer call)
1451 {
1452 #ifdef	HAVE_LIBPLOT
1453 	enum graph_type	gt = (enum graph_type)client;
1454 
1455 	MotifSelectGlobal(w);
1456 
1457 	plotutils_set_graph_type(gt);
1458 
1459 	if (! pufsd) PuPrintDialog(w, client, call);
1460 	XtManageChild(pufsd);
1461 #endif
1462 }
1463 
1464 #ifdef	HAVE_LIBPLOT
TickTypeCB(Widget w,XtPointer client,XtPointer call)1465 static void TickTypeCB(Widget w, XtPointer client, XtPointer call)
1466 {
1467 	int	n = (int)client;
1468 	int	axis = n / 256;
1469 	int	val = n % 256;
1470 	tick_type_e	v = (tick_type_e)val;
1471 	Widget	tw;
1472 
1473 	MotifSelectGlobal(w);
1474 
1475 	if (axis == 0) {
1476 		Global->MotifGlobal->xtick = val;
1477 		tw = Global->MotifGlobal->xtickfmt;
1478 	} else {
1479 		Global->MotifGlobal->ytick = val;
1480 		tw = Global->MotifGlobal->ytickfmt;
1481 	}
1482 
1483 	switch (v) {
1484 	SP_TICK_DEFAULT:
1485 	SP_TICK_NONE:
1486 #if 0
1487 		fprintf(stderr, "TickTypeCB(axis %d type %d) -> insensitive \n", axis, val);
1488 #endif
1489 		XmTextFieldSetEditable(tw, False);
1490 		break;
1491 	SP_TICK_PRINTF:
1492 	SP_TICK_STRFTIME:
1493 #if 0
1494 		fprintf(stderr, "TickTypeCB(axis %d type %d) -> sensitive \n", axis, val);
1495 #endif
1496 		XmTextFieldSetEditable(tw, True);
1497 		break;
1498 	default: {}
1499 #if 0
1500 		fprintf(stderr, "Huh ? TickTypeCB(axis %d type %d) -> sensitive \n", axis, val);
1501 #endif
1502 	}
1503 #if 0
1504 	fprintf(stderr, "SP_TICK_DEFAULT %d\n", SP_TICK_DEFAULT);
1505 	fprintf(stderr, "SP_TICK_NONE %d\n", SP_TICK_NONE);
1506 	fprintf(stderr, "SP_TICK_PRINTF %d\n", SP_TICK_PRINTF);
1507 	fprintf(stderr, "SP_TICK_STRFTIME %d\n", SP_TICK_STRFTIME);
1508 #endif
1509 }
1510 
1511 /*
1512  * A piece of dialog for configuring XY chars
1513  *	Needs to be managed by the caller.
1514  */
ConfigureXYChart(Widget parent)1515 Widget ConfigureXYChart(Widget parent)
1516 {
1517 	Widget	frame, form, w, te, l, t;
1518 	Arg	al[10];
1519 	int	ac;
1520 	XmString	xms;
1521 
1522 	MotifSelectGlobal(parent);
1523 
1524 	ac = 0;
1525 	frame = XmCreateFrame(parent, "puselectfile", al, ac);
1526 
1527 	w = XtVaCreateManagedWidget("configureXYChartFrameTitle",
1528 			xmLabelGadgetClass,		frame,
1529 			XmNchildType,			XmFRAME_TITLE_CHILD,
1530 			XmNchildVerticalAlignment,	XmALIGNMENT_CENTER,
1531 		NULL);
1532 
1533 	form = XtVaCreateManagedWidget("configureXYChartForm", xmFormWidgetClass,
1534 		frame,
1535 		NULL);
1536 
1537 	/* X Axis */
1538 	XYxAutoToggle =
1539 	t = XtVaCreateManagedWidget("xAutoToggle", xmToggleButtonGadgetClass,
1540 		form,
1541 			XmNtopAttachment,	XmATTACH_FORM,
1542 			XmNtopOffset,		10,
1543 			XmNleftAttachment,	XmATTACH_FORM,
1544 			XmNleftOffset,		10,
1545 		NULL);
1546 	l = XtVaCreateManagedWidget("xMinLabel", xmLabelGadgetClass, form,
1547 			XmNtopAttachment,	XmATTACH_FORM,
1548 			XmNtopOffset,		10,
1549 			XmNleftAttachment,	XmATTACH_WIDGET,
1550 			XmNleftWidget,		t,
1551 			XmNleftOffset,		10,
1552 		NULL);
1553 	XYxMinText =
1554 	te = XtVaCreateManagedWidget("xMinText", xmTextFieldWidgetClass, form,
1555 			XmNtopAttachment,	XmATTACH_FORM,
1556 			XmNtopOffset,		10,
1557 			XmNleftAttachment,	XmATTACH_WIDGET,
1558 			XmNleftWidget,		l,
1559 			XmNleftOffset,		10,
1560 		NULL);
1561 	l = XtVaCreateManagedWidget("xMaxLabel", xmLabelGadgetClass, form,
1562 			XmNtopAttachment,	XmATTACH_FORM,
1563 			XmNtopOffset,		10,
1564 			XmNleftAttachment,	XmATTACH_WIDGET,
1565 			XmNleftWidget,		te,
1566 			XmNleftOffset,		10,
1567 		NULL);
1568 	XYxMaxText =
1569 	te = XtVaCreateManagedWidget("xMaxText", xmTextFieldWidgetClass, form,
1570 			XmNtopAttachment,	XmATTACH_FORM,
1571 			XmNtopOffset,		10,
1572 			XmNleftAttachment,	XmATTACH_WIDGET,
1573 			XmNleftWidget,		l,
1574 			XmNleftOffset,		10,
1575 		NULL);
1576 
1577 	/* Y Axis */
1578 	XYyAutoToggle =
1579 	t = XtVaCreateManagedWidget("yAutoToggle", xmToggleButtonGadgetClass,
1580 		form,
1581 			XmNtopAttachment,	XmATTACH_WIDGET,
1582 			XmNtopWidget,		te,
1583 			XmNtopOffset,		10,
1584 			XmNleftAttachment,	XmATTACH_FORM,
1585 			XmNleftOffset,		10,
1586 		NULL);
1587 	l = XtVaCreateManagedWidget("yMinLabel", xmLabelGadgetClass, form,
1588 			XmNtopAttachment,	XmATTACH_OPPOSITE_WIDGET,
1589 			XmNtopOffset,		0,
1590 			XmNtopWidget,		t,
1591 			XmNleftAttachment,	XmATTACH_WIDGET,
1592 			XmNleftWidget,		t,
1593 			XmNleftOffset,		10,
1594 		NULL);
1595 	XYyMinText =
1596 	te = XtVaCreateManagedWidget("yMinText", xmTextFieldWidgetClass, form,
1597 			XmNtopAttachment,	XmATTACH_OPPOSITE_WIDGET,
1598 			XmNtopOffset,		0,
1599 			XmNtopWidget,		t,
1600 			XmNleftAttachment,	XmATTACH_WIDGET,
1601 			XmNleftWidget,		l,
1602 			XmNleftOffset,		10,
1603 		NULL);
1604 	l = XtVaCreateManagedWidget("yMaxLabel", xmLabelGadgetClass, form,
1605 			XmNtopAttachment,	XmATTACH_OPPOSITE_WIDGET,
1606 			XmNtopOffset,		0,
1607 			XmNtopWidget,		t,
1608 			XmNleftAttachment,	XmATTACH_WIDGET,
1609 			XmNleftWidget,		te,
1610 			XmNleftOffset,		10,
1611 		NULL);
1612 	XYyMaxText =
1613 	te = XtVaCreateManagedWidget("yMaxText", xmTextFieldWidgetClass, form,
1614 			XmNtopAttachment,	XmATTACH_OPPOSITE_WIDGET,
1615 			XmNtopOffset,		0,
1616 			XmNtopWidget,		t,
1617 			XmNleftAttachment,	XmATTACH_WIDGET,
1618 			XmNleftWidget,		l,
1619 			XmNleftOffset,		10,
1620 		NULL);
1621 
1622 	/* Line type */
1623 
1624 	/* Lines to offscreen data points */
1625 	lineToOffscreen = XtVaCreateManagedWidget("lineToOffscreen", xmToggleButtonGadgetClass,
1626 		form,
1627 			XmNtopAttachment,       XmATTACH_WIDGET,
1628 			XmNtopWidget,           te,
1629 			XmNtopOffset,           10,
1630 			XmNleftAttachment,      XmATTACH_FORM,
1631 			XmNleftOffset,          10,
1632 		NULL);
1633 
1634 	/* Axis tick labels */
1635 	Global->MotifGlobal->XLogToggle = XtVaCreateManagedWidget("xLogToggle",
1636 		xmToggleButtonGadgetClass,
1637 		form,
1638 			XmNtopAttachment,       XmATTACH_WIDGET,
1639 			XmNtopWidget,           lineToOffscreen,
1640 			XmNtopOffset,           10,
1641 			XmNleftAttachment,      XmATTACH_FORM,
1642 			XmNleftOffset,          10,
1643 		NULL);
1644 
1645 	Global->MotifGlobal->xticklblmenu = XmCreatePulldownMenu(form, "xticklblmenu", NULL, 0);
1646 	ac=0;
1647 	XtSetArg(al[ac], XmNsubMenuId, Global->MotifGlobal->xticklblmenu); ac++;
1648 	xms = XmStringCreateSimple(_("X Axis Tick Label Type"));
1649 	XtSetArg(al[ac], XmNlabelString, xms); ac++;
1650 	XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
1651 	XtSetArg(al[ac], XmNtopWidget, lineToOffscreen); ac++;
1652 	XtSetArg(al[ac], XmNtopOffset, 10); ac++;
1653 	XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1654 	XtSetArg(al[ac], XmNleftWidget, Global->MotifGlobal->XLogToggle); ac++;
1655 	XtSetArg(al[ac], XmNleftOffset, 10); ac++;
1656 	Global->MotifGlobal->xticklbloption = XmCreateOptionMenu(form, "xticklbloption", al, ac);
1657 	XtManageChild(Global->MotifGlobal->xticklbloption);
1658 
1659 	w = XtVaCreateManagedWidget("xtickdefault", xmPushButtonWidgetClass,
1660 		Global->MotifGlobal->xticklblmenu,
1661 		NULL);
1662 	Global->MotifGlobal->ticktype_w[0][SP_TICK_DEFAULT] = w;
1663 	XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x000 | SP_TICK_DEFAULT));
1664 	w = XtVaCreateManagedWidget("xticknone", xmPushButtonWidgetClass,
1665 		Global->MotifGlobal->xticklblmenu,
1666 		NULL);
1667 	Global->MotifGlobal->ticktype_w[0][SP_TICK_NONE] = w;
1668 	XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x000 | SP_TICK_NONE));
1669 	w = XtVaCreateManagedWidget("xtickprintf", xmPushButtonWidgetClass,
1670 		Global->MotifGlobal->xticklblmenu,
1671 		NULL);
1672 	Global->MotifGlobal->ticktype_w[0][SP_TICK_PRINTF] = w;
1673 	XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x000 | SP_TICK_PRINTF));
1674 	w = XtVaCreateManagedWidget("xtickstrftime", xmPushButtonWidgetClass,
1675 		Global->MotifGlobal->xticklblmenu,
1676 		NULL);
1677 	Global->MotifGlobal->ticktype_w[0][SP_TICK_STRFTIME] = w;
1678 	XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x000 | SP_TICK_STRFTIME));
1679 
1680 	Global->MotifGlobal->xtickfmt = XtVaCreateManagedWidget("xtickfmt", xmTextFieldWidgetClass,
1681 		form,
1682 			XmNtopAttachment,	XmATTACH_WIDGET,
1683 			XmNtopWidget,		lineToOffscreen,
1684 			XmNtopOffset,		10,
1685 			XmNleftAttachment,	XmATTACH_WIDGET,
1686 			XmNleftWidget,		Global->MotifGlobal->xticklbloption,
1687 			XmNleftOffset,		10,
1688 		NULL);
1689 
1690 	Global->MotifGlobal->YLogToggle = XtVaCreateManagedWidget("yLogToggle",
1691 		xmToggleButtonGadgetClass,
1692 		form,
1693 			XmNtopAttachment,       XmATTACH_WIDGET,
1694 			XmNtopWidget,           Global->MotifGlobal->XLogToggle,
1695 			XmNtopOffset,           10,
1696 			XmNleftAttachment,      XmATTACH_FORM,
1697 			XmNleftOffset,          10,
1698 		NULL);
1699 
1700 	Global->MotifGlobal->yticklblmenu = XmCreatePulldownMenu(form, "yticklblmenu", NULL, 0);
1701 	ac=0;
1702 	XtSetArg(al[ac], XmNsubMenuId, Global->MotifGlobal->yticklblmenu); ac++;
1703 	xms = XmStringCreateSimple(_("Y Axis Tick Label Type"));
1704 	XtSetArg(al[ac], XmNlabelString, xms); ac++;
1705 	XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
1706 	XtSetArg(al[ac], XmNtopWidget, Global->MotifGlobal->xtickfmt); ac++;
1707 	XtSetArg(al[ac], XmNtopOffset, 10); ac++;
1708 	XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1709 	XtSetArg(al[ac], XmNleftWidget, Global->MotifGlobal->YLogToggle); ac++;
1710 	XtSetArg(al[ac], XmNleftOffset, 10); ac++;
1711 	Global->MotifGlobal->yticklbloption = XmCreateOptionMenu(form, "yticklbloption", al, ac);
1712 	XtManageChild(Global->MotifGlobal->yticklbloption);
1713 
1714 	w = XtVaCreateManagedWidget("ytickdefault", xmPushButtonWidgetClass,
1715 		Global->MotifGlobal->yticklblmenu,
1716 		NULL);
1717 	Global->MotifGlobal->ticktype_w[1][SP_TICK_DEFAULT] = w;
1718 	XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x100 | SP_TICK_DEFAULT));
1719 	w = XtVaCreateManagedWidget("yticknone", xmPushButtonWidgetClass,
1720 		Global->MotifGlobal->yticklblmenu,
1721 		NULL);
1722 	Global->MotifGlobal->ticktype_w[1][SP_TICK_NONE] = w;
1723 	XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x100 | SP_TICK_NONE));
1724 	w = XtVaCreateManagedWidget("ytickprintf", xmPushButtonWidgetClass,
1725 		Global->MotifGlobal->yticklblmenu,
1726 		NULL);
1727 	Global->MotifGlobal->ticktype_w[1][SP_TICK_PRINTF] = w;
1728 	XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x100 | SP_TICK_PRINTF));
1729 	w = XtVaCreateManagedWidget("ytickstrftime", xmPushButtonWidgetClass,
1730 		Global->MotifGlobal->yticklblmenu,
1731 		NULL);
1732 	Global->MotifGlobal->ticktype_w[1][SP_TICK_STRFTIME] = w;
1733 	XtAddCallback(w, XmNactivateCallback, TickTypeCB, (XtPointer)(0x100 | SP_TICK_STRFTIME));
1734 
1735 	Global->MotifGlobal->ytickfmt = XtVaCreateManagedWidget("ytickfmt", xmTextFieldWidgetClass,
1736 		form,
1737 			XmNtopAttachment,	XmATTACH_WIDGET,
1738 			XmNtopWidget,		Global->MotifGlobal->XLogToggle,
1739 			XmNtopOffset,		10,
1740 			XmNleftAttachment,	XmATTACH_WIDGET,
1741 			XmNleftWidget,		Global->MotifGlobal->xticklbloption,
1742 			XmNleftOffset,		10,
1743 		NULL);
1744 
1745 	return frame;
1746 }
1747 
ConfigureXYOk(void)1748 void ConfigureXYOk(void)
1749 {
1750 	char	*s;
1751 	int	b;
1752 
1753 	s = XmTextFieldGetString(XYxMinText);
1754 	graph_set_axis_lo('x', s);
1755 
1756 	s = XmTextFieldGetString(XYxMaxText);
1757 	graph_set_axis_hi('x', s);
1758 
1759 	s = XmTextFieldGetString(XYyMinText);
1760 	graph_set_axis_lo('y', s);
1761 
1762 	s = XmTextFieldGetString(XYyMaxText);
1763 	graph_set_axis_hi('y', s);
1764 
1765 	graph_set_axis_auto(0, XmToggleButtonGadgetGetState(XYxAutoToggle));
1766 	graph_set_axis_auto(1, XmToggleButtonGadgetGetState(XYyAutoToggle));
1767 	graph_set_linetooffscreen(XmToggleButtonGadgetGetState(lineToOffscreen));
1768 
1769 	graph_set_axis_ticks(0,
1770 		/* tick label type */	Global->MotifGlobal->xtick,
1771 		/* format string */	XmTextFieldGetString(Global->MotifGlobal->xtickfmt));
1772 	graph_set_axis_ticks(1,
1773 		/* tick label type */	Global->MotifGlobal->ytick,
1774 		/* format string */	XmTextFieldGetString(Global->MotifGlobal->ytickfmt));
1775 
1776 	/* FIX ME treat these */
1777 	b = XmToggleButtonGadgetGetState(Global->MotifGlobal->YLogToggle);
1778 	b = XmToggleButtonGadgetGetState(Global->MotifGlobal->YLogToggle);
1779 }
1780 
TextFieldSetFloat(Widget w,float f)1781 static void TextFieldSetFloat(Widget w, float f)
1782 {
1783 	char	t[32];
1784 
1785 	sprintf(t, "%f", f);
1786 	XmTextFieldSetString(w, t);
1787 }
1788 
ConfigureXYReset(void)1789 void ConfigureXYReset(void)
1790 {
1791 	XmToggleButtonGadgetSetState(XYxAutoToggle, graph_get_axis_auto(0), False);
1792 	TextFieldSetFloat(XYxMinText, graph_get_axis_lo(0));
1793 	TextFieldSetFloat(XYxMaxText, graph_get_axis_hi(0));
1794 	XmToggleButtonGadgetSetState(XYyAutoToggle, graph_get_axis_auto(1), False);
1795 	TextFieldSetFloat(XYyMinText, graph_get_axis_lo(1));
1796 	TextFieldSetFloat(XYyMaxText, graph_get_axis_hi(1));
1797 	XmToggleButtonGadgetSetState(lineToOffscreen, graph_get_linetooffscreen(), False);
1798 
1799 	XtVaSetValues(Global->MotifGlobal->xticklbloption, XmNmenuHistory,
1800 		Global->MotifGlobal->ticktype_w[0][Global->PlotGlobal->ticktype[0]], NULL);
1801 	XtVaSetValues(Global->MotifGlobal->yticklbloption, XmNmenuHistory,
1802 		Global->MotifGlobal->ticktype_w[1][Global->PlotGlobal->ticktype[1]], NULL);
1803 
1804 	XmTextFieldSetString(Global->MotifGlobal->xtickfmt, graph_get_axis_tickformat(0));
1805 	XmTextFieldSetString(Global->MotifGlobal->ytickfmt, graph_get_axis_tickformat(1));
1806 }
1807 
ConfigurePieChart(Widget parent)1808 Widget ConfigurePieChart(Widget parent)
1809 {
1810 	Widget	frame, form, w, te, l, t;
1811 	Arg	al[10];
1812 	int	ac;
1813 
1814 	ac = 0;
1815 	frame = XmCreateFrame(parent, "configurePieChartFrame", al, ac);
1816 
1817 	w = XtVaCreateManagedWidget("configurePieChartFrameTitle",
1818 			xmLabelGadgetClass,		frame,
1819 			XmNchildType,			XmFRAME_TITLE_CHILD,
1820 			XmNchildVerticalAlignment,	XmALIGNMENT_CENTER,
1821 		NULL);
1822 
1823 	form = XtVaCreateManagedWidget("configurePieChartForm", xmFormWidgetClass,
1824 		frame,
1825 		NULL);
1826 	t = XtVaCreateManagedWidget("pie3d", xmToggleButtonGadgetClass,
1827 		form,
1828 			XmNtopAttachment,	XmATTACH_FORM,
1829 			XmNtopOffset,		10,
1830 			XmNleftAttachment,	XmATTACH_FORM,
1831 			XmNleftOffset,		10,
1832 		NULL);
1833 
1834 	return frame;
1835 }
1836 
ConfigurePieOk(void)1837 void ConfigurePieOk(void)
1838 {
1839 }
1840 
ConfigurePieReset(void)1841 void ConfigurePieReset(void)
1842 {
1843 }
1844 
ConfigureBarChart(Widget parent)1845 Widget ConfigureBarChart(Widget parent)
1846 {
1847 	Widget	frame, form, w, te, l, t;
1848 	Arg	al[10];
1849 	int	ac;
1850 
1851 	ac = 0;
1852 	frame = XmCreateFrame(parent, "configureBarChartFrame", al, ac);
1853 
1854 	w = XtVaCreateManagedWidget("configureBarChartFrameTitle",
1855 			xmLabelGadgetClass,		frame,
1856 			XmNchildType,			XmFRAME_TITLE_CHILD,
1857 			XmNchildVerticalAlignment,	XmALIGNMENT_CENTER,
1858 		NULL);
1859 
1860 	form = XtVaCreateManagedWidget("configureBarChartForm", xmFormWidgetClass,
1861 		frame,
1862 		NULL);
1863 	t = XtVaCreateManagedWidget("stackToggle", xmToggleButtonGadgetClass,
1864 		form,
1865 			XmNtopAttachment,	XmATTACH_FORM,
1866 			XmNtopOffset,		10,
1867 			XmNleftAttachment,	XmATTACH_FORM,
1868 			XmNleftOffset,		10,
1869 		NULL);
1870 
1871 	return frame;
1872 }
1873 
ConfigureBarOk(void)1874 void ConfigureBarOk(void)
1875 {
1876 }
1877 
ConfigureBarReset(void)1878 void ConfigureBarReset(void)
1879 {
1880 }
1881 #endif
1882 
1883 /*
1884  * Print
1885  */
1886 struct PrintWidgets {
1887 	Widget	rangeTF, fileTF, printerTF, programTF;
1888 	Widget	PrinterToggle, FileToggle, ProgramToggle;
1889 } PrintWidgets;
1890 
1891 /*
1892  * Print the spreadsheet
1893  */
ReallyPrintCB(Widget w,XtPointer client,XtPointer call)1894 void ReallyPrintCB(Widget w, XtPointer client, XtPointer call)
1895 {
1896 	/* FIX ME
1897 	 * This is simplistic, we need to print to either a file,
1898 	 * selected by the user from a dialog, or to a printer,
1899 	 * also selected by the user.
1900 	 */
1901 	FILE		*fp = NULL;
1902 	struct rng	rng;
1903 	char		*fn = NULL, *s, *p, *pr = NULL;
1904 	int		r;
1905 
1906 	MotifSelectGlobal(w);
1907 
1908 	XtUnmanageChild(PrintDialog);
1909 
1910 	if (XmToggleButtonGadgetGetState(PrintWidgets.PrinterToggle)) {
1911 		char	cmd[64];
1912 
1913 		pr = XmTextFieldGetString(PrintWidgets.printerTF);
1914 		if (pr && strlen(pr)) {
1915 			sprintf(cmd, "lpr -P%s", pr);
1916 		} else if (strlen(AppRes.printer)) {
1917 			sprintf(cmd, "lpr -P%s", AppRes.printer);
1918 			pr = AppRes.printer;
1919 		} else {
1920 			sprintf(cmd, "lpr");
1921 			pr = "[default printer]";
1922 		}
1923 
1924 		fp = popen(cmd, "w");
1925 		if (fp == NULL) {
1926 			MessageAppend(True, "Couldn't print to printer %s\n", AppRes.printer);
1927 			return;
1928 		}
1929 	} else if (XmToggleButtonGadgetGetState(PrintWidgets.FileToggle)) {
1930 		fn = XmTextFieldGetString(PrintWidgets.fileTF);
1931 
1932 		if (fn)
1933 			fp = fopen(fn, "w");
1934 		if (! fp) {
1935 			MessageAppend(True, "Couldn't write to file %s\n", fn);
1936 #ifdef	FREE_TF_STRING
1937 			XtFree(fn);
1938 #endif
1939 			return;
1940 		}
1941 	} else if (XmToggleButtonGadgetGetState(PrintWidgets.ProgramToggle)) {
1942 		fp = popen(AppRes.program, "w");
1943 
1944 		if (fp == NULL) {
1945 			MessageAppend(True, "Couldn't print to program %s\n", AppRes.program);
1946 			return;
1947 		}
1948 	} else {
1949 		MessageAppend(True, _("Internal error: can't find what to print to\n"));
1950 		return;
1951 	}
1952 
1953 	p = s = XmTextFieldGetString(PrintWidgets.rangeTF);
1954 	if ((r = parse_cell_or_range(&p, &rng)) == 0) {
1955 		ConversionError(s, _("range"));
1956 
1957 		/* FIX ME Which range is the complete spreadsheet ? */
1958 		rng.lr = 1;
1959 		rng.lc = 1;
1960 		rng.hc = 40;
1961 		rng.hr = 80;
1962 
1963 	} else if (r & RANGE) {
1964 		;
1965 	} else {
1966 		rng.hr = rng.lr;
1967 		rng.hc = rng.lc;
1968 	}
1969 #ifdef	FREE_TF_STRING
1970 	XtFree(s);
1971 #endif
1972 
1973 	print_region_cmd(&rng, fp);
1974 	if (XmToggleButtonGadgetGetState(PrintWidgets.FileToggle))
1975 		fclose(fp);
1976 	else
1977 		pclose(fp);
1978 
1979 	if (Global->zoom < 0.90 || Global->zoom > 1.1) {
1980 		int	z = Global->zoom * 100;
1981 		if (fn)
1982 		    MessageAppend(False, "Printed %s to file %s, at %d percent size\n",
1983 			range_name(&rng), fn, z);
1984 		else
1985 		    MessageAppend(False, "Printed %s to printer %s, at %d percent size\n",
1986 			range_name(&rng), pr, z);
1987 	} else if (fn) {
1988 		MessageAppend(False, "Printed %s to file %s\n", range_name(&rng), fn);
1989 	} else {
1990 		MessageAppend(False, "Printed %s to printer %s\n", range_name(&rng), pr);
1991 	}
1992 
1993 #ifdef	FREE_TF_STRING
1994 	XtFree(fn);
1995 #endif
1996 }
1997 
MotifSetPrintType(Widget w,XtPointer client,XtPointer call)1998 static void MotifSetPrintType(Widget w, XtPointer client, XtPointer call)
1999 {
2000 	char	*s = (char *)client;
2001 
2002 	MotifSelectGlobal(w);
2003 
2004 	MessageAppend(False, "Set printer type to %s\n", s);
2005 	PrintSetType(s);
2006 }
2007 
MotifSetPrintPage(Widget w,XtPointer client,XtPointer call)2008 static void MotifSetPrintPage(Widget w, XtPointer client, XtPointer call)
2009 {
2010 	int	i = (int) client;
2011 
2012 	MotifSelectGlobal(w);
2013 
2014 	MessageAppend(False, "Set page format to %s\n", PrintGetPageName(i));
2015 	PrintSetPage(PrintGetPageName(i));
2016 }
2017 
2018 /*
2019  * Select a file to print into
2020  */
PrintBrowseFileCBOk(Widget w,XtPointer client,XtPointer call)2021 void PrintBrowseFileCBOk(Widget w, XtPointer client, XtPointer call)
2022 {
2023 	char	*fn;
2024 	XmFileSelectionBoxCallbackStruct *cbp = (XmFileSelectionBoxCallbackStruct *)call;
2025 
2026 	MotifSelectGlobal(w);
2027 
2028 	if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &fn))
2029 		return;
2030 
2031 	XmTextFieldSetString(PrintWidgets.fileTF, fn);
2032 }
2033 
PrintBrowseFileCB(Widget w,XtPointer client,XtPointer call)2034 void PrintBrowseFileCB(Widget w, XtPointer client, XtPointer call)
2035 {
2036 	MotifSelectGlobal(w);
2037 
2038 	if (! pfsd) {
2039 		XmString	xms;
2040 		Arg		al[5];
2041 		int		ac = 0;
2042 
2043 		xms = XmStringCreateSimple(_("*.out"));
2044 		XtSetArg(al[ac], XmNpattern, xms); ac++;
2045 		XtSetArg(al[ac], XmNautoUnmanage, True); ac++;
2046 
2047 		pfsd = XmCreateFileSelectionDialog(toplevel, "selectfile",
2048 			al, ac);
2049 		XtDestroyWidget(
2050 			XmFileSelectionBoxGetChild(pfsd, XmDIALOG_HELP_BUTTON));
2051 		XtAddCallback(pfsd, XmNokCallback, PrintBrowseFileCBOk, NULL);
2052 
2053 		XmStringFree(xms);
2054 	}
2055 
2056 	XtManageChild(pfsd);
2057 }
2058 
CupsSelectPrinter(Widget w,XtPointer client,XtPointer call)2059 void CupsSelectPrinter(Widget w, XtPointer client, XtPointer call)
2060 {
2061 	Widget tf = (Widget)client;
2062 
2063 	MotifSelectGlobal(w);
2064 
2065 	XmTextFieldSetString(tf, XtName(w));
2066 }
2067 
2068 /*
2069  * The print dialog :
2070  *	- select where to print to (program, printer, file)
2071  *	- paper size
2072  *	- print range
2073  */
MotifCreatePrintDialog(Widget s)2074 Widget MotifCreatePrintDialog(Widget s)
2075 {
2076 	Widget		form, menu, cb, w, frame, radio, form2, cb1, cupsmenu,
2077 			cupsOption;
2078 	int		npages, i, ac, nprinters;
2079 	Arg		al[5];
2080 	XmString	xms;
2081 	int		defaultprint = 0;
2082 	char		**printers;
2083 
2084 	MotifSelectGlobal(s);
2085 
2086 	ac = 0;
2087 	form = XmCreateForm(s, "printForm", al, ac);
2088 
2089 	/* Check value of resource */
2090 #ifdef	HAVE_STRCASECMP
2091 	if (strcasecmp(AppRes.defaultPrintTo, "printer") != 0
2092 	    && strcasecmp(AppRes.defaultPrintTo, "program") != 0
2093 	    && strcasecmp(AppRes.defaultPrintTo, "file") != 0)
2094 #else
2095 	if (strcmp(AppRes.defaultPrintTo, "printer") != 0
2096 	    && strcmp(AppRes.defaultPrintTo, "program") != 0
2097 	    && strcmp(AppRes.defaultPrintTo, "file") != 0)
2098 #endif
2099 	{
2100 		defaultprint = 1;
2101 
2102 		MessageAppend(True, _("Value of defaultPrintTo resource is invalid, "
2103 			"should be one of %s, %s, or %s\n"),
2104 			"printer", "file", "program");
2105 
2106 	}
2107 
2108 	/* Destination */
2109 	frame = XtVaCreateManagedWidget("printDestinationFrame",
2110 			xmFrameWidgetClass, form,
2111 			XmNleftAttachment,	XmATTACH_FORM,
2112 			XmNtopAttachment,	XmATTACH_FORM,
2113 			XmNleftOffset,		10,
2114 			XmNtopOffset,		10,
2115 			XmNrightAttachment,	XmATTACH_FORM,
2116 			XmNrightOffset,		10,
2117 		NULL);
2118 
2119 	w = XtVaCreateManagedWidget("printDestinationFrameTitle",
2120 			xmLabelGadgetClass,		frame,
2121 			XmNchildType,			XmFRAME_TITLE_CHILD,
2122 			XmNchildVerticalAlignment,	XmALIGNMENT_CENTER,
2123 		NULL);
2124 
2125 	radio = XtVaCreateManagedWidget("printDestinationRadio",
2126 				xmRowColumnWidgetClass, frame,
2127 			XmNradioBehavior,	True,
2128 			XmNradioAlwaysOne,	True,
2129 			XmNnumColumns,		3,
2130 			XmNorientation,		XmHORIZONTAL,
2131 		NULL);
2132 
2133 	PrintWidgets.PrinterToggle =
2134 	w = XtVaCreateManagedWidget("printer", xmToggleButtonGadgetClass,
2135 		radio, NULL);
2136 #ifdef	HAVE_STRCASECMP
2137 	if (strcasecmp(AppRes.defaultPrintTo, "printer") == 0 || defaultprint)
2138 #else
2139 	if (strcmp(AppRes.defaultPrintTo, "printer") == 0 || defaultprint)
2140 #endif
2141 		XmToggleButtonGadgetSetState(w, True, False);
2142 
2143 	PrintWidgets.printerTF =
2144 	w = XtVaCreateManagedWidget("printerTF", xmTextFieldWidgetClass,
2145 			radio, NULL);
2146 	XmTextFieldSetString(w, AppRes.printer);
2147 
2148 	/*
2149 	 * Build an option menu with a list of known printers.
2150 	 *
2151 	 * We can do this if we have CUPS (www.cups.org), otherwise
2152 	 * make the damned thing insensitive.
2153 	 */
2154 	cupsmenu = XmCreatePulldownMenu(radio, "cupsMenu", NULL, 0);
2155 	ac=0;
2156 	XtSetArg(al[ac], XmNsubMenuId, cupsmenu); ac++;
2157 	xms = XmStringCreateSimple(_("Select Printer"));
2158 	XtSetArg(al[ac], XmNlabelString, xms); ac++;
2159 	cupsOption = XmCreateOptionMenu(radio, "printerOption", al, ac);
2160 	XtManageChild(cupsOption);
2161 #ifndef	HAVE_LIBCUPS
2162 	XtSetSensitive(cupsOption, False);
2163 #endif
2164 	XmStringFree(xms);
2165 
2166 #ifdef	HAVE_LIBCUPS
2167 	printers = NULL;
2168 	nprinters = cupsGetPrinters(&printers);
2169 
2170 	for (i=0; i < nprinters; i++) {
2171 		Widget	b;
2172 		b = XtVaCreateManagedWidget(printers[i],
2173 			xmPushButtonGadgetClass, cupsmenu, NULL);
2174 		XtAddCallback(b, XmNactivateCallback, CupsSelectPrinter,
2175 			(XtPointer)PrintWidgets.printerTF);
2176 		if (i == 0)
2177 			XtVaSetValues(cupsOption, XmNmenuHistory, b, NULL);
2178 	}
2179 	if (nprinters == 0) {
2180 		w = XtVaCreateManagedWidget("No printers available from CUPS",
2181 			xmPushButtonGadgetClass, cupsmenu, NULL);
2182 		XtAddCallback(w, XmNactivateCallback, CupsSelectPrinter,
2183 			(XtPointer)PrintWidgets.printerTF);
2184 	}
2185 #endif
2186 
2187 	PrintWidgets.FileToggle =
2188 	w = XtVaCreateManagedWidget("file", xmToggleButtonGadgetClass,
2189 		radio, NULL);
2190 #ifdef	HAVE_STRCASECMP
2191 	if (strcasecmp(AppRes.defaultPrintTo, "file") == 0)
2192 #else
2193 	if (strcmp(AppRes.defaultPrintTo, "file") == 0)
2194 #endif
2195 		XmToggleButtonGadgetSetState(w, True, False);
2196 	PrintWidgets.fileTF =
2197 	w = XtVaCreateManagedWidget("fileTF", xmTextFieldWidgetClass,
2198 			radio, NULL);
2199 	w = XtVaCreateManagedWidget("fileTFBrowse", xmPushButtonGadgetClass,
2200 			radio, NULL);
2201 	XtAddCallback(w, XmNactivateCallback, PrintBrowseFileCB, NULL);
2202 
2203 	PrintWidgets.ProgramToggle =
2204 	w = XtVaCreateManagedWidget("program", xmToggleButtonGadgetClass,
2205 		radio, NULL);
2206 #ifdef	HAVE_STRCASECMP
2207 	if (strcasecmp(AppRes.defaultPrintTo, "program") == 0)
2208 #else
2209 	if (strcmp(AppRes.defaultPrintTo, "program") == 0)
2210 #endif
2211 		XmToggleButtonGadgetSetState(w, True, False);
2212 	PrintWidgets.programTF =
2213 	w = XtVaCreateManagedWidget("programTF", xmTextFieldWidgetClass,
2214 			radio, NULL);
2215 	XmTextFieldSetString(w, AppRes.program);
2216 
2217 	/* Paper */
2218 	w = frame;
2219 	frame = XtVaCreateManagedWidget("printPaperFrame",
2220 				xmFrameWidgetClass, form,
2221 			XmNtopAttachment,	XmATTACH_WIDGET,
2222 			XmNtopWidget,		w,
2223 			XmNtopOffset,		10,
2224 			XmNleftAttachment,	XmATTACH_FORM,
2225 			XmNleftOffset,		10,
2226 			XmNrightAttachment,	XmATTACH_FORM,
2227 			XmNrightOffset,		10,
2228 		NULL);
2229 
2230 	form2 = XtVaCreateManagedWidget("printPaperForm",
2231 				xmFormWidgetClass, frame,
2232 		NULL);
2233 
2234 	w = XtVaCreateManagedWidget("printPaperFrameTitle",
2235 			xmLabelGadgetClass,		form2,
2236 			XmNchildType,			XmFRAME_TITLE_CHILD,
2237 			XmNchildVerticalAlignment,	XmALIGNMENT_CENTER,
2238 		NULL);
2239 
2240 	menu = XmCreatePulldownMenu(form2, "optionMenu", NULL, 0);
2241 	ac = 0;
2242 	XtSetArg(al[ac], XmNsubMenuId, menu); ac++;
2243 	xms = XmStringCreateSimple(_("Paper Format"));
2244 	XtSetArg(al[ac], XmNlabelString, xms); ac++;
2245 	cb1 = cb = XmCreateOptionMenu(form2, "optionCB", al, ac);
2246 	XtManageChild(cb);
2247 	XmStringFree(xms);
2248 
2249 	npages = PrintGetNumPageSizes();
2250 
2251 	for (i=0; i<npages; i++) {
2252 		ac = 0;
2253 		xms = XmStringCreateSimple(PrintGetPageName(i));
2254 		XtSetArg(al[ac], XmNlabelString, xms); ac++;
2255 		w = XmCreatePushButtonGadget(menu, PrintGetPageName(i), al, ac);
2256 		if (strcmp(AppRes.paper, PrintGetPageName(i)) == 0)
2257 			XtVaSetValues(menu, XmNmenuHistory, w, NULL);
2258 		XtAddCallback(w, XmNactivateCallback,
2259 			MotifSetPrintPage, (XtPointer)i);
2260 		XmStringFree(xms);
2261 		XtManageChild(w);
2262 	}
2263 
2264 	/* Print format */
2265 	menu = XmCreatePulldownMenu(form2, "optionMenu", NULL, 0);
2266 	ac = 0;
2267 	XtSetArg(al[ac], XmNsubMenuId, menu); ac++;
2268 	xms = XmStringCreateSimple(_("Printer Language"));
2269 	XtSetArg(al[ac], XmNlabelString, xms); ac++;
2270 	XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
2271 	XtSetArg(al[ac], XmNleftWidget, cb1); ac++;
2272 	XtSetArg(al[ac], XmNleftOffset, 10); ac++;
2273 	cb = XmCreateOptionMenu(form2, "optionCB", al, ac);
2274 	XtManageChild(cb);
2275 	XmStringFree(xms);
2276 
2277 	npages = PrintGetNumPageSizes();
2278 
2279 	/* Option menu with printer types (PostScript, PCL, Text, .. ) */
2280 	for (i=0; PrintGetType(i); i++) {
2281 		ac = 0;
2282 		xms = XmStringCreateSimple(PrintGetType(i));
2283 		XtSetArg(al[ac], XmNlabelString, xms); ac++;
2284 		w = XmCreatePushButtonGadget(menu, PrintGetType(i), al, ac);
2285 		XtAddCallback(w, XmNactivateCallback,
2286 			MotifSetPrintType, (XtPointer)PrintGetType(i));
2287 		XmStringFree(xms);
2288 		XtManageChild(w);
2289 	}
2290 
2291 	/* Range to print */
2292 	w = frame;
2293 	frame = XtVaCreateManagedWidget("printRangeFrame",
2294 				xmFrameWidgetClass, form,
2295 			XmNtopAttachment,	XmATTACH_WIDGET,
2296 			XmNtopWidget,		w,
2297 			XmNtopOffset,		10,
2298 			XmNleftAttachment,	XmATTACH_FORM,
2299 			XmNleftOffset,		10,
2300 			XmNrightAttachment,	XmATTACH_FORM,
2301 			XmNrightOffset,		10,
2302 		NULL);
2303 
2304 	w = XtVaCreateManagedWidget("printRangeFrameTitle",
2305 			xmLabelGadgetClass,		frame,
2306 			XmNchildType,			XmFRAME_TITLE_CHILD,
2307 			XmNchildVerticalAlignment,	XmALIGNMENT_CENTER,
2308 		NULL);
2309 
2310 	PrintWidgets.rangeTF =
2311 	w = XtVaCreateManagedWidget("printRangeTF", xmTextFieldWidgetClass,
2312 		frame,
2313 		NULL);
2314 	RegisterRangeSelector(w);
2315 
2316 	return form;
2317 }
2318 
printCB(Widget w,XtPointer client,XtPointer call)2319 void printCB(Widget w, XtPointer client, XtPointer call)
2320 {
2321 	Widget	d, ok, cancel, help;
2322 	Arg	al[5];
2323 	int	ac;
2324 
2325 	MotifSelectGlobal(w);
2326 
2327 	if (PrintDialog == NULL) {
2328 		ac = 0;
2329 		XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
2330 		PrintDialog = XmCreateTemplateDialog(mw, "printDialog", al, ac);
2331 		d = MotifCreatePrintDialog(PrintDialog);
2332 		XtManageChild(d);
2333 
2334 		ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, PrintDialog,
2335 			NULL);
2336 		XtAddCallback(ok, XmNactivateCallback, ReallyPrintCB, NULL);
2337 
2338 		cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass, PrintDialog,
2339 			NULL);
2340 		XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, PrintDialog);
2341 
2342 		help = XtVaCreateManagedWidget("help",
2343 			xmPushButtonGadgetClass, PrintDialog, NULL);
2344 	}
2345 
2346 	XtManageChild(PrintDialog);
2347 }
2348 
SetDefaultFileCB(Widget w,XtPointer client,XtPointer call)2349 void SetDefaultFileCB(Widget w, XtPointer client, XtPointer call)
2350 {
2351 	char	*s, *xx;
2352 	Widget	tf, f;
2353 
2354 	MotifSelectGlobal(w);
2355 
2356 	f = XtParent(w);
2357 
2358 	/* Set default file format */
2359 
2360 	/* Set separator in List file format */
2361 	if ((tf = XtNameToWidget(f, "*listSeparatorTF")) != NULL) {
2362 		xx = XmTextFieldGetString(tf);
2363 		s = XtMalloc(strlen(xx) + 8);
2364 		strcpy(s, "list ");
2365 		strcat(s, xx);
2366 		list_set_options(1, s);
2367 		XtFree(s);
2368 	}
2369 
2370 	XtPopdown(DefaultFileShell);
2371 }
2372 
CancelTemplate(Widget w,XtPointer client,XtPointer call)2373 void CancelTemplate(Widget w, XtPointer client, XtPointer call)
2374 {
2375 	Widget	bb = (Widget)client;
2376 
2377 	MotifSelectGlobal(w);
2378 	XtUnmanageChild(bb);
2379 }
2380 
DestroyTemplate(Widget w,XtPointer client,XtPointer call)2381 void DestroyTemplate(Widget w, XtPointer client, XtPointer call)
2382 {
2383 	Widget	bb = (Widget)client;
2384 
2385 	MotifSelectGlobal(w);
2386 
2387 	XtDestroyWidget(bb);
2388 }
2389 
CancelDialog(Widget w,XtPointer client,XtPointer call)2390 void CancelDialog(Widget w, XtPointer client, XtPointer call)
2391 {
2392 	Widget	shell = (Widget)client;
2393 
2394 	MotifSelectGlobal(w);
2395 
2396 	XtPopdown(shell);
2397 }
2398 
DefaultFileFormatCB(Widget w,XtPointer client,XtPointer call)2399 void DefaultFileFormatCB(Widget w, XtPointer client, XtPointer call)
2400 {
2401 	char		*f = (char *)client;
2402 
2403 	MotifSelectGlobal(w);
2404 
2405 	file_set_default_format(f);
2406 }
2407 
DefaultFileDialogReset(void)2408 void DefaultFileDialogReset(void)
2409 {
2410 	Widget	tw, menu, b;
2411 	char	s[2], ffs[16], *ff;
2412 
2413 	MotifSelectGlobal(w);
2414 
2415 	s[0] = list_get_separator();
2416 	s[1] = '\0';
2417 
2418 	tw = XtNameToWidget(DefaultFileDialog, "*listSeparatorTF");
2419 	if (tw) XmTextFieldSetString(tw, s);
2420 
2421 	menu = XtNameToWidget(DefaultFileDialog, "*optionCB");
2422 	ff = file_get_default_format();
2423 	strcpy(ffs, "*");
2424 	if (ff)
2425 		strcat(ffs, ff);
2426 	else
2427 		strcat(ffs, "oleo");
2428 
2429 	b = XtNameToWidget(DefaultFileDialog, ffs);
2430 	XtVaSetValues(menu, XmNmenuHistory, b, NULL);
2431 }
2432 
CreateFileFormatOption(Widget parent,XtCallbackProc f)2433 Widget CreateFileFormatOption(Widget parent, XtCallbackProc f)
2434 {
2435 	Arg		al[10];
2436 	int		ac = 0, i;
2437 	XmString	xms;
2438 	Widget		cb, menu, b;
2439 	char		*ff;
2440 
2441 	menu = XmCreatePulldownMenu(parent, "optionMenu", NULL, 0);
2442 	ac = 0;
2443 	XtSetArg(al[ac], XmNsubMenuId, menu); ac++;
2444 	xms = XmStringCreateSimple(_("File Format"));
2445 	XtSetArg(al[ac], XmNlabelString, xms); ac++;
2446 	cb = XmCreateOptionMenu(parent, "optionCB", al, ac);
2447 	XtManageChild(cb);
2448 	XmStringFree(xms);
2449 
2450 	i=1;
2451 	while (1) {
2452 		ff = file_get_format(i);
2453 		if (ff == NULL)
2454 			break;
2455 
2456 		b = XtVaCreateManagedWidget(ff, xmPushButtonGadgetClass,
2457 			menu,
2458 			NULL);
2459 		XtAddCallback(b, XmNactivateCallback, f, ff);
2460 
2461 		i++;
2462 	}
2463 
2464 	return menu;
2465 }
2466 
MotifCreateDefaultFileDialog(Widget s)2467 Widget MotifCreateDefaultFileDialog(Widget s)
2468 {
2469 	Widget		form, menu, cb, w, ok, cancel, frame, radio, oldframe;
2470 	int		npages, i, ac;
2471 	Arg		al[5];
2472 	XmString	xms;
2473 
2474 	ac = 0;
2475 	form = XmCreateForm(s, "defaultFileForm", al, ac);
2476 
2477 	/* List File Separator Character */
2478 	frame = XtVaCreateManagedWidget("listSeparatorFrame",
2479 			xmFrameWidgetClass, form,
2480 			XmNleftAttachment,	XmATTACH_FORM,
2481 			XmNtopAttachment,	XmATTACH_FORM,
2482 			XmNleftOffset,		10,
2483 			XmNtopOffset,		10,
2484 			XmNrightAttachment,	XmATTACH_FORM,
2485 			XmNrightOffset,		10,
2486 		NULL);
2487 
2488 	w = XtVaCreateManagedWidget("listSeparatorFrameTitle",
2489 			xmLabelGadgetClass,		frame,
2490 			XmNchildType,			XmFRAME_TITLE_CHILD,
2491 			XmNchildVerticalAlignment,	XmALIGNMENT_CENTER,
2492 		NULL);
2493 
2494 	w = XtVaCreateManagedWidget("listSeparatorTF", xmTextFieldWidgetClass,
2495 			frame,
2496 			XmNmaxLength,		1,
2497 		NULL);
2498 
2499 	/* Default File Format */
2500 	oldframe = frame;
2501 	frame = XtVaCreateManagedWidget("defaultFormatFrame",
2502 			xmFrameWidgetClass, form,
2503 			XmNleftAttachment,	XmATTACH_FORM,
2504 			XmNtopAttachment,	XmATTACH_WIDGET,
2505 			XmNtopWidget,		oldframe,
2506 			XmNleftOffset,		10,
2507 			XmNtopOffset,		10,
2508 			XmNrightAttachment,	XmATTACH_FORM,
2509 			XmNrightOffset,		10,
2510 		NULL);
2511 
2512 	w = XtVaCreateManagedWidget("defaultFormatFrameTitle",
2513 			xmLabelGadgetClass,		frame,
2514 			XmNchildType,			XmFRAME_TITLE_CHILD,
2515 			XmNchildVerticalAlignment,	XmALIGNMENT_CENTER,
2516 		NULL);
2517 
2518 	menu = CreateFileFormatOption(frame, DefaultFileFormatCB);
2519 
2520 	/* FIX ME : buttons */
2521 	ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, form,
2522 			XmNtopAttachment,	XmATTACH_WIDGET,
2523 			XmNtopOffset,		10,
2524 			XmNtopWidget,		frame,
2525 			XmNleftAttachment,	XmATTACH_FORM,
2526 			XmNleftOffset,		10,
2527 			XmNrightAttachment,	XmATTACH_NONE,
2528 			XmNbottomAttachment,	XmATTACH_FORM,
2529 			XmNbottomOffset,	10,
2530 		NULL);
2531 	XtAddCallback(ok, XmNactivateCallback, SetDefaultFileCB, NULL);
2532 
2533 	cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass,
2534 		form,
2535 			XmNtopAttachment,	XmATTACH_WIDGET,
2536 			XmNtopOffset,		10,
2537 			XmNtopWidget,		frame,
2538 			XmNleftAttachment,	XmATTACH_WIDGET,
2539 			XmNleftWidget,		ok,
2540 			XmNleftOffset,		10,
2541 			XmNrightAttachment,	XmATTACH_NONE,
2542 			XmNbottomAttachment,	XmATTACH_FORM,
2543 			XmNbottomOffset,	10,
2544 		NULL);
2545 	XtAddCallback(cancel, XmNactivateCallback, CancelDialog, DefaultFileShell);
2546 
2547 	return form;
2548 }
2549 
DefaultFileCB(Widget w,XtPointer client,XtPointer call)2550 void DefaultFileCB(Widget w, XtPointer client, XtPointer call)
2551 {
2552 	MotifSelectGlobal(w);
2553 
2554 	if (DefaultFileShell == NULL) {
2555 		DefaultFileShell = XtVaCreatePopupShell("defaultFileShell",
2556 				topLevelShellWidgetClass,
2557 				toplevel,
2558 			NULL);
2559 		DefaultFileDialog = MotifCreateDefaultFileDialog(DefaultFileShell);
2560 	}
2561 
2562 	DefaultFileDialogReset();
2563 
2564 	XtManageChild(DefaultFileDialog);
2565 	XtPopup(DefaultFileShell, XtGrabNone);
2566 }
2567 
2568 /****************************************************************
2569  *								*
2570  *		GUI stuff					*
2571  *								*
2572  ****************************************************************/
2573 /*
2574  * XbaeMatrix calls this whenever we leave a cell.
2575  * The cell may have been edited, we can veto the edit by setting the
2576  *	doit flag to false.
2577  */
LeaveCell(Widget w,XtPointer client,XtPointer call)2578 void LeaveCell(Widget w, XtPointer client, XtPointer call)
2579 {
2580 	char	*r;
2581 	CELL	*cp;
2582 	XbaeMatrixLeaveCellCallbackStruct *cbp =
2583 		(XbaeMatrixLeaveCellCallbackStruct *)call;
2584 
2585 	MotifSelectGlobal(w);
2586 
2587 	cbp->doit = True;
2588 
2589 	/*
2590 	 * Check whether this cell has a formula.
2591 	 * Don't change the value if it does.
2592 	 */
2593 	if ((cp = find_cell (curow, cucol)) && cp->cell_formula) {
2594 		Debug(__FILE__, "LeaveCell(%d,%d) has a formula !!\n",
2595 			cbp->row, cbp->column, cbp->value);
2596 
2597 		return;
2598 	}
2599 
2600 	Debug(__FILE__, "LeaveCell(%d,%d,%s)\n",
2601 		cbp->row, cbp->column, cbp->value);
2602 
2603 	/*
2604 	 * Have oleo put the new cell content in place.
2605 	 *
2606 	 * This supposedly returns NULL when all is well, otherwise
2607 	 * an error message.
2608 	 */
2609 	r = new_value(cbp->row + 1, cbp->column + 1, cbp->value);
2610 	if (r) {
2611 		MessageAppend(True, r);
2612 		cbp->doit = False;	/* veto */
2613 	} else {
2614 		Global->modified = 1;
2615 
2616 		recalculate(1);
2617 
2618 		if (! cp)
2619 		    cp = find_cell (curow, cucol);
2620 		if (cp && cp->cell_formula) {
2621 			UpdateStatus();
2622 #if 0
2623 			XbaeMatrixRefreshCell(mat, curow - 1, cucol - 1);
2624 #endif
2625 			/*
2626 			 * This veto prevents Xbae from displaying the formula
2627 			 * again. By preventing this, it'll display what we
2628 			 * just put in there: the result of formula evaluation.
2629 			 *
2630 			 * Oh boy.
2631 			 */
2632 			cbp->doit = False;	/* veto */
2633 		}
2634 		MotifUpdateDisplay();
2635 	}
2636 }
2637 
2638 /*
2639  * Yuck. Apparently oleo doesn't have an API to change cells.
2640  * I seem to have to call goto_region, *and* set curow/cucol.
2641  */
EnterCell(Widget w,XtPointer client,XtPointer call)2642 void EnterCell(Widget w, XtPointer client, XtPointer call)
2643 {
2644 	struct	rng	r;
2645 	CELL		*cp;
2646 	XbaeMatrixEnterCellCallbackStruct *cbp =
2647 		(XbaeMatrixEnterCellCallbackStruct *)call;
2648 	char		*dec;
2649 
2650 	MotifSelectGlobal(w);
2651 
2652 	Debug(__FILE__, "EnterCell (%d, %d)\n", cbp->row, cbp->column);
2653 
2654 	/* Tell oleo to move */
2655 	curow = cbp->row + 1;
2656 	cucol = cbp->column + 1;
2657 
2658 	r.lr = r.hr = cbp->row + 1;
2659 	r.hc = r.lc = cbp->column + 1;
2660 	goto_region(&r);
2661 
2662 	/* Change Formula editor */
2663 #if 1
2664 	if (cp = find_cell (curow, cucol)) {
2665 		dec = decomp (curow, cucol, cp);
2666 		XmTextFieldSetString(formulatf, dec);
2667 	} else {
2668 		XmTextFieldSetString(formulatf, "");
2669 	}
2670 #else
2671 	if ((cp = find_cell (curow, cucol)) && cp->cell_formula) {
2672 		dec = decomp (curow, cucol, cp);
2673 		XmTextFieldSetString(formulatf, dec);
2674 	} else {
2675 		XmTextFieldSetString(formulatf, "");
2676 	}
2677 #endif
2678 }
2679 
ModifyVerify(Widget w,XtPointer client,XtPointer call)2680 void ModifyVerify(Widget w, XtPointer client, XtPointer call)
2681 {
2682 	XbaeMatrixModifyVerifyCallbackStruct *cbp =
2683 		(XbaeMatrixModifyVerifyCallbackStruct *)call;
2684 
2685 	MotifSelectGlobal(w);
2686 
2687 	Debug(__FILE__, "ModifyVerify(%d,%d) '%s'\n",
2688 		cbp->row, cbp->column,
2689 		cbp->prev_text);
2690 }
2691 
WriteCell(Widget w,XtPointer client,XtPointer call)2692 void WriteCell(Widget w, XtPointer client, XtPointer call)
2693 {
2694 	XbaeMatrixWriteCellCallbackStruct *cbp =
2695 		(XbaeMatrixWriteCellCallbackStruct *)call;
2696 
2697 	MotifSelectGlobal(w);
2698 
2699 	Debug(__FILE__, "WriteCell(%d, %d, %s)\n",
2700 		cbp->row, cbp->column, cbp->string);
2701 }
2702 
DrawCell(Widget w,XtPointer client,XtPointer call)2703 void DrawCell(Widget w, XtPointer client, XtPointer call)
2704 {
2705 	/* This needs to be called otherwise WriteCell won't work. */
2706 	XbaeMatrixDrawCellCallbackStruct *cbp =
2707 		(XbaeMatrixDrawCellCallbackStruct *)call;
2708 
2709 	MotifSelectGlobal(w);
2710 
2711 	cbp->type = XbaeString;
2712 #if 1
2713 	cbp->string = cell_value_string(cbp->row + 1, cbp->column + 1,
2714 		True);
2715 #else
2716 	if (curow == cbp->row + 1 && cucol == cbp->column + 1) {
2717 		cbp->string = cell_value_string(cbp->row + 1, cbp->column + 1,
2718 			True);
2719 	} else {
2720 		cbp->string = print_cell(find_cell(cbp->row + 1,
2721 			cbp->column + 1));
2722 	}
2723 #endif
2724 
2725 #if 0
2726 	if (cbp->string && strlen(cbp->string))
2727 		fprintf(stderr, "OleoDrawCell(%d,%d) -> [%s]\n",
2728 			cbp->row, cbp->column, cbp->string);
2729 #endif
2730 
2731 #ifdef	VERBOSE
2732 	Debug(__FILE__, "DrawCell(%d, %d, %s)\n",
2733 		cbp->row, cbp->column, cbp->string);
2734 #endif
2735 }
2736 
FormulaCB(Widget w,XtPointer client,XtPointer call)2737 void FormulaCB(Widget w, XtPointer client, XtPointer call)
2738 {
2739 	char	*s, *r;
2740 
2741 	MotifSelectGlobal(w);
2742 
2743 	s = XmTextFieldGetString(w);
2744 	Debug(__FILE__, "FormulaCB(%s) -> %d,%d\n", s, curow, cucol);
2745 
2746 	r = new_value(curow, cucol, s);
2747 	if (r) {
2748 		MessageAppend(True, r);
2749 	} else
2750 		Global->modified = 1;
2751 
2752 #ifdef	FREE_TF_STRING
2753 	XtFree(s);
2754 #endif
2755 
2756 	recalculate(1);		/* 1 is recalculate all */
2757 	MotifUpdateDisplay();	/* refresh */
2758 }
2759 
2760 #ifdef	XmNresizeRowCallback
ResizeRowCB(Widget w,XtPointer client,XtPointer call)2761 void ResizeRowCB(Widget w, XtPointer client, XtPointer call)
2762 {
2763 	XbaeMatrixResizeRowCallbackStruct *cbp =
2764 		(XbaeMatrixResizeRowCallbackStruct *)call;
2765 
2766 	fprintf(stderr, "Resize row %d to height %d\n",
2767 		cbp->which,
2768 		cbp->row_heights[cbp->which]);
2769 }
2770 #endif
2771 
ResizeColumnCB(Widget w,XtPointer client,XtPointer call)2772 void ResizeColumnCB(Widget w, XtPointer client, XtPointer call)
2773 {
2774 	XbaeMatrixResizeColumnCallbackStruct *cbp =
2775 		(XbaeMatrixResizeColumnCallbackStruct *)call;
2776 	struct rng	rng;
2777 	char		wid[20];
2778 
2779 	MotifSelectGlobal(w);
2780 
2781 	/* Set a range which is a column */
2782 	rng.lr = 0;
2783 	rng.hr = -1;
2784 	rng.lc = rng.hc = cbp->which + 1;
2785 #if 0
2786 	fprintf(stderr, "Resize column %d to %d, using range %s\n",
2787 		cbp->which,
2788 		cbp->column_widths[cbp->which],
2789 		range_name(&rng));
2790 #endif
2791 	sprintf(wid, "%d", cbp->column_widths[cbp->which]);
2792 	set_region_width(&rng, wid);
2793 }
2794 
2795 /****************************************************************
2796  *								*
2797  *		File interaction				*
2798  *								*
2799  ****************************************************************/
2800 
MotifSetWindowName(const char * s)2801 void MotifSetWindowName(const char *s)
2802 {
2803 	char	*t;
2804 
2805 	t = XtMalloc(strlen(s) + 32);	/* enough */
2806 	sprintf(t, _("[Oleo: %s]"), s);
2807 	XtVaSetValues(toplevel, XmNtitle, t, NULL);
2808 	XtVaSetValues(toplevel, XmNiconName, t, NULL);
2809 
2810 	XtFree(t);
2811 }
2812 
FileFormatCB(Widget w,XtPointer client,XtPointer call)2813 void FileFormatCB(Widget w, XtPointer client, XtPointer call)
2814 {
2815 	char		*f = (char *)client, *p;
2816 	XmString	xms;
2817 
2818 	MotifSelectGlobal(w);
2819 
2820 	p = file_get_pattern(f);
2821 	if (p == NULL)
2822 		p = f;
2823 
2824 	strcpy(Global->MotifGlobal->fileformat, f);
2825 
2826 	strcpy(Global->MotifGlobal->pattern, "*.");
2827 	strcat(Global->MotifGlobal->pattern, p);
2828 
2829 	xms = XmStringCreateSimple(Global->MotifGlobal->pattern);
2830 	XtVaSetValues(fsd, XmNpattern, xms, NULL);
2831 	XmStringFree(xms);
2832 }
2833 
ReallyLoadCB(Widget w,XtPointer client,XtPointer call)2834 void ReallyLoadCB(Widget w, XtPointer client, XtPointer call)
2835 {
2836 	XmFileSelectionBoxCallbackStruct *cbp =
2837 		(XmFileSelectionBoxCallbackStruct *)call;
2838 	FILE	*fp;
2839 	char	*s;
2840 
2841 	MotifSelectGlobal(w);
2842 
2843 	if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &s)) {
2844 		/* handle error */
2845 		return;
2846 	}
2847 
2848 	if (Global->modified) {
2849 		/* Handle unsaved changes */
2850 	}
2851 
2852 	/* From here it's irreversible */
2853 
2854 	ResetColumnWidths();
2855 	XbaeMatrixCancelEdit(mat, True);
2856 
2857 	fp = fopen(s, "r");
2858 	if (fp == NULL) {
2859 		/* handle error */
2860 		XtFree(s);
2861 		return;
2862 	}
2863 
2864 	FileSetCurrentFileName(s);
2865 
2866 	read_file_generic(fp, 0, Global->MotifGlobal->fileformat, s);
2867 
2868 	if (fclose(fp) != 0) {
2869 		/* handle error */
2870 		XtFree(s);
2871 		return;
2872 	}
2873 	FixA0();
2874 
2875 	/* Force calculate */
2876 	recalculate(1);		/* 1 is all */
2877 
2878 	/* Force redisplay */
2879 	MotifUpdateDisplay();
2880 
2881 	/* Set the widget as well as the spreadsheet to a default state. */
2882 	Global->modified = 0;
2883 	curow = cucol = 1;
2884 	XbaeMatrixEditCell(mat, 0, 0);
2885 
2886 	MotifSetWindowName(s);
2887 	MessageAppend(False, _("Read file '%s'\n"), s);
2888 
2889 	XtFree(s);
2890 }
2891 
DefaultFileResetCB(Widget w,XtPointer client,XtPointer call)2892 void DefaultFileResetCB(Widget w, XtPointer client, XtPointer call)
2893 {
2894 	Widget		menu, x;
2895 	char		format[32], *f, *p;
2896 	XmString	xms;
2897 
2898 	MotifSelectGlobal(w);
2899 
2900 	f = file_get_default_format();
2901 
2902 	strcpy(format, "*.");
2903 	strcat(format, f ? f : "oleo");
2904 
2905 	x = XtNameToWidget(fsd, format);
2906 	menu = XtNameToWidget(fsd, "*optionCB");
2907 	XtVaSetValues(menu, XmNmenuHistory, x, NULL);
2908 
2909 	p = file_get_pattern(f ? f : "oleo");
2910 	strcpy(format, "*.");
2911 	strcat(format, p);
2912 
2913 	xms = XmStringCreateSimple(format);
2914 	XtVaSetValues(fsd, XmNpattern, xms, NULL);
2915 	XmStringFree(xms);
2916 }
2917 
CreateFSD()2918 void CreateFSD()
2919 {
2920 	Arg		al[10];
2921 	int		ac = 0;
2922 	XmString	xms;
2923 	Widget		cb, menu, b;
2924 
2925 	ac = 0;
2926 	XtSetArg(al[ac], XmNautoUnmanage, True); ac++;
2927 	xms = XmStringCreateSimple(_("*.oleo"));
2928 	XtSetArg(al[ac], XmNpattern, xms); ac++;
2929 
2930 	fsd = XmCreateFileSelectionDialog(toplevel, "selectfile",
2931 		al, ac);
2932 	XtDestroyWidget(
2933 		XmFileSelectionBoxGetChild(fsd, XmDIALOG_HELP_BUTTON));
2934 	XmStringFree(xms);
2935 
2936 	/* Option menu */
2937 	menu = CreateFileFormatOption(fsd, FileFormatCB);
2938 
2939 	XtAddCallback(XtParent(fsd), XmNpopupCallback, DefaultFileResetCB, (XtPointer)menu);
2940 }
2941 
PopupLoad(void)2942 void PopupLoad(void)
2943 {
2944 	Arg	al[10];
2945 	int	ac = 0;
2946 
2947 	if (fsd == NULL)
2948 		CreateFSD();
2949 
2950 	XtRemoveAllCallbacks(fsd, XmNokCallback);
2951 	XtAddCallback(fsd, XmNokCallback, ReallyLoadCB, NULL);
2952 
2953 	ac = 0;
2954 	XtSetArg(al[ac], XmNtitle, _("Choose a file to load")); ac++;
2955 	XtSetValues(fsd, al, ac);
2956 	XtManageChild(fsd);
2957 }
2958 
LoadCB(Widget w,XtPointer client,XtPointer call)2959 void LoadCB(Widget w, XtPointer client, XtPointer call)
2960 {
2961 	MotifSelectGlobal(w);
2962 
2963 	PopupLoad();
2964 }
2965 
NewCB(Widget w,XtPointer client,XtPointer call)2966 void NewCB(Widget w, XtPointer client, XtPointer call)
2967 {
2968 	MotifSelectGlobal(w);
2969 
2970 	/* FIX ME Open a new window */
2971 	none(w, client, call);
2972 }
2973 
DestroyToplevel(Widget w,XtPointer client,XtPointer call)2974 void DestroyToplevel(Widget w, XtPointer client, XtPointer call)
2975 {
2976 #if 0
2977 	fprintf(stderr, "In DestroyToplevel()\n");
2978 #endif
2979 
2980 	/*
2981 	 * Calling this solves all the issues...
2982 	 */
2983 	QuitCB(w, client, call);
2984 }
2985 
2986 /*
2987  * MDI : Experimental code to open a second window.
2988  */
2989 
OpenNewCB(Widget w,XtPointer client,XtPointer call)2990 void OpenNewCB(Widget w, XtPointer client, XtPointer call)
2991 {
2992 	Widget	m;
2993 	Display	*d = XtDisplayOfObject(w);
2994 	XtAppContext appc = Global->MotifGlobal->app_c;
2995 
2996 	MdiOpen();
2997 	/* Now we've got another Global pointer */
2998 	Global->MotifGlobal->app_c = appc;
2999 
3000 	toplevel = XtVaAppCreateShell(PACKAGE, PACKAGE,
3001 		topLevelShellWidgetClass, d, NULL);
3002 	RegisterWMClose(toplevel);
3003 	XtVaSetValues(toplevel, XmNdeleteResponse, XmDO_NOTHING, NULL);
3004 
3005 	/* FIX ME do we need to do this again ?? */
3006 	XtVaGetApplicationResources(toplevel, &AppRes,
3007 		resources, num_resources,
3008 		NULL);
3009 
3010 	/* Without this we have NULL in cwin. */
3011 	io_init_windows(AppRes.rows, AppRes.columns, 1, 2, 1, 1, 1, 1);
3012 
3013 	m = GscBuildMainWindow(toplevel);
3014 	XtManageChild(m);
3015 	XtRealizeWidget(toplevel);
3016 
3017 	PopupLoad();
3018 }
3019 
OpenCB(Widget w,XtPointer client,XtPointer call)3020 void OpenCB(Widget w, XtPointer client, XtPointer call)
3021 {
3022 	MotifSelectGlobal(w);
3023 
3024 	/*
3025 	 * FIX ME
3026 	 *
3027 	 * Figure out when to open a new window :
3028 	 *	- when this window has been modified
3029 	 *	- when this window has an open file
3030 	 */
3031 	if (Global->modified || MdiHasFile())
3032 		OpenNewCB(w, client, call);
3033 	else
3034 		LoadCB(w, client, call);
3035 }
3036 
ReallyCloseCB(Widget w,XtPointer client,XtPointer call)3037 void ReallyCloseCB(Widget w, XtPointer client, XtPointer call)
3038 {
3039 	MotifSelectGlobal(w);
3040 	/*
3041 	 * Destroying the widget tree should take care of calling
3042 	 *	MdiClose(), and therefore also of closing the Global
3043 	 *	structure.
3044 	 * When MdiClose notices this is the last window, it'll also
3045 	 *	exit the application.
3046 	 */
3047 	XtDestroyWidget(toplevel);
3048 }
3049 
CloseCB(Widget w,XtPointer client,XtPointer call)3050 void CloseCB(Widget w, XtPointer client, XtPointer call)
3051 {
3052 	Arg	al[3];
3053 	int	ac;
3054 	Widget	md;
3055 
3056 	MotifSelectGlobal(w);
3057 
3058 	if (Global->modified && !option_filter) {
3059 		XmString xms = XmStringCreateLtoR(
3060 			_("There are unsaved changes.\n"
3061 			  "Do you want to quit anyway ?"),
3062 			XmFONTLIST_DEFAULT_TAG);
3063 
3064 		ac = 0;
3065 		/* Application resource for message allow i18n */
3066 		XtSetArg(al[ac], XmNmessageString, xms); ac++;
3067 
3068 		md = XmCreateQuestionDialog(toplevel, "quitMB", al, ac);
3069 		XtAddCallback(md, XmNokCallback, ReallyCloseCB, NULL);
3070 		XtDestroyWidget(XmMessageBoxGetChild(md,
3071 			XmDIALOG_HELP_BUTTON));
3072 		XtManageChild(md);
3073 		XmStringFree(xms);
3074 		return;
3075 	}
3076 
3077 	/* No dialog - just close */
3078 	XtDestroyWidget(toplevel);
3079 }
3080 
OleoOpenForWrite(const char * s)3081 FILE *OleoOpenForWrite(const char *s)
3082 {
3083 	FILE	*fp;
3084 	int	len;
3085 	char	*fn;
3086 
3087 	if (access(s, R_OK) == 0) {
3088 		/* Maybe replace it ? */
3089 		len = strlen(s) + 2 + strlen(".old");
3090 		fn = malloc(len);
3091 		strcpy(fn, s);
3092 		strcat(fn, ".old");
3093 		unlink(fn);
3094 		if (rename(s, fn) < 0) {
3095 			MessageAppend(True,
3096 				_("OleoOpenForWrite: can't move %s to %s"),
3097 				s, fn);
3098 			free(fn);
3099 			return NULL;
3100 		}
3101 		free(fn);
3102 	}
3103 
3104 	fp = fopen(s, "w");
3105 	if (fp == NULL) {
3106 		/* handle error */
3107 		MessageAppend(True,
3108 			_("OleoOpenForWrite: couldn't open file '%s' for write"),
3109 			s);
3110 		return NULL;
3111 	}
3112 
3113 	return fp;
3114 }
3115 
ReallySave(const char * s)3116 void ReallySave(const char *s)
3117 {
3118 	FILE	*fp;
3119 
3120 	fp = OleoOpenForWrite(s);
3121 	if (fp == NULL) {
3122 		/* handle error */
3123 		MessageAppend(True,
3124 			_("ReallySaveCB(%s): couldn't open file for writing"),
3125 			s);
3126 		return;
3127 	}
3128 
3129 	write_file_generic(fp, 0, Global->MotifGlobal->fileformat);
3130 
3131 	if (fclose(fp) != 0) {
3132 		/* handle error */
3133 		MessageAppend(True, _("ReallySaveCB: file close failed"));
3134 		return;
3135 	}
3136 
3137 	Global->modified = 0;
3138 	MessageAppend(False, _("Saved file '%s'\n"), s);
3139 	MotifSetWindowName(s);
3140 }
3141 
ReallySaveCB(Widget w,XtPointer client,XtPointer call)3142 void ReallySaveCB(Widget w, XtPointer client, XtPointer call)
3143 {
3144 	XmFileSelectionBoxCallbackStruct *cbp =
3145 		(XmFileSelectionBoxCallbackStruct *)call;
3146 	char	*s, *t;
3147 
3148 	MotifSelectGlobal(w);
3149 
3150 	if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &s)) {
3151 		/* handle error */
3152 		MessageAppend(True,
3153 		    _("ReallySaveCB: couldn't figure out file to save into"));
3154 		return;
3155 	}
3156 
3157 	ReallySave(s);
3158 	XtFree(s);
3159 }
3160 
3161 /*
3162  * Called from the menu system.
3163  * Always pop up a FileSB.
3164  */
SaveAsCB(Widget w,XtPointer client,XtPointer call)3165 void SaveAsCB(Widget w, XtPointer client, XtPointer call)
3166 {
3167 	Arg	al[10];
3168 	int	ac = 0;
3169 
3170 	MotifSelectGlobal(w);
3171 
3172 	if (fsd == NULL)
3173 		CreateFSD();
3174 
3175 	XtRemoveAllCallbacks(fsd, XmNokCallback);
3176 	XtAddCallback(fsd, XmNokCallback, ReallySaveCB, NULL);
3177 
3178 	ac = 0;
3179 	XtSetArg(al[ac], XmNtitle, _("Choose a file to save in")); ac++;
3180 	XtSetValues(fsd, al, ac);
3181 	XtManageChild(fsd);
3182 }
3183 
3184 /*
3185  * Called from the menu system.
3186  * If we don't have a current file, call SaveAs.
3187  */
SaveCB(Widget w,XtPointer client,XtPointer call)3188 void SaveCB(Widget w, XtPointer client, XtPointer call)
3189 {
3190 	char	*s;
3191 
3192 	MotifSelectGlobal(w);
3193 
3194 	if (s = FileGetCurrentFileName()) {
3195 		ReallySave(s);
3196 		return;
3197 	}
3198 
3199 	SaveAsCB(w, client, call);
3200 }
3201 
3202 /****************************************************************
3203  *								*
3204  *		Build Help Widgets				*
3205  *								*
3206  ****************************************************************/
3207 #ifdef	HAVE_XmHTML_H
3208 static void
anchorCB(Widget widget,XtPointer client,XtPointer call)3209 anchorCB(Widget widget, XtPointer client, XtPointer call)
3210 {
3211         XmHTMLAnchorCallbackStruct *cbs = (XmHTMLAnchorCallbackStruct *) call;
3212 	char	*anchor;
3213 
3214 	MotifSelectGlobal(w);
3215 #if 0
3216 	fprintf(stderr, "AnchorCB(%s)\n", cbs->href);
3217 #endif
3218         cbs->doit = True;
3219         cbs->visited = True;
3220 
3221 	anchor = strchr(cbs->href, '#');
3222 
3223 	XmHTMLAnchorScrollToName(Html, anchor);
3224 }
3225 
3226 static void
HelpBuildWindow(void)3227 HelpBuildWindow(void)
3228 {
3229 	Widget	f, sep, ok;
3230 
3231 	if (! Html) {
3232 		hd = XtVaCreatePopupShell("helpShell",
3233 				topLevelShellWidgetClass,
3234 				toplevel,
3235 				XmNdeleteResponse, XmUNMAP,
3236 			NULL);
3237 
3238 		f = XtVaCreateManagedWidget("form", xmFormWidgetClass, hd,
3239 			NULL);
3240 
3241 		ok = XtVaCreateManagedWidget("ok",
3242 			xmPushButtonGadgetClass, f,
3243 				XmNtopAttachment,	XmATTACH_NONE,
3244 				XmNtopOffset,		10,
3245 				XmNtopWidget,		sep,
3246 				XmNleftAttachment,	XmATTACH_FORM,
3247 				XmNrightAttachment,	XmATTACH_FORM,
3248 				XmNleftOffset,		10,
3249 				XmNrightOffset,		10,
3250 				XmNbottomAttachment,	XmATTACH_FORM,
3251 				XmNbottomOffset,	10,
3252 			NULL);
3253 		XtAddCallback(ok, XmNactivateCallback, PopDownHelpCB, hd);
3254 
3255 		sep = XtVaCreateManagedWidget("separator",
3256 			xmSeparatorGadgetClass, f,
3257 				XmNorientation,		XmHORIZONTAL,
3258 				XmNleftAttachment,	XmATTACH_FORM,
3259 				XmNrightAttachment,	XmATTACH_FORM,
3260 				XmNleftOffset,		10,
3261 				XmNrightOffset,		10,
3262 				XmNbottomAttachment,	XmATTACH_WIDGET,
3263 				XmNbottomOffset,	10,
3264 				XmNbottomWidget,	ok,
3265 			NULL);
3266 
3267 		Html = XtVaCreateManagedWidget("html",
3268 			xmHTMLWidgetClass, f,
3269 				XmNmarginWidth,			20,
3270 				XmNmarginHeight,		20,
3271 				XmNwidth,			600,
3272 				XmNheight,			500,
3273 				XmNenableBadHTMLWarnings,	XmHTML_NONE,
3274 				XmNscrollBarDisplayPolicy,	XmSTATIC,
3275 				XmNtopAttachment,		XmATTACH_FORM,
3276 				XmNleftAttachment,		XmATTACH_FORM,
3277 				XmNrightAttachment,		XmATTACH_FORM,
3278 				XmNleftOffset,			10,
3279 				XmNrightOffset,			10,
3280 				XmNtopOffset,			10,
3281 				XmNbottomAttachment,		XmATTACH_WIDGET,
3282 				XmNbottomOffset,		10,
3283 				XmNbottomWidget,		sep,
3284 			NULL);
3285 
3286 		XtAddCallback(Html, XmNactivateCallback,
3287 			(XtCallbackProc)anchorCB, NULL);
3288 	}
3289 }
3290 #endif
3291 
3292 /*
3293  * Load a file into the help window.
3294  * This probably needs to look at the language.
3295  */
3296 #define	HELP_FILE_LENGTH	200000
3297 
3298 #ifndef	HTMLDIR
3299 #define	HTMLDIR			"/usr/local/share/oleo"
3300 #endif
3301 
3302 static void
HelpLoadFile(char * fn,char * anchor)3303 HelpLoadFile(char *fn, char *anchor)
3304 {
3305 #ifdef	HAVE_XmHTML_H
3306 	char	*buffer = XtMalloc(HELP_FILE_LENGTH);
3307 	FILE	*fp = fopen("oleo.html", "r");
3308 	char	*n;
3309 
3310 	if (fn == NULL) {
3311 		XmHTMLTextSetString(Html,
3312 			_("<html><body>"
3313 			  "Can't find the requested help file\n"
3314 			  "</body></html>"));
3315 		return;
3316 	}
3317 
3318 	n = XtMalloc(256);
3319 	fp = fopen(fn, "r");
3320 	if (fp == NULL) {
3321 		sprintf(n, "%s/%s/%s",
3322                         HTMLDIR,
3323                         getenv("LANGUAGE") != NULL ? getenv("LANGUAGE") : "",
3324                         fn);
3325 		fp = fopen(n, "r");
3326 	}
3327 
3328 	if (fp == NULL) {
3329 		sprintf(n, "%s/%s/%s",
3330                         HTMLDIR,
3331                         getenv("LANG") != NULL ? getenv("LANG") : "",
3332                         fn);
3333 		fp = fopen(n, "r");
3334 	}
3335 
3336 	if (fp == NULL) {
3337 		sprintf(n, "%s/%s", HTMLDIR, fn);
3338 		fp = fopen(n, "r");
3339 	}
3340 
3341 	if (fp) {
3342 		fread(buffer, 1, HELP_FILE_LENGTH, fp);
3343 		fclose(fp);
3344 		XmHTMLTextSetString(Html, buffer);
3345 	} else {
3346 		XmHTMLTextSetString(Html,
3347 			_("<html><body>"
3348 			  "Can't find the requested help file\n"
3349 			  "</body></html>"));
3350                 return;
3351 	}
3352 	XtFree(buffer);
3353 
3354 	if (anchor)
3355 		MessageAppend(False, _("Help requested on '%s'"), anchor);
3356 	else
3357 		MessageAppend(False, _("Help requested on using Oleo"));
3358 
3359 	if (anchor)
3360 		XmHTMLAnchorScrollToName(Html, anchor);
3361 	XtFree(n);
3362 #endif
3363 }
3364 
helpUsingCB(Widget w,XtPointer client,XtPointer call)3365 void helpUsingCB(Widget w, XtPointer client, XtPointer call)
3366 {
3367 #ifdef	HAVE_XmHTML_H
3368 	MotifSelectGlobal(w);
3369 
3370 	HelpBuildWindow();
3371 	HelpLoadFile("oleo.html", client);
3372 	XtPopup(hd, XtGrabNone);
3373 	XtManageChild(XtParent(Html));		/* LessTif only, harmless otherwise */
3374 #endif
3375 }
3376 
helpAboutCB(Widget w,XtPointer client,XtPointer call)3377 void helpAboutCB(Widget w, XtPointer client, XtPointer call)
3378 {
3379 	MotifSelectGlobal(w);
3380 
3381 	/* FIX ME */	versionCB(w, client, call);
3382 }
3383 
helpVersionCB(Widget w,XtPointer client,XtPointer call)3384 void helpVersionCB(Widget w, XtPointer client, XtPointer call)
3385 {
3386 	MotifSelectGlobal(w);
3387 
3388 	/* FIX ME */	versionCB(w, client, call);
3389 }
3390 
3391 void
MotifUpdateWidth(int col,int wid)3392 MotifUpdateWidth(int col, int wid)
3393 {
3394 	if (Global->MotifGlobal == 0)
3395 		return;
3396 
3397 	if (! columnwidths)
3398 		ResetColumnWidths();
3399 	columnwidths[col - 1] = wid;
3400 
3401 	if (mat)
3402 		XtVaSetValues(mat,
3403 				XmNcolumnWidths,	columnwidths,
3404 			NULL);
3405 }
3406 
3407 void
ResetColumnWidths(void)3408 ResetColumnWidths(void)
3409 {
3410 	int	i;
3411 
3412 	if (Global->MotifGlobal == 0)
3413 		return;
3414 
3415 	columnwidths = (short *)XtCalloc(AppRes.columns, sizeof(short));
3416 	for (i=0; i<AppRes.columns; i++)
3417 		columnwidths[i] = AppRes.columnWidth;
3418 }
3419 
3420 void
SetRowColumnLabels(void)3421 SetRowColumnLabels(void)
3422 {
3423 	int	i;
3424 	char	tmp[10];
3425 
3426 	rowlabels = (char **)XtCalloc(AppRes.rows, sizeof(char *));
3427 	columnlabels = (char **)XtCalloc(AppRes.columns, sizeof(char *));
3428 	columnmaxlengths = (int *)XtCalloc(AppRes.columns, sizeof(int));
3429 
3430 	for (i=0; i<AppRes.rows; i++) {
3431 		sprintf(tmp, Global->a0 ? "%d" : "R%d", i + 1);
3432 		rowlabels[i] = XtNewString(tmp);
3433 	}
3434 	for (i=0; i<AppRes.columns; i++) {
3435 		if (Global->a0)
3436 			columnlabels[i] = XtNewString(col_to_str(i+1));
3437 		else {
3438 			sprintf(tmp, "C%d", i + 1);
3439 			columnlabels[i] = XtNewString(tmp);
3440 		}
3441 		columnmaxlengths[i] = 64000;
3442 	}
3443 }
3444 
3445 void
ChangeRowColumnLabels(void)3446 ChangeRowColumnLabels(void)
3447 {
3448 	int	i;
3449 	char	tmp[10];
3450 
3451 	for (i=0; i<AppRes.rows; i++) {
3452 		sprintf(tmp, Global->a0 ? "%d" : "R%d", i + 1);
3453 		XtFree(rowlabels[i]);
3454 		rowlabels[i] = XtNewString(tmp);
3455 	}
3456 	for (i=0; i<AppRes.columns; i++) {
3457 		XtFree(columnlabels[i]);
3458 		if (Global->a0)
3459 			columnlabels[i] = XtNewString(col_to_str(i+1));
3460 		else {
3461 			sprintf(tmp, "C%d", i + 1);
3462 			columnlabels[i] = XtNewString(tmp);
3463 		}
3464 		columnmaxlengths[i] = 64000;
3465 	}
3466 }
3467 
3468 /****************************************************************
3469  *								*
3470  *		Some option settings				*
3471  *								*
3472  ****************************************************************/
FixA0()3473 static void FixA0()
3474 {
3475 	if (Global->MotifGlobal->havea0 == Global->a0)
3476 		return;
3477 
3478 	Global->MotifGlobal->havea0 = Global->a0;
3479 
3480 	/* Update matrix */
3481 	ChangeRowColumnLabels();
3482 	XtVaSetValues(mat,
3483 			XmNrowLabels,		rowlabels,
3484 			XmNcolumnLabels,	columnlabels,
3485 		NULL);
3486 }
3487 
ToggleA0(Widget w,XtPointer client,XtPointer call)3488 void ToggleA0(Widget w, XtPointer client, XtPointer call)
3489 {
3490 	MotifSelectGlobal(w);
3491 
3492 	if (Global->a0)
3493 		Global->a0 = 0;
3494 	else
3495 		Global->a0 = 1;
3496 
3497 	FixA0();
3498 }
3499 
3500 /****************************************************************
3501  *								*
3502  *		Edit Menu					*
3503  *								*
3504  ****************************************************************/
UndoCB(Widget w,XtPointer client,XtPointer call)3505 void UndoCB(Widget w, XtPointer client, XtPointer call)
3506 {
3507 	MotifSelectGlobal(w);
3508 
3509 	none(w, client, call);
3510 }
3511 
EditInsertCB(Widget w,XtPointer client,XtPointer call)3512 void EditInsertCB(Widget w, XtPointer client, XtPointer call)
3513 {
3514 	MotifSelectGlobal(w);
3515 
3516 	/* FIX ME */
3517 		/* Need to figure out whether to insert row or column */
3518 		/* Need to figure out how many rows/columns to treat */
3519 	insert_row(1);
3520 		/* Also need to clear the current cell */
3521 	MotifUpdateDisplay();
3522 }
3523 
EditDeleteCB(Widget w,XtPointer client,XtPointer call)3524 void EditDeleteCB(Widget w, XtPointer client, XtPointer call)
3525 {
3526 	MotifSelectGlobal(w);
3527 
3528 	/* FIX ME */
3529 		/* Need to figure out whether to delete row or column */
3530 		/* Need to figure out how many rows/columns to treat */
3531 	delete_row(1);
3532 		/* Also need to clear the current cell */
3533 	MotifUpdateDisplay();
3534 }
3535 
EditRecalculateCB(Widget w,XtPointer client,XtPointer call)3536 void EditRecalculateCB(Widget w, XtPointer client, XtPointer call)
3537 {
3538 	MotifSelectGlobal(w);
3539 
3540 	recalculate(1);
3541 	MotifUpdateDisplay();
3542 }
3543 
3544 /****************************************************************
3545  *								*
3546  *		Copy/Paste stuff				*
3547  *								*
3548  ****************************************************************/
3549 /*
3550  * This, and the other copy/paste functions, must act as follows :
3551  * - a region is assumed to be selected in the spreadsheet
3552  * - the region is converted into more than one selections (only on
3553  *	request though) : text, value/formula group, ...
3554  * - copying to/from the X selection mechanism
3555  * - conversion in the other way (preferably the value/formula group,
3556  *	otherwise text, which can come from other sources as well... )
3557  *
3558  * Note that this bypasses the existing oleo copy/paste mechanism.
3559  */
CopyCB(Widget w,XtPointer client,XtPointer call)3560 void CopyCB(Widget w, XtPointer client, XtPointer call)
3561 {
3562 	MotifSelectGlobal(w);
3563 
3564 	none(w, client, call);
3565 }
3566 
CutCB(Widget w,XtPointer client,XtPointer call)3567 void CutCB(Widget w, XtPointer client, XtPointer call)
3568 {
3569 	MotifSelectGlobal(w);
3570 
3571 	none(w, client, call);
3572 }
3573 
PasteCB(Widget w,XtPointer client,XtPointer call)3574 void PasteCB(Widget w, XtPointer client, XtPointer call)
3575 {
3576 	MotifSelectGlobal(w);
3577 
3578 	none(w, client, call);
3579 }
3580 
3581 /****************************************************************
3582  *								*
3583  *		Oleo move/copy functionality			*
3584  *								*
3585  ****************************************************************/
CreateCopyDialog(char * t,void (* cb)(Widget,XtPointer,XtPointer))3586 void CreateCopyDialog(char *t, void (*cb)(Widget, XtPointer, XtPointer))
3587 {
3588 	Widget		w, rc, cap;
3589 	Arg		al[3];
3590 	int		ac;
3591 	XmString	ok, cancel;
3592 
3593 	if (copyDialog == NULL) {
3594 		ac = 0;
3595 		ok = XmStringCreateSimple(_("OK"));
3596 		cancel = XmStringCreateSimple(_("Cancel"));
3597 		XtSetArg(al[ac], XmNokLabelString, ok); ac++;
3598 		XtSetArg(al[ac], XmNcancelLabelString, cancel); ac++;
3599 		XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
3600 		copyDialog = XmCreateTemplateDialog(toplevel, "copyDialog",
3601 			al, ac);
3602 		XmStringFree(ok);
3603 		XmStringFree(cancel);
3604 
3605 		rc = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass,
3606 			copyDialog,
3607 			NULL);
3608 
3609 		cap = XtVaCreateManagedWidget("cap1", xbaeCaptionWidgetClass,
3610 			rc,
3611 			NULL);
3612 		w = XtVaCreateManagedWidget("r1", xmTextFieldWidgetClass, cap,
3613 			NULL);
3614 		RegisterRangeSelector(w);
3615 		cap = XtVaCreateManagedWidget("cap2", xbaeCaptionWidgetClass,
3616 			rc,
3617 			NULL);
3618 		w = XtVaCreateManagedWidget("r2", xmTextFieldWidgetClass, cap,
3619 			NULL);
3620 		RegisterRangeSelector(w);
3621 	}
3622 
3623 	XtRemoveAllCallbacks(copyDialog, XmNokCallback);
3624 	XtAddCallback(copyDialog, XmNokCallback, cb, NULL);
3625 	XtAddCallback(copyDialog, XmNcancelCallback, CancelTemplate, copyDialog);
3626 
3627 	XtVaSetValues(XtParent(copyDialog), XmNtitle, t, NULL);
3628 }
3629 
ReallyCopyRegionCB(Widget w,XtPointer client,XtPointer call)3630 void ReallyCopyRegionCB(Widget w, XtPointer client, XtPointer call)
3631 {
3632 	Widget		ft, tt;
3633 	char		*f, *t, *p;
3634 	struct rng	from, to;
3635 	int		r;
3636 
3637 	MotifSelectGlobal(w);
3638 
3639 	ft = XtNameToWidget(copyDialog, "*r1");
3640 	tt = XtNameToWidget(copyDialog, "*r2");
3641 
3642 	f = XmTextFieldGetString(ft);
3643 	t = XmTextFieldGetString(tt);
3644 
3645 	p = f;
3646 	if ((r = parse_cell_or_range(&p, &from)) == 0)
3647 		ConversionError(f, _("range"));
3648 	else if ((r & RANGE) == 0) {
3649 		/* It's a cell address, not a range */
3650 		from.hr = from.lr;
3651 		from.hc = from.lc;
3652 	}
3653 
3654 	p = t;
3655 	if ((r = parse_cell_or_range(&p, &to)) == 0)
3656 		ConversionError(t, _("range"));
3657 	else if ((r & RANGE) == 0) {
3658 		/* It's a cell address, not a range */
3659 		to.hr = to.lr;
3660 		to.hc = to.lc;
3661 	}
3662 
3663 	copy_region(&from, &to);
3664 	Global->modified = 1;
3665 
3666 	recalculate(1);
3667 	MotifUpdateDisplay();
3668 
3669 #if 0
3670 	XtFree(f);
3671 	XtFree(t);
3672 #endif
3673 }
3674 
ReallyMoveCB(Widget w,XtPointer client,XtPointer call)3675 void ReallyMoveCB(Widget w, XtPointer client, XtPointer call)
3676 {
3677 	Widget		ft, tt;
3678 	char		*f, *t, *p;
3679 	struct rng	from, to;
3680 	int		r;
3681 
3682 	MotifSelectGlobal(w);
3683 
3684 	ft = XtNameToWidget(copyDialog, "*r1");
3685 	tt = XtNameToWidget(copyDialog, "*r2");
3686 
3687 	f = XmTextFieldGetString(ft);
3688 	t = XmTextFieldGetString(tt);
3689 
3690 	MessageAppend(False, "ReallyMoveCB (%s -> %s)!!\n", f, t);
3691 
3692 	p = f;
3693 	if ((r = parse_cell_or_range(&p, &from)) == 0)
3694 		ConversionError(f, _("range"));
3695 	else if ((r & RANGE) == 0) {
3696 		/* It's a cell address, not a range */
3697 		from.hr = from.lr;
3698 		from.hc = from.lc;
3699 	}
3700 
3701 	p = t;
3702 	if ((r = parse_cell_or_range(&p, &to)) == 0)
3703 		ConversionError(t, _("range"));
3704 	else if ((r & RANGE) == 0) {
3705 		/* It's a cell address, not a range */
3706 		to.hr = to.lr;
3707 		to.hc = to.lc;
3708 	}
3709 
3710 	move_region(&from, &to);
3711 	Global->modified = 1;
3712 
3713 	recalculate(1);
3714 	MotifUpdateDisplay();
3715 #if 0
3716 	XtFree(f);
3717 	XtFree(t);
3718 #endif
3719 }
3720 
ReallyCopyValuesCB(Widget w,XtPointer client,XtPointer call)3721 void ReallyCopyValuesCB(Widget w, XtPointer client, XtPointer call)
3722 {
3723 	Widget		ft, tt;
3724 	char		*f, *t, *p;
3725 	struct rng	from, to;
3726 	int		r;
3727 
3728 	MotifSelectGlobal(w);
3729 
3730 	ft = XtNameToWidget(copyDialog, "*r1");
3731 	tt = XtNameToWidget(copyDialog, "*r2");
3732 
3733 	f = XmTextFieldGetString(ft);
3734 	t = XmTextFieldGetString(tt);
3735 
3736 	p = f;
3737 	if ((r = parse_cell_or_range(&p, &from)) == 0)
3738 		ConversionError(f, _("range"));
3739 	else if ((r & RANGE) == 0) {
3740 		/* It's a cell address, not a range */
3741 		from.hr = from.lr;
3742 		from.hc = from.lc;
3743 	}
3744 
3745 	p = t;
3746 	if ((r = parse_cell_or_range(&p, &to)) == 0)
3747 		ConversionError(t, _("range"));
3748 	else if ((r & RANGE) == 0) {
3749 		/* It's a cell address, not a range */
3750 		to.hr = to.lr;
3751 		to.hc = to.lc;
3752 	}
3753 
3754 	copy_values_region(&from, &to);
3755 	Global->modified = 1;
3756 
3757 	recalculate(1);
3758 	MotifUpdateDisplay();
3759 #if 0
3760 	XtFree(f);
3761 	XtFree(t);
3762 #endif
3763 }
3764 
CopyRegionCB(Widget w,XtPointer client,XtPointer call)3765 void CopyRegionCB(Widget w, XtPointer client, XtPointer call)
3766 {
3767 	MotifSelectGlobal(w);
3768 
3769 	CreateCopyDialog(_("Copy a region"), ReallyCopyRegionCB);
3770 	XtManageChild(copyDialog);
3771 }
3772 
CopyValuesCB(Widget w,XtPointer client,XtPointer call)3773 void CopyValuesCB(Widget w, XtPointer client, XtPointer call)
3774 {
3775 	MotifSelectGlobal(w);
3776 
3777 	CreateCopyDialog(_("Copy Values"), ReallyCopyValuesCB);
3778 	XtManageChild(copyDialog);
3779 }
3780 
MoveCB(Widget w,XtPointer client,XtPointer call)3781 void MoveCB(Widget w, XtPointer client, XtPointer call)
3782 {
3783 	MotifSelectGlobal(w);
3784 
3785 	CreateCopyDialog(_("Move"), ReallyMoveCB);
3786 	XtManageChild(copyDialog);
3787 }
3788 
MarkCellCB(Widget w,XtPointer client,XtPointer call)3789 void MarkCellCB(Widget w, XtPointer client, XtPointer call)
3790 {
3791 	MotifSelectGlobal(w);
3792 
3793 }
3794 
MarkRegionCB(Widget w,XtPointer client,XtPointer call)3795 void MarkRegionCB(Widget w, XtPointer client, XtPointer call)
3796 {
3797 	MotifSelectGlobal(w);
3798 
3799 }
3800 
MarkFromDialogCB(Widget w,XtPointer client,XtPointer call)3801 void MarkFromDialogCB(Widget w, XtPointer client, XtPointer call)
3802 {
3803 	MotifSelectGlobal(w);
3804 
3805 }
3806 
3807 /****************************************************************
3808  *								*
3809  *		Formats Dialog					*
3810  *								*
3811  ****************************************************************/
3812 static int formats_list[] = {
3813 	/* 0 */		FMT_DEF,
3814 	/* 1 */		FMT_HID,
3815 	/* 2 */		FMT_GPH,
3816 	/* 3 */		FMT_GEN,
3817 	/* 4 */		FMT_DOL,
3818 	/* 5 */		FMT_CMA,
3819 	/* 6 */		FMT_PCT,
3820 	/* 7 */		FMT_DEF,
3821 	/* 8 */		FMT_DEF,
3822 	/* 9 */		FMT_FXT,
3823 	/* 10 */	FMT_DEF,
3824 	/* 11 */	FMT_DATE,
3825 	/* 12 */	FMT_DEF,
3826 	/* 13 */	FMT_DEF,
3827 	/* 14 */	FMT_DEF,
3828 	/* 15 */	FMT_DEF,
3829 	/* 16 */	FMT_DEF
3830 };
3831 
3832 /*
3833  * This is ugly.
3834  *
3835  * Yeah gets called whenever the user manipulates the option menu.
3836  * The OK callback only has to figure out what got selected last
3837  * (from the global variable) and do its thing.
3838  * A cleaner but harder solution would have to figure out which
3839  * button is currently selected and translate that into a format.
3840  */
Yeah(Widget w,XtPointer client,XtPointer call)3841 void Yeah(Widget w, XtPointer client, XtPointer call)
3842 {
3843 	MotifSelectGlobal(w);
3844 
3845 	Global->MotifGlobal->fmt = formats_list[(int) client];
3846 #if 0
3847 	fprintf(stderr, "Yeah %d->%d\n", (int)client, Global->MotifGlobal->fmt);
3848 #endif
3849 }
3850 
3851 int	date_format;
MotifDateFormat(Widget w,XtPointer client,XtPointer call)3852 void MotifDateFormat(Widget w, XtPointer client, XtPointer call)
3853 {
3854 	MotifSelectGlobal(w);
3855 
3856 	date_format = (int) client;
3857 }
3858 
CreateFormatsDialog(Widget p)3859 void CreateFormatsDialog(Widget p)
3860 {
3861 	Widget		frame, f, tf, l;
3862 	XmString	xms, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10,
3863 			x11, x12, x13, x14, x15;
3864 	extern char	*date_formats[];
3865 	Widget		menu, cb;
3866 	Arg		al[5];
3867 	int		ac, i;
3868 
3869 	frame = XtVaCreateManagedWidget("formatsFrame", xmFrameWidgetClass, p,
3870 		NULL);
3871 	l = XtVaCreateManagedWidget("formatsFrameTitle", xmLabelGadgetClass,
3872 		frame,
3873 			XmNchildType,			XmFRAME_TITLE_CHILD,
3874 			XmNchildVerticalAlignment,	XmALIGNMENT_CENTER,
3875 		NULL);
3876 
3877 	f = XtVaCreateManagedWidget("formatsForm", xmFormWidgetClass, frame,
3878 		NULL);
3879 
3880 	l = XtVaCreateManagedWidget("formatsL", xmLabelGadgetClass, f,
3881 			XmNleftAttachment,	XmATTACH_FORM,
3882 			XmNtopAttachment,	XmATTACH_FORM,
3883 			XmNleftOffset,		10,
3884 			XmNtopOffset,		10,
3885 		NULL);
3886 
3887 	tf = XtVaCreateManagedWidget("formatsTf", xmTextFieldWidgetClass, f,
3888 			XmNleftAttachment,	XmATTACH_WIDGET,
3889 			XmNleftWidget,		l,
3890 			XmNleftOffset,		10,
3891 			XmNtopAttachment,	XmATTACH_FORM,
3892 			XmNtopOffset,		10,
3893 			XmNrightAttachment,	XmATTACH_FORM,
3894 			XmNrightOffset,		10,
3895 		NULL);
3896 	RegisterRangeSelector(tf);
3897 
3898 	xms = XmStringCreateSimple(_("Formats :"));
3899 
3900 	x0 = XmStringCreateSimple(_("Default"));	/* FMT_DEF */
3901 	x1 = XmStringCreateSimple(_("Hidden"));		/* FMT_HID */
3902 	x2 = XmStringCreateSimple(_("Graph"));		/* FMT_GPH */
3903 	x3 = XmStringCreateSimple(_("General"));	/* FMT_GEN */
3904 	x4 = XmStringCreateSimple(_("Dollar"));		/* FMT_DOL */
3905 	x5 = XmStringCreateSimple(_("Comma"));		/* FMT_CMA */
3906 	x6 = XmStringCreateSimple(_("Percent"));	/* FMT_PCT */
3907 	x7 = XmStringCreateSimple(_("Integer"));
3908 	x8 = XmStringCreateSimple(_("Decimal"));
3909 	x9 = XmStringCreateSimple(_("Fixed"));
3910 	x10 = XmStringCreateSimple(_("Exponent"));
3911 	x11 = XmStringCreateSimple(_("Date"));		/* FMT_DATE */
3912 	x12 = XmStringCreateSimple(_("User-1"));
3913 	x13 = XmStringCreateSimple(_("User-2"));
3914 	x14 = XmStringCreateSimple(_("User-3"));
3915 	x15 = XmStringCreateSimple(_("User-4"));
3916 
3917 	w = XmVaCreateSimpleOptionMenu(f, "formatsOption",
3918 		xms, /* mnemonic ? */0, /* initial selection */ 0,
3919 		/* callback */ Yeah,
3920 		/* Type, LabelString, Mnemonic, Accelerator, AcceleratorText */
3921 		XmVaPUSHBUTTON, x0, 'D', NULL, NULL,
3922 		XmVaPUSHBUTTON, x1, 'P', NULL, NULL,
3923 		XmVaPUSHBUTTON, x2, ' ', NULL, NULL,
3924 		XmVaPUSHBUTTON, x3, ' ', NULL, NULL,
3925 		XmVaPUSHBUTTON, x4, ' ', NULL, NULL,
3926 		XmVaPUSHBUTTON, x5, ' ', NULL, NULL,
3927 		XmVaPUSHBUTTON, x6, ' ', NULL, NULL,
3928 		XmVaPUSHBUTTON, x7, ' ', NULL, NULL,
3929 		XmVaPUSHBUTTON, x8, ' ', NULL, NULL,
3930 		XmVaPUSHBUTTON, x9, ' ', NULL, NULL,
3931 		XmVaPUSHBUTTON, x10, ' ', NULL, NULL,
3932 		XmVaPUSHBUTTON, x11, ' ', NULL, NULL,
3933 		XmVaPUSHBUTTON, x12, ' ', NULL, NULL,
3934 		XmVaPUSHBUTTON, x13, ' ', NULL, NULL,
3935 		XmVaPUSHBUTTON, x14, ' ', NULL, NULL,
3936 		XmVaPUSHBUTTON, x15, ' ', NULL, NULL,
3937 
3938 		XmNtopAttachment,	XmATTACH_WIDGET,
3939 		XmNtopWidget,		tf,
3940 		XmNtopOffset,		10,
3941 		XmNrightAttachment,	XmATTACH_FORM,
3942 		XmNrightOffset,		10,
3943 		XmNleftAttachment,	XmATTACH_FORM,
3944 		XmNleftOffset,		10,
3945 		NULL);
3946 	XtManageChild(w);
3947 
3948 	XmStringFree(xms);
3949 	XmStringFree(x0);
3950 	XmStringFree(x1);
3951 	XmStringFree(x2);
3952 	XmStringFree(x3);
3953 	XmStringFree(x4);
3954 	XmStringFree(x5);
3955 	XmStringFree(x6);
3956 	XmStringFree(x7);
3957 	XmStringFree(x8);
3958 	XmStringFree(x9);
3959 	XmStringFree(x10);
3960 	XmStringFree(x11);
3961 	XmStringFree(x12);
3962 	XmStringFree(x13);
3963 	XmStringFree(x14);
3964 	XmStringFree(x15);
3965 
3966 	/* Precision */
3967 	l = XtVaCreateManagedWidget("precisionL", xmLabelGadgetClass, f,
3968 			XmNleftAttachment,	XmATTACH_FORM,
3969 			XmNleftOffset,		10,
3970 			XmNtopAttachment,	XmATTACH_WIDGET,
3971 			XmNtopOffset,		10,
3972 			XmNtopWidget,		w,
3973 		NULL);
3974 	tf = XtVaCreateManagedWidget("precisionTf", xmTextFieldWidgetClass, f,
3975 		XmNtopAttachment,	XmATTACH_WIDGET,
3976 		XmNtopWidget,		w,
3977 		XmNtopOffset,		10,
3978 		XmNrightAttachment,	XmATTACH_FORM,
3979 		XmNrightOffset,		10,
3980 		XmNleftAttachment,	XmATTACH_WIDGET,
3981 		XmNleftWidget,		l,
3982 		XmNleftOffset,		10,
3983 		NULL);
3984 
3985 	/* A dialog for date formats */
3986 	menu = XmCreatePulldownMenu(f, "optionMenu", NULL, 0);
3987 	ac = 0;
3988 	XtSetArg(al[ac], XmNsubMenuId, menu); ac++;
3989 	xms = XmStringCreateSimple(_("Date Format"));
3990 	XtSetArg(al[ac], XmNlabelString, xms); ac++;
3991 	cb = XmCreateOptionMenu(f, "optionCB", al, ac);
3992 	XtVaSetValues(cb,
3993 		XmNtopAttachment,	XmATTACH_WIDGET,
3994 		XmNtopWidget,		tf,
3995 		XmNtopOffset,		10,
3996 		XmNrightAttachment,	XmATTACH_FORM,
3997 		XmNrightOffset,		10,
3998 		XmNleftAttachment,	XmATTACH_FORM,
3999 		XmNleftOffset,		10,
4000 		XmNbottomAttachment,	XmATTACH_FORM,
4001 		XmNbottomOffset,	10,
4002 		NULL);
4003 	XtManageChild(cb);
4004 	XmStringFree(xms);
4005 
4006 	for (i=0; date_formats[i]; i++) {
4007 		ac = 0;
4008 		xms = XmStringCreateSimple(date_formats[i]);
4009 		XtSetArg(al[ac], XmNlabelString, xms); ac++;
4010 		w = XmCreatePushButtonGadget(menu, "button", al, ac);
4011 		if (i == 0)
4012 			XtVaSetValues(menu, XmNmenuHistory, w, NULL);
4013 		XtAddCallback(w, XmNactivateCallback,
4014 			MotifDateFormat, (XtPointer)i);
4015 		XmStringFree(xms);
4016 		XtManageChild(w);
4017 	}
4018 }
4019 
4020 /*
4021  * Set formats both on cells/ranges and as default.
4022  *	client_data = 1 means set the default.
4023  */
FormatsDialogOk(Widget w,XtPointer client,XtPointer call)4024 void FormatsDialogOk(Widget w, XtPointer client, XtPointer call)
4025 {
4026 	struct rng	rng;
4027 	Widget		om, b = NULL, tf, pr;
4028 	char		*p, *s = NULL, *prec = NULL;
4029 	int		r, precision;
4030 
4031 	MotifSelectGlobal(w);
4032 	XtUnmanageChild(FormatD);
4033 
4034 	om = XtNameToWidget(FormatD, "*formatsFrame*formatsOption*formatsOption");
4035 	tf = XtNameToWidget(FormatD, "*formatsFrame*formatsTf");
4036 	pr = XtNameToWidget(FormatD, "*formatsFrame*precisionTf");
4037 
4038 	if (om)
4039 		XtVaGetValues(om, XmNmenuHistory, &b, NULL);
4040 	if (tf)
4041 		p = s = XmTextFieldGetString(tf);
4042 	if (pr) {
4043 		prec = XmTextFieldGetString(pr);
4044 		if (prec) precision = atoi(prec);
4045 	}
4046 
4047 	/* date */
4048 	if (Global->MotifGlobal->fmt == FMT_DATE)
4049 		precision = date_format;
4050 
4051 	if (client) {	/* Set default */
4052 			default_fmt = Global->MotifGlobal->fmt;
4053 			default_prc = precision;
4054 
4055 			MessageAppend(False, "Set Default Format %d, precision %d\n",
4056 				default_fmt, default_prc);
4057 
4058 			recalculate(1);
4059 			MotifUpdateDisplay();
4060 	} else {
4061 	    if (p) {
4062 		if ((r = parse_cell_or_range(&p, &rng)) == 0)
4063 			ConversionError(s, _("range"));
4064 		else if (r & RANGE) {
4065 			MessageAppend(False, "FormatRegion %s\n",
4066 				range_name(&rng));
4067 
4068 			format_region(&rng, Global->MotifGlobal->fmt, -1);
4069 			precision_region(&rng, precision);
4070 
4071 			recalculate(1);
4072 			MotifUpdateDisplay();
4073 		} else {
4074 			rng.hr = rng.lr;
4075 			rng.hc = rng.lc;
4076 
4077 			format_region(&rng, Global->MotifGlobal->fmt, -1);
4078 			precision_region(&rng, precision);
4079 
4080 			recalculate(1);
4081 			MotifUpdateDisplay();
4082 		}
4083 	    }
4084 	}
4085 
4086 
4087 #ifdef	FREE_TF_STRING
4088 	XtFree(s);
4089 	XtFree(prec);
4090 #endif
4091 }
4092 
FormatsDialogReset(Widget d)4093 void FormatsDialogReset(Widget d)
4094 {
4095 }
4096 
FormatsDialog(Widget w,XtPointer client,XtPointer call)4097 void FormatsDialog(Widget w, XtPointer client, XtPointer call)
4098 {
4099 	Widget	ok, cancel, help, tf;
4100 	int	c = (int)client, ac;
4101 	Arg	al[5];
4102 
4103 	MotifSelectGlobal(w);
4104 
4105 	if (! FormatD) {
4106 		ac = 0;
4107 		XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
4108 		FormatD = XmCreateTemplateDialog(mw, "formatsDialog", al, ac);
4109 		CreateFormatsDialog(FormatD);
4110 
4111 		ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, FormatD,
4112 			NULL);
4113 		cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass, FormatD,
4114 			NULL);
4115 		help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass, FormatD,
4116 			NULL);
4117 
4118 		XtAddCallback(ok, XmNactivateCallback, FormatsDialogOk,
4119 			(XtPointer)client);	/* Whether or not it's a default setting */
4120 		XtAddCallback(help, XmNactivateCallback, helpUsingCB,
4121 			(XtPointer)"#HelpFormats");
4122 		XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, FormatD);
4123 	}
4124 
4125 	tf = XtNameToWidget(FormatD, "*formatsFrame*formatsTf");
4126 	if (tf) XtSetSensitive(tf, 1 - c);
4127 
4128 	FormatsDialogReset(FormatD);
4129 	XtManageChild(FormatD);
4130 }
4131 
4132 /****************************************************************
4133  *								*
4134  *		Generic Dialog Support				*
4135  *								*
4136  ****************************************************************/
4137 /*
4138  * Walk up widget tree until a shell is found.
4139  * The previous widget is the one returned.
4140  */
FindDialog(Widget w)4141 static Widget FindDialog(Widget w)
4142 {
4143 	Widget	p, q;
4144 
4145 	p = q = w;
4146 	for (p=q=w; q=p, p=XtParent(p); p != NULL && q != NULL & !XmIsDialogShell(p)) ;
4147 
4148 	return q;
4149 }
4150 
4151 /****************************************************************
4152  *								*
4153  *		User Preferences				*
4154  *								*
4155  ****************************************************************/
4156 void
UserPreferencesOk(Widget w,XtPointer client,XtPointer call)4157 UserPreferencesOk(Widget w, XtPointer client, XtPointer call)
4158 {
4159 	Widget		mft, ft, etf;
4160 	char		*mf, f;
4161 	XmFontList	fl;
4162 	XmFontListEntry	fle;
4163 	XFontSet	fs;
4164 	char		m1[2][80], **missing = (char **)&m1[0];
4165 	char		m2[80], *def = &m2[0];
4166 	int		nmissing = 0;
4167 	Display		*d = XtDisplayOfObject(w);
4168 
4169 	MotifSelectGlobal(w);
4170 
4171 	XtUnmanageChild(UserPref);
4172 
4173 	mft = XtNameToWidget(UserPref, "*matrixfonttf");
4174 	ft = XtNameToWidget(UserPref, "*fonttf");
4175 	etf = XtNameToWidget(UserPref, "*encodingTf");
4176 
4177 	if (ft == NULL || mft == NULL || etf == NULL)
4178 		return;	/* Huh ?? */
4179 
4180 	mf = XmTextFieldGetString(mft);
4181 
4182 	/* set preferences now */
4183 	fs = XCreateFontSet(d, mf, &missing, &nmissing, &def);
4184 	if (fs != NULL) {
4185 		fle = XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG, XmFONT_IS_FONTSET, fs);
4186 		fl = XmFontListAppendEntry(NULL, fle);
4187 		XtVaSetValues(mat, XmNfontList, fl, NULL);
4188 	/* FIX ME potential leak : can we free fl, fle, fs yet ? */
4189 
4190 		OleoSetEncoding(XmTextFieldGetString(etf));
4191 	}
4192 
4193 	XtFree(mf);
4194 }
4195 
4196 void
UserPreferencesReset(Widget w)4197 UserPreferencesReset(Widget w)
4198 {
4199 	Widget	e = XtNameToWidget(w, "*encodingTf");
4200 
4201 	if (e) XmTextFieldSetString(e, OleoGetEncoding());
4202 }
4203 
4204 #ifdef	HAVE_XLT_FONTCHOOSER
4205 #include <Xlt/FontChooser.h>
4206 #endif
4207 
4208 static void
ChooseFont(Widget w,XtPointer client,XtPointer call)4209 ChooseFont(Widget w, XtPointer client, XtPointer call)
4210 {
4211 #ifdef	HAVE_XLT_FONTCHOOSER
4212 	char	*s;
4213 	Widget	tf;
4214 
4215 	MotifSelectGlobal(w);
4216 
4217 	XtVaGetValues(w, XltNfontName, &s, NULL);
4218 
4219 	fprintf(stderr, "Selected font '%s'\n", s);
4220 
4221 	tf = XtNameToWidget(UserPref, "*matrixfonttf");
4222 	if (tf)
4223 		XmTextFieldSetString(tf, s);
4224 #endif
4225 }
4226 
4227 void
FontChooserCB(Widget w,XtPointer client,XtPointer call)4228 FontChooserCB(Widget w, XtPointer client, XtPointer call)
4229 {
4230 #ifdef	HAVE_XLT_FONTCHOOSER
4231 	Widget	tf = (Widget)client, fc;
4232 	Arg	al[5];
4233 	int	ac;
4234 
4235 	MotifSelectGlobal(w);
4236 
4237 	ac = 0;
4238 	fc = XltCreateFontChooserDialog(toplevel, "font chooser", al, ac);
4239 	XtManageChild(fc);
4240 
4241 	XtAddCallback(fc, XmNokCallback, ChooseFont, NULL);
4242 #endif
4243 }
4244 
4245 void
CreateUserPreferences(Widget parent)4246 CreateUserPreferences(Widget parent)
4247 {
4248 	Widget	form, l, t, b;
4249 
4250 	form = XtVaCreateManagedWidget("form", xmFormWidgetClass,
4251 		parent,
4252 		NULL);
4253 	XtManageChild(form);
4254 
4255 	l = XtVaCreateManagedWidget("matrixfontlabel", xmLabelGadgetClass,
4256 		form,
4257 			XmNtopAttachment,	XmATTACH_FORM,
4258 			XmNtopOffset,		10,
4259 			XmNleftAttachment,	XmATTACH_FORM,
4260 			XmNleftOffset,		10,
4261 			XmNrightAttachment,	XmATTACH_NONE,
4262 			XmNbottomAttachment,	XmATTACH_NONE,
4263 		NULL);
4264 
4265 	t = XtVaCreateManagedWidget("matrixfonttf", xmTextFieldWidgetClass,
4266 		form,
4267 			XmNtopAttachment,	XmATTACH_FORM,
4268 			XmNtopOffset,		10,
4269 			XmNleftAttachment,	XmATTACH_WIDGET,
4270 			XmNleftOffset,		10,
4271 			XmNleftWidget,		l,
4272 			XmNrightAttachment,	XmATTACH_NONE,
4273 			XmNbottomAttachment,	XmATTACH_NONE,
4274 		NULL);
4275 
4276 	b = XtVaCreateManagedWidget("matrixfontbutton", xmPushButtonGadgetClass,
4277 		form,
4278 			XmNtopAttachment,	XmATTACH_FORM,
4279 			XmNtopOffset,		10,
4280 			XmNleftAttachment,	XmATTACH_WIDGET,
4281 			XmNleftOffset,		10,
4282 			XmNleftWidget,		t,
4283 			XmNrightAttachment,	XmATTACH_FORM,
4284 			XmNrightOffset,		10,
4285 		NULL);
4286 	XtAddCallback(b, XmNactivateCallback, FontChooserCB, (XtPointer)t);
4287 
4288 	l = XtVaCreateManagedWidget("fontlabel", xmLabelGadgetClass,
4289 		form,
4290 			XmNtopAttachment,	XmATTACH_WIDGET,
4291 			XmNtopOffset,		10,
4292 			XmNtopWidget,		t,
4293 			XmNleftAttachment,	XmATTACH_FORM,
4294 			XmNleftOffset,		10,
4295 			XmNrightAttachment,	XmATTACH_WIDGET,
4296 			XmNrightWidget,		t,
4297 			XmNrightOffset,		10,
4298 			XmNbottomAttachment,	XmATTACH_NONE,
4299 		NULL);
4300 
4301 	t = XtVaCreateManagedWidget("fonttf", xmTextFieldWidgetClass,
4302 		form,
4303 			XmNtopAttachment,	XmATTACH_WIDGET,
4304 			XmNtopOffset,		10,
4305 			XmNtopWidget,		t,
4306 			XmNrightAttachment,	XmATTACH_OPPOSITE_WIDGET,
4307 			XmNrightWidget,		t,
4308 			XmNleftAttachment,	XmATTACH_OPPOSITE_WIDGET,
4309 			XmNleftWidget,		t,
4310 		NULL);
4311 
4312 	b = XtVaCreateManagedWidget("fontbutton", xmPushButtonGadgetClass,
4313 		form,
4314 			XmNtopAttachment,	XmATTACH_OPPOSITE_WIDGET,
4315 			XmNtopOffset,		0,
4316 			XmNtopWidget,		t,
4317 			XmNleftAttachment,	XmATTACH_WIDGET,
4318 			XmNleftOffset,		10,
4319 			XmNleftWidget,		t,
4320 			XmNrightAttachment,	XmATTACH_FORM,
4321 			XmNrightOffset,		10,
4322 		NULL);
4323 	XtAddCallback(b, XmNactivateCallback, FontChooserCB, (XtPointer)t);
4324 
4325 	l = XtVaCreateManagedWidget("encodingLabel", xmLabelGadgetClass,
4326 		form,
4327 			XmNtopAttachment,	XmATTACH_WIDGET,
4328 			XmNtopOffset,		10,
4329 			XmNtopWidget,		t,
4330 			XmNleftAttachment,	XmATTACH_FORM,
4331 			XmNleftOffset,		10,
4332 			XmNrightAttachment,	XmATTACH_WIDGET,
4333 			XmNrightWidget,		t,
4334 			XmNrightOffset,		10,
4335 			XmNbottomAttachment,	XmATTACH_NONE,
4336 		NULL);
4337 
4338 	t = XtVaCreateManagedWidget("encodingTf", xmTextFieldWidgetClass,
4339 		form,
4340 			XmNtopAttachment,	XmATTACH_WIDGET,
4341 			XmNtopOffset,		10,
4342 			XmNtopWidget,		t,
4343 			XmNbottomAttachment,	XmATTACH_NONE,
4344 			XmNrightAttachment,	XmATTACH_OPPOSITE_WIDGET,
4345 			XmNrightWidget,		t,
4346 			XmNleftAttachment,	XmATTACH_OPPOSITE_WIDGET,
4347 			XmNleftWidget,		t,
4348 		NULL);
4349 }
4350 
4351 void
DoUserPreferences(Widget w,XtPointer client,XtPointer call)4352 DoUserPreferences(Widget w, XtPointer client, XtPointer call)
4353 {
4354 	Widget	ok, cancel, help, tf;
4355 	int	c = (int)client, ac;
4356 	Arg	al[5];
4357 
4358 	MotifSelectGlobal(w);
4359 
4360 	if (! UserPref) {
4361 		ac = 0;
4362 		XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
4363 		UserPref = XmCreateTemplateDialog(mw, "UserPreferences",
4364 			al, ac);
4365 		CreateUserPreferences(UserPref);
4366 
4367 		ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, UserPref,
4368 			NULL);
4369 		cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass, UserPref,
4370 			NULL);
4371 		help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass, UserPref,
4372 			NULL);
4373 
4374 		XtAddCallback(ok, XmNactivateCallback, UserPreferencesOk, NULL);
4375 		XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, UserPref);
4376 		XtAddCallback(help, XmNactivateCallback, helpUsingCB,
4377 			(XtPointer)"#HelpUserPreferences");
4378 	}
4379 
4380 	UserPreferencesReset(UserPref);
4381 	XtManageChild(UserPref);
4382 }
4383 
4384 void
SaveUserPreferences(Widget w,XtPointer client,XtPointer call)4385 SaveUserPreferences(Widget w, XtPointer client, XtPointer call)
4386 {
4387 	MotifSelectGlobal(w);
4388 
4389 	save_preferences();
4390 }
4391 
4392 /****************************************************************
4393  *								*
4394  *		Database Interaction				*
4395  *								*
4396  ****************************************************************/
4397 void
DoMySQLRead(Widget w,XtPointer client,XtPointer call)4398 DoMySQLRead(Widget w, XtPointer client, XtPointer call)
4399 {
4400 	MotifSelectGlobal(w);
4401 
4402 	none(w, client, call);
4403 }
4404 
4405 void
DoMySQLWrite(Widget w,XtPointer client,XtPointer call)4406 DoMySQLWrite(Widget w, XtPointer client, XtPointer call)
4407 {
4408 	MotifSelectGlobal(w);
4409 
4410 	none(w, client, call);
4411 }
4412 
4413 void
DoXbaseRead(Widget w,XtPointer client,XtPointer call)4414 DoXbaseRead(Widget w, XtPointer client, XtPointer call)
4415 {
4416 	MotifSelectGlobal(w);
4417 
4418 	none(w, client, call);
4419 }
4420 
4421 void
DoXbaseWrite(Widget w,XtPointer client,XtPointer call)4422 DoXbaseWrite(Widget w, XtPointer client, XtPointer call)
4423 {
4424 	MotifSelectGlobal(w);
4425 
4426 	none(w, client, call);
4427 }
4428 
4429 void
MySQLDialogOk(Widget w,XtPointer client,XtPointer call)4430 MySQLDialogOk(Widget w, XtPointer client, XtPointer call)
4431 {
4432 	Widget	d = FindDialog(w),
4433 		dbhosttf = XtNameToWidget(d, "*dbhosttf"),
4434 		dbnametf = XtNameToWidget(d, "*dbnametf"),
4435 		dbusertf = XtNameToWidget(d, "*dbusertf");
4436 	char	*h, *n, *u;
4437 
4438 	MotifSelectGlobal(w);
4439 	XtUnmanageChild(MySQLDialog);
4440 
4441 	if (dbhosttf == NULL || dbnametf == NULL)
4442 		return;
4443 
4444 	h = XmTextFieldGetString(dbhosttf);
4445 	DatabaseSetHost(h);
4446 
4447 	n = XmTextFieldGetString(dbnametf);
4448 	DatabaseSetName(n);
4449 
4450 	u = XmTextFieldGetString(dbusertf);
4451 	DatabaseSetUser(u);
4452 
4453 	MessageAppend(False, "Database host %s name %s user %s", h, n, u);
4454 
4455 	XtFree(h);
4456 	XtFree(n);
4457 	XtFree(u);
4458 }
4459 
4460 void
ConfigureMySQLDialogReset(Widget w)4461 ConfigureMySQLDialogReset(Widget w)
4462 {
4463 	Widget	d = FindDialog(w),
4464 		dbhosttf = XtNameToWidget(d, "*dbhosttf"),
4465 		dbnametf = XtNameToWidget(d, "*dbnametf"),
4466 		dbusertf = XtNameToWidget(d, "*dbusertf");
4467 
4468 	if (dbhosttf == NULL || dbnametf == NULL)
4469 		return;
4470 
4471 	XmTextFieldSetString(dbhosttf, DatabaseGetHost());
4472 	XmTextFieldSetString(dbnametf, DatabaseGetName());
4473 	XmTextFieldSetString(dbusertf, DatabaseGetUser());
4474 }
4475 
4476 void
CreateConfigureMySQLDialog(Widget parent)4477 CreateConfigureMySQLDialog(Widget parent)
4478 {
4479 	Widget	form, l, t;
4480 
4481 	form = XtVaCreateManagedWidget("form", xmFormWidgetClass,
4482 		parent,
4483 		NULL);
4484 	XtManageChild(form);
4485 
4486 	l = XtVaCreateManagedWidget("dbhostlabel", xmLabelGadgetClass,
4487 		form,
4488 			XmNtopAttachment,	XmATTACH_FORM,
4489 			XmNtopOffset,		10,
4490 			XmNleftAttachment,	XmATTACH_FORM,
4491 			XmNleftOffset,		10,
4492 			XmNrightAttachment,	XmATTACH_NONE,
4493 			XmNbottomAttachment,	XmATTACH_NONE,
4494 		NULL);
4495 
4496 	t = XtVaCreateManagedWidget("dbhosttf", xmTextFieldWidgetClass,
4497 		form,
4498 			XmNtopAttachment,	XmATTACH_FORM,
4499 			XmNtopOffset,		10,
4500 			XmNleftAttachment,	XmATTACH_WIDGET,
4501 			XmNleftOffset,		10,
4502 			XmNleftWidget,		l,
4503 			XmNrightAttachment,	XmATTACH_FORM,
4504 			XmNrightOffset,		10,
4505 			XmNbottomAttachment,	XmATTACH_NONE,
4506 		NULL);
4507 
4508 	l = XtVaCreateManagedWidget("dbnamelabel", xmLabelGadgetClass,
4509 		form,
4510 			XmNtopAttachment,	XmATTACH_WIDGET,
4511 			XmNtopOffset,		10,
4512 			XmNtopWidget,		t,
4513 			XmNleftAttachment,	XmATTACH_FORM,
4514 			XmNleftOffset,		10,
4515 			XmNrightAttachment,	XmATTACH_NONE,
4516 			XmNbottomAttachment,	XmATTACH_NONE,
4517 		NULL);
4518 
4519 	t = XtVaCreateManagedWidget("dbnametf", xmTextFieldWidgetClass,
4520 		form,
4521 			XmNtopAttachment,	XmATTACH_WIDGET,
4522 			XmNtopOffset,		10,
4523 			XmNtopWidget,		t,
4524 			XmNleftAttachment,	XmATTACH_WIDGET,
4525 			XmNleftOffset,		10,
4526 			XmNleftWidget,		l,
4527 			XmNrightAttachment,	XmATTACH_FORM,
4528 			XmNrightOffset,		10,
4529 			XmNbottomAttachment,	XmATTACH_NONE,
4530 		NULL);
4531 
4532 	l = XtVaCreateManagedWidget("dbuserlabel", xmLabelGadgetClass,
4533 		form,
4534 			XmNtopAttachment,	XmATTACH_WIDGET,
4535 			XmNtopOffset,		10,
4536 			XmNtopWidget,		t,
4537 			XmNleftAttachment,	XmATTACH_FORM,
4538 			XmNleftOffset,		10,
4539 			XmNrightAttachment,	XmATTACH_NONE,
4540 			XmNbottomAttachment,	XmATTACH_NONE,
4541 		NULL);
4542 
4543 	t = XtVaCreateManagedWidget("dbusertf", xmTextFieldWidgetClass,
4544 		form,
4545 			XmNtopAttachment,	XmATTACH_WIDGET,
4546 			XmNtopOffset,		10,
4547 			XmNtopWidget,		t,
4548 			XmNleftAttachment,	XmATTACH_WIDGET,
4549 			XmNleftOffset,		10,
4550 			XmNleftWidget,		l,
4551 			XmNrightAttachment,	XmATTACH_FORM,
4552 			XmNrightOffset,		10,
4553 			XmNbottomAttachment,	XmATTACH_NONE,
4554 		NULL);
4555 }
4556 
4557 void
ConfigureMySQL(Widget w,XtPointer client,XtPointer call)4558 ConfigureMySQL(Widget w, XtPointer client, XtPointer call)
4559 {
4560 	Widget	ok, cancel, help, tf;
4561 	int	c = (int)client, ac;
4562 	Arg	al[5];
4563 
4564 	MotifSelectGlobal(w);
4565 
4566 	if (! MySQLDialog) {
4567 		ac = 0;
4568 		XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
4569 		MySQLDialog = XmCreateTemplateDialog(mw, "mySQLDialog", al, ac);
4570 		CreateConfigureMySQLDialog(MySQLDialog);
4571 
4572 		ok = XtVaCreateManagedWidget("ok", xmPushButtonGadgetClass, MySQLDialog,
4573 			NULL);
4574 		cancel = XtVaCreateManagedWidget("cancel", xmPushButtonGadgetClass, MySQLDialog,
4575 			NULL);
4576 		help = XtVaCreateManagedWidget("help", xmPushButtonGadgetClass, MySQLDialog,
4577 			NULL);
4578 
4579 		XtAddCallback(ok, XmNactivateCallback, MySQLDialogOk, NULL);
4580 		XtAddCallback(help, XmNactivateCallback, helpUsingCB,
4581 			(XtPointer)"#HelpMySQL");
4582 		XtAddCallback(cancel, XmNactivateCallback, CancelTemplate, MySQLDialog);
4583 	}
4584 
4585 	ConfigureMySQLDialogReset(MySQLDialog);
4586 	XtManageChild(MySQLDialog);
4587 }
4588 
4589 void
ExecuteCommandOk(Widget w,XtPointer client,XtPointer call)4590 ExecuteCommandOk(Widget w, XtPointer client, XtPointer call)
4591 {
4592 	XmSelectionBoxCallbackStruct *cbp = (XmSelectionBoxCallbackStruct *)call;
4593 	String	s;
4594 
4595 	MotifSelectGlobal(w);
4596 
4597 	if (! XmStringGetLtoR(cbp->value, XmFONTLIST_DEFAULT_TAG, &s)) {
4598 		MessageAppend(True, "Couldn't convert XmString into string\n");
4599 		return;
4600 	}
4601 
4602 	MessageAppend(False, "Executing command '%s'\n", s);
4603 
4604 	execute_command(s);
4605 	XtFree(s);
4606 }
4607 
4608 void
ExecuteCommandCB(Widget w,XtPointer client,XtPointer call)4609 ExecuteCommandCB(Widget w, XtPointer client, XtPointer call)
4610 {
4611 	int	ac;
4612 	Arg	al[5];
4613 
4614 	MotifSelectGlobal(w);
4615 
4616 	if (! ExecuteCommandDialog) {
4617 		ac = 0;
4618 		XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
4619 		ExecuteCommandDialog = XmCreatePromptDialog(mw, "executeCommandDialog", al, ac);
4620 
4621 		XtAddCallback(ExecuteCommandDialog, XmNokCallback, ExecuteCommandOk, NULL);
4622 		XtAddCallback(ExecuteCommandDialog, XmNhelpCallback, helpUsingCB,
4623 			(XtPointer)"#HelpExecuteCommand");
4624 		XtAddCallback(ExecuteCommandDialog, XmNcancelCallback, CancelTemplate,
4625 			(XtPointer)ExecuteCommandDialog);
4626 	}
4627 
4628 	XtManageChild(ExecuteCommandDialog);
4629 }
4630 
4631 /****************************************************************
4632  *								*
4633  *		Build Motif GUI					*
4634  *								*
4635  ****************************************************************/
4636 /*
4637  * Build a splash screen
4638  */
4639 
4640 Widget
GscBuildSplash(Widget parent)4641 GscBuildSplash(Widget parent)
4642 {
4643 	Arg		al[10];
4644 	int		ac;
4645 	Pixel		bg, fg;
4646 	Display		*dpy = XtDisplay(parent);
4647 	int		depth;
4648 	Widget		sh, rc, iconlabel, textlabel, form;
4649 	XmString	x1, x2, xms;
4650 
4651 #ifdef	HAVE_LIBXPM
4652 	XpmAttributes	attrib;
4653 	Pixmap		mask;
4654 #endif
4655 
4656 	sh = XtVaCreatePopupShell("splashShell", xmMenuShellWidgetClass, parent,
4657 #if 0
4658 			XmNallowShellResize,	False,
4659 #endif
4660 			XmNx,			300,
4661 			XmNy,			300,
4662 			XmNwidth,		100,
4663 			XmNheight,		100,
4664 		NULL);
4665 
4666 	/* MenuShell wants an RC child */
4667 	rc = XtVaCreateManagedWidget("splash", xmRowColumnWidgetClass, sh, NULL);
4668 
4669 	form = XtVaCreateWidget("form", xmFormWidgetClass, rc, NULL);
4670 
4671 	ac = 0;
4672 
4673 #ifdef	HAVE_LIBXPM
4674         attrib.closeness = 256;
4675 	attrib.valuemask = 0;
4676         attrib.valuemask |= XpmCloseness;
4677 
4678         ac = XpmCreatePixmapFromData(XtDisplay(rc),
4679                 XRootWindowOfScreen(XtScreen(rc)),
4680                 oleo_icon,
4681                 &Global->MotifGlobal->oleo_icon_pm,
4682                 &mask,
4683                 &attrib);
4684 
4685         if ( ac < 0 ) {
4686                 fprintf ( stderr, "GBSplash: XpmCreatePixmapFromData failed. ");
4687 
4688                 switch ( ac ) {
4689                 case -1:
4690                         fprintf ( stderr, "XpmOpenFailed failed\n" );
4691                         XpmFreeAttributes(&attrib);
4692                         goto skip_xpm_icon;
4693                 break;
4694 
4695                 case -2:
4696                         fprintf ( stderr, "XpmFileInvalid\n" );
4697                         XpmFreeAttributes(&attrib);
4698                         goto skip_xpm_icon;
4699                 break;
4700 
4701                 case -3:
4702                         fprintf ( stderr, "XpmNoMemory\n" );
4703                         goto skip_xpm_icon;
4704                         XpmFreeAttributes(&attrib);
4705                 break;
4706 
4707                 case -4:
4708                         while ( attrib.closeness <= 10000 ) {
4709                                 attrib.closeness += 256;
4710                                 ac = XpmCreatePixmapFromData(XtDisplay(rc),
4711 		XRootWindowOfScreen(XtScreen(rc)),
4712 		oleo_icon,
4713 		&Global->MotifGlobal->oleo_icon_pm,
4714 		&mask,
4715 		&attrib);
4716                                 if ( ac == -4 ) continue;
4717                                 if ( ac >= 0 ) break;
4718                                 if ( ac == -1 || ac == -2 || ac == -3  ) {
4719                                         fprintf ( stderr, "secondary error %d\n", ac );
4720                                         XpmFreeAttributes(&attrib);
4721                                         goto skip_xpm_icon;
4722                                 }
4723                         } /* while ( attrib.closeness <= 10000 ) */
4724                         if ( attrib.closeness > 10000 ) {
4725                                 fprintf ( stderr, "giving up, can't get close colors\n" );
4726                                 XpmFreeAttributes(&attrib);
4727                                 goto skip_xpm_icon;
4728                         } else
4729                                 fprintf ( stderr, "\n" );
4730                 break;
4731 
4732                 default:
4733                 break;
4734                 } /* switch (ac) */
4735         } /* if ( ac < 0 ) */
4736 
4737         ac = 0;
4738 
4739 	XpmFreeAttributes(&attrib);
4740 
4741 	XtSetArg(al[ac], XmNlabelPixmap,	Global->MotifGlobal->oleo_icon_pm); ac++;
4742 	XtSetArg(al[ac], XmNlabelType,		XmPIXMAP); ac++;
4743 	XtSetArg(al[ac], XmNshadowThickness,	0); ac++;
4744 	XtSetArg(al[ac], XmNleftAttachment,	XmATTACH_FORM); ac++;
4745 	XtSetArg(al[ac], XmNleftOffset,		0); ac++;
4746 	XtSetArg(al[ac], XmNrightAttachment,	XmATTACH_NONE); ac++;
4747 	XtSetArg(al[ac], XmNtopAttachment,	XmATTACH_FORM); ac++;
4748 	XtSetArg(al[ac], XmNtopOffset,		0); ac++;
4749 	iconlabel = XmCreatePushButtonGadget(form, "iconsplash", al, ac);
4750 	XtManageChild(iconlabel);
4751 	XtAddCallback(iconlabel, XmNactivateCallback, PopDownSplash, NULL);
4752 #endif
4753 
4754         skip_xpm_icon: /* XpmCreatePixmapFromData call failed -- skip it */
4755 
4756 	ac = 0;
4757 	x1 = XmStringCreateLtoR(GNU_PACKAGE " " VERSION "\n",
4758 		"large");
4759 	x2 = XmStringCreateLtoR(CopyRightString, "small");
4760 	xms = XmStringConcat(x1, x2);
4761 	XtSetArg(al[ac], XmNlabelString,	xms); ac++;
4762 	XtSetArg(al[ac], XmNlabelType,		XmSTRING); ac++;
4763 	XtSetArg(al[ac], XmNshadowThickness,	0); ac++;
4764 #ifdef	HAVE_LIBXPM
4765 	XtSetArg(al[ac], XmNleftAttachment,	XmATTACH_WIDGET); ac++;
4766 	XtSetArg(al[ac], XmNleftWidget,		iconlabel); ac++;
4767 #else
4768 	XtSetArg(al[ac], XmNleftAttachment,	XmATTACH_FORM); ac++;
4769 #endif
4770 	XtSetArg(al[ac], XmNleftOffset,		0); ac++;
4771 	XtSetArg(al[ac], XmNrightAttachment,	XmATTACH_FORM); ac++;
4772 	XtSetArg(al[ac], XmNrightOffset,	0); ac++;
4773 	XtSetArg(al[ac], XmNtopAttachment,	XmATTACH_FORM); ac++;
4774 	XtSetArg(al[ac], XmNtopOffset,		0); ac++;
4775 	textlabel = XmCreatePushButtonGadget(form, "textsplash", al, ac);
4776 	XtManageChild(textlabel);
4777 	XtAddCallback(textlabel, XmNactivateCallback, PopDownSplash, NULL);
4778 
4779 	XmStringFree(x1);
4780 	XmStringFree(x2);
4781 	XmStringFree(xms);
4782 
4783 	XtManageChild(form);
4784 
4785 	return sh;
4786 }
4787 
Traverse()4788 void Traverse()
4789 {
4790 	if (! XmProcessTraversal(mat, XmTRAVERSE_CURRENT)) {
4791 		fprintf(stderr, _("XmProcessTraversal failed\n"));
4792 	}
4793 }
4794 
4795 /*
4796  * Create the main widget tree.
4797  */
4798 Widget
GscBuildMainWindow(Widget parent)4799 GscBuildMainWindow(Widget parent)
4800 {
4801 	int	i;
4802 
4803 	/*
4804 	 * Structure
4805 	 */
4806 	mw = XmCreateMainWindow(parent, "mw", NULL, 0);
4807 	XtManageChild(mw);
4808 
4809 	mb = XmCreateMenuBar(mw, "menubar", NULL, 0);
4810 	XtManageChild(mb);
4811 
4812 	filemenu = XmCreatePulldownMenu(mb, "filemenu", NULL, 0);
4813 	XtManageChild(filemenu);
4814 
4815 	XtVaCreateManagedWidget("filecascade", xmCascadeButtonGadgetClass, mb,
4816 			XmNsubMenuId,	filemenu,
4817 		NULL);
4818 
4819 	editmenu = XmCreatePulldownMenu(mb, "editmenu", NULL, 0);
4820 	XtManageChild(editmenu);
4821 
4822 	XtVaCreateManagedWidget("editcascade", xmCascadeButtonGadgetClass, mb,
4823 			XmNsubMenuId,	editmenu,
4824 		NULL);
4825 
4826 	stylemenu = XmCreatePulldownMenu(mb, "stylemenu", NULL, 0);
4827 	XtManageChild(stylemenu);
4828 
4829 	XtVaCreateManagedWidget("stylecascade", xmCascadeButtonGadgetClass, mb,
4830 			XmNsubMenuId,	stylemenu,
4831 		NULL);
4832 
4833 	optionsmenu = XmCreatePulldownMenu(mb, "optionsmenu", NULL, 0);
4834 	XtManageChild(optionsmenu);
4835 
4836 	XtVaCreateManagedWidget("optionscascade", xmCascadeButtonGadgetClass, mb,
4837 			XmNsubMenuId,	optionsmenu,
4838 		NULL);
4839 
4840 	graphmenu = XmCreatePulldownMenu(mb, "graphmenu", NULL, 0);
4841 	XtManageChild(graphmenu);
4842 
4843 	XtVaCreateManagedWidget("graphcascade", xmCascadeButtonGadgetClass, mb,
4844 			XmNsubMenuId,	graphmenu,
4845 		NULL);
4846 
4847 	helpmenu = XmCreatePulldownMenu(mb, "helpmenu", NULL, 0);
4848 	XtManageChild(helpmenu);
4849 
4850 	w = XtVaCreateManagedWidget("helpcascade", xmCascadeButtonGadgetClass,
4851 		mb,
4852 			XmNsubMenuId,	helpmenu,
4853 		NULL);
4854 	XtVaSetValues(mb, XmNmenuHelpWidget, w, NULL);
4855 
4856 	/*
4857 	 * Row- and column labels
4858 	 */
4859 	if (! columnwidths)
4860 		ResetColumnWidths();
4861 	SetRowColumnLabels();
4862 
4863 	/*
4864 	 * The main thing : BaeMatrix
4865 	 *
4866 	 * A couple of application resources determine how big the matrix
4867 	 * should be made.
4868 	 * FIX ME.
4869 	 */
4870 	mat = XtVaCreateManagedWidget("bae", xbaeMatrixWidgetClass, mw,
4871 			XmNrowLabels,		rowlabels,
4872 			XmNcolumnLabels,	columnlabels,
4873 			XmNcolumnWidths,	columnwidths,
4874 			XmNcolumnMaxLengths,	columnmaxlengths,
4875 			XmNrows,		AppRes.rows,
4876 			XmNcolumns,		AppRes.columns,
4877 		NULL);
4878 	XtAddCallback(mat, XmNleaveCellCallback, LeaveCell, NULL);
4879 	XtAddCallback(mat, XmNenterCellCallback, EnterCell, NULL);
4880 	XtAddCallback(mat, XmNmodifyVerifyCallback, ModifyVerify, NULL);
4881 	XtAddCallback(mat, XmNdrawCellCallback, DrawCell, NULL);
4882 	XtAddCallback(mat, XmNwriteCellCallback, WriteCell, NULL);
4883 	XtAddCallback(mat, XmNselectCellCallback, SelectCellCB, NULL);
4884 	XtAddCallback(mat, XmNresizeColumnCallback, ResizeColumnCB, NULL);
4885 #ifdef	XmNresizeRowCallback
4886 	XtAddCallback(mat, XmNresizeRowCallback, ResizeRowCB, NULL);
4887 #endif
4888 
4889 	/*
4890 	 * We're building a small combo of two widgets which will represent
4891 	 * one area in the MainWindow : a status area, and a formula editor.
4892 	 */
4893 	w = XtVaCreateManagedWidget("statusformula", xmFormWidgetClass,
4894 		mw,
4895 		NULL);
4896 	statustf = XtVaCreateManagedWidget("status", xmTextFieldWidgetClass,
4897 		w,
4898 			XmNeditable,		False,
4899 			XmNblinkRate,		0,
4900 		NULL);
4901 
4902 	formulatf = XtVaCreateManagedWidget("formula", xmTextFieldWidgetClass,
4903 		w,
4904 			XmNleftWidget,		statustf,
4905 			XmNleftOffset,		5,
4906 			XmNleftAttachment,	XmATTACH_WIDGET,
4907 		NULL);
4908 	XtAddCallback(formulatf, XmNactivateCallback, FormulaCB, 0);
4909 
4910 	/*
4911 	 * Oleo error messages
4912 	 */
4913 	msgtext = XmCreateScrolledText(mw, "messages", NULL, 0);
4914 	XtVaSetValues(mw,
4915 			XmNmessageWindow,	XtParent(msgtext),
4916 			XmNcommandWindow,	w,
4917 		NULL);
4918 	XtManageChild(msgtext);
4919 
4920 	if (Global->MotifGlobal->early_msg_text) {
4921 		XmTextSetString(msgtext, Global->MotifGlobal->early_msg_text);
4922 		free(Global->MotifGlobal->early_msg_text);
4923 		Global->MotifGlobal->early_msg_text = NULL;
4924 
4925 		XmTextShowPosition(msgtext, XmTextGetLastPosition(msgtext));
4926 		XBell(XtDisplay(msgtext), 30);
4927 	}
4928 
4929 	/*
4930 	 * Menu system contents :
4931 	 *	File Menu.
4932 	 */
4933 	w = XtVaCreateManagedWidget("new", xmPushButtonGadgetClass, filemenu,
4934 		NULL);
4935 	XtAddCallback(w, XmNactivateCallback, NewCB, NULL);
4936 
4937 	w = XtVaCreateManagedWidget("open", xmPushButtonGadgetClass, filemenu,
4938 		NULL);
4939 	XtAddCallback(w, XmNactivateCallback, OpenCB, NULL);
4940 
4941 	w = XtVaCreateManagedWidget("save", xmPushButtonGadgetClass, filemenu,
4942 		NULL);
4943 	XtAddCallback(w, XmNactivateCallback, SaveCB, NULL);
4944 
4945 	w = XtVaCreateManagedWidget("saveas", xmPushButtonGadgetClass, filemenu,
4946 		NULL);
4947 	XtAddCallback(w, XmNactivateCallback, SaveAsCB, NULL);
4948 
4949 	w = XtVaCreateManagedWidget("close", xmPushButtonGadgetClass, filemenu,
4950 		NULL);
4951 	XtAddCallback(w, XmNactivateCallback, CloseCB, NULL);
4952 
4953 	w = XtVaCreateManagedWidget("print", xmPushButtonGadgetClass, filemenu,
4954 		NULL);
4955 	XtAddCallback(w, XmNactivateCallback, printCB, NULL);
4956 
4957 	w = XtVaCreateManagedWidget("quit", xmPushButtonGadgetClass, filemenu,
4958 		NULL);
4959 	XtAddCallback(w, XmNactivateCallback, QuitCB, NULL);
4960 
4961 	/*
4962 	 *	Edit Menu.
4963 	 */
4964 	w = XtVaCreateManagedWidget("undo", xmPushButtonGadgetClass, editmenu,
4965 		NULL);
4966 	XtAddCallback(w, XmNactivateCallback, UndoCB, NULL);
4967 
4968 	XtVaCreateManagedWidget("sep1", xmSeparatorGadgetClass, editmenu,
4969 		NULL);
4970 
4971 	w = XtVaCreateManagedWidget("copy", xmPushButtonGadgetClass, editmenu,
4972 		NULL);
4973 	XtAddCallback(w, XmNactivateCallback, CopyCB, NULL);
4974 
4975 	w = XtVaCreateManagedWidget("cut", xmPushButtonGadgetClass, editmenu,
4976 		NULL);
4977 	XtAddCallback(w, XmNactivateCallback, CutCB, NULL);
4978 
4979 	w = XtVaCreateManagedWidget("paste", xmPushButtonGadgetClass, editmenu,
4980 		NULL);
4981 	XtAddCallback(w, XmNactivateCallback, PasteCB, NULL);
4982 
4983 	XtVaCreateManagedWidget("sep2", xmSeparatorGadgetClass, editmenu,
4984 		NULL);
4985 
4986 	w = XtVaCreateManagedWidget("sort", xmPushButtonGadgetClass, editmenu,
4987 		NULL);
4988 	XtAddCallback(w, XmNactivateCallback, none, NULL);
4989 
4990 	w = XtVaCreateManagedWidget("copyvalues", xmPushButtonGadgetClass,
4991 		editmenu,
4992 		NULL);
4993 	XtAddCallback(w, XmNactivateCallback, CopyValuesCB, NULL);
4994 
4995 	w = XtVaCreateManagedWidget("copyregion", xmPushButtonGadgetClass,
4996 		editmenu,
4997 		NULL);
4998 	XtAddCallback(w, XmNactivateCallback, CopyRegionCB, NULL);
4999 
5000 	w = XtVaCreateManagedWidget("move", xmPushButtonGadgetClass,
5001 		editmenu,
5002 		NULL);
5003 	XtAddCallback(w, XmNactivateCallback, MoveCB, NULL);
5004 
5005 	XtVaCreateManagedWidget("sep3", xmSeparatorGadgetClass, editmenu,
5006 		NULL);
5007 
5008 	w = XtVaCreateManagedWidget("insert", xmPushButtonGadgetClass,
5009 		editmenu,
5010 		NULL);
5011 	XtAddCallback(w, XmNactivateCallback, EditInsertCB, NULL);
5012 
5013 	w = XtVaCreateManagedWidget("delete", xmPushButtonGadgetClass,
5014 		editmenu,
5015 		NULL);
5016 	XtAddCallback(w, XmNactivateCallback, EditDeleteCB, NULL);
5017 
5018 	XtVaCreateManagedWidget("sep4", xmSeparatorGadgetClass, editmenu,
5019 		NULL);
5020 
5021 	w = XtVaCreateManagedWidget("recalculate", xmPushButtonGadgetClass,
5022 		editmenu,
5023 		NULL);
5024 	XtAddCallback(w, XmNactivateCallback, EditRecalculateCB, NULL);
5025 
5026 	XtVaCreateManagedWidget("sep5", xmSeparatorGadgetClass, editmenu,
5027 		NULL);
5028 
5029 	w = XtVaCreateManagedWidget("setregion", xmPushButtonGadgetClass,
5030 		editmenu,
5031 		NULL);
5032 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5033 
5034 	w = XtVaCreateManagedWidget("markcell", xmPushButtonGadgetClass,
5035 		editmenu,
5036 		NULL);
5037 	XtAddCallback(w, XmNactivateCallback, MarkCellCB, NULL);
5038 
5039 	w = XtVaCreateManagedWidget("markregion", xmPushButtonGadgetClass,
5040 		editmenu,
5041 		NULL);
5042 	XtAddCallback(w, XmNactivateCallback, MarkRegionCB, NULL);
5043 
5044 	w = XtVaCreateManagedWidget("setmark", xmPushButtonGadgetClass,
5045 		editmenu,
5046 		NULL);
5047 	XtAddCallback(w, XmNactivateCallback, MarkFromDialogCB, NULL);
5048 
5049 	w = XtVaCreateManagedWidget("gotocell", xmPushButtonGadgetClass,
5050 		editmenu,
5051 		NULL);
5052 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5053 
5054 
5055 	/*
5056 	 *	Style Menu.
5057 	 */
5058 	w = XtVaCreateManagedWidget("format", xmPushButtonGadgetClass,
5059 		stylemenu,
5060 		NULL);
5061 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5062 
5063 	w = XtVaCreateManagedWidget("alignment", xmPushButtonGadgetClass,
5064 		stylemenu,
5065 		NULL);
5066 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5067 
5068 	w = XtVaCreateManagedWidget("font", xmPushButtonGadgetClass,
5069 		stylemenu,
5070 		NULL);
5071 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5072 
5073 	XtVaCreateManagedWidget("sep1", xmSeparatorGadgetClass, stylemenu,
5074 		NULL);
5075 
5076 	w = XtVaCreateManagedWidget("width", xmPushButtonGadgetClass,
5077 		stylemenu,
5078 		NULL);
5079 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5080 
5081 	w = XtVaCreateManagedWidget("height", xmPushButtonGadgetClass,
5082 		stylemenu,
5083 		NULL);
5084 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5085 
5086 	XtVaCreateManagedWidget("sep2", xmSeparatorGadgetClass, stylemenu,
5087 		NULL);
5088 
5089 	w = XtVaCreateManagedWidget("protection", xmPushButtonGadgetClass,
5090 		stylemenu,
5091 		NULL);
5092 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5093 
5094 	/*
5095 	 *	Graph Menu.
5096 	 */
5097 	w = XtVaCreateManagedWidget("define", xmPushButtonGadgetClass,
5098 		graphmenu,
5099 		NULL);
5100 #ifdef	HAVE_LIBPLOT
5101 	XtAddCallback(w, XmNactivateCallback, ConfigureGraph, NULL);
5102 #else
5103 	XtAddCallback(w, XmNactivateCallback, NoPlotutils, NULL);
5104 #endif
5105 
5106 #ifdef	HAVE_SciPlot_H
5107 	w = XtVaCreateManagedWidget("show", xmPushButtonGadgetClass, graphmenu,
5108 		NULL);
5109 	XtAddCallback(w, XmNactivateCallback, ShowGraph, NULL);
5110 
5111 	w = XtVaCreateManagedWidget("print", xmPushButtonGadgetClass, graphmenu,
5112 		NULL);
5113 	XtAddCallback(w, XmNactivateCallback, PrintGraph, NULL);
5114 #endif
5115 
5116 #ifdef	HAVE_LIBPLOT
5117 	/* GNU Plotutils */
5118 	w = XtVaCreateManagedWidget("pulabel", xmLabelGadgetClass, graphmenu,
5119 		NULL);
5120 	w = XtVaCreateManagedWidget("pushowpie", xmPushButtonGadgetClass,
5121 		graphmenu,
5122 		NULL);
5123 	XtAddCallback(w, XmNactivateCallback, PuShowChart, PuPieChart);
5124 
5125 	w = XtVaCreateManagedWidget("pushowbar", xmPushButtonGadgetClass,
5126 		graphmenu,
5127 		NULL);
5128 	XtAddCallback(w, XmNactivateCallback, PuShowChart, PuBarChart);
5129 	w = XtVaCreateManagedWidget("pushowxy", xmPushButtonGadgetClass,
5130 		graphmenu,
5131 		NULL);
5132 	XtAddCallback(w, XmNactivateCallback, PuShowChart, PuXYChart);
5133 	w = XtVaCreateManagedWidget("puprintpie", xmPushButtonGadgetClass,
5134 		graphmenu,
5135 		NULL);
5136 	XtAddCallback(w, XmNactivateCallback, PuPrint, (XtPointer)GRAPH_PIE);
5137 	w = XtVaCreateManagedWidget("puprintbar", xmPushButtonGadgetClass,
5138 		graphmenu,
5139 		NULL);
5140 	XtAddCallback(w, XmNactivateCallback, PuPrint, (XtPointer)GRAPH_BAR);
5141 	w = XtVaCreateManagedWidget("puprintxy", xmPushButtonGadgetClass,
5142 		graphmenu,
5143 		NULL);
5144 	XtAddCallback(w, XmNactivateCallback, PuPrint, (XtPointer)GRAPH_XY);
5145 #endif
5146 
5147 
5148 	/*
5149 	 *	Options Menu.
5150 	 */
5151 	w = XtVaCreateManagedWidget("a0", xmToggleButtonGadgetClass,
5152 		optionsmenu,
5153 		NULL);
5154 	XtAddCallback(w, XmNvalueChangedCallback, ToggleA0, NULL);
5155 	XmToggleButtonGadgetSetState(w, Global->a0, False);
5156 
5157 	w = XtVaCreateManagedWidget("edges", xmToggleButtonGadgetClass,
5158 		optionsmenu,
5159 		NULL);
5160 	XtAddCallback(w, XmNvalueChangedCallback, none, NULL);
5161 	XmToggleButtonGadgetSetState(w, cwin->flags & WIN_EDGES, False);
5162 
5163 	w = XtVaCreateManagedWidget("autorecalc", xmToggleButtonGadgetClass,
5164 		optionsmenu,
5165 		NULL);
5166 	XtAddCallback(w, XmNvalueChangedCallback, none, NULL);
5167 	XmToggleButtonGadgetSetState(w, Global->auto_recalc, False);
5168 
5169 	w = XtVaCreateManagedWidget("loadhooks", xmToggleButtonGadgetClass,
5170 		optionsmenu,
5171 		NULL);
5172 	XtAddCallback(w, XmNvalueChangedCallback, none, NULL);
5173 	XmToggleButtonGadgetSetState(w, UserPreferences.run_load_hooks, False);
5174 
5175 	w = XtVaCreateManagedWidget("statusline", xmToggleButtonGadgetClass,
5176 		optionsmenu,
5177 		NULL);
5178 	XmToggleButtonGadgetSetState(w, Global->a0, False);
5179 	XtAddCallback(w, XmNvalueChangedCallback, none, NULL);
5180 
5181 	w = XtVaCreateManagedWidget("backup", xmToggleButtonGadgetClass,
5182 		optionsmenu,
5183 		NULL);
5184 	XmToggleButtonGadgetSetState(w, __make_backups, False);
5185 	XtAddCallback(w, XmNvalueChangedCallback, none, NULL);
5186 
5187 	w = XtVaCreateManagedWidget("backupcopy", xmToggleButtonGadgetClass,
5188 		optionsmenu,
5189 		NULL);
5190 	XmToggleButtonGadgetSetState(w, __backup_by_copying, False);
5191 	XtAddCallback(w, XmNvalueChangedCallback, none, NULL);
5192 
5193 	XtVaCreateManagedWidget("sep1", xmSeparatorGadgetClass, optionsmenu,
5194 		NULL);
5195 
5196 	w = XtVaCreateManagedWidget("formats", xmPushButtonGadgetClass,
5197 		optionsmenu,
5198 		NULL);
5199 	XtAddCallback(w, XmNactivateCallback, FormatsDialog, NULL);
5200 
5201 	w = XtVaCreateManagedWidget("defaultformat", xmPushButtonGadgetClass,
5202 		optionsmenu,
5203 		NULL);
5204 	XtAddCallback(w, XmNactivateCallback, FormatsDialog, (XtPointer) 1);
5205 
5206 	w = XtVaCreateManagedWidget("printoptions", xmPushButtonGadgetClass,
5207 		optionsmenu,
5208 		NULL);
5209 	XtAddCallback(w, XmNactivateCallback, PrintOptionsCB, NULL);
5210 
5211 	w = XtVaCreateManagedWidget("defaultfileformat",
5212 		xmPushButtonGadgetClass, optionsmenu,
5213 		NULL);
5214 	XtAddCallback(w, XmNactivateCallback, DefaultFileCB, NULL);
5215 
5216 	XtVaCreateManagedWidget("sep2", xmSeparatorGadgetClass, optionsmenu,
5217 		NULL);
5218 
5219 	w = XtVaCreateManagedWidget("setvariable", xmPushButtonGadgetClass,
5220 		optionsmenu,
5221 		NULL);
5222 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5223 
5224 	w = XtVaCreateManagedWidget("showvariable", xmPushButtonGadgetClass,
5225 		optionsmenu,
5226 		NULL);
5227 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5228 
5229 	w = XtVaCreateManagedWidget("listvariables", xmPushButtonGadgetClass,
5230 		optionsmenu,
5231 		NULL);
5232 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5233 
5234 	w = XtVaCreateManagedWidget("showoptions", xmPushButtonGadgetClass,
5235 		optionsmenu,
5236 		NULL);
5237 	XtAddCallback(w, XmNactivateCallback, none, NULL);
5238 
5239 	XtVaCreateManagedWidget("sep3", xmSeparatorGadgetClass, optionsmenu,
5240 		NULL);
5241 
5242 	w = XtVaCreateManagedWidget("userpreferences", xmPushButtonGadgetClass,
5243 		optionsmenu,
5244 		NULL);
5245 	XtAddCallback(w, XmNactivateCallback, DoUserPreferences, NULL);
5246 
5247 	w = XtVaCreateManagedWidget("saveuserpreferences", xmPushButtonGadgetClass,
5248 		optionsmenu,
5249 		NULL);
5250 	XtAddCallback(w, XmNactivateCallback, SaveUserPreferences, NULL);
5251 
5252 	/*
5253 	 * Database Access
5254 	 */
5255 	dbmenu = XmCreatePulldownMenu(mb, "dbmenu", NULL, 0);
5256 	XtManageChild(dbmenu);
5257 
5258 	w = XtVaCreateManagedWidget("dbcascade", xmCascadeButtonGadgetClass,
5259 		mb,
5260 			XmNsubMenuId,	dbmenu,
5261 		NULL);
5262 
5263 #ifdef	HAVE_LIBMYSQLCLIENT
5264 	w = XtVaCreateManagedWidget("configuremysql", xmPushButtonGadgetClass,
5265 		dbmenu,
5266 		NULL);
5267 	XtAddCallback(w, XmNactivateCallback, ConfigureMySQL, NULL);
5268 
5269 	w = XtVaCreateManagedWidget("readmysql", xmPushButtonGadgetClass,
5270 		dbmenu,
5271 		NULL);
5272 	XtAddCallback(w, XmNactivateCallback, DoMySQLRead, NULL);
5273 
5274 	w = XtVaCreateManagedWidget("writemysql", xmPushButtonGadgetClass,
5275 		dbmenu,
5276 		NULL);
5277 	XtAddCallback(w, XmNactivateCallback, DoMySQLWrite, NULL);
5278 #endif
5279 
5280 #if defined(HAVE_LIBMYSQLCLIENT) && defined(HAVE_LIBXBASE)
5281 	w = XtVaCreateManagedWidget("sep", xmSeparatorGadgetClass,
5282 		dbmenu,
5283 		NULL);
5284 #endif
5285 #if (! defined(HAVE_LIBMYSQLCLIENT)) && (! defined(HAVE_LIBXBASE))
5286 	/* This only happens if no db linked in */
5287 	w = XtVaCreateManagedWidget("nodbms", xmLabelGadgetClass,
5288 		dbmenu,
5289 		NULL);
5290 #endif
5291 
5292 #ifdef	HAVE_LIBXBASE
5293 	w = XtVaCreateManagedWidget("readxbase", xmPushButtonGadgetClass,
5294 		dbmenu,
5295 		NULL);
5296 	XtAddCallback(w, XmNactivateCallback, DoXbaseRead, NULL);
5297 
5298 	w = XtVaCreateManagedWidget("writexbase", xmPushButtonGadgetClass,
5299 		dbmenu,
5300 		NULL);
5301 	XtAddCallback(w, XmNactivateCallback, DoXbaseWrite, NULL);
5302 #endif
5303 
5304 	/*
5305 	 * Add test code here
5306 	 */
5307 #ifdef	HAVE_TEST
5308 	testmenu = XmCreatePulldownMenu(mb, "testmenu", NULL, 0);
5309 	XtManageChild(testmenu);
5310 
5311 	w = XtVaCreateManagedWidget("testcascade", xmCascadeButtonGadgetClass,
5312 		mb,
5313 			XmNsubMenuId,	testmenu,
5314 		NULL);
5315 
5316 	w = XtVaCreateManagedWidget("Traverse", xmPushButtonGadgetClass, testmenu,
5317 		NULL);
5318 	XtAddCallback(w, XmNactivateCallback, Traverse, NULL);
5319 
5320 	w = XtVaCreateManagedWidget("OpenNew", xmPushButtonGadgetClass, testmenu,
5321 		NULL);
5322 	XtAddCallback(w, XmNactivateCallback, OpenNewCB, NULL);
5323 
5324 	w = XtVaCreateManagedWidget("ExecuteCommand", xmPushButtonGadgetClass, testmenu,
5325 		NULL);
5326 	XtAddCallback(w, XmNactivateCallback, ExecuteCommandCB, NULL);
5327 
5328 #endif	/* HAVE_TEST */
5329 
5330 	/*
5331 	 *	Help Menu.
5332 	 */
5333 	w = XtVaCreateManagedWidget("about", xmPushButtonGadgetClass, helpmenu,
5334 		NULL);
5335 	XtAddCallback(w, XmNactivateCallback, helpAboutCB, NULL);
5336 
5337 	w = XtVaCreateManagedWidget("version", xmPushButtonGadgetClass,
5338 		helpmenu,
5339 		NULL);
5340 	XtAddCallback(w, XmNactivateCallback, helpVersionCB, NULL);
5341 
5342 	w = XtVaCreateManagedWidget("using", xmPushButtonGadgetClass, helpmenu,
5343 		NULL);
5344 	XtAddCallback(w, XmNactivateCallback, helpUsingCB, NULL);
5345 
5346 	XtVaCreateManagedWidget("sep1", xmSeparatorGadgetClass, helpmenu, NULL);
5347 
5348 	w = XtVaCreateManagedWidget("math", xmPushButtonGadgetClass, helpmenu,
5349 		NULL);
5350 	XtAddCallback(w, XmNactivateCallback, helpUsingCB,
5351 		"#HelpMathFunctions");
5352 
5353 	w = XtVaCreateManagedWidget("trig", xmPushButtonGadgetClass, helpmenu,
5354 		NULL);
5355 	XtAddCallback(w, XmNactivateCallback, helpUsingCB,
5356 		"#HelpTrigonometricFunctions");
5357 
5358 	w = XtVaCreateManagedWidget("stats", xmPushButtonGadgetClass, helpmenu,
5359 		NULL);
5360 	XtAddCallback(w, XmNactivateCallback, helpUsingCB,
5361 		"#HelpStatisticalFunctions");
5362 
5363 	w = XtVaCreateManagedWidget("bool", xmPushButtonGadgetClass, helpmenu,
5364 		NULL);
5365 	XtAddCallback(w, XmNactivateCallback, helpUsingCB,
5366 		"#HelpBooleanFunctions");
5367 
5368 	w = XtVaCreateManagedWidget("string", xmPushButtonGadgetClass, helpmenu,
5369 		NULL);
5370 	XtAddCallback(w, XmNactivateCallback, helpUsingCB,
5371 		"#HelpStringFunctions");
5372 
5373 	w = XtVaCreateManagedWidget("struct", xmPushButtonGadgetClass, helpmenu,
5374 		NULL);
5375 	XtAddCallback(w, XmNactivateCallback, helpUsingCB,
5376 		"#HelpStructuralFunctions");
5377 
5378 	w = XtVaCreateManagedWidget("search", xmPushButtonGadgetClass, helpmenu,
5379 		NULL);
5380 	XtAddCallback(w, XmNactivateCallback, helpUsingCB,
5381 		"#HelpSearchFunctions");
5382 
5383 	w = XtVaCreateManagedWidget("bus", xmPushButtonGadgetClass, helpmenu,
5384 		NULL);
5385 	XtAddCallback(w, XmNactivateCallback, helpUsingCB,
5386 		"#HelpBusinessFunctions");
5387 
5388 	w = XtVaCreateManagedWidget("date", xmPushButtonGadgetClass, helpmenu,
5389 		NULL);
5390 	XtAddCallback(w, XmNactivateCallback, helpUsingCB,
5391 		"#HelpDateFunctions");
5392 
5393 	XtVaCreateManagedWidget("sep2", xmSeparatorGadgetClass, helpmenu, NULL);
5394 
5395 	w = XtVaCreateManagedWidget("expr", xmPushButtonGadgetClass, helpmenu,
5396 		NULL);
5397 	XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpExpressions");
5398 
5399 	w = XtVaCreateManagedWidget("error", xmPushButtonGadgetClass, helpmenu,
5400 		NULL);
5401 	XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpErrorValues");
5402 
5403 	w = XtVaCreateManagedWidget("format", xmPushButtonGadgetClass, helpmenu,
5404 		NULL);
5405 	XtAddCallback(w, XmNactivateCallback, helpUsingCB, NULL);
5406 
5407 	w = XtVaCreateManagedWidget("option", xmPushButtonGadgetClass, helpmenu,
5408 		NULL);
5409 	XtAddCallback(w, XmNactivateCallback, helpUsingCB, "#HelpOptions");
5410 
5411 	return mw;
5412 }
5413 
5414 static void
xio_redraw_input_cursor(int on)5415 xio_redraw_input_cursor (int on)
5416 {
5417 #ifdef	VERBOSE
5418 	Debug(__FILE__, "xio_redraw_input_cursor\n");
5419 #endif
5420 }
5421 
5422 static void
xio_cellize_cursor(void)5423 xio_cellize_cursor (void)
5424 {
5425 #ifdef	VERBOSE
5426 	Debug(__FILE__, "xio_cellize_cursor\n");
5427 #endif
5428 	xio_redraw_input_cursor (0);
5429 }
5430 
5431 static void
xio_inputize_cursor(void)5432 xio_inputize_cursor (void)
5433 {
5434 #ifdef	VERBOSE
5435 	Debug(__FILE__, "xio_inputize_cursor\n");
5436 #endif
5437 	xio_redraw_input_cursor (1);
5438 }
5439 
5440 /* This redraws the input area without recomputing anything. */
5441 static void
xio_redraw_input(void)5442 xio_redraw_input (void)
5443 {
5444 #ifdef	VERBOSE
5445 	Debug(__FILE__, "xio_redraw_input\n");
5446 #endif
5447 }
5448 
5449 static void
xio_fix_input(void)5450 xio_fix_input (void)
5451 {
5452 #ifdef	VERBOSE
5453 	Debug(__FILE__, "xio_fix_input\n");
5454 #endif
5455 }
5456 
5457 static void
xio_move_cursor(void)5458 xio_move_cursor (void)
5459 {
5460 #ifdef	VERBOSE
5461 	Debug(__FILE__, "xio_move_cursor\n");
5462 #endif
5463 }
5464 
5465 static void
xio_erase(int len)5466 xio_erase (int len)
5467 {
5468 #ifdef	VERBOSE
5469 	Debug(__FILE__, "xio_erase\n");
5470 #endif
5471 }
5472 
5473 static void
xio_insert(int len)5474 xio_insert (int len)
5475 {
5476 #ifdef	VERBOSE
5477 	Debug(__FILE__, "xio_insert\n");
5478 #endif
5479 }
5480 
5481 static void
xio_over(char * str,int len)5482 xio_over (char * str, int len)
5483 {
5484 #ifdef	VERBOSE
5485 	Debug(__FILE__, "xio_over\n");
5486 #endif
5487 }
5488 
5489 static void
xio_scan_for_input(int blockp)5490 xio_scan_for_input (int blockp)
5491 {
5492 }
5493 
5494 static int
xio_input_avail(void)5495 xio_input_avail (void)
5496 {
5497 }
5498 
5499 static void
xio_wait_for_input(void)5500 xio_wait_for_input (void)
5501 {
5502 #ifdef	VERBOSE
5503 	Debug(__FILE__, "xio_wait_for_input ...\n");
5504 #endif
5505 }
5506 
5507 static int
xio_read_kbd(char * buffer,int size)5508 xio_read_kbd (char *buffer, int size)
5509 {
5510 	int amt_read = size < Global->MotifGlobal->chars_buffered ? size : Global->MotifGlobal->chars_buffered;
5511 #ifdef	VERBOSE
5512 	Debug(__FILE__, "xio_read_kbd ...\n");
5513 #endif
5514 	if (amt_read)
5515 		bcopy (Global->MotifGlobal->input_buf, (char *) buffer, amt_read);
5516 	Global->MotifGlobal->chars_buffered -= amt_read;
5517 	if (Global->MotifGlobal->chars_buffered)
5518 		bcopy ((char *) Global->MotifGlobal->input_buf + amt_read, (char *) Global->MotifGlobal->input_buf, Global->MotifGlobal->chars_buffered);
5519 	return amt_read;
5520 }
5521 
5522 static void
xio_nodelay(int delayp)5523 xio_nodelay (int delayp)
5524 {
5525 #ifdef	VERBOSE
5526 	Debug(__FILE__, "xio_nodelay ...\n");
5527 #endif
5528 }
5529 
5530 static int
xio_getch(void)5531 xio_getch (void)
5532 {
5533 #ifdef	VERBOSE
5534 	Debug(__FILE__, "xio_getch ...\n");
5535 #endif
5536 	return 0;
5537 }
5538 
5539 static void
xio_clear_input_before(void)5540 xio_clear_input_before (void)
5541 {
5542 #ifdef	VERBOSE
5543 	Debug(__FILE__, "xio_clear_input_before\n");
5544 #endif
5545 }
5546 
5547 static void
xio_clear_input_after(void)5548 xio_clear_input_after (void)
5549 {
5550 #ifdef	VERBOSE
5551 	Debug(__FILE__, "xio_clear_input_after\n");
5552 #endif
5553 }
5554 
5555 static void
UpdateStatus(void)5556 UpdateStatus(void)
5557 {
5558 	CELL	*cp;
5559 	char	buf[1024];
5560 	char	*ptr, *pos = buf, *dec;
5561 
5562 	if (!user_status) {
5563 		Debug(__FILE__, "UpdateStatus: no user_status\n");
5564 		return;
5565 	}
5566 
5567 	if (mkrow != NON_ROW) {
5568 		struct rng r;
5569 		*pos++ = '*';
5570 		set_rng (&r, curow, cucol, mkrow, mkcol);
5571 		ptr = range_name (&r);
5572 	} else
5573 		ptr = cell_name (curow, cucol);
5574 
5575 	strcpy(buf, ptr);
5576 
5577 	/* Put formula in its own widget */
5578 	if ((cp = find_cell (curow, cucol)) && cp->cell_formula) {
5579 		dec = decomp (curow, cucol, cp);
5580 		if (formulatf)
5581 			XmTextFieldSetString(formulatf, dec);
5582 	}
5583 
5584 	/* Value */
5585 	ptr = cell_value_string (curow, cucol, True);
5586 	if (ptr) {
5587 		strcat(buf, " [");
5588 		strcat(buf, ptr);
5589 		strcat(buf, "]");
5590 	}
5591 
5592 	if (statustf)
5593 		XmTextFieldSetString(statustf, buf);
5594 }
5595 
5596 /*
5597  * Copy the spreadsheet values into Xbae
5598  * Then do an event loop until there are no more input events.
5599  */
5600 static void
xio_update_status(void)5601 xio_update_status (void)
5602 {
5603 	XEvent	ev;
5604 
5605 	UpdateStatus();
5606 
5607 
5608 #ifdef	VERBOSEx
5609 	Debug(__FILE__, "xio_update_status(%d,%d)...", curow, cucol);
5610 #endif
5611 
5612 	while (XtAppPending(app)) {
5613 		XtAppNextEvent(app, &ev);
5614 		(void) XtDispatchEvent(&ev);
5615 	}
5616 
5617 #ifdef	VERBOSEx
5618 	Debug(__FILE__, " done\n");
5619 #endif
5620 }
5621 
5622 static int
xio_get_chr(char * prompt)5623 xio_get_chr (char *prompt)
5624 {
5625 #ifdef	VERBOSE
5626 	Debug(__FILE__, "xio_get_chr(%s)\n", prompt);
5627 #endif
5628 
5629 	MessageAppend(True, prompt);
5630 	return io_getch ();
5631 }
5632 
5633 static void
xio_pr_cell_win(struct window * win,CELLREF r,CELLREF c,CELL * cp)5634 xio_pr_cell_win (struct window *win, CELLREF r, CELLREF c, CELL *cp)
5635 {
5636 #ifdef	VERBOSEx
5637 	Debug(__FILE__, "xio_pr_cell_win\n");
5638 #endif
5639 }
5640 
5641 static void
xio_repaint_win(struct window * win)5642 xio_repaint_win (struct window *win)
5643 {
5644 #ifdef	VERBOSEx
5645 	Debug(__FILE__, "xio_repaint_win\n");
5646 #endif
5647 }
5648 
5649 
5650 static void
xio_repaint(void)5651 xio_repaint (void)
5652 {
5653 #ifdef	VERBOSEx
5654 	Debug(__FILE__, "xio_repaint\n");
5655 #endif
5656 }
5657 
5658 
5659 static void
xio_hide_cell_cursor(void)5660 xio_hide_cell_cursor (void)
5661 {
5662 #ifdef	VERBOSEx
5663 	Debug(__FILE__, "xio_hide_cell_cursor\n");
5664 #endif
5665 }
5666 
5667 static void
xio_display_cell_cursor(void)5668 xio_display_cell_cursor (void)
5669 {
5670 #ifdef	VERBOSEx
5671 	Debug(__FILE__, "xio_display_cell_cursor\n");
5672 #endif
5673 }
5674 
5675 /* Refresh the existing image. */
5676 
5677 static void
xio_redisp(void)5678 xio_redisp (void)
5679 {
5680 #ifdef	VERBOSE
5681 	Debug(__FILE__, "xio_redisp\n");
5682 #endif
5683 }
5684 
5685 extern void
xio_close_display(int e)5686 xio_close_display(int e)
5687 {
5688 #ifdef	VERBOSE
5689 	Debug(__FILE__, "xio_close_display\n");
5690 #endif
5691 	if (toplevel && XtDisplay(toplevel)) {
5692 		XtDestroyWidget(toplevel);
5693 	}
5694 
5695 	toplevel = NULL;
5696 }
5697 
5698 static void
xio_flush(void)5699 xio_flush (void)
5700 {
5701 #if 0
5702 	XFlush (theDisplay);
5703 #endif
5704 }
5705 
5706 
5707 static void
xio_bell(void)5708 xio_bell (void)
5709 {
5710 #if 0
5711 	XBell (XtDisplay(toplevel), 30);
5712 	XFlush (XtDisplay(toplevel));
5713 #endif
5714 }
5715 
5716 extern void
xio_open_display(void)5717 xio_open_display (void)
5718 {
5719 #ifdef	VERBOSE
5720 	Debug(__FILE__, "xio_open_display\n");
5721 #endif
5722 }
5723 
5724 int
io_col_to_input_pos(int c)5725 io_col_to_input_pos (int c)
5726 {
5727 #if 1
5728   Debug(__FILE__, "io_col_to_input_pos\n");
5729   return 0;
5730 #else
5731   struct input_view * iv = &thePort->input_view;
5732   char * prompt = (iv->expanded_keymap_prompt
5733 		   ? iv->expanded_keymap_prompt
5734 		   : (iv->prompt ? iv->prompt : ""));
5735   int prompt_wid = iv->prompt_metric (prompt, strlen(prompt));
5736 
5737   c -= prompt_wid;
5738   {
5739     int cpos;
5740     int max = iv->visibility_end - iv->visibility_begin + 1;
5741     for (cpos = 1; cpos <= max; ++cpos)
5742       if (iv->input_metric (iv->input_area->buf + iv->visibility_begin, cpos)
5743 	  >= c)
5744 	break;
5745     return iv->visibility_begin + cpos - 1;
5746   }
5747 #endif
5748 }
5749 
5750 void
set_x_default_point_size(int l)5751 set_x_default_point_size (int l)
5752 {
5753   /* If the display is not open (ie, we're running on a non x screen, */
5754   /* silently return - allows stuff in startup file to work right.PGA */
5755   if (!toplevel)
5756     return;
5757 }
5758 
5759 void
xio_command_loop(int i)5760 xio_command_loop (int i)
5761 {
5762 	XtAppMainLoop(app);
5763 }
5764 
PopDownSplash()5765 void PopDownSplash()
5766 {
5767 	if (SplashShell)
5768 		XtDestroyWidget(SplashShell);
5769 	SplashShell = 0;
5770 }
5771 
MotifGlobalInitialize(void)5772 void MotifGlobalInitialize(void)
5773 {
5774 	if (Global->MotifGlobal)
5775 		return;
5776 
5777 	Global->MotifGlobal = (struct MotifGlobalType *)XtMalloc(sizeof(struct MotifGlobalType));
5778 	memset(Global->MotifGlobal, 0, sizeof(struct MotifGlobalType));
5779 
5780 	Global->MotifGlobal->input_buf_allocated = 1024;
5781 	strcpy(Global->MotifGlobal->fileformat, "oleo");
5782 	Global->MotifGlobal->havea0 = -1;
5783 	Global->MotifGlobal->selectedcells = NULL;
5784 	Global->MotifGlobal->newcall = True;
5785 	Global->MotifGlobal->needrecalculate = False;
5786 }
5787 
motif_init(int * argc,char ** argv)5788 void motif_init(int *argc, char **argv)
5789 {
5790 	Display	*dpy;
5791 
5792 	MotifGlobalInitialize();
5793 
5794 	io_command_loop = xio_command_loop;
5795 	io_open_display = xio_open_display;
5796 	io_redisp = xio_redisp;
5797 	io_repaint = xio_repaint;
5798 	io_repaint_win = xio_repaint_win;
5799 	io_close_display = xio_close_display;
5800 	io_input_avail = xio_input_avail;
5801 	io_scan_for_input = xio_scan_for_input;
5802 	io_wait_for_input = xio_wait_for_input;
5803 	io_read_kbd = xio_read_kbd;
5804 	io_nodelay = xio_nodelay;
5805 	io_getch = xio_getch;
5806 	io_bell = xio_bell;
5807 	io_get_chr = xio_get_chr;
5808 	io_update_status = xio_update_status;
5809 	io_fix_input = xio_fix_input;
5810 	io_move_cursor = xio_move_cursor;
5811 	io_erase = xio_erase;
5812 	io_insert = xio_insert;
5813 	io_over = xio_over;
5814 	io_flush = xio_flush;
5815 	io_clear_input_before = xio_clear_input_before;
5816 	io_clear_input_after = xio_clear_input_after;
5817 	io_pr_cell_win = xio_pr_cell_win;
5818 	io_hide_cell_cursor = xio_hide_cell_cursor;
5819 	io_display_cell_cursor = xio_display_cell_cursor;
5820 	io_cellize_cursor = xio_cellize_cursor;
5821 	io_inputize_cursor = xio_inputize_cursor;
5822 
5823 	/*
5824 	 * XAPPLRESDIR is a variable that can be set to determine
5825 	 *	where to find an application resource file.
5826 	 * If it isn't defined yet, let's define one so the odds are
5827 	 *	good for finding our (i18n) application resources.
5828 	 */
5829 #ifndef	APPLRESDIR
5830 #define	APPLRESDIR	HTMLDIR
5831 #endif
5832 
5833 	if (getenv("XAPPLRESDIR") == NULL) {
5834 #ifdef	HAVE_PUTENV
5835 		putenv("XAPPLRESDIR=" APPLRESDIR);
5836 #endif
5837 	}
5838 
5839 	/*
5840 	 * Open a connection to the display and create a toplevel shell widget.
5841 	 */
5842 	XtToolkitInitialize();
5843 	app = XtCreateApplicationContext();
5844 	XtAppSetFallbackResources(app, fallback);
5845 	dpy = XtOpenDisplay(app, NULL, PACKAGE, PACKAGE,
5846 		/* options */		NULL, 0,
5847 		/* command line */	argc, argv);
5848 
5849 	toplevel = XtVaAppCreateShell(PACKAGE, PACKAGE,
5850 		topLevelShellWidgetClass, dpy, NULL);
5851 	RegisterWMClose(toplevel);
5852 	XtVaSetValues(toplevel, XmNdeleteResponse, XmDO_NOTHING, NULL);
5853 
5854 	/*
5855 	 * Add converter for tearoffs.
5856 	 */
5857 #if XmVersion >= 1002
5858 	XmRepTypeInstallTearOffModelConverter();
5859 #endif
5860 
5861 	XtVaGetApplicationResources(toplevel, &AppRes,
5862 		resources, num_resources,
5863 		NULL);
5864 
5865 	if (AppRes.show_version > 0) {
5866 		long	t = AppRes.show_version;
5867 
5868 		SplashShell = GscBuildSplash(toplevel);
5869 		XtPopup(SplashShell, XtGrabNone);
5870 
5871 		/* Splash remains on screen for configurable time (milliseconds) */
5872 		XtAppAddTimeOut(app, t, PopDownSplash, 0);
5873 	}
5874 
5875 	/* Without this we have NULL in cwin. */
5876 	io_init_windows(AppRes.rows, AppRes.columns, 1, 2, 1, 1, 1, 1);
5877 }
5878 
RaiseSplash()5879 void RaiseSplash()
5880 {
5881 	/* This needs to be triggered by a timeout because otherwise it won't work */
5882 
5883 	if (SplashShell)
5884 		XRaiseWindow(XtDisplay(SplashShell), XtWindow(SplashShell));
5885 }
5886 
motif_build_gui(void)5887 void motif_build_gui(void)
5888 {
5889 	RegisterWMClose(toplevel);
5890 	XtVaSetValues(toplevel, XmNdeleteResponse, XmDO_NOTHING, NULL);
5891 
5892 	w = GscBuildMainWindow(toplevel);
5893 	XtManageChild(w);
5894 	XtRealizeWidget(toplevel);
5895 
5896 #ifdef	HAVE_LIBXPM
5897 	XtVaSetValues(toplevel, XmNiconPixmap, Global->MotifGlobal->oleo_icon_pm, NULL);
5898 #endif
5899 
5900 	if (AppRes.show_version > 0) {
5901 		/* 30ms is an arbitrary short value. 1 probably works as well. */
5902 		XtAppAddTimeOut(app, 30L, RaiseSplash, 0);
5903 	}
5904 
5905 	if (! XmProcessTraversal(mat, XmTRAVERSE_CURRENT)) {
5906 		fprintf(stderr, _("XmProcessTraversal failed\n"));
5907 	}
5908 
5909 	if (Global->MotifGlobal->needrecalculate) {
5910 		recalculate(1);
5911 	}
5912 
5913 }
5914 
ReallyQuit(Widget w,XtPointer client,XtPointer call)5915 void ReallyQuit(Widget w, XtPointer client, XtPointer call)
5916 {
5917 	kill_oleo();
5918 }
5919 
QuitCB(Widget w,XtPointer client,XtPointer call)5920 void QuitCB(Widget w, XtPointer client, XtPointer call)
5921 {
5922 	Widget		md;
5923 	Arg		al[4];
5924 	int		ac;
5925 
5926 	MotifSelectGlobal(w);
5927 
5928 	/* FIX ME this should work on all open files */
5929 	MdiQuit();
5930 
5931 	if (Global->modified && !option_filter) {
5932 		XmString xms = XmStringCreateLtoR(
5933 			_("There are unsaved changes.\n"
5934 			  "Do you want to quit anyway ?"),
5935 			XmFONTLIST_DEFAULT_TAG);
5936 
5937 		ac = 0;
5938 		/* Application resource for message allow i18n */
5939 		XtSetArg(al[ac], XmNmessageString, xms); ac++;
5940 
5941 		md = XmCreateQuestionDialog(toplevel, "quitMB", al, ac);
5942 		XtAddCallback(md, XmNokCallback, ReallyQuit, NULL);
5943 		XtDestroyWidget(XmMessageBoxGetChild(md,
5944 			XmDIALOG_HELP_BUTTON));
5945 		XtManageChild(md);
5946 		XmStringFree(xms);
5947 		return;
5948 	}
5949 
5950 	kill_oleo();
5951 }
5952 
5953 static char *gpl_string =
5954 #include "gpl.h"
5955 ;
5956 
gplCB(Widget w,XtPointer client,XtPointer call)5957 void gplCB(Widget w, XtPointer client, XtPointer call)
5958 {
5959 	Widget		x, t, p;
5960 	Arg		al[4];
5961 	int		ac;
5962 
5963 	MotifSelectGlobal(w);
5964 
5965 	ac = 0;
5966 	XtSetArg(al[ac], XmNautoUnmanage, False); ac++;
5967 	x = XmCreateTemplateDialog(toplevel, "versionD", al, ac);
5968 
5969 	ac = 0;
5970 	XtSetArg(al[ac], XmNeditable, False); ac++;
5971 	t = XmCreateScrolledText(x, "gpl", al, ac);
5972 	XtManageChild(t);
5973 
5974 	XmTextSetString(t, gpl_string);
5975 
5976 	ac = 0;
5977 	p = XmCreatePushButtonGadget(x, "ok", al, ac);
5978 	XtManageChild(p);
5979 	XtAddCallback(p, XmNactivateCallback, DestroyTemplate, x);
5980 
5981 	XtManageChild(x);
5982 }
5983 
versionCB(Widget w,XtPointer client,XtPointer call)5984 void versionCB(Widget w, XtPointer client, XtPointer call)
5985 {
5986 	Widget		x;
5987 	XmString	xms, xms1, xms2;
5988 	Arg		al[2];
5989 	int		ac;
5990 	char		xbae[64];
5991 
5992 	MotifSelectGlobal(w);
5993 
5994 	xms1 = XmStringCreateLtoR(GNU_PACKAGE " " VERSION,
5995 		XmFONTLIST_DEFAULT_TAG);
5996 	xms2 = XmStringCreateLtoR(CopyRightString, XmFONTLIST_DEFAULT_TAG);
5997 	xms = XmStringConcat(xms1, xms2);
5998 	XmStringFree(xms1);
5999 	XmStringFree(xms2);
6000 
6001 	/* Now add info about libraries used */
6002 	xms1 = xms;
6003 	xms2 = XmStringCreateLtoR("\n\nLibraries used :", XmFONTLIST_DEFAULT_TAG);
6004 	xms = XmStringConcat(xms1, xms2);
6005 	XmStringFree(xms1);
6006 	XmStringFree(xms2);
6007 
6008 	xms1 = xms;
6009 	xms2 = XmStringCreateLtoR("\n  " XmVERSION_STRING, XmFONTLIST_DEFAULT_TAG);
6010 	xms = XmStringConcat(xms1, xms2);
6011 	XmStringFree(xms1);
6012 	XmStringFree(xms2);
6013 
6014 #if XbaeVersion > 40800
6015 	sprintf(xbae, "\n  %s", XbaeGetVersionTxt());
6016 #else
6017 	sprintf(xbae, "\n  Xbae %d", XbaeVersion);
6018 #endif
6019 	xms1 = xms;
6020 	xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG);
6021 	xms = XmStringConcat(xms1, xms2);
6022 	XmStringFree(xms1);
6023 	XmStringFree(xms2);
6024 
6025 #ifdef	HAVE_XmHTML_H
6026 	xms1 = xms;
6027 	xms2 = XmStringCreateLtoR("\n  " XmHTMLVERSION_STRING, XmFONTLIST_DEFAULT_TAG);
6028 	xms = XmStringConcat(xms1, xms2);
6029 	XmStringFree(xms1);
6030 	XmStringFree(xms2);
6031 #endif
6032 
6033 #ifdef	HAVE_SciPlot_H
6034 	sprintf(xbae, "\n  SciPlot %f", _SCIPLOT_WIDGET_VERSION);
6035 	xms1 = xms;
6036 	xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG);
6037 	xms = XmStringConcat(xms1, xms2);
6038 	XmStringFree(xms1);
6039 	XmStringFree(xms2);
6040 #endif
6041 
6042 #ifdef	HAVE_LIBMYSQLCLIENT
6043 	sprintf(xbae, "\n  MySQL %s", MYSQL_SERVER_VERSION);
6044 	xms1 = xms;
6045 	xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG);
6046 	xms = XmStringConcat(xms1, xms2);
6047 	XmStringFree(xms1);
6048 	XmStringFree(xms2);
6049 #endif
6050 
6051 #ifdef	HAVE_LIBCUPS
6052 	sprintf(xbae, "\n  CUPS %f", CUPS_VERSION);
6053 	xms1 = xms;
6054 	xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG);
6055 	xms = XmStringConcat(xms1, xms2);
6056 	XmStringFree(xms1);
6057 	XmStringFree(xms2);
6058 #endif
6059 
6060 #ifdef	HAVE_LIBPLOT
6061 #if defined(PL_LIBPLOT_VER_STRING)
6062 	sprintf(xbae, "\n  GNU PlotUtils (libplot version %s)", PL_LIBPLOT_VER_STRING);
6063 #else
6064 	sprintf(xbae, "\n  GNU PlotUtils (libplot version %s)", LIBPLOT_VERSION);
6065 #endif
6066 	xms1 = xms;
6067 	xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG);
6068 	xms = XmStringConcat(xms1, xms2);
6069 	XmStringFree(xms1);
6070 	XmStringFree(xms2);
6071 #endif
6072 
6073 #if defined(HAVE_LIBXDB)
6074     {
6075 	extern char	*oleoXdbVersion();
6076 	char	*v = oleoXdbVersion();
6077 
6078 	if (v) {
6079 		sprintf(xbae, "\n  XBase library version %s", v);
6080 		xms1 = xms;
6081 		xms2 = XmStringCreateLtoR(xbae, XmFONTLIST_DEFAULT_TAG);
6082 		xms = XmStringConcat(xms1, xms2);
6083 		XmStringFree(xms1);
6084 		XmStringFree(xms2);
6085 	}
6086     }
6087 #endif
6088 
6089 	ac = 0;
6090 	XtSetArg(al[0], XmNmessageString, xms); ac++;
6091 	x = XmCreateMessageDialog(toplevel, "versionD", al, ac);
6092 
6093 	XtAddCallback(x, XmNhelpCallback, gplCB, NULL);
6094 
6095 	XmStringFree(xms);
6096 	XtManageChild(x);
6097 }
6098 
6099 /*
6100  * These are necessary from io-x11.c
6101  */
get_x11_args(int * argc_p,char ** argv)6102 void get_x11_args (int * argc_p, char ** argv)
6103 {
6104 }
6105 
x11_graphics(void)6106 void x11_graphics(void)
6107 {
6108 }
6109 
motif_main_loop(void)6110 void motif_main_loop(void)
6111 {
6112 	XtAppMainLoop(app);
6113 }
6114 
6115 /*
6116  *
6117  */
6118 static void
MotifSelectGlobal(Widget w)6119 MotifSelectGlobal(Widget w)
6120 {
6121 	Widget	p;
6122 
6123 	for (p=w; XtParent(p); p=XtParent(p)) ;
6124 
6125 	MdiSelectGlobal(offsetof(struct OleoGlobal, MotifGlobal),
6126 		offsetof(struct MotifGlobalType, toplevel_w),
6127 		p);
6128 }
6129 
6130 void
ActivateCellWidget(Widget w,XtPointer client,XtPointer call)6131 ActivateCellWidget(Widget w, XtPointer client, XtPointer call)
6132 {
6133 	char	*cell_name = (char *)client;
6134 
6135 	execute_command(cell_name);
6136 }
6137 
6138 void
MotifButton(int r,int c,char * lbl,char * cmd)6139 MotifButton(int r, int c, char *lbl, char *cmd)
6140 {
6141 	Widget	button;
6142 	char	*command;
6143 
6144 	if (mat == 0) {
6145 		Global->MotifGlobal->needrecalculate = True;
6146 		return;
6147 	}
6148 
6149 #if XbaeVersion > 4007
6150 	if (XbaeMatrixGetCellWidget(mat, r-1, c-1) == NULL) {
6151 		button = XtVaCreateManagedWidget(lbl, xmPushButtonWidgetClass, mat, NULL);
6152 		XbaeMatrixSetCellWidget(mat, r-1, c-1, button);
6153 
6154 		command = strdup(cmd);
6155 		XtAddCallback(button, XmNactivateCallback, ActivateCellWidget, (XtPointer)command);
6156 
6157 		fprintf(stderr, "MotifButton(%d,%d,%s,%s)\n", r-1, c-1, lbl, command);
6158 	}
6159 #endif
6160 }
6161