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