The R Project SVN R

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4394 ripley 1
/*
2
 * GraphApp - Cross-Platform Graphics Programming Library.
3
 *
4
 * File: dialogs.c -- standard file dialogs and a few others.
5
 * Platform: Windows  Version: 2.42  Date: 1998/07/07
6
 *
7
 * Version: 1.00  Changes: Original version by Lachlan Patrick.
8
 * Version: 1.50  Changes: Uses new rectangles, callbacks.
9
 * Version: 2.20  Changes: Handle null strings correctly now.
10
 * Version: 2.40  Changes: Now uses YES, NO, CANCEL symbols.
11
 * Version: 2.42  Changes: Askstring fixed by Laurent Piguet.
12
 */
13
 
14
/* Copyright (C) 1993-1998 Lachlan Patrick
15
 
16
   This file is part of GraphApp, a cross-platform C graphics library.
17
 
18
   GraphApp is free software; you can redistribute it and/or modify it
19
   under the terms of the GNU Library General Public License.
20
   GraphApp is distributed in the hope that it will be useful, but
21
   WITHOUT ANY WARRANTY.
22
 
23
   See the file COPYLIB.TXT for details.
24
*/
25
 
26
#include "internal.h"
27
 
22842 murdoch 28
#define BUFSIZE _MAX_PATH
29
static char strbuf[BUFSIZE];
4394 ripley 30
 
31
static char *filter[] = {
32
	"All Files (*.*)",	"*.*",
33
	"Text Files (*.TXT)",	"*.txt",
34
	"HTML Files (*.HTM)",	"*.htm",
6509 ripley 35
	"PNG Files (*.PNG)",	"*.png",
4394 ripley 36
	"JPEG Files (*.JPG)",	"*.jpg",
37
	"BMP Files (*.BMP)",	"*.bmp",
38
	""
39
};
40
 
41
static char *userfilter;
42
void setuserfilter(char *uf) {
43
   userfilter=uf;
44
}
45
 
46
/*
47
 *  Error reporting dialog.
48
 */
49
void apperror(char *errstr)
50
{
51
	if (! errstr)
52
		errstr = "Unspecified error";
53
	MessageBox(0, errstr, "Graphics Library Error",
54
		MB_TASKMODAL | MB_ICONSTOP | MB_OK);
55
	exitapp();
56
}
57
 
58
void askok(char *info)
59
{
60
	if (! info)
61
		info = "";
62
	MessageBox(0, info, "Information",
63
		MB_TASKMODAL | MB_ICONINFORMATION | MB_OK);
64
}
65
 
66
int askokcancel(char *question)
67
{
68
	int result;
69
 
70
	if (! question)
71
		question = "";
72
	result = MessageBox(0, question, "Question",
73
		MB_TASKMODAL | MB_ICONQUESTION | MB_OKCANCEL);
74
 
75
	switch (result) {
76
		case IDOK: result = YES; break;
77
		case IDCANCEL:
78
		default: result = CANCEL; break;
79
	}
80
	return result;
81
}
82
 
83
int askyesno(char *question)
84
{
85
	int result;
86
 
87
	if (! question)
88
		question = "";
89
	result = MessageBox(0, question, "Question",
90
		MB_TASKMODAL | MB_ICONQUESTION | MB_YESNO);
91
 
92
	switch (result) {
93
		case IDYES: result = YES; break;
94
		case IDNO:  result = NO; break;
95
		default: result = CANCEL; break;
96
	}
97
	return result;
98
}
99
 
100
int askyesnocancel(char *question)
101
{
102
	int result;
103
 
104
	if (! question)
105
		question = "";
106
	result = MessageBox(0, question, "Question",
107
		MB_TASKMODAL | MB_ICONQUESTION | MB_YESNOCANCEL);
108
 
109
	switch (result) {
110
		case IDYES: result = YES; break;
111
		case IDNO:  result = NO; break;
112
		case IDCANCEL:
113
		default: result = CANCEL; break;
114
	}
115
	return result;
116
}
117
 
118
static char cod[MAX_PATH]=""; /*current open directory*/
119
 
