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
 
37592 murdoch 26
/* Copyright (C) 2004--2006 	The R Foundation
28991 murdoch 27
 
28
   Additions for R, Chris Jackson
29
   Find and replace dialog boxes and dialog handlers */
30
 
33091 ripley 31
#define ENABLE_NLS 1
32
#include "../win-nls.h"
4394 ripley 33
#include "internal.h"
28991 murdoch 34
#include "ga.h"
29159 murdoch 35
#include "../shext.h"		/* for selectfolder */
4394 ripley 36
 
22842 murdoch 37
#define BUFSIZE _MAX_PATH
38
static char strbuf[BUFSIZE];
4394 ripley 39
 
40
static char *filter[] = {
41
	"All Files (*.*)",	"*.*",
42
	"Text Files (*.TXT)",	"*.txt",
43
	"HTML Files (*.HTM)",	"*.htm",
6509 ripley 44
	"PNG Files (*.PNG)",	"*.png",
4394 ripley 45
	"JPEG Files (*.JPG)",	"*.jpg",
46
	"BMP Files (*.BMP)",	"*.bmp",
47
	""
48
};
49
 
28854 murdoch 50
unsigned int TopmostDialogs = 0; /* May be MB_TOPMOST */
51
 
4394 ripley 52
static char *userfilter;
53
void setuserfilter(char *uf) {
54
   userfilter=uf;
55
}
56
 
28991 murdoch 57
static HWND hModelessDlg = NULL;
58
 
36921 ripley 59
int myMessageBox(HWND h, char *text, char *caption, UINT type)
60
{
36938 ripley 61
    if(is_NT && (localeCP != GetACP())) {
36921 ripley 62
	wchar_t wc[1000], wcaption[100];
63
	mbstowcs(wcaption, caption, 100);
64
	mbstowcs(wc, text, 1000);
65
	return MessageBoxW(h, wc, wcaption, type);
66
    } else
67
	return MessageBoxA(h, text, caption, type);
68
}
69
 
4394 ripley 70
/*
71
 *  Error reporting dialog.
72
 */
73
void apperror(char *errstr)
74
{
75
	if (! errstr)
76
		errstr = "Unspecified error";
36921 ripley 77
	myMessageBox(0, errstr, "Graphics Library Error",
28854 murdoch 78
		MB_TASKMODAL | MB_ICONSTOP | MB_OK | TopmostDialogs);
4394 ripley 79
	exitapp();
80
}
81
 
82
void askok(char *info)
83
{
84
	if (! info)
85
		info = "";
36921 ripley 86
	myMessageBox(0, info, "Information",
28854 murdoch 87
		MB_TASKMODAL | MB_ICONINFORMATION | MB_OK | TopmostDialogs);
4394 ripley 88
}
89
 
90
int askokcancel(char *question)
91
{
92
	int result;
93
 
94
	if (! question)
95
		question = "";
36921 ripley 96
	result = myMessageBox(0, question, G_("Question"),
28854 murdoch 97
		MB_TASKMODAL | MB_ICONQUESTION | MB_OKCANCEL | TopmostDialogs);
4394 ripley 98
 
99
	switch (result) {
100
		case IDOK: result = YES; break;
101
		case IDCANCEL:
102
		default: result = CANCEL; break;
103
	}
104
	return result;
105
}
106
 
107
int askyesno(char *question)
108
{
109
	int result;
110
 
111
	if (! question)
112
		question = "";
36921 ripley 113
	result = myMessageBox(0, question, G_("Question"),
28854 murdoch 114
		MB_TASKMODAL | MB_ICONQUESTION | MB_YESNO | TopmostDialogs);
4394 ripley 115
 
116
	switch (result) {
117
		case IDYES: result = YES; break;
118
		case IDNO:  result = NO; break;
119
		default: result = CANCEL; break;
120
	}
121
	return result;
122
}
123
 
124
int askyesnocancel(char *question)
125
{
126
	int result;
127
 
128
	if (! question)
129
		question = "";
36921 ripley 130
	result = myMessageBox(0, question, G_("Question"),
28854 murdoch 131
		MB_TASKMODAL | MB_ICONQUESTION | MB_YESNOCANCEL | MB_SETFOREGROUND | TopmostDialogs);
4394 ripley 132
 
133
	switch (result) {
134
		case IDYES: result = YES; break;
135
		case IDNO:  result = NO; break;
136
		case IDCANCEL:
137
		default: result = CANCEL; break;
138
	}
139
	return result;
140
}
141
 
