1 /*
2  * Copyright (c) 1996 Michael J. Hammel <mjhammel@csn.net>
3  *
4  * This program is free software; you can redistribute it and/or modify          * it under the terms of the GNU General Public License as published by          * the Free Software Foundation; either version 2 of the License, or             * (at your option) any later version.                                           *
5  * This program is distributed in the hope that it will be useful,               * but WITHOUT ANY WARRANTY; without even the implied warranty of                * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 * GNU General Public License for more details.                                  *
6  * You should have received a copy of the GNU General Public License             * along with this program; if not, write to the Free Software                   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                     *
7  * insert.c - routines to handle special inserts into a note
8  *
9  */
10 
11 #include <X11/StringDefs.h>
12 #include <X11/Intrinsic.h>
13 #include <X11/Xaw/Form.h>
14 #include <X11/Xaw/Box.h>
15 #include <X11/Xaw/Label.h>
16 #include <X11/Xaw/Command.h>
17 #include <X11/Xaw/Text.h>
18 #include <X11/Xaw/AsciiText.h>
19 #include <X11/Shell.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <time.h>
24 
25 #include "xpostit.h"
26 
27 /* globals */
28 
29 /* local variables */
30 static Widget 		insert_widget;
31 static Widget		insert_boxes[12];
32 static Widget		insert_buttons[3];
33 static Widget		insert_leftarrows[11];
34 static int			active_item;
35 
36 /* external variables */
37 extern Widget			toplevel;
38 
39 /* external routines */
40 extern PostItNote	*FindNote();
41 extern InsertText();
42 void InsertPopDown();
43 void InsertAccept();
44 void InsertCancel();
45 void InsertLeftArrowCB();
46 
47 /*
48  * CreateInsertPrompt - create a prompt for insert information
49  */
50 void
CreateInsertPrompt(pn)51 CreateInsertPrompt(pn)
52 PostItNote 	*pn;
53 {
54 	Arg 				args[30];
55 	register int 	nargs;
56 	XtCallbackRec	callbacks[2];
57 
58 	Widget		insert_form;
59 	Widget		insert_forms[12];
60 	Widget		insert_labels[11];
61 	Dimension	width;
62 	Window 		root, child;
63 	int 			root_x, root_y, child_x, child_y;
64 	int			i;
65 	unsigned int 	buttons;
66 
67 	/* initialize marker */
68 	active_item=0;
69 
70 	/* get mouse location */
71 	XQueryPointer(display, XtWindow(toplevel), &root, &child,
72 		      &root_x, &root_y, &child_x, &child_y, &buttons);
73 
74 	/*
75 	 * Create a popup shell widget
76 	 */
77 	nargs = 0;
78 	SetArg(XtNtitle, PostItInsertPrompt);
79 	SetArg(XtNx, root_x);
80 	SetArg(XtNy, root_y);
81 	insert_widget = XtCreatePopupShell(
82 			"InsertShell",
83 			transientShellWidgetClass,
84 			toplevel,
85 			args, nargs);
86 
87 	/* the form inside which all other windows will be put */
88 	nargs = 0;
89 	SetArg(XtNborderWidth, 0);
90 	insert_form = XtCreateManagedWidget(
91 			"InsertForm",
92 			formWidgetClass,
93 			insert_widget,
94 			args, nargs);
95 
96 	/* the boxes, one for each line of input */
97 	for ( i=0; i<12; i++)
98 	{
99 		nargs = 0;
100 		SetArg( XtNborderWidth, 0);
101 		SetArg( XtNtop, XtChainTop );
102 		SetArg( XtNbottom, XtChainTop );
103 		SetArg( XtNleft, XtChainLeft );
104 		SetArg( XtNright, XtChainLeft );
105 		SetArg( XtNvertDistance, 0 );
106 		SetArg( XtNhorizDistance, 0 );
107 		SetArg( XtNdefaultDistance, 0 );
108 		SetArg( XtNorientation, XtorientHorizontal );
109 		SetArg( XtNvSpace, 0 );
110 		SetArg( XtNhSpace, 0 );
111 		if ( i!= 0 )
112 		{
113 			SetArg( XtNfromVert, insert_boxes[i-1] );
114 		}
115 		insert_boxes[i] = XtCreateManagedWidget(
116 				"InsertBox",
117 				boxWidgetClass,
118 				insert_form,
119 				args, nargs);
120 	}
121 
122 	/*
123 	 * the forms, one for each box, which provides constraints
124 	 * for other windows inside that box.
125 	 */
126 	nargs = 0;
127 	SetArg(XtNborderWidth, 0);
128 	for ( i=0; i<11; i++)
129 	{
130 		insert_forms[i] = XtCreateManagedWidget(
131 			"InsertForm",
132 			formWidgetClass,
133 			insert_boxes[i],
134 			args, nargs);
135 	}
136 
137 	/*
138 	 * The selection button in each box
139 	 */
140 	for ( i=0; i<11; i++)
141 	{
142 		bzero(callbacks, sizeof(callbacks));
143 		SetCallback(InsertLeftArrowCB, (XtPointer)i);
144 		nargs = 0;
145 		SetArg( XtNcallback, callbacks);
146 		SetArg( XtNlabel, "-");
147 		SetArg( XtNborderWidth, 1);
148 		SetArg( XtNtop, XtChainTop );
149 		SetArg( XtNbottom, XtChainTop );
150 		SetArg( XtNleft, XtChainLeft );
151 		SetArg( XtNright, XtChainLeft );
152 		SetArg( XtNvertDistance, 0 );
153 		SetArg( XtNhorizDistance, 0 );
154 		SetArg( XtNdefaultDistance, 0 );
155 		SetArg( XtNshapeStyle, XmuShapeRectangle );
156 		insert_leftarrows[i] = XtCreateManagedWidget(
157 			"InsertArrow",
158 			commandWidgetClass,
159 			insert_forms[i],
160 			args, nargs);
161 	}
162 
163 	/* The labels of each box */
164 	for ( i=0; i<11; i++)
165 	{
166 		nargs = 0;
167 		SetArg( XtNborderWidth, 0);
168 		SetArg( XtNtop, XtChainTop );
169 		SetArg( XtNbottom, XtChainTop );
170 		SetArg( XtNleft, XtChainLeft );
171 		SetArg( XtNright, XtChainLeft );
172 		SetArg( XtNfromHoriz, insert_leftarrows[i] );
173 		SetArg( XtNvertDistance, 0 );
174 		SetArg( XtNhorizDistance, 0 );
175 		SetArg( XtNdefaultDistance, 0 );
176 		SetArg( XtNshapeStyle, XmuShapeRectangle );
177 		switch(i)
178 		{
179 			case 0: SetArg(XtNlabel, "mm/dd/yy"); break;
180 			case 1: SetArg(XtNlabel, "<mm/dd/yy>"); break;
181 			case 2: SetArg(XtNlabel, "(mm/dd/yy)"); break;
182 			case 3: SetArg(XtNlabel, "mm/dd/yy - hh:mm"); break;
183 			case 4: SetArg(XtNlabel, "mm/dd/yy(hh:mm)"); break;
184 			case 5: SetArg(XtNlabel, "Jan 1, 1996"); break;
185 			case 6: SetArg(XtNlabel, "Jan 1, 1996 - hh:mm"); break;
186 			case 7: SetArg(XtNlabel, "Jan 1, 1996 (hh:mm)"); break;
187 			case 8: SetArg(XtNlabel, "Tuesday Jan 1, 1996"); break;
188 			case 9: SetArg(XtNlabel, "Tuesday Jan 1, 1996 - hh:mm"); break;
189 			case 10: SetArg(XtNlabel, "Tuesday Jan 1, 1996 (hh:mm)"); break;
190 		}
191 		insert_labels[i] = XtCreateManagedWidget(
192 			"InsertLabel",
193 			labelWidgetClass,
194 			insert_forms[i],
195 			args, nargs);
196 	}
197 
198 	/*
199 	 * now make all the labels the same width
200 	 */
201 	nargs = 0;
202 	SetArg( XtNwidth, &width);
203 
204 	/* ugly - hard code the longest box! */
205 	XtGetValues ( insert_labels[9], args, nargs );
206 
207 	nargs = 0;
208 	SetArg( XtNwidth, width);
209 	SetArg( XtNjustify, XtJustifyLeft);
210 	for ( i=0; i<11; i++)
211 	{
212 		XtSetValues ( insert_labels[i], args, nargs );
213 	}
214 
215 
216 	/*
217 	 * create the Cancel/Accept command buttons
218 	 */
219 	bzero(callbacks, sizeof(callbacks));
220 	SetCallback(InsertAccept, (XtPointer)pn);
221 	nargs = 0;
222 	SetArg(XtNcallback, callbacks);
223 	SetArg(XtNlabel, "Accept");
224 	insert_buttons[1] = XtCreateManagedWidget(
225 		"InsertButtons",
226 		commandWidgetClass,
227 		insert_boxes[11],
228 		args, nargs);
229 
230 	bzero(callbacks, sizeof(callbacks));
231 	SetCallback(InsertCancel, (XtPointer)pn);
232 	nargs = 0;
233 	SetArg(XtNcallback, callbacks);
234 	SetArg(XtNlabel, "Cancel");
235 	insert_buttons[0] = XtCreateManagedWidget(
236 		"InsertButtons",
237 		commandWidgetClass,
238 		insert_boxes[11],
239 		args, nargs);
240 
241 	XtPopup( insert_widget, XtGrabNonexclusive );
242 }
243 
244 /*
245  * InsertAccept - Accept selected date value
246  *	This routine has the potential to be very OS specific.
247  */
248 void
InsertAccept(w,client_data,call_data)249 InsertAccept(w, client_data, call_data)
250 caddr_t client_data, call_data;
251 Widget w;
252 {
253 	PostItNote 	*pn = (PostItNote *)client_data;
254 	char			cmd[1024];
255 	time_t		time_tp;
256 	struct tm	*tm_tp;
257 	char			dayname[12];
258 	char			year[5];
259 	char			month[10];
260 
261 	/* get todays date and current time */
262 	time(&time_tp);
263 	tm_tp = localtime(&time_tp);
264 
265 	/*
266 	 * convert numeric values to strings now, even if we don't use them,
267 	 * since we need these in more than one place.
268 	 */
269 	switch ( tm_tp->tm_wday )
270 	{
271 		case 0:	sprintf(dayname, "Sunday"); break;
272 		case 1:	sprintf(dayname, "Monday"); break;
273 		case 2:	sprintf(dayname, "Tuesday"); break;
274 		case 3:	sprintf(dayname, "Wednesday"); break;
275 		case 4:	sprintf(dayname, "Thursday"); break;
276 		case 5:	sprintf(dayname, "Friday"); break;
277 		case 6:	sprintf(dayname, "Saturday"); break;
278 	}
279 	switch ( tm_tp->tm_mon )
280 	{
281 		case 0: sprintf(month, "Jan"); break;
282 		case 1: sprintf(month, "Feb"); break;
283 		case 2: sprintf(month, "Mar"); break;
284 		case 3: sprintf(month, "Apr"); break;
285 		case 4: sprintf(month, "May"); break;
286 		case 5: sprintf(month, "Jun"); break;
287 		case 6: sprintf(month, "Jul"); break;
288 		case 7: sprintf(month, "Aug"); break;
289 		case 8: sprintf(month, "Sept"); break;
290 		case 9: sprintf(month, "Oct"); break;
291 		case 10: sprintf(month, "Nov"); break;
292 		case 11: sprintf(month, "Dec"); break;
293 	}
294 	if ( tm_tp->tm_year > 100 )
295 		sprintf(year,"20");
296 	else
297 		sprintf(year,"19");
298 
299 	switch (active_item)
300 	{
301 		case 0:
302 			sprintf (cmd,
303 				"%02d/%02d/%02d", tm_tp->tm_mon, tm_tp->tm_mday, tm_tp->tm_year );
304 			break;
305 
306 		case 1:
307 			sprintf (cmd,
308 				"<%02d/%02d/%02d>", tm_tp->tm_mon, tm_tp->tm_mday, tm_tp->tm_year );
309 			break;
310 
311 		case 2:
312 			sprintf (cmd,
313 				"(%02d/%02d/%02d)", tm_tp->tm_mon, tm_tp->tm_mday, tm_tp->tm_year );
314 			break;
315 
316 		case 3:
317 			sprintf (cmd,
318 				"%02d/%02d/%02d - %02d:%02d",
319 				tm_tp->tm_mon, tm_tp->tm_mday, tm_tp->tm_year,
320 				tm_tp->tm_hour, tm_tp->tm_min );
321 			break;
322 
323 		case 4:
324 			sprintf (cmd,
325 				"%02d/%02d/%02d(%02d:%02d)",
326 				tm_tp->tm_mon, tm_tp->tm_mday, tm_tp->tm_year,
327 				tm_tp->tm_hour, tm_tp->tm_min );
328 			break;
329 
330 		case 5:
331 			sprintf (cmd,
332 				"%s %d, %s%d", month, tm_tp->tm_mday, year, tm_tp->tm_year);
333 			break;
334 
335 		case 6:
336 			sprintf (cmd,
337 				"%s %d, %s%d - %02d:%02d",
338 				month, tm_tp->tm_mday, year, tm_tp->tm_year,
339 				tm_tp->tm_hour, tm_tp->tm_min );
340 			break;
341 
342 		case 7:
343 			sprintf (cmd,
344 				"%s %d, %s%d (%02d:%02d)",
345 				month, tm_tp->tm_mday, year, tm_tp->tm_year,
346 				tm_tp->tm_hour, tm_tp->tm_min );
347 			break;
348 
349 		case 8:
350 			sprintf (cmd,
351 				"%s %s %d, %s%d",
352 				dayname, month, tm_tp->tm_mday, year, tm_tp->tm_year);
353 			break;
354 
355 		case 9:
356 			sprintf (cmd,
357 				"%s %s %d, %s%d - %02d:%02d",
358 				dayname, month, tm_tp->tm_mday, year, tm_tp->tm_year,
359 				tm_tp->tm_hour, tm_tp->tm_min );
360 			break;
361 
362 		case 10:
363 			sprintf (cmd,
364 				"%s %s %d, %s%d (%02d:%02d)",
365 				dayname, month, tm_tp->tm_mday, year, tm_tp->tm_year,
366 				tm_tp->tm_hour, tm_tp->tm_min );
367 			break;
368 
369 	}
370 
371 	/* stuff the output into the note */
372 	InsertText(pn, cmd, False, TEXT_TYPE);
373 
374 	XtSetSensitive ( pn->pn_savewidget, True );
375 	InsertPopDown();
376 }
377 
378 /*
379  * InsertCancel - Cancel an insert
380  */
381 void
InsertCancel(w,client_data,call_data)382 InsertCancel(w, client_data, call_data)
383 caddr_t client_data, call_data;
384 Widget w;
385 {
386 	InsertPopDown();
387 }
388 
389 /*
390  * InsertPopDown - removes the Insert Dialog box
391  */
392 void
InsertPopDown()393 InsertPopDown()
394 {
395 	XtPopdown( insert_widget );
396 	XtDestroyWidget(insert_widget);
397 
398 }
399 
400 
401 /*
402  * InsertLeftArrowcB - handle a left arrow click
403  */
404 void
InsertLeftArrowCB(w,client_data,call_data)405 InsertLeftArrowCB(w, client_data, call_data)
406 caddr_t client_data, call_data;
407 Widget w;
408 {
409 	int	nargs;
410 	Arg	args[3];
411 
412 	nargs=0;
413 	SetArg( XtNlabel, ">");
414 	XtSetValues ( insert_leftarrows[(int)client_data], args, nargs );
415 
416 	active_item=(int)client_data;
417 }
418