120
void askchangedir()
121
{
4606 ripley 122
    char *s, msg[MAX_PATH + 40];
123
 
124
/* if cod has never been used, set it to current directory */
125
    if (!cod[0]) GetCurrentDirectory(MAX_PATH, cod);
126
    s = askcdstring(" Change working directory to:", cod);
127
    if (s && (SetCurrentDirectory(s) == FALSE)) {
25313 ripley 128
	snprintf(msg, MAX_PATH + 40,
129
		 "Unable to set '%s' as working directory", s);
4606 ripley 130
	askok(msg);
131
    }
132
    /* in every case reset cod (to new directory if all went ok
133
       or to old since user may have edited it */
134
    GetCurrentDirectory(MAX_PATH, cod);
4394 ripley 135
}
136
 
137
char *askfilename(char *title, char *default_name)
138
{
22872 murdoch 139
	if (*askfilenames(title, default_name, 0, userfilter?userfilter:filter[0], 0,
140
				          strbuf, BUFSIZE)) return strbuf;
141
	else return NULL;
4394 ripley 142
}
143
 
22872 murdoch 144
char *askfilenames(char *title, char *default_name, int multi,
145
			       char *filters, int filterindex, char *strbuf, int bufsize)
22842 murdoch 146
{
147
	int i;
148
	OPENFILENAME ofn;
149
        char cwd[MAX_PATH]="";
150
	if (! default_name)
151
		default_name = "";
152
	strcpy(strbuf, default_name);
153
        GetCurrentDirectory(MAX_PATH,cwd);
154
        if (!strcmp(cod,"")) strcpy(cod,cwd);
155
 
156
	ofn.lStructSize     = sizeof(OPENFILENAME);
157
	ofn.hwndOwner       = current_window ?
158
				current_window->handle : 0;
159
	ofn.hInstance       = 0;
22872 murdoch 160
    ofn.lpstrFilter     = filters;
22842 murdoch 161
	ofn.lpstrCustomFilter = NULL;
162
	ofn.nMaxCustFilter  = 0;
22872 murdoch 163
	ofn.nFilterIndex    = filterindex;
22842 murdoch 164
	ofn.lpstrFile       = strbuf;
165
	ofn.nMaxFile        = bufsize;
166
	ofn.lpstrFileTitle  = NULL;
167
	ofn.nMaxFileTitle   = _MAX_FNAME + _MAX_EXT;
168
        ofn.lpstrInitialDir = cod;
169
	ofn.lpstrTitle      = title;
22872 murdoch 170
	ofn.Flags           = OFN_CREATEPROMPT | OFN_HIDEREADONLY | OFN_EXPLORER;
171
	if (multi) ofn.Flags |= OFN_ALLOWMULTISELECT;
22842 murdoch 172
	ofn.nFileOffset     = 0;
173
	ofn.nFileExtension  = 0;
174
	ofn.lpstrDefExt     = "*";
175
	ofn.lCustData       = 0L;
176
	ofn.lpfnHook        = NULL;
177
	ofn.lpTemplateName  = NULL;
178
 
179
	if (GetOpenFileName(&ofn) == 0) {
180
		GetCurrentDirectory(MAX_PATH,cod);
181
		SetCurrentDirectory(cwd);
182
		strbuf[0] = 0;
183
		strbuf[1] = 0;
184
		return strbuf;
185
	} else {
186
		GetCurrentDirectory(MAX_PATH,cod);
187
		SetCurrentDirectory(cwd);
188
		for (i=0; i<10; i++)
189
			if (peekevent()) doevent();
190
		return strbuf;
191
	}
192
}
193
 
194
int countFilenames(char *list)
195
{
196
	char *temp;
197
	int count;
198
	count = 0;
199
	for (temp = list; *temp; temp += strlen(temp)+1) count++;
200
	return count;
201
}
202
 
4394 ripley 203
char *askfilesave(char *title, char *default_name)
204
{
8707 ripley 205
    return askfilesavewithdir(title, default_name, NULL);
206
}
207
 