142
static char cod[MAX_PATH]=""; /*current open directory*/
143
 
144
void askchangedir()
145
{
4606 ripley 146
    char *s, msg[MAX_PATH + 40];
147
 
148
/* if cod has never been used, set it to current directory */
149
    if (!cod[0]) GetCurrentDirectory(MAX_PATH, cod);
33088 ripley 150
    s = askcdstring(G_(" Change working directory to:"), cod);
4606 ripley 151
    if (s && (SetCurrentDirectory(s) == FALSE)) {
25313 ripley 152
	snprintf(msg, MAX_PATH + 40,
33088 ripley 153
		 G_("Unable to set '%s' as working directory"), s);
4606 ripley 154
	askok(msg);
155
    }
156
    /* in every case reset cod (to new directory if all went ok
157
       or to old since user may have edited it */
158
    GetCurrentDirectory(MAX_PATH, cod);
4394 ripley 159
}
160
 
161
char *askfilename(char *title, char *default_name)
162
{
22872 murdoch 163
	if (*askfilenames(title, default_name, 0, userfilter?userfilter:filter[0], 0,
37592 murdoch 164
				          strbuf, BUFSIZE, NULL)) return strbuf;
22872 murdoch 165
	else return NULL;
4394 ripley 166
}
167
 
37592 murdoch 168
char *askfilenamewithdir(char *title, char *default_name, char *dir)
169
{
170
	if (*askfilenames(title, default_name, 0, userfilter?userfilter:filter[0], 0,
171
				          strbuf, BUFSIZE, dir)) return strbuf;
172
	else return NULL;
173
}
174
 
22872 murdoch 175
char *askfilenames(char *title, char *default_name, int multi,
37592 murdoch 176
			       char *filters, int filterindex, char *strbuf, int bufsize,
177
			       char *dir)
22842 murdoch 178
{
179
	int i;
180
	OPENFILENAME ofn;
181
        char cwd[MAX_PATH]="";
182
	if (! default_name)
183
		default_name = "";
184
	strcpy(strbuf, default_name);
185
        GetCurrentDirectory(MAX_PATH,cwd);
37592 murdoch 186
        if (!strcmp(cod,"")) {
187
            if (!dir) strcpy(cod,cwd);
188
            else strcpy(cod,dir);
189
        }
22842 murdoch 190
 
191
	ofn.lStructSize     = sizeof(OPENFILENAME);
192
	ofn.hwndOwner       = current_window ?
193
				current_window->handle : 0;
194
	ofn.hInstance       = 0;
37592 murdoch 195
	ofn.lpstrFilter     = filters;
22842 murdoch 196
	ofn.lpstrCustomFilter = NULL;
197
	ofn.nMaxCustFilter  = 0;
22872 murdoch 198
	ofn.nFilterIndex    = filterindex;
22842 murdoch 199
	ofn.lpstrFile       = strbuf;
200
	ofn.nMaxFile        = bufsize;
201
	ofn.lpstrFileTitle  = NULL;
202
	ofn.nMaxFileTitle   = _MAX_FNAME + _MAX_EXT;
203
        ofn.lpstrInitialDir = cod;
204
	ofn.lpstrTitle      = title;
22872 murdoch 205
	ofn.Flags           = OFN_CREATEPROMPT | OFN_HIDEREADONLY | OFN_EXPLORER;
206
	if (multi) ofn.Flags |= OFN_ALLOWMULTISELECT;
22842 murdoch 207
	ofn.nFileOffset     = 0;
208
	ofn.nFileExtension  = 0;
209
	ofn.lpstrDefExt     = "*";
210
	ofn.lCustData       = 0L;
211
	ofn.lpfnHook        = NULL;
212
	ofn.lpTemplateName  = NULL;
213
 
214
	if (GetOpenFileName(&ofn) == 0) {
215
		GetCurrentDirectory(MAX_PATH,cod);
216
		SetCurrentDirectory(cwd);
217
		strbuf[0] = 0;
218
		strbuf[1] = 0;
219
		return strbuf;
220
	} else {
221
		GetCurrentDirectory(MAX_PATH,cod);
222
		SetCurrentDirectory(cwd);
223
		for (i=0; i<10; i++)
224
			if (peekevent()) doevent();
225
		return strbuf;
226
	}
227
}
228
 