208
char *askfilesavewithdir(char *title, char *default_name, char *dir)
209
{
4394 ripley 210
	int i;
211
	OPENFILENAME ofn;
212
        char cwd[MAX_PATH];
213
 
214
	if (! default_name)
215
		default_name = "";
216
	strcpy(strbuf, default_name);
217
 
218
	ofn.lStructSize     = sizeof(OPENFILENAME);
219
	ofn.hwndOwner       = current_window ?
220
				current_window->handle : 0;
221
	ofn.hInstance       = 0;
222
        ofn.lpstrFilter     = userfilter?userfilter:filter[0];
223
	ofn.lpstrCustomFilter = NULL;
224
	ofn.nMaxCustFilter  = 0;
225
	ofn.nFilterIndex    = 0;
226
	ofn.lpstrFile       = strbuf;
22842 murdoch 227
	ofn.nMaxFile        = BUFSIZE;
4394 ripley 228
	ofn.lpstrFileTitle  = NULL;
229
	ofn.nMaxFileTitle   = _MAX_FNAME + _MAX_EXT;
8707 ripley 230
	if(dir && strlen(dir) > 0)
231
	    ofn.lpstrInitialDir = dir;
232
	else {
233
	    if (GetCurrentDirectory(MAX_PATH,cwd))
234
		ofn.lpstrInitialDir = cwd;
235
	    else
236
		ofn.lpstrInitialDir = NULL;
237
	}
4394 ripley 238
	ofn.lpstrTitle      = title;
239
	ofn.Flags           = OFN_OVERWRITEPROMPT |
240
                              OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
241
	ofn.nFileOffset     = 0;
242
	ofn.nFileExtension  = 0;
243
	ofn.lpstrDefExt     = "*";
244
	ofn.lCustData       = 0L;
245
	ofn.lpfnHook        = NULL;
246
	ofn.lpTemplateName  = NULL;
247
 
248
	if (GetSaveFileName(&ofn) == 0)
249
		return NULL;
250
	else {
251
		for (i=0; i<10; i++)
252
			if (peekevent()) doevent();
253
		return strbuf;
254
	}
255
}
256
 
257
/*
258
 *  Input a string using a dialog box.
259
 */
260
 
261
/*
262
 *  Dialog information structure:
263
 */
264
	#define NOT_CHOSEN_YET -2
265
 
266
	typedef struct dialog_data_class {
267
		int 	hit;
268
		char *	result;
269
		label	question;
22785 ripley 270
		field	text, pass;
4394 ripley 271
		button	yes, no, cancel;
272
	} dialog_data;
273
 
274
	#define data(w) ((dialog_data *) (getdata(w)))
275
 
276
/*
277
 *  Some strings to use:
278
 */
4606 ripley 279
	static char * OKAY_STRING	= "OK";
4394 ripley 280
	static char * CANCEL_STRING	= "Cancel";
4606 ripley 281
	static char * BROWSE_STRING	= "Browse";
4394 ripley 282
 
283
	static char * QUESTION_TITLE	= "Question";
284
	static char * PASSWORD_TITLE	= "Password Entry";
4606 ripley 285
	static char * FINDDIR_TITLE	= "Change directory";
4394 ripley 286
 
287
static void add_data(window w)
288
{
289
	dialog_data *d;
290
 
291
	d = create (dialog_data);
292
	if (! d)
293
		return;
294
	d->hit = NOT_CHOSEN_YET;
295
 
296
	setdata(w, d);
297
}
298
 
299
static char * get_dialog_string(window w)
300
{
301
	dialog_data *d = data(w);
302
 
303
	if (d->hit < YES) /* cancelled */
304
		return NULL;
305
	del_string(d->result);
306
	if (d->text)	/* question dialog */
307
		d->result = new_string(gettext(d->text));
308
 
309
	return d->result;
310
}
311
 
312
static void hit_button(control c)
313
{
314
	window w = parentwindow(c);
315
	dialog_data *d = data(w);
316
	int value = getvalue(c);
317
 
318
	d->hit = value;
319
	hide(w);
320
}
321
 
15268 ripley 322
#ifndef OLD
323
extern void selectfolder(char *); /* from ../shext.c */
324
 