229
int countFilenames(char *list)
230
{
231
	char *temp;
232
	int count;
233
	count = 0;
234
	for (temp = list; *temp; temp += strlen(temp)+1) count++;
235
	return count;
236
}
237
 
4394 ripley 238
char *askfilesave(char *title, char *default_name)
239
{
8707 ripley 240
    return askfilesavewithdir(title, default_name, NULL);
241
}
242
 
243
char *askfilesavewithdir(char *title, char *default_name, char *dir)
244
{
4394 ripley 245
	int i;
246
	OPENFILENAME ofn;
247
        char cwd[MAX_PATH];
248
 
249
	if (! default_name)
250
		default_name = "";
251
	strcpy(strbuf, default_name);
252
 
253
	ofn.lStructSize     = sizeof(OPENFILENAME);
254
	ofn.hwndOwner       = current_window ?
255
				current_window->handle : 0;
256
	ofn.hInstance       = 0;
257
        ofn.lpstrFilter     = userfilter?userfilter:filter[0];
258
	ofn.lpstrCustomFilter = NULL;
259
	ofn.nMaxCustFilter  = 0;
260
	ofn.nFilterIndex    = 0;
261
	ofn.lpstrFile       = strbuf;
22842 murdoch 262
	ofn.nMaxFile        = BUFSIZE;
4394 ripley 263
	ofn.lpstrFileTitle  = NULL;
264
	ofn.nMaxFileTitle   = _MAX_FNAME + _MAX_EXT;
8707 ripley 265
	if(dir && strlen(dir) > 0)
266
	    ofn.lpstrInitialDir = dir;
267
	else {
268
	    if (GetCurrentDirectory(MAX_PATH,cwd))
269
		ofn.lpstrInitialDir = cwd;
270
	    else
271
		ofn.lpstrInitialDir = NULL;
272
	}
4394 ripley 273
	ofn.lpstrTitle      = title;
274
	ofn.Flags           = OFN_OVERWRITEPROMPT |
275
                              OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
276
	ofn.nFileOffset     = 0;
277
	ofn.nFileExtension  = 0;
278
	ofn.lpstrDefExt     = "*";
279
	ofn.lCustData       = 0L;
280
	ofn.lpfnHook        = NULL;
281
	ofn.lpTemplateName  = NULL;
282
 
283
	if (GetSaveFileName(&ofn) == 0)
284
		return NULL;
285
	else {
286
		for (i=0; i<10; i++)
287
			if (peekevent()) doevent();
288
		return strbuf;
289
	}
290
}
291
 
292
/*
293
 *  Input a string using a dialog box.
294
 */
295
 
296
/*
297
 *  Dialog information structure:
298
 */
299
	#define NOT_CHOSEN_YET -2
300
 
301
	typedef struct dialog_data_class {
302
		int 	hit;
303
		char *	result;
304
		label	question;
22785 ripley 305
		field	text, pass;
4394 ripley 306
		button	yes, no, cancel;
307
	} dialog_data;
308
 
309
	#define data(w) ((dialog_data *) (getdata(w)))
310
 
311
/*
312
 *  Some strings to use:
313
 */
4606 ripley 314
	static char * OKAY_STRING	= "OK";
4394 ripley 315
	static char * CANCEL_STRING	= "Cancel";
4606 ripley 316
	static char * BROWSE_STRING	= "Browse";
4394 ripley 317
 
318
	static char * QUESTION_TITLE	= "Question";
319
	static char * PASSWORD_TITLE	= "Password Entry";
35919 ripley 320
	static char * FINDDIR_TITLE	= "Choose directory";
4394 ripley 321
 
322
static void add_data(window w)
323
{
324
	dialog_data *d;
325
 
326
	d = create (dialog_data);
327
	if (! d)
328
		return;
329
	d->hit = NOT_CHOSEN_YET;
330
 
331
	setdata(w, d);
332
}
333
 
334
static char * get_dialog_string(window w)
335
{
336
	dialog_data *d = data(w);
337
 
338
	if (d->hit < YES) /* cancelled */
339
		return NULL;
340
	del_string(d->result);
341
	if (d->text)	/* question dialog */
342
		d->result = new_string(gettext(d->text));
343
 
344
	return d->result;
345
}
346
 
347
static void hit_button(control c)
348
{
349
	window w = parentwindow(c);
350
	dialog_data *d = data(w);
351
	int value = getvalue(c);
352
 
353
	d->hit = value;
354
	hide(w);
355
}
356
 
15268 ripley 357
#ifndef OLD
358
 
4606 ripley 359
static void browse_button(control c)
360
{
361
    window w = parentwindow(c);
362
    dialog_data *d = data(w);
15268 ripley 363
    char strbuf[MAX_PATH];
23715 murdoch 364
    strcpy(strbuf, gettext(d->text));
15268 ripley 365
    selectfolder(strbuf);
366
    if(strlen(strbuf)) settext(d->text, strbuf);
367
}
368
#else
369
static void browse_button(control c)
370
{
371
    window w = parentwindow(c);
372
    dialog_data *d = data(w);
4606 ripley 373
 
374
    OPENFILENAME ofn;
33088 ripley 375
    char strbuf[_MAX_PATH] = "anything", *p;
4606 ripley 376
 
377
    ofn.lStructSize     = sizeof(OPENFILENAME);
378
    ofn.hwndOwner       = 0;
379
    ofn.hInstance       = 0;
34081 ripley 380
    ofn.lpstrFilter     = "All files (*.*)\0*.*\0\0";
4606 ripley 381
    ofn.lpstrCustomFilter = NULL;
382
    ofn.nMaxCustFilter  = 0;
383
    ofn.nFilterIndex    = 0;
384
    ofn.lpstrFile       = strbuf;
385
    ofn.nMaxFile        = _MAX_PATH;
386
    ofn.lpstrFileTitle  = NULL;
387
    ofn.nMaxFileTitle   = _MAX_FNAME + _MAX_EXT;
388
    ofn.lpstrInitialDir = gettext(d->text);
33088 ripley 389
    ofn.lpstrTitle      = G_("Select working directory");
4606 ripley 390
    ofn.Flags           = OFN_HIDEREADONLY;
391
    ofn.nFileOffset     = 0;
392
    ofn.nFileExtension  = 0;
393
    ofn.lpstrDefExt     = "";
394
    ofn.lCustData       = 0L;
395
    ofn.lpfnHook        = NULL;
396
    ofn.lpTemplateName  = NULL;
397
 
398
    if(GetSaveFileName(&ofn) && strlen(strbuf)) {
399
	 p = strrchr(strbuf,'\\'); if(p) *p ='\0';
400
	 settext(d->text, strbuf);
401
    }
402
}
15268 ripley 403
#endif
4606 ripley 404
 
4394 ripley 405
static void hit_key(window w, int key)
406
{
407
	button btn;
408
	char *name = NULL;
409
 
410
	w = parentwindow(w);
411
 
412
	if (data(w) == NULL)
413
		return;
414
 
415
	if ((btn = data(w)->yes) != NULL) {
416
		name = getname(btn);
417
		if ((key == '\n') || (tolower(name[0]) == tolower(key)))
418
		{
419
			flashcontrol(btn);
420
			activatecontrol(btn);
421
			return;
422
		}
423
	}
424
 
425
	if ((btn = data(w)->cancel) != NULL) {
426
		name = getname(btn);
427
		if ((key == ESC) || (tolower(name[0]) == tolower(key)))
428
		{
429
			flashcontrol(btn);
430
			activatecontrol(btn);
431
			return;
432
		}
433
	}
434
 
435
	if ((btn = data(w)->no) != NULL) {
436
		name = getname(btn);
437
		if ((key == ESC) || (tolower(name[0]) == tolower(key)))
438
		{
439
			flashcontrol(btn);
440
			activatecontrol(btn);
441
			return;
442
		}
443
	}
444
 
445
}
446
 
447
/*
448
 *  Handle the events from a message dialog, hide the window afterwards.
449
 */
450
static int handle_message_dialog(window w)
451
{
452
	window old;
453
	dialog_data *d = data(w);
454
 
455
	old = currentdrawing();
456
	d->hit = NOT_CHOSEN_YET;
457
 
458
	show(w);
459
	while (d->hit == NOT_CHOSEN_YET)
460
		doevent();
461
	hide(w);
462
 
463
	if (old) drawto(old);
464
 
465
	return d->hit;
466
}
467
 
8707 ripley 468
static window init_askstr_dialog(char *title, char *question,
4394 ripley 469
				 char *default_str)