4606 ripley 325
static void browse_button(control c)
326
{
327
    window w = parentwindow(c);
328
    dialog_data *d = data(w);
15268 ripley 329
    char strbuf[MAX_PATH];
23715 murdoch 330
    strcpy(strbuf, gettext(d->text));
15268 ripley 331
    selectfolder(strbuf);
332
    if(strlen(strbuf)) settext(d->text, strbuf);
333
}
334
#else
335
static void browse_button(control c)
336
{
337
    window w = parentwindow(c);
338
    dialog_data *d = data(w);
4606 ripley 339
 
340
    OPENFILENAME ofn;
22842 murdoch 341
    char strbuf[_MAX_PATH]="anything", *p;
4606 ripley 342
 
343
    ofn.lStructSize     = sizeof(OPENFILENAME);
344
    ofn.hwndOwner       = 0;
345
    ofn.hInstance       = 0;
346
    ofn.lpstrFilter     = "All files (*.*)\0*.*\0\0";
347
    ofn.lpstrCustomFilter = NULL;
348
    ofn.nMaxCustFilter  = 0;
349
    ofn.nFilterIndex    = 0;
350
    ofn.lpstrFile       = strbuf;
351
    ofn.nMaxFile        = _MAX_PATH;
352
    ofn.lpstrFileTitle  = NULL;
353
    ofn.nMaxFileTitle   = _MAX_FNAME + _MAX_EXT;
354
    ofn.lpstrInitialDir = gettext(d->text);
355
    ofn.lpstrTitle      = "Select working directory";
356
    ofn.Flags           = OFN_HIDEREADONLY;
357
    ofn.nFileOffset     = 0;
358
    ofn.nFileExtension  = 0;
359
    ofn.lpstrDefExt     = "";
360
    ofn.lCustData       = 0L;
361
    ofn.lpfnHook        = NULL;
362
    ofn.lpTemplateName  = NULL;
363
 
364
    if(GetSaveFileName(&ofn) && strlen(strbuf)) {
365
	 p = strrchr(strbuf,'\\'); if(p) *p ='\0';
366
	 settext(d->text, strbuf);
367
    }
368
}
15268 ripley 369
#endif
4606 ripley 370
 
4394 ripley 371
static void hit_key(window w, int key)
372
{
373
	button btn;
374
	char *name = NULL;
375
 
376
	w = parentwindow(w);
377
 
378
	if (data(w) == NULL)
379
		return;
380
 
381
	if ((btn = data(w)->yes) != NULL) {
382
		name = getname(btn);
383
		if ((key == '\n') || (tolower(name[0]) == tolower(key)))
384
		{
385
			flashcontrol(btn);
386
			activatecontrol(btn);
387
			return;
388
		}
389
	}
390
 
391
	if ((btn = data(w)->cancel) != NULL) {
392
		name = getname(btn);
393
		if ((key == ESC) || (tolower(name[0]) == tolower(key)))
394
		{
395
			flashcontrol(btn);
396
			activatecontrol(btn);
397
			return;
398
		}
399
	}
400
 
401
	if ((btn = data(w)->no) != NULL) {
402
		name = getname(btn);
403
		if ((key == ESC) || (tolower(name[0]) == tolower(key)))
404
		{
405
			flashcontrol(btn);
406
			activatecontrol(btn);
407
			return;
408
		}
409
	}
410
 
411
}
412
 
413
/*
414
 *  Handle the events from a message dialog, hide the window afterwards.
415
 */
416
static int handle_message_dialog(window w)
417
{
418
	window old;
419
	dialog_data *d = data(w);
420
 
421
	old = currentdrawing();
422
	d->hit = NOT_CHOSEN_YET;
423
 
424
	show(w);
425
	while (d->hit == NOT_CHOSEN_YET)
426
		doevent();
427
	hide(w);
428
 
429
	if (old) drawto(old);
430
 
431
	return d->hit;
432
}
433
 
8707 ripley 434
static window init_askstr_dialog(char *title, char *question,
4394 ripley 435
				 char *default_str)
436
{
437
	window win;
438
	dialog_data *d;
439
	int tw, bw, h, middle;
440
 
441
	if (! question)
442
		question= "";
443
	if (! default_str)
444
		default_str = "";
445
 
446
	tw = strwidth(SystemFont, CANCEL_STRING) * 8;
447
	h = getheight(SystemFont);
448
 
449
	if (tw < 150) tw = 150;
450
 
451
	win = newwindow(title, rect(0,0,tw+30,h*9+12),
452
			Titlebar | Centered | Modal);
18082 ripley 453
        setbackground(win, dialog_bg());
4394 ripley 454
	add_data(win);
455
	d = data(win);
456
	d->question = newlabel(question, rect(10,h,tw+4,h*2+2),
457
			AlignLeft);
4606 ripley 458
	if (title == FINDDIR_TITLE) {
459
	    bw = strwidth(SystemFont, BROWSE_STRING) * 3/2;
460
	    d->text = newfield(default_str, rect(10,h*4,tw+4-bw,h*3/2));
8707 ripley 461
	    newbutton(BROWSE_STRING, rect(20+tw-bw, h*4-2, bw, h+10),
4606 ripley 462
		      browse_button);
463
	}
464
	else if (title == PASSWORD_TITLE)
4394 ripley 465
		d->text = newpassword(default_str, rect(10,h*4,tw+4,h*3/2));
466
	else
467
		d->text = newfield(default_str, rect(10,h*4,tw+4,h*3/2));
468
 
469
	middle = (tw+30)/2;
470
	bw = strwidth(SystemFont, CANCEL_STRING) * 3/2;
471
 
472
	d->yes = newbutton(OKAY_STRING,
4606 ripley 473
			rect(middle-bw-10, h*7, bw, h+10), hit_button);
4394 ripley 474
	setvalue(d->yes, YES);
475
 
476
	d->cancel = newbutton(CANCEL_STRING,
4606 ripley 477
			rect(middle+10, h*7, bw, h+10), hit_button);
4394 ripley 478
	setvalue(d->cancel, CANCEL);
479
 
480
	setkeydown(win, hit_key);
481
 
482
	return win;
483
}
484
 