470
{
471
	window win;
472
	dialog_data *d;
473
	int tw, bw, h, middle;
474
 
475
	if (! question)
476
		question= "";
477
	if (! default_str)
478
		default_str = "";
479
 
480
	tw = strwidth(SystemFont, CANCEL_STRING) * 8;
481
	h = getheight(SystemFont);
482
 
483
	if (tw < 150) tw = 150;
484
 
485
	win = newwindow(title, rect(0,0,tw+30,h*9+12),
486
			Titlebar | Centered | Modal);
18082 ripley 487
        setbackground(win, dialog_bg());
4394 ripley 488
	add_data(win);
489
	d = data(win);
490
	d->question = newlabel(question, rect(10,h,tw+4,h*2+2),
491
			AlignLeft);
4606 ripley 492
	if (title == FINDDIR_TITLE) {
35919 ripley 493
	    bw = strwidth(SystemFont, G_(BROWSE_STRING)) * 3/2;
4606 ripley 494
	    d->text = newfield(default_str, rect(10,h*4,tw+4-bw,h*3/2));
35919 ripley 495
	    newbutton(G_(BROWSE_STRING), rect(20+tw-bw, h*4-2, bw, h+10),
4606 ripley 496
		      browse_button);
497
	}
498
	else if (title == PASSWORD_TITLE)
4394 ripley 499
		d->text = newpassword(default_str, rect(10,h*4,tw+4,h*3/2));
500
	else
501
		d->text = newfield(default_str, rect(10,h*4,tw+4,h*3/2));
502
 
503
	middle = (tw+30)/2;
504
	bw = strwidth(SystemFont, CANCEL_STRING) * 3/2;
505
 
506
	d->yes = newbutton(OKAY_STRING,
4606 ripley 507
			rect(middle-bw-10, h*7, bw, h+10), hit_button);
4394 ripley 508
	setvalue(d->yes, YES);
509
 
510
	d->cancel = newbutton(CANCEL_STRING,
4606 ripley 511
			rect(middle+10, h*7, bw, h+10), hit_button);
4394 ripley 512
	setvalue(d->cancel, CANCEL);
513
 
514
	setkeydown(win, hit_key);
515
 
516
	return win;
517
}
518
 
519
char *askstring(char *question, char *default_str)
520
{
521
	static window win = NULL;
522
	window prev = current_window;
523
 
524
	if (! win)
525
		win = init_askstr_dialog(QUESTION_TITLE, question, default_str);
526
	else {
527
		settext(data(win)->question, question);
528
		settext(data(win)->text, default_str);
529
	}
28854 murdoch 530
	if (TopmostDialogs & MB_TOPMOST)
531
	    BringToTop(win, 1);
4394 ripley 532
	handle_message_dialog(win);
533
	current_window = prev;
28854 murdoch 534
 
4394 ripley 535
	return get_dialog_string(win);
536
}
537
 
4606 ripley 538
char *askcdstring(char *question, char *default_str)
539
{
540
	static window win = NULL;
541
	window prev = current_window;
542
 
543
	if (! win)
544
		win = init_askstr_dialog(FINDDIR_TITLE, question, default_str);
545
	else {
546
		settext(data(win)->question, question);
547
		settext(data(win)->text, default_str);
548
	}
28854 murdoch 549
	if (TopmostDialogs & MB_TOPMOST)
550
	    BringToTop(win, 1);
4606 ripley 551
	handle_message_dialog(win);
552
	current_window = prev;
28854 murdoch 553
 
4606 ripley 554
	return get_dialog_string(win);
555
}
556
 
4394 ripley 557
char *askpassword(char *question, char *default_str)
558
{
559
	static window win = NULL;
560
	window prev = current_window;
561
 
562
	if (! win)
563
		win = init_askstr_dialog(PASSWORD_TITLE, question, default_str);
564
	else {
565
		settext(data(win)->question, question);
566
		settext(data(win)->text, default_str);
567
	}
28854 murdoch 568
	if (TopmostDialogs & MB_TOPMOST)
569
	    BringToTop(win, 1);
4394 ripley 570
	handle_message_dialog(win);
571
	current_window = prev;
28854 murdoch 572
 
4394 ripley 573
	return get_dialog_string(win);
574
}
575
 
22785 ripley 576
char *askUserPass(char *title)
577
{
578
    static window win = NULL;
579
    dialog_data *d;
580
    window prev = current_window;
581
 
582
    if (! win) {
583
	int tw, bw, h, middle;
584
 
585
	tw = strwidth(SystemFont, CANCEL_STRING) * 8;
586
	h = getheight(SystemFont);
587
	if (tw < 150) tw = 150;
588
	win = newwindow(title, rect(0, 0, tw+30, h*9+12),
589
			Titlebar | Centered | Modal);
590
        setbackground(win, dialog_bg());
591
	add_data(win);
592
	d = data(win);
33088 ripley 593
	d->question = newlabel(G_("User"), rect(10, h, tw+4, h*2+2), AlignLeft);
594
	bw = strwidth(SystemFont, G_("Password"));
22785 ripley 595
	d->text = newfield("", rect(20+bw, h, tw-6-bw, h*3/2));
33093 ripley 596
	newlabel(_("Password"), rect(10, h*4, tw+4, h*2+2), AlignLeft);
22785 ripley 597
	d->pass = newpassword("", rect(20+bw, h*4, tw-6-bw, h*3/2));
598
	middle = (tw+30)/2;
599
	bw = strwidth(SystemFont, CANCEL_STRING) * 3/2;
600
 
601
	d->yes = newbutton(OKAY_STRING,
602
			rect(middle-bw-10, h*7, bw, h+10), hit_button);
603
	setvalue(d->yes, YES);
604
 
605
	d->cancel = newbutton(CANCEL_STRING,
606
			rect(middle+10, h*7, bw, h+10), hit_button);
607
	setvalue(d->cancel, CANCEL);
608
 
609
	setkeydown(win, hit_key);
610
    } else {
611
	d = data(win);
612
	settext(d->text, "");
613
	settext(d->pass, "");
614
    }
28854 murdoch 615
    if (TopmostDialogs & MB_TOPMOST)
616
	BringToTop(win, 1);
22785 ripley 617
    handle_message_dialog(win);
618
    current_window = prev;
619
    {
620
	char *user, *pass;
621
	static char buf[1000];
622
	if (d->hit < YES) /* cancelled */ return "";
623
	if (d->text) user = new_string(gettext(d->text));
624
	else return "";
625
	if (d->pass) pass = new_string(gettext(d->pass));
626
	else return "";
25313 ripley 627
	snprintf(buf, 1000, "%s:%s", user, pass);
22785 ripley 628
	return buf;
629
    }
630
    return ""; /* -Wall */
631
}
28991 murdoch 632
 
633
int modeless_active()
634
{
635
    if (hModelessDlg)
636
	return 1;
637
    return 0;
638
}
639
 
640
PROTECTED
641
HWND get_modeless()
642
{
643
    return hModelessDlg;
644
}
645
 
646
void finddialog(textbox t){
647
    static FINDREPLACE fr;
648
    static char szFindWhat[80];
649
 
650
    fr.lStructSize = sizeof(fr);
651
    fr.hwndOwner = t->handle;
652
    fr.lpstrFindWhat = szFindWhat;
653
    fr.wFindWhatLen = 80;
654
    fr.Flags = FR_DOWN;
655
    fr.lCustData        = 0 ;
656
    fr.lpfnHook         = NULL ;
657
    fr.lpTemplateName   = NULL ;
658
 
659
    hModelessDlg = FindText(&fr);
660
}
661
 
662
void replacedialog(textbox t){
663
    static FINDREPLACE fr;
664
    static char szFindWhat[80];
665
    static char szReplaceWith[80];
666
 
667
    fr.lStructSize = sizeof(fr);
668
    fr.hwndOwner = t->handle;
669
    fr.lpstrFindWhat = szFindWhat;
670
    fr.lpstrReplaceWith = szReplaceWith;
671
    fr.wFindWhatLen = 80;
672
    fr.wReplaceWithLen = 80;
673
    fr.Flags = FR_DOWN;
674
    fr.lCustData        = 0 ;
675
    fr.lpfnHook         = NULL ;
676
    fr.lpTemplateName   = NULL ;
677
 
678
    hModelessDlg = ReplaceText(&fr);
679
}
680
 
681
 
682
/* Find and select a string in a rich edit control */
683
 