485
char *askstring(char *question, char *default_str)
486
{
487
	static window win = NULL;
488
	window prev = current_window;
489
 
490
	if (! win)
491
		win = init_askstr_dialog(QUESTION_TITLE, question, default_str);
492
	else {
493
		settext(data(win)->question, question);
494
		settext(data(win)->text, default_str);
495
	}
496
	handle_message_dialog(win);
497
	current_window = prev;
498
	return get_dialog_string(win);
499
}
500
 
4606 ripley 501
char *askcdstring(char *question, char *default_str)
502
{
503
	static window win = NULL;
504
	window prev = current_window;
505
 
506
	if (! win)
507
		win = init_askstr_dialog(FINDDIR_TITLE, question, default_str);
508
	else {
509
		settext(data(win)->question, question);
510
		settext(data(win)->text, default_str);
511
	}
512
	handle_message_dialog(win);
513
	current_window = prev;
514
	return get_dialog_string(win);
515
}
516
 
4394 ripley 517
char *askpassword(char *question, char *default_str)
518
{
519
	static window win = NULL;
520
	window prev = current_window;
521
 
522
	if (! win)
523
		win = init_askstr_dialog(PASSWORD_TITLE, question, default_str);
524
	else {
525
		settext(data(win)->question, question);
526
		settext(data(win)->text, default_str);
527
	}
528
	handle_message_dialog(win);
529
	current_window = prev;
530
	return get_dialog_string(win);
531
}
532
 
22785 ripley 533
char *askUserPass(char *title)
534
{
535
    static window win = NULL;
536
    dialog_data *d;
537
    window prev = current_window;
538
 
539
    if (! win) {
540
	int tw, bw, h, middle;
541
 
542
	tw = strwidth(SystemFont, CANCEL_STRING) * 8;
543
	h = getheight(SystemFont);
544
	if (tw < 150) tw = 150;
545
	win = newwindow(title, rect(0, 0, tw+30, h*9+12),
546
			Titlebar | Centered | Modal);
547
        setbackground(win, dialog_bg());
548
	add_data(win);
549
	d = data(win);
550
	d->question = newlabel("User", rect(10, h, tw+4, h*2+2), AlignLeft);
551
	bw = strwidth(SystemFont, "Password");
552
	d->text = newfield("", rect(20+bw, h, tw-6-bw, h*3/2));
553
	newlabel("Password", rect(10, h*4, tw+4, h*2+2), AlignLeft);
554
	d->pass = newpassword("", rect(20+bw, h*4, tw-6-bw, h*3/2));
555
	middle = (tw+30)/2;
556
	bw = strwidth(SystemFont, CANCEL_STRING) * 3/2;
557
 
558
	d->yes = newbutton(OKAY_STRING,
559
			rect(middle-bw-10, h*7, bw, h+10), hit_button);
560
	setvalue(d->yes, YES);
561
 
562
	d->cancel = newbutton(CANCEL_STRING,
563
			rect(middle+10, h*7, bw, h+10), hit_button);
564
	setvalue(d->cancel, CANCEL);
565
 
566
	setkeydown(win, hit_key);
567
    } else {
568
	d = data(win);
569
	settext(d->text, "");
570
	settext(d->pass, "");
571
    }
572
    handle_message_dialog(win);
573
    current_window = prev;
574
    {
575
	char *user, *pass;
576
	static char buf[1000];
577
	if (d->hit < YES) /* cancelled */ return "";
578
	if (d->text) user = new_string(gettext(d->text));
579
	else return "";
580
	if (d->pass) pass = new_string(gettext(d->pass));
581
	else return "";
25313 ripley 582
	snprintf(buf, 1000, "%s:%s", user, pass);
22785 ripley 583
	return buf;
584
    }
585
    return ""; /* -Wall */
586
}