684
int richeditfind(HWND hwnd, char *what, int matchcase, int wholeword, int down)
685
{
686
    long start, end;
687
    CHARRANGE sel;
688
    WPARAM w = 0;
689
    FINDTEXTEX ft;
690
    sendmessage (hwnd, EM_EXGETSEL, 0, &sel) ;
691
    start = sel.cpMin;
692
    end = sel.cpMax;
693
    ft.lpstrText = what;
694
    ft.chrgText.cpMin = start;
695
    ft.chrgText.cpMax = end;
696
    if (down) {
697
	w = w | FR_DOWN;
698
	ft.chrg.cpMin = end;
699
	ft.chrg.cpMax = -1;
700
    }
701
    else {
702
	ft.chrg.cpMin = start;
703
	ft.chrg.cpMax = 0;
704
    }
705
    if (matchcase) w = w | FR_MATCHCASE;
706
    if (wholeword) w = w | FR_WHOLEWORD;
707
    if (sendmessage(hwnd, EM_FINDTEXTEX, w, &ft) == -1)
708
	return 0;
709
    else {
710
	sendmessage (hwnd, EM_EXSETSEL, 0, &(ft.chrgText));
711
	sendmessage (hwnd, EM_SCROLLCARET, 0, 0) ;
712
    }
713
    return 1;
714
}
715
 
716
int richeditreplace(HWND hwnd, char *what, char *replacewith, int matchcase, int wholeword, int down)
717
{
718
    /* If current selection is the find string, replace it and find next */
719
    long start, end;
720
    CHARRANGE sel;
721
    char *buf;
722
    textbox t = find_by_handle(hwnd);
31401 murdoch 723
    if (t) {
724
	sendmessage (hwnd, EM_EXGETSEL, 0, &sel) ;
725
	start = sel.cpMin;
726
	end = sel.cpMax;
727
	if (start < end) {
728
	    buf = (char *) malloc(end - start + 1);
729
	    sendmessage(hwnd, EM_GETSELTEXT, 0, buf);
730
	    if (!strcmp(buf, what)) {
731
		checklimittext(t, strlen(replacewith) - strlen(what) + 2);
732
		sendmessage (hwnd, EM_REPLACESEL, 1, replacewith);
733
	    }
734
	    free(buf);
28991 murdoch 735
	}
31401 murdoch 736
	/* else just find next */
737
	if (richeditfind(hwnd, what, matchcase, wholeword, down))
738
	    return 1;
28991 murdoch 739
    }
740
    return 0;
741
}
742
 
743
PROTECTED
744
void handle_findreplace(HWND hwnd, LPFINDREPLACE pfr)
745
{
746
    CHARRANGE sel;
747
    int matchcase=0, wholeword=0, down=0;
748
    char buf[100];
749
    if (pfr->Flags & FR_MATCHCASE) matchcase = 1;
750
    if (pfr->Flags & FR_WHOLEWORD) wholeword = 1;
751
    if (pfr->Flags & FR_DOWN) down = 1;
752
 
753
    if (pfr->Flags & FR_FINDNEXT) {
754
	if (!richeditfind(hwnd, pfr->lpstrFindWhat, matchcase, wholeword, down)) {
33088 ripley 755
	    snprintf(buf, 100, G_("\"%s\" not found"), pfr->lpstrFindWhat);
28991 murdoch 756
	    askok(buf);
757
	}
758
    }
759
    else if (pfr->Flags & FR_REPLACE) {
760
	if (!richeditreplace(hwnd, pfr->lpstrFindWhat, pfr->lpstrReplaceWith, matchcase, wholeword, down)) {
33088 ripley 761
	    snprintf(buf, 100, G_("\"%s\" not found"), pfr->lpstrFindWhat);
28991 murdoch 762
	    askok(buf);
763
	}
764
    }
765
    else if (pfr->Flags & FR_REPLACEALL) {
766
	/* replace all in the whole buffer then return to original selection state */
767
	sendmessage (hwnd, EM_EXGETSEL, 0, &sel) ;
768
	sendmessage (hwnd, EM_SETSEL, 0, 0) ;
769
	while ( richeditreplace(hwnd, pfr->lpstrFindWhat, pfr->lpstrReplaceWith, matchcase, wholeword, down) ) ;
770
	sendmessage (hwnd, EM_EXSETSEL, 0, &sel) ;
771
    }
772
 
773
    else if (pfr->Flags & FR_DIALOGTERM)
774
	hModelessDlg = NULL;
775
}
776