1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #ifdef HAVE_CONFIG_H
30 #include "../config.h"
31 #endif
32
33 #include "search.h"
34 #include "regularExp.h"
35 #include "textBuf.h"
36 #include "text.h"
37 #include "nedit.h"
38 #include "server.h"
39 #include "window.h"
40 #include "userCmds.h"
41 #include "preferences.h"
42 #include "file.h"
43 #include "highlight.h"
44 #include "selection.h"
45 #ifdef REPLACE_SCOPE
46 #include "textDisp.h"
47 #include "textP.h"
48 #endif
49 #include "../util/DialogF.h"
50 #include "../util/misc.h"
51 #include "../util/utils.h"
52 #include "../util/nedit_malloc.h"
53
54 #include "../util/textfield.h"
55
56 #include <stdlib.h>
57 #include <stdio.h>
58 #include <string.h>
59 #include <ctype.h>
60 #include <wctype.h>
61 #include <wchar.h>
62 #include <errno.h>
63 #include <sys/stat.h>
64 #include <sys/param.h>
65 #include <Xm/Xm.h>
66 #include <X11/Shell.h>
67 #include <Xm/XmP.h>
68 #include <Xm/Form.h>
69 #include <Xm/Label.h>
70 #ifdef REPLACE_SCOPE
71 #if XmVersion >=
1002
72 #include <Xm/PrimitiveP.h>
73 #endif
74 #endif
75 #include <Xm/PushB.h>
76 #include <Xm/RowColumn.h>
77 #include <Xm/Text.h>
78 #include <Xm/ToggleB.h>
79 #include <Xm/List.h>
80 #include <X11/Xatom.h>
81 #include <X11/keysym.h>
82 #include <X11/X.h>
83
84 #ifdef HAVE_DEBUG_H
85 #include "../debug.h"
86 #endif
87
88
89 int NHist =
0;
90 time_t lastSearchdbModTime =
0;
91
92 typedef struct _SelectionInfo {
93 int done;
94 WindowInfo* window;
95 char* selection;
96 } SelectionInfo;
97
98 typedef struct {
99 int direction;
100 int searchType;
101 int searchWrap;
102 } SearchSelectedCallData;
103
104
105 static char *SearchHistory[
MAX_SEARCH_HISTORY];
106 static char *ReplaceHistory[
MAX_SEARCH_HISTORY];
107 static int SearchTypeHistory[
MAX_SEARCH_HISTORY];
108 static int HistStart =
0;
109
110 static int textFieldNonEmpty(Widget w);
111 static void setTextField(WindowInfo* window, Time time, Widget textField);
112 static void getSelectionCB(Widget w, XtPointer selectionInfo, Atom *selection,
113 Atom *type, XtPointer value,
unsigned long *length,
int *format);
114 static void fFocusCB(Widget w, WindowInfo *window,
caddr_t *callData);
115 static void rFocusCB(Widget w, WindowInfo *window,
caddr_t *callData);
116 static void rKeepCB(Widget w, WindowInfo *window,
caddr_t *callData);
117 static void fKeepCB(Widget w, WindowInfo *window,
caddr_t *callData);
118 static void replaceCB(Widget w, WindowInfo *window,
119 XmAnyCallbackStruct *callData);
120 static void replaceAllCB(Widget w, WindowInfo *window,
121 XmAnyCallbackStruct *callData);
122 static void rInSelCB(Widget w, WindowInfo *window,
123 XmAnyCallbackStruct *callData);
124 static void rCancelCB(Widget w, WindowInfo *window,
caddr_t callData);
125 static void fCancelCB(Widget w, WindowInfo *window,
caddr_t callData);
126 static void rFindCB(Widget w,WindowInfo *window,XmAnyCallbackStruct *callData);
127 static void rFindTextValueChangedCB(Widget w, WindowInfo *window, XKeyEvent *event);
128 static void rFindArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event);
129
130 static void rSetActionButtons(WindowInfo* window,
131 int replaceBtn,
132 int replaceFindBtn,
133 int replaceAndFindBtn,
134 #ifndef REPLACE_SCOPE
135 int replaceInWinBtn,
136 int replaceInSelBtn,
137 #endif
138 int replaceAllBtn);
139 #ifdef REPLACE_SCOPE
140 static void rScopeWinCB(Widget w, WindowInfo *window,
141 XmAnyCallbackStruct *callData);
142 static void rScopeSelCB(Widget w, WindowInfo *window,
143 XmAnyCallbackStruct *callData);
144 static void rScopeMultiCB(Widget w, WindowInfo *window,
145 XmAnyCallbackStruct *callData);
146 static void replaceAllScopeCB(Widget w, WindowInfo *window,
147 XmAnyCallbackStruct *callData);
148 #endif
149
150 static void replaceArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event);
151 static void fUpdateActionButtons(WindowInfo *window);
152 static void findTextValueChangedCB(Widget w, WindowInfo *window, XKeyEvent *event);
153 static void findArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event);
154 static void replaceFindCB(Widget w, WindowInfo *window, XmAnyCallbackStruct *callData);
155 static void findCB(Widget w, WindowInfo *window,XmAnyCallbackStruct *callData);
156 static void replaceMultiFileCB(Widget w, WindowInfo *window,
157 XmAnyCallbackStruct *callData);
158 static void rMultiFileReplaceCB(Widget w, WindowInfo *window,
159 XmAnyCallbackStruct * callData);
160 static void rMultiFileCancelCB(Widget w, WindowInfo *window,
caddr_t callData);
161 static void rMultiFileSelectAllCB(Widget w, WindowInfo *window,
162 XmAnyCallbackStruct *callData);
163 static void rMultiFileDeselectAllCB(Widget w, WindowInfo *window,
164 XmAnyCallbackStruct * callData);
165 static void rMultiFilePathCB(Widget w, WindowInfo *window,
166 XmAnyCallbackStruct *callData);
167 static void uploadFileListItems(WindowInfo* window, Bool replace);
168 static int countWindows(
void);
169 static int countWritableWindows(
void);
170 static void collectWritableWindows(WindowInfo* window);
171 static void freeWritableWindowsCB(Widget w, WindowInfo* window,
172 XmAnyCallbackStruct *callData);
173 static void checkMultiReplaceListForDoomedW(WindowInfo* window,
174 WindowInfo* doomedWindow);
175 static void removeDoomedWindowFromList(WindowInfo* window,
int index);
176 static void unmanageReplaceDialogs(
const WindowInfo *window);
177 static void flashTimeoutProc(XtPointer clientData, XtIntervalId *id);
178 static void eraseFlash(WindowInfo *window);
179 static int getReplaceDlogInfo(WindowInfo *window,
int *direction,
180 char *searchString,
char *replaceString,
int *searchType);
181 static int getFindDlogInfo(WindowInfo *window,
int *direction,
182 char *searchString,
int *searchType);
183 static void selectedSearchCB(Widget w, XtPointer callData, Atom *selection,
184 Atom *type, XtPointer value,
unsigned long *length,
int *format);
185 static void iSearchTextClearAndPasteAP(Widget w, XEvent *event, String *args,
186 Cardinal *nArg);
187 static void iSearchTextClearCB(Widget w, WindowInfo *window,
188 XmAnyCallbackStruct *callData);
189 static void iSearchTextActivateCB(Widget w, WindowInfo *window,
190 XmAnyCallbackStruct *callData);
191 static void iSearchTextValueChangedCB(Widget w, WindowInfo *window,
192 XmAnyCallbackStruct *callData);
193 static void iSearchTextKeyEH(Widget w, WindowInfo *window,
194 XKeyEvent *event, Boolean *continueDispatch);
195 static int searchLiteral(
const char *string,
const char *searchString,
int caseSense,
196 int direction,
int wrap,
int beginPos,
int *startPos,
int *endPos,
197 int *searchExtentBW,
int *searchExtentFW);
198 static int searchLiteralWord(
const char *string,
const char *searchString,
int caseSense,
199 int direction,
int wrap,
int beginPos,
int *startPos,
int *endPos,
200 const char * delimiters);
201 static int searchRegex(
const char *string,
const char *searchString,
int direction,
202 int wrap,
int beginPos,
int *startPos,
int *endPos,
int *searchExtentBW,
203 int *searchExtentFW,
const char *delimiters,
int defaultFlags);
204 static int forwardRegexSearch(
const char *string,
const char *searchString,
int wrap,
205 int beginPos,
int *startPos,
int *endPos,
int *searchExtentBW,
206 int *searchExtentFW,
const char *delimiters,
int defaultFlags);
207 static int backwardRegexSearch(
const char *string,
const char *searchString,
int wrap,
208 int beginPos,
int *startPos,
int *endPos,
int *searchExtentBW,
209 int *searchExtentFW,
const char *delimiters,
int defaultFlags);
210 static void resetFindTabGroup(WindowInfo *window);
211 static void resetReplaceTabGroup(WindowInfo *window);
212 static int searchMatchesSelection(WindowInfo *window,
const char *searchString,
213 int searchType,
int *left,
int *right,
int *searchExtentBW,
214 int *searchExtentFW);
215 static int findMatchingChar(WindowInfo *window,
char toMatch,
216 void *toMatchStyle,
int charPos,
int startLimit,
int endLimit,
217 int *matchPos);
218 static Boolean replaceUsingRE(
const char* searchStr,
const char* replaceStr,
219 const char* sourceStr,
int beginPos,
char* destStr,
int maxDestLen,
220 int prevChar,
const char* delimiters,
int defaultFlags);
221 static void enableFindAgainCmds(
void);
222 static void saveSearchHistory(
const char *searchString,
223 const char *replaceString,
int searchType,
int isIncremental);
224 static int historyIndex(
int nCycles);
225 static char *searchTypeArg(
int searchType);
226 static char *searchWrapArg(
int searchWrap);
227 static char *directionArg(
int direction);
228 static int isRegexType(
int searchType);
229 static int defaultRegexFlags(
int searchType);
230 static void findRegExpToggleCB(Widget w, XtPointer clientData,
231 XtPointer callData);
232 static void replaceRegExpToggleCB(Widget w, XtPointer clientData,
233 XtPointer callData);
234 static void iSearchRegExpToggleCB(Widget w, XtPointer clientData,
235 XtPointer callData);
236 static void findCaseToggleCB(Widget w, XtPointer clientData,
237 XtPointer callData);
238 static void replaceCaseToggleCB(Widget w, XtPointer clientData,
239 XtPointer callData);
240 static void iSearchCaseToggleCB(Widget w, XtPointer clientData,
241 XtPointer callData);
242 static void iSearchTryBeepOnWrap(WindowInfo *window,
int direction,
243 int beginPos,
int startPos);
244 static void iSearchRecordLastBeginPos(WindowInfo *window,
int direction,
245 int initPos);
246 static Boolean prefOrUserCancelsSubst(
const Widget parent,
247 const Display* display);
248
249 static int translateEscPos(EscSeqArray *array,
int pos);
250 static void translatePosAndRestoreBuf(
251 textBuffer *buf,
252 EscSeqArray *array,
253 int found,
254 int *begin,
255 int *end,
256 int *extentBW,
257 int *extentFW);
258
259 typedef struct _charMatchTable {
260 char c;
261 char match;
262 char direction;
263 } charMatchTable;
264
265 #define N_MATCH_CHARS 13
266 #define N_FLASH_CHARS 6
267 static charMatchTable MatchingChars[
N_MATCH_CHARS] = {
268 {
'{',
'}',
SEARCH_FORWARD},
269 {
'}',
'{',
SEARCH_BACKWARD},
270 {
'(',
')',
SEARCH_FORWARD},
271 {
')',
'(',
SEARCH_BACKWARD},
272 {
'[',
']',
SEARCH_FORWARD},
273 {
']',
'[',
SEARCH_BACKWARD},
274 {
'<',
'>',
SEARCH_FORWARD},
275 {
'>',
'<',
SEARCH_BACKWARD},
276 {
'/',
'/',
SEARCH_FORWARD},
277 {
'""',
'""',
SEARCH_FORWARD},
278 {
'\'',
'\'',
SEARCH_FORWARD},
279 {
'`',
'`',
SEARCH_FORWARD},
280 {
'\\',
'\\',
SEARCH_FORWARD},
281 };
282
283
284
285
286
287 static char *searchTypeStrings[] = {
288 "literal",
289 "case",
290 "regex",
291 "word",
292 "caseWord",
293 "regexNoCase",
294 NULL
295 };
296
297
298
299
300
301
302
303
304
305
306
307 static WindowInfo *windowNotToClose =
NULL;
308
309 Boolean WindowCanBeClosed(WindowInfo *window)
310 {
311 if (windowNotToClose &&
312 GetTopDocument(window->shell) ==
313 GetTopDocument(windowNotToClose->shell)) {
314 return False;
315 }
316 return True;
317 }
318
319
320
321
322
323
324 static void initToggleButtons(
int searchType, Widget regexToggle,
325 Widget caseToggle, Widget* wordToggle,
326 Bool* lastLiteralCase,
327 Bool* lastRegexCase)
328 {
329
330
331 switch (searchType) {
332 case SEARCH_LITERAL:
333 *lastLiteralCase = False;
334 *lastRegexCase = True;
335 XmToggleButtonSetState(regexToggle, False, False);
336 XmToggleButtonSetState(caseToggle, False, False);
337 if (wordToggle) {
338 XmToggleButtonSetState(*wordToggle, False, False);
339 XtSetSensitive(*wordToggle, True);
340 }
341 break;
342 case SEARCH_CASE_SENSE:
343 *lastLiteralCase = True;
344 *lastRegexCase = True;
345 XmToggleButtonSetState(regexToggle, False, False);
346 XmToggleButtonSetState(caseToggle, True, False);
347 if (wordToggle) {
348 XmToggleButtonSetState(*wordToggle, False, False);
349 XtSetSensitive(*wordToggle, True);
350 }
351 break;
352 case SEARCH_LITERAL_WORD:
353 *lastLiteralCase = False;
354 *lastRegexCase = True;
355 XmToggleButtonSetState(regexToggle, False, False);
356 XmToggleButtonSetState(caseToggle, False, False);
357 if (wordToggle) {
358 XmToggleButtonSetState(*wordToggle, True, False);
359 XtSetSensitive(*wordToggle, True);
360 }
361 break;
362 case SEARCH_CASE_SENSE_WORD:
363 *lastLiteralCase = True;
364 *lastRegexCase = True;
365 XmToggleButtonSetState(regexToggle, False, False);
366 XmToggleButtonSetState(caseToggle, True, False);
367 if (wordToggle) {
368 XmToggleButtonSetState(*wordToggle, True, False);
369 XtSetSensitive(*wordToggle, True);
370 }
371 break;
372 case SEARCH_REGEX:
373 *lastLiteralCase = False;
374 *lastRegexCase = True;
375 XmToggleButtonSetState(regexToggle, True, False);
376 XmToggleButtonSetState(caseToggle, True, False);
377 if (wordToggle) {
378 XmToggleButtonSetState(*wordToggle, False, False);
379 XtSetSensitive(*wordToggle, False);
380 }
381 break;
382 case SEARCH_REGEX_NOCASE:
383 *lastLiteralCase = False;
384 *lastRegexCase = False;
385 XmToggleButtonSetState(regexToggle, True, False);
386 XmToggleButtonSetState(caseToggle, False, False);
387 if (wordToggle) {
388 XmToggleButtonSetState(*wordToggle, False, False);
389 XtSetSensitive(*wordToggle, False);
390 }
391 break;
392 }
393 }
394
395 #ifdef REPLACE_SCOPE
396
397
398
399
400
401
402 static int selectionSpansMultipleLines(WindowInfo *window)
403 {
404 int selStart, selEnd, isRect, rectStart, rectEnd, lineStartStart,
405 lineStartEnd;
406 int lineWidth;
407 textDisp *textD;
408
409 if (!BufGetSelectionPos(window->buffer, &selStart, &selEnd, &isRect,
410 &rectStart, &rectEnd))
411 return FALSE;
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 lineStartStart = BufStartOfLine(window->buffer, selStart);
428 lineStartEnd = BufStartOfLine(window->buffer, selEnd);
429
430 if (lineStartStart != lineStartEnd )
431 return TRUE;
432
433 if (window->wrapMode !=
CONTINUOUS_WRAP)
434 return FALSE;
435
436
437 textD = ((TextWidget)window->textArea)->text.textD;
438 if (textD->font->fonts->font->max_advance_width >
0)
439 lineWidth = textD->width / textD->font->fonts->font->max_advance_width;
440 else
441 lineWidth =
1;
442 if (lineWidth <
1) lineWidth =
1;
443
444
445
446 if ((selStart-lineStartStart)/lineWidth !=
447 (selEnd-lineStartStart)/lineWidth )
448 return TRUE;
449
450 return FALSE;
451 }
452 #endif
453
454 void DoFindReplaceDlog(WindowInfo *window,
int direction,
int keepDialogs,
455 int searchType, Time time)
456 {
457
458
459 if (window->replaceDlog ==
NULL)
460 CreateReplaceDlog(window->shell, window);
461
462 setTextField(window, time, window->replaceText);
463
464
465 if (XtIsManaged(window->replaceDlog)) {
466 RaiseDialogWindow(XtParent(window->replaceDlog));
467 return;
468 }
469
470
471 XNETextSetString(window->replaceWithText,
"");
472
473
474 initToggleButtons(searchType, window->replaceRegexToggle,
475 window->replaceCaseToggle, &window->replaceWordToggle,
476 &window->replaceLastLiteralCase,
477 &window->replaceLastRegexCase);
478
479
480 XmToggleButtonSetState(window->replaceRevToggle,
481 direction ==
SEARCH_FORWARD ? False: True, True);
482
483
484 XmToggleButtonSetState(window->replaceKeepBtn, keepDialogs, True);
485
486 #ifdef REPLACE_SCOPE
487
488
489
490
491
492 if (window->wasSelected) {
493
494
495 switch(GetPrefReplaceDefScope()) {
496 case REPL_DEF_SCOPE_SELECTION:
497
498
499 RadioButtonChangeState(window->replaceScopeSelToggle,
500 True, True);
501 break;
502 case REPL_DEF_SCOPE_SMART:
503 if (selectionSpansMultipleLines(window)) {
504
505
506 RadioButtonChangeState(window->replaceScopeSelToggle,
507 True, True);
508 }
509 else {
510
511
512 RadioButtonChangeState(window->replaceScopeWinToggle,
513 True, True);
514 }
515 break;
516 default:
517
518 RadioButtonChangeState(window->replaceScopeWinToggle,
519 True, True);
520 window->replaceScope =
REPL_SCOPE_WIN;
521 break;
522 }
523 }
524 else {
525
526 RadioButtonChangeState(window->replaceScopeWinToggle, True, True);
527 window->replaceScope =
REPL_SCOPE_WIN;
528 }
529 #endif
530
531 UpdateReplaceActionButtons(window);
532
533
534
535 ReadSearchHistory();
536
537
538 window->rHistIndex =
0;
539
540
541 ManageDialogCenteredOnPointer(window->replaceDlog);
542
543
544
545
546 XmProcessTraversal(window->replaceText, XmTRAVERSE_CURRENT);
547 }
548
549 static void setTextField(WindowInfo *window, Time time, Widget textField)
550 {
551 XEvent nextEvent;
552 char *primary_selection =
0;
553 SelectionInfo *selectionInfo = NEditNew(SelectionInfo);
554
555 if (GetPrefFindReplaceUsesSelection()) {
556 selectionInfo->done =
0;
557 selectionInfo->window = window;
558 selectionInfo->selection =
0;
559 XtGetSelectionValue(window->textArea,
XA_PRIMARY,
XA_STRING,
560 getSelectionCB, selectionInfo, time);
561 while (selectionInfo->done ==
0) {
562 XtAppNextEvent(XtWidgetToApplicationContext(window->textArea), &nextEvent);
563 ServerDispatchEvent(&nextEvent);
564 }
565 primary_selection = selectionInfo->selection;
566 }
567 if (primary_selection ==
0) {
568 primary_selection = NEditStrdup(
"");
569 }
570
571
572 XNETextSetString(textField, primary_selection);
573
574 NEditFree(primary_selection);
575 NEditFree(selectionInfo);
576 }
577
578 static void getSelectionCB(Widget w, XtPointer si, Atom *selection,
579 Atom *type, XtPointer v,
unsigned long *length,
int *format)
580 {
581 SelectionInfo *selectionInfo = si;
582 char *value = v;
583 WindowInfo *window = selectionInfo->window;
584
585
586 if (*type ==
XT_CONVERT_FAIL || *type !=
XA_STRING || value ==
NULL || *length ==
0) {
587 NEditFree(value);
588 selectionInfo->selection =
0;
589 selectionInfo->done =
1;
590 return;
591 }
592
593 if (*format !=
8) {
594 DialogF(
DF_WARN, window->shell,
1,
"Invalid Format",
595 "XNEdit can''t handle non 8-bit text",
"OK");
596 NEditFree(value);
597 selectionInfo->selection =
0;
598 selectionInfo->done =
1;
599 return;
600 }
601 selectionInfo->selection = (
char*)NEditMalloc(*length+
1);
602 memcpy(selectionInfo->selection, value, *length);
603 selectionInfo->selection[*length] =
0;
604 NEditFree(value);
605 selectionInfo->done =
1;
606 }
607
608 void DoFindDlog(WindowInfo *window,
int direction,
int keepDialogs,
609 int searchType, Time time)
610 {
611
612
613 if (window->findDlog ==
NULL)
614 CreateFindDlog(window->shell, window);
615
616 setTextField(window, time, window->findText);
617
618
619 if (XtIsManaged(window->findDlog)) {
620 RaiseDialogWindow(XtParent(window->findDlog));
621 return;
622 }
623
624
625 initToggleButtons(searchType, window->findRegexToggle,
626 window->findCaseToggle, &window->findWordToggle,
627 &window->findLastLiteralCase,
628 &window->findLastRegexCase);
629
630
631 XmToggleButtonSetState(window->findRevToggle,
632 direction ==
SEARCH_FORWARD ? False : True, True);
633
634
635 XmToggleButtonSetState(window->findKeepBtn, keepDialogs, True);
636
637
638 fUpdateActionButtons(window);
639
640
641
642 ReadSearchHistory();
643
644
645 window->fHistIndex =
0;
646
647
648 ManageDialogCenteredOnPointer(window->findDlog);
649
650
651
652
653 XmProcessTraversal(window->findText, XmTRAVERSE_CURRENT);
654 }
655
656 void DoReplaceMultiFileDlog(WindowInfo *window)
657 {
658 char searchString[
SEARCHMAX], replaceString[
SEARCHMAX];
659 int direction, searchType;
660
661
662 if (!getReplaceDlogInfo(window, &direction, searchString, replaceString,
663 &searchType))
664 return;
665
666
667 if (*searchString ==
'\0') {
668
669 resetReplaceTabGroup(window);
670
671 if (!XmToggleButtonGetState(window->replaceKeepBtn))
672 unmanageReplaceDialogs(window);
673 return;
674 }
675
676
677 if (window->replaceMultiFileDlog ==
NULL)
678 CreateReplaceMultiFileDlog(window);
679
680
681
682
683 collectWritableWindows(window);
684
685
686 uploadFileListItems(window, False);
687
688
689 ManageDialogCenteredOnPointer(window->replaceMultiFileDlog);
690 }
691
692
693
694
695
696
697
698
699
700 void RemoveFromMultiReplaceDialog(WindowInfo *doomedWindow)
701 {
702 WindowInfo *w;
703
704 for (w=WindowList; w!=
NULL; w=w->next)
705 if (w->writableWindows)
706
707 checkMultiReplaceListForDoomedW(w, doomedWindow);
708 }
709
710 void CreateReplaceDlog(Widget parent, WindowInfo *window)
711 {
712 Arg args[
50];
713 int argcnt, defaultBtnOffset;
714 XmString st1;
715 Widget form, btnForm;
716 #ifdef REPLACE_SCOPE
717 Widget scopeForm, replaceAllBtn;
718 #else
719 Widget label3, allForm;
720 #endif
721 Widget inWinBtn, inSelBtn, inMultiBtn;
722 Widget searchTypeBox;
723 Widget label2, label1, label, replaceText, findText;
724 Widget findBtn, cancelBtn, replaceBtn;
725 Widget replaceFindBtn;
726 Widget searchDirBox, reverseBtn, keepBtn;
727 char title[
MAXPATHLEN +
19];
728 Dimension shadowThickness;
729
730 argcnt =
0;
731 XtSetArg(args[argcnt], XmNautoUnmanage, False); argcnt++;
732 form = CreateFormDialog(parent,
"replaceDialog", args, argcnt);
733 XtVaSetValues(form, XmNshadowThickness,
0,
NULL);
734 if (GetPrefKeepSearchDlogs()) {
735 snprintf(title,
sizeof(title),
736 "Replace/Find (in %s)", window->filename);
737 XtVaSetValues(XtParent(form), XmNtitle, title,
NULL);
738 }
else
739 XtVaSetValues(XtParent(form), XmNtitle,
"Replace/Find",
NULL);
740
741 argcnt =
0;
742 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
743 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
744 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
745 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
746 XtSetArg(args[argcnt], XmNleftOffset,
4); argcnt++;
747 XtSetArg(args[argcnt], XmNtopOffset,
6); argcnt++;
748 XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_BEGINNING); argcnt++;
749 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"String to Find:"));
750 argcnt++;
751 XtSetArg(args[argcnt], XmNmnemonic,
't'); argcnt++;
752 label1 = XmCreateLabel(form,
"label1", args, argcnt);
753 XmStringFree(st1);
754 XtManageChild(label1);
755
756 argcnt =
0;
757 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
758 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
759 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_NONE); argcnt++;
760 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
761 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
762 XtSetArg(args[argcnt], XmNtopOffset,
6); argcnt++;
763 XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_END); argcnt++;
764 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
765 "(use up arrow key to recall previous)")); argcnt++;
766 label2 = XmCreateLabel(form,
"label2", args, argcnt);
767 XmStringFree(st1);
768 XtManageChild(label2);
769
770 argcnt =
0;
771 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
772 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
773 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
774 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
775 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
776 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
777 XtSetArg(args[argcnt], XmNtopWidget, label1); argcnt++;
778 XtSetArg(args[argcnt], XmNleftOffset,
6); argcnt++;
779 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
780 XtSetArg(args[argcnt], XmNmaxLength,
SEARCHMAX); argcnt++;
781 findText = XNECreateText(form,
"replaceString", args, argcnt);
782 XtAddCallback(findText, XmNfocusCallback, (XtCallbackProc)rFocusCB, window);
783 XtAddCallback(findText, XmNvalueChangedCallback,
784 (XtCallbackProc)rFindTextValueChangedCB, window);
785 XtAddEventHandler(findText, KeyPressMask, False,
786 (XtEventHandler)rFindArrowKeyCB, window);
787 RemapDeleteKey(findText);
788 XtManageChild(findText);
789 XmAddTabGroup(findText);
790 XtVaSetValues(label1, XmNuserData, findText,
NULL);
791
792 argcnt =
0;
793 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
794 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
795 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
796 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
797 XtSetArg(args[argcnt], XmNtopWidget, findText); argcnt++;
798 XtSetArg(args[argcnt], XmNleftOffset,
6); argcnt++;
799 XtSetArg(args[argcnt], XmNtopOffset,
6); argcnt++;
800 XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_BEGINNING); argcnt++;
801 XtSetArg(args[argcnt], XmNlabelString,
802 st1=
MKSTRING(
"Replace With:")); argcnt++;
803 XtSetArg(args[argcnt], XmNmnemonic,
'W'); argcnt++;
804 label = XmCreateLabel(form,
"label", args, argcnt);
805 XmStringFree(st1);
806 XtManageChild(label);
807
808 argcnt =
0;
809 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
810 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
811 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
812 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
813 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
814 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
815 XtSetArg(args[argcnt], XmNtopWidget, label); argcnt++;
816 XtSetArg(args[argcnt], XmNleftOffset,
6); argcnt++;
817 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
818 XtSetArg(args[argcnt], XmNmaxLength,
SEARCHMAX); argcnt++;
819 replaceText = XNECreateText(form,
"replaceWithString", args, argcnt);
820 XtAddEventHandler(replaceText, KeyPressMask, False,
821 (XtEventHandler)replaceArrowKeyCB, window);
822 RemapDeleteKey(replaceText);
823 XtManageChild(replaceText);
824 XmAddTabGroup(replaceText);
825 XtVaSetValues(label, XmNuserData, replaceText,
NULL);
826
827 argcnt =
0;
828 XtSetArg(args[argcnt], XmNorientation, XmHORIZONTAL); argcnt++;
829 XtSetArg(args[argcnt], XmNpacking, XmPACK_TIGHT); argcnt++;
830 XtSetArg(args[argcnt], XmNmarginHeight,
0); argcnt++;
831 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
832 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
833 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
834 XtSetArg(args[argcnt], XmNtopWidget, replaceText); argcnt++;
835 XtSetArg(args[argcnt], XmNleftOffset,
2); argcnt++;
836 XtSetArg(args[argcnt], XmNrightOffset,
4); argcnt++;
837 searchTypeBox = XmCreateRowColumn(form,
"searchTypeBox", args, argcnt);
838 XtManageChild(searchTypeBox);
839 XmAddTabGroup(searchTypeBox);
840
841 argcnt =
0;
842 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
843 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
844 XtSetArg(args[argcnt], XmNlabelString,
845 st1=
MKSTRING(
"Regular Expression")); argcnt++;
846 XtSetArg(args[argcnt], XmNmnemonic,
'R'); argcnt++;
847 window->replaceRegexToggle = XmCreateToggleButton(searchTypeBox,
"regExp", args, argcnt);
848 XmStringFree(st1);
849 XtManageChild(window->replaceRegexToggle);
850 XtAddCallback(window->replaceRegexToggle, XmNvalueChangedCallback, (XtCallbackProc) replaceRegExpToggleCB, window);
851
852 argcnt =
0;
853 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
854 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
855 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Case Sensitive")); argcnt++;
856 XtSetArg(args[argcnt], XmNmnemonic,
'C'); argcnt++;
857 window->replaceCaseToggle = XmCreateToggleButton(searchTypeBox,
"caseSensitive", args, argcnt);
858 XmStringFree(st1);
859 XtManageChild(window->replaceCaseToggle);
860 XtAddCallback(window->replaceCaseToggle, XmNvalueChangedCallback, (XtCallbackProc) replaceCaseToggleCB, window);
861
862 argcnt =
0;
863 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
864 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
865 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Whole Word")); argcnt++;
866 XtSetArg(args[argcnt], XmNmnemonic,
'h'); argcnt++;
867 window->replaceWordToggle = XmCreateToggleButton(searchTypeBox,
"wholeWord", args, argcnt);
868 XmStringFree(st1);
869 XtManageChild(window->replaceWordToggle);
870
871 argcnt =
0;
872 XtSetArg(args[argcnt], XmNorientation, XmHORIZONTAL); argcnt++;
873 XtSetArg(args[argcnt], XmNpacking, XmPACK_TIGHT); argcnt++;
874 XtSetArg(args[argcnt], XmNmarginHeight,
0); argcnt++;
875 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
876 XtSetArg(args[argcnt], XmNtopOffset,
0); argcnt++;
877 XtSetArg(args[argcnt], XmNtopWidget, searchTypeBox); argcnt++;
878 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
879 XtSetArg(args[argcnt], XmNleftOffset,
2); argcnt++;
880 XtSetArg(args[argcnt], XmNradioBehavior, False); argcnt++;
881 searchDirBox = XmCreateRowColumn(form,
"searchDirBox", args, argcnt);
882 XtManageChild(searchDirBox);
883 XmAddTabGroup(searchDirBox);
884
885 argcnt =
0;
886 XtSetArg(args[argcnt], XmNlabelString,
887 st1=
MKSTRING(
"Search Backward")); argcnt++;
888 XtSetArg(args[argcnt], XmNmnemonic,
'B'); argcnt++;
889 reverseBtn = XmCreateToggleButton(searchDirBox,
"reverse", args, argcnt);
890 XmStringFree(st1);
891 XtManageChild(reverseBtn);
892
893 argcnt =
0;
894 XtSetArg(args[argcnt], XmNlabelString,
895 st1=
MKSTRING(
"Keep Dialog")); argcnt++;
896 XtSetArg(args[argcnt], XmNmnemonic,
'K'); argcnt++;
897 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
898 XtSetArg(args[argcnt], XmNtopOffset,
0); argcnt++;
899 XtSetArg(args[argcnt], XmNtopWidget, searchTypeBox); argcnt++;
900 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
901 XtSetArg(args[argcnt], XmNrightOffset,
4); argcnt++;
902 keepBtn = XmCreateToggleButton(form,
"keep", args, argcnt);
903 XtAddCallback(keepBtn, XmNvalueChangedCallback,
904 (XtCallbackProc)rKeepCB, window);
905 XmStringFree(st1);
906 XtManageChild(keepBtn);
907 XmAddTabGroup(keepBtn);
908
909 #ifdef REPLACE_SCOPE
910 argcnt =
0;
911 XtSetArg(args[argcnt], XmNorientation, XmHORIZONTAL); argcnt++;
912 XtSetArg(args[argcnt], XmNpacking, XmPACK_TIGHT); argcnt++;
913 XtSetArg(args[argcnt], XmNmarginHeight,
0); argcnt++;
914 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
915 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
916 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
917 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
918 XtSetArg(args[argcnt], XmNtopWidget, searchDirBox); argcnt++;
919 XtSetArg(args[argcnt], XmNleftOffset,
2); argcnt++;
920 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
921 XtSetArg(args[argcnt], XmNradioBehavior, True); argcnt++;
922 XtSetArg(args[argcnt], XmNradioAlwaysOne, True); argcnt++;
923 scopeForm = XmCreateRowColumn(form,
"scope", args, argcnt);
924 XtManageChild(scopeForm);
925 XmAddTabGroup(scopeForm);
926
927 argcnt =
0;
928 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
929 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
930 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"In Window"));
931 argcnt++;
932 XtSetArg(args[argcnt], XmNmnemonic,
'i'); argcnt++;
933 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
934 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
935 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
936 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
937 inWinBtn = XmCreateToggleButton(scopeForm,
"inWindow", args, argcnt);
938 XtAddCallback(inWinBtn, XmNvalueChangedCallback,
939 (XtCallbackProc)rScopeWinCB, window);
940 XmStringFree(st1);
941 XtManageChild(inWinBtn);
942
943 argcnt =
0;
944 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
945 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
946 XtSetArg(args[argcnt], XmNlabelString,
947 st1=
MKSTRING(
"In Selection")); argcnt++;
948 XtSetArg(args[argcnt], XmNmnemonic,
'S'); argcnt++;
949 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
950 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
951 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++;
952 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
953 XtSetArg(args[argcnt], XmNleftWidget, inWinBtn); argcnt++;
954 inSelBtn = XmCreateToggleButton(scopeForm,
"inSel", args, argcnt);
955 XtAddCallback(inSelBtn, XmNvalueChangedCallback,
956 (XtCallbackProc)rScopeSelCB, window);
957 XmStringFree(st1);
958 XtManageChild(inSelBtn);
959
960 argcnt =
0;
961 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
962 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
963 XtSetArg(args[argcnt], XmNlabelString,
964 st1=
MKSTRING(
"In Multiple Documents")); argcnt++;
965 XtSetArg(args[argcnt], XmNmnemonic,
'M'); argcnt++;
966 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
967 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
968 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++;
969 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
970 XtSetArg(args[argcnt], XmNleftWidget, inSelBtn); argcnt++;
971 inMultiBtn = XmCreateToggleButton(scopeForm,
"multiFile", args, argcnt);
972 XtAddCallback(inMultiBtn, XmNvalueChangedCallback,
973 (XtCallbackProc)rScopeMultiCB, window);
974 XmStringFree(st1);
975 XtManageChild(inMultiBtn);
976 #else
977 argcnt =
0;
978 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_NONE); argcnt++;
979 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
980 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
981 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
982 XtSetArg(args[argcnt], XmNtopWidget, searchDirBox); argcnt++;
983 XtSetArg(args[argcnt], XmNleftOffset,
6); argcnt++;
984 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
985 allForm = XmCreateForm(form,
"all", args, argcnt);
986 XtManageChild(allForm);
987 XmAddTabGroup(allForm);
988
989 argcnt =
0;
990 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
991 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
992 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
993 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
994 XtSetArg(args[argcnt], XmNleftOffset,
4); argcnt++;
995 XtSetArg(args[argcnt], XmNtopOffset,
6); argcnt++;
996 XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_BEGINNING); argcnt++;
997 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Replace all in:"));
998 argcnt++;
999 label3 = XmCreateLabel(allForm,
"label3", args, argcnt);
1000 XmStringFree(st1);
1001 XtManageChild(label3);
1002
1003 argcnt =
0;
1004 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1005 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1006 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Window"));
1007 argcnt++;
1008 XtSetArg(args[argcnt], XmNmnemonic,
'i'); argcnt++;
1009 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1010 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1011 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++;
1012 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
1013 XtSetArg(args[argcnt], XmNleftWidget, label3); argcnt++;
1014 inWinBtn = XmCreatePushButton(allForm,
"inWindow", args, argcnt);
1015 XtAddCallback(inWinBtn, XmNactivateCallback,
1016 (XtCallbackProc)replaceAllCB, window);
1017 XmStringFree(st1);
1018 XtManageChild(inWinBtn);
1019
1020 argcnt =
0;
1021 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1022 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1023 XtSetArg(args[argcnt], XmNlabelString,
1024 st1=
MKSTRING(
"Selection")); argcnt++;
1025 XtSetArg(args[argcnt], XmNmnemonic,
'S'); argcnt++;
1026 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1027 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1028 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++;
1029 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
1030 XtSetArg(args[argcnt], XmNleftWidget, inWinBtn); argcnt++;
1031 inSelBtn = XmCreatePushButton(allForm,
"inSel", args, argcnt);
1032 XtAddCallback(inSelBtn, XmNactivateCallback,
1033 (XtCallbackProc)rInSelCB, window);
1034 XmStringFree(st1);
1035 XtManageChild(inSelBtn);
1036
1037 argcnt =
0;
1038 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1039 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1040 XtSetArg(args[argcnt], XmNlabelString,
1041 st1=
MKSTRING(
"Multiple Documents...")); argcnt++;
1042 XtSetArg(args[argcnt], XmNmnemonic,
'M'); argcnt++;
1043 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1044 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1045 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_WIDGET); argcnt++;
1046 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
1047 XtSetArg(args[argcnt], XmNleftWidget, inSelBtn); argcnt++;
1048 inMultiBtn = XmCreatePushButton(allForm,
"multiFile", args, argcnt);
1049 XtAddCallback(inMultiBtn, XmNactivateCallback,
1050 (XtCallbackProc)replaceMultiFileCB, window);
1051 XmStringFree(st1);
1052 XtManageChild(inMultiBtn);
1053
1054 #endif
1055
1056 argcnt =
0;
1057 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
1058 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
1059 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
1060 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1061 #ifdef REPLACE_SCOPE
1062 XtSetArg(args[argcnt], XmNtopWidget, scopeForm); argcnt++;
1063 #else
1064 XtSetArg(args[argcnt], XmNtopWidget, allForm); argcnt++;
1065 #endif
1066 XtSetArg(args[argcnt], XmNleftOffset,
6); argcnt++;
1067 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
1068 btnForm = XmCreateForm(form,
"buttons", args, argcnt);
1069 XtManageChild(btnForm);
1070 XmAddTabGroup(btnForm);
1071
1072 argcnt =
0;
1073 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1074 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1075 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Replace")); argcnt++;
1076 XtSetArg(args[argcnt], XmNshowAsDefault, (
short)
1); argcnt++;
1077 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1078 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1079 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1080 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++;
1081 #ifdef REPLACE_SCOPE
1082 XtSetArg(args[argcnt], XmNleftPosition,
0); argcnt++;
1083 XtSetArg(args[argcnt], XmNrightPosition,
21); argcnt++;
1084 #else
1085 XtSetArg(args[argcnt], XmNleftPosition,
0); argcnt++;
1086 XtSetArg(args[argcnt], XmNrightPosition,
25); argcnt++;
1087 #endif
1088 replaceBtn = XmCreatePushButton(btnForm,
"replace", args, argcnt);
1089 XtAddCallback(replaceBtn, XmNactivateCallback, (XtCallbackProc)replaceCB, window);
1090 XmStringFree(st1);
1091 XtManageChild(replaceBtn);
1092 XtVaGetValues(replaceBtn, XmNshadowThickness, &shadowThickness,
NULL);
1093 defaultBtnOffset = shadowThickness +
4;
1094
1095 argcnt =
0;
1096 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1097 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1098 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Find")); argcnt++;
1099 XtSetArg(args[argcnt], XmNmnemonic,
'F'); argcnt++;
1100 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1101 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++;
1102 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1103 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1104 #ifdef REPLACE_SCOPE
1105 XtSetArg(args[argcnt], XmNleftPosition,
21); argcnt++;
1106 XtSetArg(args[argcnt], XmNrightPosition,
33); argcnt++;
1107 #else
1108 XtSetArg(args[argcnt], XmNleftPosition,
25); argcnt++;
1109 XtSetArg(args[argcnt], XmNrightPosition,
42); argcnt++;
1110 #endif
1111 XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++;
1112 XtSetArg(args[argcnt], XmNbottomOffset, defaultBtnOffset); argcnt++;
1113 findBtn = XmCreatePushButton(btnForm,
"find", args, argcnt);
1114 XtAddCallback(findBtn, XmNactivateCallback, (XtCallbackProc)rFindCB, window);
1115 XmStringFree(st1);
1116 XtManageChild(findBtn);
1117
1118 argcnt =
0;
1119 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1120 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1121 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Replace & Find")); argcnt++;
1122 XtSetArg(args[argcnt], XmNmnemonic,
'n'); argcnt++;
1123 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1124 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++;
1125 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1126 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1127 #ifdef REPLACE_SCOPE
1128 XtSetArg(args[argcnt], XmNleftPosition,
33); argcnt++;
1129 XtSetArg(args[argcnt], XmNrightPosition,
62); argcnt++;
1130 #else
1131 XtSetArg(args[argcnt], XmNleftPosition,
42); argcnt++;
1132 XtSetArg(args[argcnt], XmNrightPosition,
79); argcnt++;
1133 #endif
1134 XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++;
1135 XtSetArg(args[argcnt], XmNbottomOffset, defaultBtnOffset); argcnt++;
1136 replaceFindBtn = XmCreatePushButton(btnForm,
"replacefind", args, argcnt);
1137 XtAddCallback(replaceFindBtn, XmNactivateCallback, (XtCallbackProc)replaceFindCB, window);
1138 XmStringFree(st1);
1139 XtManageChild(replaceFindBtn);
1140
1141 #ifdef REPLACE_SCOPE
1142 argcnt =
0;
1143 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1144 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1145 XtSetArg(args[argcnt], XmNlabelString,
1146 st1=
MKSTRING(
"Replace All")); argcnt++;
1147 XtSetArg(args[argcnt], XmNmnemonic,
'A'); argcnt++;
1148 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1149 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1150 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1151 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1152 XtSetArg(args[argcnt], XmNleftPosition,
62); argcnt++;
1153 XtSetArg(args[argcnt], XmNrightPosition,
85); argcnt++;
1154 XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++;
1155 replaceAllBtn = XmCreatePushButton(btnForm,
"all", args, argcnt);
1156 XtAddCallback(replaceAllBtn, XmNactivateCallback,
1157 (XtCallbackProc)replaceAllScopeCB, window);
1158 XmStringFree(st1);
1159 XtManageChild(replaceAllBtn);
1160 #endif
1161
1162 argcnt =
0;
1163 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1164 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1165 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Cancel")); argcnt++;
1166 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1167 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++;
1168 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1169 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1170 #ifdef REPLACE_SCOPE
1171 XtSetArg(args[argcnt], XmNleftPosition,
85); argcnt++;
1172 XtSetArg(args[argcnt], XmNrightPosition,
100); argcnt++;
1173 #else
1174 XtSetArg(args[argcnt], XmNleftPosition,
79); argcnt++;
1175 XtSetArg(args[argcnt], XmNrightPosition,
100); argcnt++;
1176 #endif
1177 XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++;
1178 XtSetArg(args[argcnt], XmNbottomOffset, defaultBtnOffset); argcnt++;
1179 cancelBtn = XmCreatePushButton(btnForm,
"cancel", args, argcnt);
1180 XmStringFree(st1);
1181 XtAddCallback(cancelBtn, XmNactivateCallback, (XtCallbackProc)rCancelCB,
1182 window);
1183 XtManageChild(cancelBtn);
1184
1185 XtVaSetValues(form, XmNcancelButton, cancelBtn,
NULL);
1186 AddDialogMnemonicHandler(form,
FALSE);
1187
1188 window->replaceDlog = form;
1189 window->replaceText = findText;
1190 window->replaceWithText = replaceText;
1191 window->replaceRevToggle = reverseBtn;
1192 window->replaceKeepBtn = keepBtn;
1193 window->replaceBtns = btnForm;
1194 window->replaceBtn = replaceBtn;
1195 window->replaceAndFindBtn = replaceFindBtn;
1196 window->replaceFindBtn = findBtn;
1197 window->replaceSearchTypeBox = searchTypeBox;
1198 #ifdef REPLACE_SCOPE
1199 window->replaceAllBtn = replaceAllBtn;
1200 window->replaceScopeWinToggle = inWinBtn;
1201 window->replaceScopeSelToggle = inSelBtn;
1202 window->replaceScopeMultiToggle = inMultiBtn;
1203 #else
1204 window->replaceInWinBtn = inWinBtn;
1205 window->replaceAllBtn = inMultiBtn;
1206 window->replaceInSelBtn = inSelBtn;
1207 #endif
1208 }
1209
1210 void CreateFindDlog(Widget parent, WindowInfo *window)
1211 {
1212 Arg args[
50];
1213 int argcnt, defaultBtnOffset;
1214 XmString st1;
1215 Widget form, btnForm, searchTypeBox;
1216 Widget findText, label1, label2, cancelBtn, findBtn;
1217 Widget searchDirBox, reverseBtn, keepBtn;
1218 char title[
MAXPATHLEN +
11];
1219 Dimension shadowThickness;
1220
1221 argcnt =
0;
1222 XtSetArg(args[argcnt], XmNautoUnmanage, False); argcnt++;
1223 form = CreateFormDialog(parent,
"findDialog", args, argcnt);
1224 XtVaSetValues(form, XmNshadowThickness,
0,
NULL);
1225 if (GetPrefKeepSearchDlogs()) {
1226 snprintf(title,
sizeof(title),
"Find (in %s)", window->filename);
1227 XtVaSetValues(XtParent(form), XmNtitle, title,
NULL);
1228 }
else
1229 XtVaSetValues(XtParent(form), XmNtitle,
"Find",
NULL);
1230
1231 argcnt =
0;
1232 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1233 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1234 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
1235 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
1236 XtSetArg(args[argcnt], XmNleftOffset,
6); argcnt++;
1237 XtSetArg(args[argcnt], XmNtopOffset,
6); argcnt++;
1238 XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_BEGINNING); argcnt++;
1239 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"String to Find:"));
1240 argcnt++;
1241 XtSetArg(args[argcnt], XmNmnemonic,
'S'); argcnt++;
1242 label1 = XmCreateLabel(form,
"label1", args, argcnt);
1243 XmStringFree(st1);
1244 XtManageChild(label1);
1245
1246 argcnt =
0;
1247 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1248 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1249 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_NONE); argcnt++;
1250 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
1251 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
1252 XtSetArg(args[argcnt], XmNtopOffset,
6); argcnt++;
1253 XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_END); argcnt++;
1254 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
1255 "(use up arrow key to recall previous)")); argcnt++;
1256 label2 = XmCreateLabel(form,
"label2", args, argcnt);
1257 XmStringFree(st1);
1258 XtManageChild(label2);
1259
1260 argcnt =
0;
1261 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1262 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1263 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
1264 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1265 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
1266 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
1267 XtSetArg(args[argcnt], XmNtopWidget, label1); argcnt++;
1268 XtSetArg(args[argcnt], XmNleftOffset,
6); argcnt++;
1269 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
1270 XtSetArg(args[argcnt], XmNmaxLength,
SEARCHMAX); argcnt++;
1271 findText = XNECreateText(form,
"searchString", args, argcnt);
1272 XtAddCallback(findText, XmNfocusCallback, (XtCallbackProc)fFocusCB, window);
1273 XtAddCallback(findText, XmNvalueChangedCallback,
1274 (XtCallbackProc)findTextValueChangedCB, window);
1275 XtAddEventHandler(findText, KeyPressMask, False,
1276 (XtEventHandler)findArrowKeyCB, window);
1277 RemapDeleteKey(findText);
1278 XtManageChild(findText);
1279 XmAddTabGroup(findText);
1280 XtVaSetValues(label1, XmNuserData, findText,
NULL);
1281
1282 argcnt =
0;
1283 XtSetArg(args[argcnt], XmNorientation, XmHORIZONTAL); argcnt++;
1284 XtSetArg(args[argcnt], XmNpacking, XmPACK_TIGHT); argcnt++;
1285 XtSetArg(args[argcnt], XmNmarginHeight,
0); argcnt++;
1286 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
1287 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
1288 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
1289 XtSetArg(args[argcnt], XmNtopWidget, findText); argcnt++;
1290 XtSetArg(args[argcnt], XmNleftOffset,
2); argcnt++;
1291 XtSetArg(args[argcnt], XmNrightOffset,
4); argcnt++;
1292
1293 searchTypeBox = XmCreateRowColumn(form,
"searchTypeBox", args, argcnt);
1294 XtManageChild(searchTypeBox);
1295 XmAddTabGroup(searchTypeBox);
1296
1297 argcnt =
0;
1298 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1299 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1300 XtSetArg(args[argcnt], XmNlabelString,
1301 st1=
MKSTRING(
"Regular Expression")); argcnt++;
1302 XtSetArg(args[argcnt], XmNmnemonic,
'R'); argcnt++;
1303 window->findRegexToggle = XmCreateToggleButton(searchTypeBox,
"regExp", args, argcnt);
1304 XmStringFree(st1);
1305 XtManageChild(window->findRegexToggle);
1306 XtAddCallback(window->findRegexToggle, XmNvalueChangedCallback, (XtCallbackProc) findRegExpToggleCB, window);
1307
1308 argcnt =
0;
1309 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1310 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1311 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Case Sensitive")); argcnt++;
1312 XtSetArg(args[argcnt], XmNmnemonic,
'C'); argcnt++;
1313 window->findCaseToggle = XmCreateToggleButton(searchTypeBox,
"caseSensitive", args, argcnt);
1314 XmStringFree(st1);
1315 XtManageChild(window->findCaseToggle);
1316 XtAddCallback(window->findCaseToggle, XmNvalueChangedCallback, (XtCallbackProc) findCaseToggleCB, window);
1317
1318 argcnt =
0;
1319 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1320 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1321 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Whole Word")); argcnt++;
1322 XtSetArg(args[argcnt], XmNmnemonic,
'h'); argcnt++;
1323 window->findWordToggle = XmCreateToggleButton(searchTypeBox,
"wholeWord", args, argcnt);
1324 XmStringFree(st1);
1325 XtManageChild(window->findWordToggle);
1326
1327 argcnt =
0;
1328 XtSetArg(args[argcnt], XmNorientation, XmHORIZONTAL); argcnt++;
1329 XtSetArg(args[argcnt], XmNpacking, XmPACK_TIGHT); argcnt++;
1330 XtSetArg(args[argcnt], XmNmarginHeight,
0); argcnt++;
1331 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
1332 XtSetArg(args[argcnt], XmNtopOffset,
0); argcnt++;
1333 XtSetArg(args[argcnt], XmNtopWidget, searchTypeBox); argcnt++;
1334 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
1335 XtSetArg(args[argcnt], XmNleftOffset,
2); argcnt++;
1336 XtSetArg(args[argcnt], XmNradioBehavior, False); argcnt++;
1337 searchDirBox = XmCreateRowColumn(form,
"searchDirBox", args, argcnt);
1338 XtManageChild(searchDirBox);
1339 XmAddTabGroup(searchDirBox);
1340
1341 argcnt =
0;
1342 XtSetArg(args[argcnt], XmNlabelString,
1343 st1=
MKSTRING(
"Search Backward")); argcnt++;
1344 XtSetArg(args[argcnt], XmNmnemonic,
'B'); argcnt++;
1345 reverseBtn = XmCreateToggleButton(searchDirBox,
"reverse", args, argcnt);
1346 XmStringFree(st1);
1347 XtManageChild(reverseBtn);
1348
1349 argcnt =
0;
1350 XtSetArg(args[argcnt], XmNlabelString,
1351 st1=
MKSTRING(
"Keep Dialog")); argcnt++;
1352 XtSetArg(args[argcnt], XmNmnemonic,
'K'); argcnt++;
1353 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
1354 XtSetArg(args[argcnt], XmNtopOffset,
0); argcnt++;
1355 XtSetArg(args[argcnt], XmNtopWidget, searchTypeBox); argcnt++;
1356 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
1357 XtSetArg(args[argcnt], XmNrightOffset,
4); argcnt++;
1358 keepBtn = XmCreateToggleButton(form,
"keep", args, argcnt);
1359 XtAddCallback(keepBtn, XmNvalueChangedCallback,
1360 (XtCallbackProc)fKeepCB, window);
1361 XmStringFree(st1);
1362 XtManageChild(keepBtn);
1363 XmAddTabGroup(keepBtn);
1364
1365 argcnt =
0;
1366 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
1367 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
1368 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
1369 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1370 XtSetArg(args[argcnt], XmNtopWidget, searchDirBox); argcnt++;
1371 XtSetArg(args[argcnt], XmNleftOffset,
2); argcnt++;
1372 XtSetArg(args[argcnt], XmNrightOffset,
4); argcnt++;
1373 btnForm = XmCreateForm(form,
"buttons", args, argcnt);
1374 XtManageChild(btnForm);
1375 XmAddTabGroup(btnForm);
1376
1377 argcnt =
0;
1378 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1379 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1380 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Find")); argcnt++;
1381 XtSetArg(args[argcnt], XmNshowAsDefault, (
short)
1); argcnt++;
1382 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1383 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1384 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
1385 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1386 XtSetArg(args[argcnt], XmNleftPosition,
20); argcnt++;
1387 XtSetArg(args[argcnt], XmNbottomOffset,
6); argcnt++;
1388 findBtn = XmCreatePushButton(btnForm,
"find", args, argcnt);
1389 XtAddCallback(findBtn, XmNactivateCallback, (XtCallbackProc)findCB, window);
1390 XmStringFree(st1);
1391 XtManageChild(findBtn);
1392 XtVaGetValues(findBtn, XmNshadowThickness, &shadowThickness,
NULL);
1393 defaultBtnOffset = shadowThickness +
4;
1394
1395 argcnt =
0;
1396 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1397 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1398 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Cancel")); argcnt++;
1399 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1400 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1401 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_NONE); argcnt++;
1402 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1403 XtSetArg(args[argcnt], XmNrightPosition,
80); argcnt++;
1404 XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++;
1405 cancelBtn = XmCreatePushButton(btnForm,
"cancel", args, argcnt);
1406 XtAddCallback(cancelBtn, XmNactivateCallback, (XtCallbackProc)fCancelCB,
1407 window);
1408 XmStringFree(st1);
1409 XtManageChild(cancelBtn);
1410 XtVaSetValues(form, XmNcancelButton, cancelBtn,
NULL);
1411 AddDialogMnemonicHandler(form,
FALSE);
1412
1413 window->findDlog = form;
1414 window->findText = findText;
1415 window->findRevToggle = reverseBtn;
1416 window->findKeepBtn = keepBtn;
1417 window->findBtns = btnForm;
1418 window->findBtn = findBtn;
1419 window->findSearchTypeBox = searchTypeBox;
1420 }
1421
1422 void CreateReplaceMultiFileDlog(WindowInfo *window)
1423 {
1424 Arg args[
50];
1425 int argcnt, defaultBtnOffset;
1426 XmString st1;
1427 Widget list, label1, form, pathBtn;
1428 Widget btnForm, replaceBtn, selectBtn, deselectBtn, cancelBtn;
1429 Dimension shadowThickness;
1430
1431 argcnt =
0;
1432 XtSetArg(args[argcnt], XmNautoUnmanage, False); argcnt++;
1433 XtSetArg (args[argcnt], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
1434 argcnt ++;
1435
1436
1437
1438
1439
1440
1441
1442
1443 form = CreateFormDialog(window->shell,
"replaceMultiFileDialog",
1444 args, argcnt);
1445 XtVaSetValues(form, XmNshadowThickness,
0,
NULL);
1446 XtVaSetValues(XtParent(form), XmNtitle,
"Replace All in Multiple Documents",
1447 NULL);
1448
1449
1450 argcnt =
0;
1451 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1452 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1453 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
1454 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_NONE); argcnt++;
1455
1456
1457
1458
1459
1460
1461
1462 XtSetArg(args[argcnt], XmNtopOffset,
10); argcnt++;
1463 XtSetArg(args[argcnt], XmNleftOffset,
6); argcnt++;
1464 XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_BEGINNING); argcnt++;
1465 XtSetArg(args[argcnt], XmNlabelString,
1466 st1=
MKSTRING(
"Files in which to Replace All:")); argcnt++;
1467 XtSetArg(args[argcnt], XmNmnemonic,
'F'); argcnt++;
1468 label1 = XmCreateLabel(form,
"label1", args, argcnt);
1469 XmStringFree(st1);
1470 XtManageChild(label1);
1471
1472
1473 argcnt =
0;
1474 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1475 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1476 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_NONE); argcnt++;
1477 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
1478 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1479 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1480 XtSetArg(args[argcnt], XmNset, False); argcnt++;
1481 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
1482 XtSetArg(args[argcnt], XmNtopOffset,
6); argcnt++;
1483 XtSetArg(args[argcnt], XmNalignment, XmALIGNMENT_END); argcnt++;
1484 XtSetArg(args[argcnt], XmNlabelString,
1485 st1=
MKSTRING(
"Show Path Names")); argcnt++;
1486 XtSetArg(args[argcnt], XmNmnemonic,
'P'); argcnt++;
1487 pathBtn = XmCreateToggleButton(form,
"path", args, argcnt);
1488 XmStringFree(st1);
1489 XtAddCallback(pathBtn, XmNvalueChangedCallback,
1490 (XtCallbackProc)rMultiFilePathCB, window);
1491 XtManageChild(pathBtn);
1492
1493
1494
1495
1496
1497
1498
1499
1500 argcnt =
0;
1501 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
1502 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
1503 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_NONE); argcnt++;
1504 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_FORM); argcnt++;
1505 XtSetArg(args[argcnt], XmNleftOffset,
6); argcnt++;
1506 XtSetArg(args[argcnt], XmNrightOffset,
6); argcnt++;
1507 XtSetArg(args[argcnt], XmNtopOffset,
6); argcnt++;
1508 XtSetArg(args[argcnt], XmNresizable, (
short)
0); argcnt++;
1509 btnForm = XmCreateForm(form,
"buttons", args, argcnt);
1510 XtManageChild(btnForm);
1511
1512
1513 argcnt =
0;
1514 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1515 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1516 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Replace")); argcnt++;
1517 XtSetArg(args[argcnt], XmNshowAsDefault, (
short)
1); argcnt++;
1518 XtSetArg(args[argcnt], XmNmnemonic,
'R'); argcnt++;
1519 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1520 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1521 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1522 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1523 XtSetArg(args[argcnt], XmNleftPosition,
0); argcnt++;
1524 XtSetArg(args[argcnt], XmNrightPosition,
25); argcnt++;
1525 replaceBtn = XmCreatePushButton(btnForm,
"replace", args, argcnt);
1526 XmStringFree(st1);
1527 XtAddCallback(replaceBtn, XmNactivateCallback,
1528 (XtCallbackProc)rMultiFileReplaceCB, window);
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540 XtManageChild(replaceBtn);
1541 XtVaGetValues(replaceBtn, XmNshadowThickness, &shadowThickness,
NULL);
1542 defaultBtnOffset = shadowThickness +
4;
1543
1544
1545 argcnt =
0;
1546 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1547 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1548 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Select All"));
1549 argcnt++;
1550 XtSetArg(args[argcnt], XmNmnemonic,
'S'); argcnt++;
1551 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1552 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1553 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1554 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1555 XtSetArg(args[argcnt], XmNleftPosition,
25); argcnt++;
1556 XtSetArg(args[argcnt], XmNrightPosition,
50); argcnt++;
1557 XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++;
1558 selectBtn = XmCreatePushButton(btnForm,
"select", args, argcnt);
1559 XmStringFree(st1);
1560 XtAddCallback(selectBtn, XmNactivateCallback,
1561 (XtCallbackProc)rMultiFileSelectAllCB, window);
1562 XtManageChild(selectBtn);
1563
1564
1565 argcnt =
0;
1566 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1567 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1568 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Deselect All"));
1569 argcnt++;
1570 XtSetArg(args[argcnt], XmNmnemonic,
'D'); argcnt++;
1571 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1572 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1573 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1574 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1575 XtSetArg(args[argcnt], XmNleftPosition,
50); argcnt++;
1576 XtSetArg(args[argcnt], XmNrightPosition,
75); argcnt++;
1577 XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++;
1578 deselectBtn = XmCreatePushButton(btnForm,
"deselect", args, argcnt);
1579 XmStringFree(st1);
1580 XtAddCallback(deselectBtn, XmNactivateCallback,
1581 (XtCallbackProc)rMultiFileDeselectAllCB, window);
1582 XtManageChild(deselectBtn);
1583
1584
1585 argcnt =
0;
1586 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1587 XtSetArg(args[argcnt], XmNhighlightThickness,
2); argcnt++;
1588 XtSetArg(args[argcnt], XmNlabelString, st1=
MKSTRING(
"Cancel")); argcnt++;
1589 XtSetArg(args[argcnt], XmNmnemonic,
'C'); argcnt++;
1590 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_FORM); argcnt++;
1591 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_NONE); argcnt++;
1592 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_POSITION); argcnt++;
1593 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_POSITION); argcnt++;
1594 XtSetArg(args[argcnt], XmNleftPosition,
75); argcnt++;
1595 XtSetArg(args[argcnt], XmNrightPosition,
100); argcnt++;
1596 XtSetArg(args[argcnt], XmNtopOffset, defaultBtnOffset); argcnt++;
1597 cancelBtn = XmCreatePushButton(btnForm,
"cancel", args, argcnt);
1598 XmStringFree(st1);
1599 XtAddCallback(cancelBtn, XmNactivateCallback,
1600 (XtCallbackProc)rMultiFileCancelCB, window);
1601 XtManageChild(cancelBtn);
1602
1603
1604 argcnt =
0;
1605 XtSetArg(args[argcnt], XmNtraversalOn, True); argcnt++;
1606 XtSetArg(args[argcnt], XmNtopAttachment, XmATTACH_WIDGET); argcnt++;
1607 XtSetArg(args[argcnt], XmNbottomAttachment, XmATTACH_WIDGET); argcnt++;
1608 XtSetArg(args[argcnt], XmNleftAttachment, XmATTACH_FORM); argcnt++;
1609 XtSetArg(args[argcnt], XmNrightAttachment, XmATTACH_FORM); argcnt++;
1610 XtSetArg(args[argcnt], XmNbottomWidget, btnForm); argcnt++;
1611 XtSetArg(args[argcnt], XmNtopWidget, label1); argcnt++;
1612 XtSetArg(args[argcnt], XmNleftOffset,
10); argcnt++;
1613 XtSetArg(args[argcnt], XmNvisibleItemCount,
10); argcnt++;
1614 XtSetArg(args[argcnt], XmNtopOffset,
6); argcnt++;
1615 XtSetArg(args[argcnt], XmNbottomOffset,
6); argcnt++;
1616 XtSetArg(args[argcnt], XmNrightOffset,
10); argcnt++;
1617
1618
1619
1620 XtSetArg(args[argcnt], XmNselectionPolicy, XmMULTIPLE_SELECT); argcnt++;
1621 list = XmCreateScrolledList(form,
"list_of_files", args, argcnt);
1622 AddMouseWheelSupport(list);
1623 XtManageChild(list);
1624
1625
1626 XmAddTabGroup(list);
1627 XmAddTabGroup(btnForm);
1628 XmAddTabGroup(pathBtn);
1629
1630 XtVaSetValues(label1, XmNuserData, list,
NULL);
1631
1632
1633 XtVaSetValues(form, XmNcancelButton, cancelBtn,
NULL);
1634 AddDialogMnemonicHandler(form,
FALSE);
1635
1636 window->replaceMultiFileDlog = form;
1637 window->replaceMultiFileList = list;
1638 window->replaceMultiFilePathBtn = pathBtn;
1639
1640
1641
1642 XtAddCallback(form, XmNunmapCallback,
1643 (XtCallbackProc)freeWritableWindowsCB, window);
1644 }
1645
1646
1647
1648
1649
1650 static void checkMultiReplaceListForDoomedW(WindowInfo* window,
1651 WindowInfo* doomedWindow)
1652 {
1653 WindowInfo *w;
1654 int i;
1655
1656
1657
1658 if (window == doomedWindow) {
1659 XtUnmanageChild(window->replaceMultiFileDlog);
1660 return;
1661 }
1662
1663
1664 for (i =
0; i < window->nWritableWindows; ++i) {
1665 w = window->writableWindows[i];
1666 if (w == doomedWindow) {
1667 removeDoomedWindowFromList(window, i);
1668 break;
1669 }
1670 }
1671 }
1672
1673
1674
1675
1676
1677 static void removeDoomedWindowFromList(WindowInfo* window,
int index)
1678 {
1679 int entriesToMove;
1680
1681
1682 if (window->nWritableWindows <=
1) {
1683 XtUnmanageChild(window->replaceMultiFileDlog);
1684 return;
1685 }
1686
1687 entriesToMove = window->nWritableWindows - index -
1;
1688 memmove(&(window->writableWindows[index]),
1689 &(window->writableWindows[index+
1]),
1690 (
size_t)(entriesToMove*
sizeof(WindowInfo*)));
1691 window->nWritableWindows -=
1;
1692
1693 XmListDeletePos(window->replaceMultiFileList, index +
1);
1694 }
1695
1696
1697
1698
1699
1700
1701
1702
1703 static void fFocusCB(Widget w, WindowInfo *window,
caddr_t *callData)
1704 {
1705 window = WidgetToWindow(w);
1706 SET_ONE_RSRC(window->findDlog, XmNdefaultButton, window->findBtn);
1707 }
1708 static void rFocusCB(Widget w, WindowInfo *window,
caddr_t *callData)
1709 {
1710 window = WidgetToWindow(w);
1711 SET_ONE_RSRC(window->replaceDlog, XmNdefaultButton, window->replaceBtn);
1712 }
1713
1714
1715 static void rKeepCB(Widget w, WindowInfo *window,
caddr_t *callData)
1716 {
1717 char title[
MAXPATHLEN +
19];
1718
1719 window = WidgetToWindow(w);
1720
1721 if (XmToggleButtonGetState(w)) {
1722 snprintf(title,
sizeof(title),
1723 "Replace/Find (in %s)", window->filename);
1724 XtVaSetValues(XtParent(window->replaceDlog), XmNtitle, title,
NULL);
1725 }
else
1726 XtVaSetValues(XtParent(window->replaceDlog), XmNtitle,
"Replace/Find",
NULL);
1727 }
1728 static void fKeepCB(Widget w, WindowInfo *window,
caddr_t *callData)
1729 {
1730 char title[
MAXPATHLEN +
11];
1731
1732 window = WidgetToWindow(w);
1733
1734 if (XmToggleButtonGetState(w)) {
1735 snprintf(title,
sizeof(title),
"Find (in %s)", window->filename);
1736 XtVaSetValues(XtParent(window->findDlog), XmNtitle, title,
NULL);
1737 }
else
1738 XtVaSetValues(XtParent(window->findDlog), XmNtitle,
"Find",
NULL);
1739 }
1740
1741 static void replaceCB(Widget w, WindowInfo *window,
1742 XmAnyCallbackStruct *callData)
1743 {
1744 char searchString[
SEARCHMAX], replaceString[
SEARCHMAX];
1745 int direction, searchType;
1746 char *params[
5];
1747
1748 window = WidgetToWindow(w);
1749
1750
1751 if (!getReplaceDlogInfo(window, &direction, searchString, replaceString,
1752 &searchType))
1753 return;
1754
1755
1756 resetReplaceTabGroup(window);
1757
1758
1759 params[
0] = searchString;
1760 params[
1] = replaceString;
1761 params[
2] = directionArg(direction);
1762 params[
3] = searchTypeArg(searchType);
1763 params[
4] = searchWrapArg(GetPrefSearchWraps());
1764 windowNotToClose = window;
1765 XtCallActionProc(window->lastFocus,
"replace", callData->event, params,
5);
1766 windowNotToClose =
NULL;
1767
1768
1769 if (!XmToggleButtonGetState(window->replaceKeepBtn))
1770 unmanageReplaceDialogs(window);
1771 }
1772
1773 static void replaceAllCB(Widget w, WindowInfo *window,
1774 XmAnyCallbackStruct *callData)
1775 {
1776 char searchString[
SEARCHMAX], replaceString[
SEARCHMAX];
1777 int direction, searchType;
1778 char *params[
3];
1779
1780 window = WidgetToWindow(w);
1781
1782
1783 if (!getReplaceDlogInfo(window, &direction, searchString, replaceString,
1784 &searchType))
1785 return;
1786
1787
1788 resetReplaceTabGroup(window);
1789
1790
1791 params[
0] = searchString;
1792 params[
1] = replaceString;
1793 params[
2] = searchTypeArg(searchType);
1794 windowNotToClose = window;
1795 XtCallActionProc(window->lastFocus,
"replace_all", callData->event,
1796 params,
3);
1797 windowNotToClose =
NULL;
1798
1799
1800 if (!XmToggleButtonGetState(window->replaceKeepBtn))
1801 unmanageReplaceDialogs(window);
1802 }
1803
1804 static void replaceMultiFileCB(Widget w, WindowInfo *window,
1805 XmAnyCallbackStruct *callData)
1806 {
1807 window = WidgetToWindow(w);
1808 DoReplaceMultiFileDlog(window);
1809 }
1810
1811
1812
1813
1814
1815 static void freeWritableWindowsCB(Widget w, WindowInfo* window,
1816 XmAnyCallbackStruct *callData)
1817 {
1818 window = WidgetToWindow(w);
1819 NEditFree(window->writableWindows);
1820 window->writableWindows =
NULL;
1821 window->nWritableWindows =
0;
1822 }
1823
1824
1825
1826
1827 static int compareWindowNames(
const void *windowA,
const void *windowB)
1828 {
1829 return strcmp((*((WindowInfo**)windowA))->filename,
1830 (*((WindowInfo**)windowB))->filename);
1831 }
1832
1833
1834
1835
1836 static int countWindows(
void)
1837 {
1838 int nWindows;
1839 const WindowInfo *w;
1840
1841 for (w=WindowList, nWindows=
0; w!=
NULL; w=w->next, ++nWindows);
1842
1843 return nWindows;
1844 }
1845
1846
1847
1848
1849 static int countWritableWindows(
void)
1850 {
1851 int nWritable, nBefore, nAfter;
1852 WindowInfo *w;
1853
1854 nBefore = countWindows();
1855 for (w=WindowList, nWritable=
0; w!=
NULL; w=w->next) {
1856
1857
1858
1859 CheckForChangesToFile(w);
1860 nAfter = countWindows();
1861 if (nAfter != nBefore) {
1862
1863 nBefore = nAfter;
1864 w = WindowList;
1865 nWritable =
0;
1866 continue;
1867 }
1868 if (!
IS_ANY_LOCKED(w->lockReasons)) ++nWritable;
1869 }
1870 return nWritable;
1871 }
1872
1873
1874
1875
1876
1877 static void collectWritableWindows(WindowInfo* window)
1878 {
1879 int nWritable = countWritableWindows();
1880 int i;
1881 WindowInfo *w;
1882 WindowInfo **windows;
1883
1884 NEditFree(window->writableWindows);
1885
1886
1887 windows = (WindowInfo **)NEditMalloc(
sizeof(WindowInfo *) * nWritable);
1888 for (w=WindowList, i=
0; w!=
NULL; w=w->next)
1889 if (!
IS_ANY_LOCKED(w->lockReasons)) windows[i++] = w;
1890 qsort(windows, nWritable,
sizeof(WindowInfo *), compareWindowNames);
1891
1892 window->writableWindows = windows;
1893 window->nWritableWindows = nWritable;
1894 }
1895
1896 static void rMultiFileReplaceCB(Widget w, WindowInfo *window,
1897 XmAnyCallbackStruct *callData)
1898 {
1899 char searchString[
SEARCHMAX], replaceString[
SEARCHMAX];
1900 int direction, searchType;
1901 char *params[
4];
1902 int nSelected, i;
1903 WindowInfo *writableWin;
1904 Bool replaceFailed, noWritableLeft;
1905
1906 window = WidgetToWindow(w);
1907 nSelected =
0;
1908 for (i=
0; i<window->nWritableWindows; ++i)
1909 if (XmListPosSelected(window->replaceMultiFileList, i+
1))
1910 ++nSelected;
1911
1912 if (!nSelected)
1913 {
1914 DialogF(
DF_INF, XtParent(window->replaceMultiFileDlog),
1,
"No Files",
1915 "No files selected!",
"OK");
1916 return;
1917 }
1918
1919
1920 resetReplaceTabGroup(window);
1921
1922
1923
1924
1925 if (DialogF(
DF_QUES, window->shell,
2,
"Multi-File Replacement",
1926 "Multi-file replacements are difficult to undo.\n"
1927 "Proceed with the replacement ?",
"Yes",
"Cancel") !=
1)
1928 {
1929
1930 XtUnmanageChild(window->replaceMultiFileDlog);
1931
1932 return;
1933 }
1934
1935
1936
1937
1938
1939 if (!getReplaceDlogInfo(window, &direction, searchString, replaceString,
1940 &searchType))
1941 return;
1942
1943
1944 resetReplaceTabGroup(window);
1945
1946 params[
0] = searchString;
1947 params[
1] = replaceString;
1948 params[
2] = searchTypeArg(searchType);
1949
1950 replaceFailed = True;
1951 noWritableLeft = True;
1952
1953 for (i=
0; i<window->nWritableWindows; ++i) {
1954 writableWin = window->writableWindows[i];
1955 if (XmListPosSelected(window->replaceMultiFileList, i+
1)) {
1956
1957
1958
1959
1960 if (!
IS_ANY_LOCKED(writableWin->lockReasons)) {
1961 noWritableLeft = False;
1962 writableWin->multiFileReplSelected = True;
1963 writableWin->multiFileBusy = True;
1964 writableWin->replaceFailed = False;
1965 XtCallActionProc(writableWin->lastFocus,
"replace_all",
1966 callData->event, params,
3);
1967 writableWin->multiFileBusy = False;
1968 if (!writableWin->replaceFailed)
1969 replaceFailed = False;
1970 }
1971 }
else {
1972 writableWin->multiFileReplSelected = False;
1973 }
1974 }
1975
1976 if (!XmToggleButtonGetState(window->replaceKeepBtn)) {
1977
1978 unmanageReplaceDialogs(window);
1979 }
else {
1980
1981 XtUnmanageChild(window->replaceMultiFileDlog);
1982 }
1983
1984
1985
1986 if (replaceFailed) {
1987 if (GetPrefSearchDlogs()) {
1988 if (noWritableLeft) {
1989 DialogF(
DF_INF, window->shell,
1,
"Read-only Files",
1990 "All selected files have become read-only.",
"OK");
1991 }
else {
1992 DialogF(
DF_INF, window->shell,
1,
"String not found",
1993 "String was not found",
"OK");
1994 }
1995 }
else {
1996 XBell(TheDisplay,
0);
1997 }
1998 }
1999 }
2000
2001 static void rMultiFileCancelCB(Widget w, WindowInfo *window,
caddr_t callData)
2002 {
2003 window = WidgetToWindow(w);
2004
2005
2006 resetReplaceTabGroup(window);
2007
2008
2009 XtUnmanageChild(window->replaceMultiFileDlog);
2010 }
2011
2012 static void rMultiFileSelectAllCB(Widget w, WindowInfo *window,
2013 XmAnyCallbackStruct *callData)
2014 {
2015 int i;
2016 char policy;
2017 Widget list;
2018
2019 window = WidgetToWindow(w);
2020 list = window->replaceMultiFileList;
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031 XtVaGetValues(list, XmNselectionPolicy, &policy,
NULL);
2032 XtVaSetValues(list, XmNselectionPolicy, XmMULTIPLE_SELECT,
NULL);
2033
2034
2035 XmListDeselectAllItems(window->replaceMultiFileList);
2036
2037 for (i=
0; i<window->nWritableWindows; ++i) {
2038 XmListSelectPos(list, i+
1,
FALSE);
2039 }
2040
2041
2042 XtVaSetValues(list, XmNselectionPolicy, policy,
NULL);
2043 }
2044
2045 static void rMultiFileDeselectAllCB(Widget w, WindowInfo *window,
2046 XmAnyCallbackStruct *callData)
2047 {
2048 window = WidgetToWindow(w);
2049 XmListDeselectAllItems(window->replaceMultiFileList);
2050 }
2051
2052 static void rMultiFilePathCB(Widget w, WindowInfo *window,
2053 XmAnyCallbackStruct *callData)
2054 {
2055 window = WidgetToWindow(w);
2056 uploadFileListItems(window, True);
2057 }
2058
2059
2060
2061
2062
2063
2064
2065
2066 static void uploadFileListItems(WindowInfo* window, Bool replace)
2067 {
2068 XmStringTable names;
2069 int nWritable, i, *selected, selectedCount;
2070 char buf[
2*
MAXPATHLEN], policy;
2071 Bool usePathNames;
2072 WindowInfo *w;
2073 Widget list;
2074
2075 nWritable = window->nWritableWindows;
2076 list = window->replaceMultiFileList;
2077
2078 names = (XmStringTable) NEditMalloc(nWritable *
sizeof(XmString*));
2079
2080 usePathNames = XmToggleButtonGetState(window->replaceMultiFilePathBtn);
2081
2082
2083
2084
2085
2086 for (i =
0; i < nWritable; ++i) {
2087 w = window->writableWindows[i];
2088 if (usePathNames && window->filenameSet) {
2089 snprintf(buf,
sizeof(buf),
"%s%s", w->path, w->filename);
2090 }
else {
2091 snprintf(buf,
sizeof(buf),
"%s", w->filename);
2092 }
2093 names[i] = XmStringCreateSimple(buf);
2094 }
2095
2096
2097
2098
2099
2100
2101
2102
2103 XtVaGetValues(list, XmNselectionPolicy, &policy,
NULL);
2104 XtVaSetValues(list, XmNselectionPolicy, XmMULTIPLE_SELECT,
NULL);
2105 if (replace) {
2106
2107
2108 XmListGetSelectedPos(list, &selected, &selectedCount);
2109
2110 XmListReplaceItemsPos(list, names, nWritable,
1);
2111
2112
2113 XmListDeselectAllItems(list);
2114 for (i =
0; i < selectedCount; ++i) {
2115 XmListSelectPos(list, selected[i], False);
2116 }
2117
2118 NEditFree(selected);
2119 }
else {
2120 Arg args[
1];
2121 int nVisible;
2122 int firstSelected =
0;
2123
2124
2125 XmListDeleteAllItems(list);
2126
2127
2128 XmListAddItems(list, names, nWritable,
1);
2129
2130
2131 selectedCount =
0;
2132 for (i =
0; i < nWritable; ++i) {
2133 if (window->writableWindows[i]->multiFileReplSelected) {
2134 XmListSelectPos(list, i+
1, False);
2135 ++selectedCount;
2136
2137 if (firstSelected ==
0) firstSelected = i+
1;
2138 }
2139 }
2140
2141
2142
2143 if (selectedCount ==
0) {
2144 for (i =
0; i < nWritable; ++i) {
2145 XmListSelectPos(list, i+
1, False);
2146 }
2147 firstSelected =
1;
2148 }
2149
2150
2151
2152
2153
2154 XtSetArg(args[
0], XmNvisibleItemCount, &nVisible);
2155 XtGetValues(list, args,
1);
2156
2157
2158 if (nWritable <= nVisible) {
2159
2160 firstSelected =
1;
2161 }
2162 else {
2163 int maxFirst = nWritable - nVisible +
1;
2164 if (firstSelected > maxFirst)
2165 firstSelected = maxFirst;
2166 }
2167 XmListSetPos(list, firstSelected);
2168 }
2169
2170
2171 XtVaSetValues(list, XmNselectionPolicy, policy,
NULL);
2172
2173 for (i =
0; i < nWritable; ++i)
2174 XmStringFree(names[i]);
2175 NEditFree(names);
2176 }
2177
2178
2179
2180
2181
2182 static void unmanageReplaceDialogs(
const WindowInfo *window)
2183 {
2184
2185
2186 if (window->replaceMultiFileDlog &&
2187 XtIsManaged(window->replaceMultiFileDlog)) {
2188 XtUnmanageChild(window->replaceMultiFileDlog);
2189 }
2190
2191 if (window->replaceDlog &&
2192 XtIsManaged(window->replaceDlog)) {
2193 XtUnmanageChild(window->replaceDlog);
2194 }
2195 }
2196
2197 static void rInSelCB(Widget w, WindowInfo *window,
2198 XmAnyCallbackStruct *callData)
2199 {
2200 char searchString[
SEARCHMAX], replaceString[
SEARCHMAX];
2201 int direction, searchType;
2202 char *params[
3];
2203
2204 window = WidgetToWindow(w);
2205
2206
2207 if (!getReplaceDlogInfo(window, &direction, searchString, replaceString,
2208 &searchType))
2209 return;
2210
2211
2212 resetReplaceTabGroup(window);
2213
2214
2215 params[
0] = searchString;
2216 params[
1] = replaceString;
2217 params[
2] = searchTypeArg(searchType);
2218 windowNotToClose = window;
2219 XtCallActionProc(window->lastFocus,
"replace_in_selection",
2220 callData->event, params,
3);
2221 windowNotToClose =
NULL;
2222
2223
2224 if (!XmToggleButtonGetState(window->replaceKeepBtn))
2225 unmanageReplaceDialogs(window);
2226 }
2227
2228 static void rCancelCB(Widget w, WindowInfo *window,
caddr_t callData)
2229 {
2230 window = WidgetToWindow(w);
2231
2232
2233 resetReplaceTabGroup(window);
2234
2235
2236 unmanageReplaceDialogs(window);
2237 }
2238
2239 static void fCancelCB(Widget w, WindowInfo *window,
caddr_t callData)
2240 {
2241 window = WidgetToWindow(w);
2242
2243
2244 resetFindTabGroup(window);
2245
2246
2247 XtUnmanageChild(window->findDlog);
2248 }
2249
2250 static void rFindCB(Widget w, WindowInfo *window,XmAnyCallbackStruct *callData)
2251 {
2252 char searchString[
SEARCHMAX], replaceString[
SEARCHMAX];
2253 int direction, searchType;
2254 char *params[
4];
2255
2256 window = WidgetToWindow(w);
2257
2258
2259 if (!getReplaceDlogInfo(window, &direction, searchString, replaceString,
2260 &searchType))
2261 return;
2262
2263
2264 resetReplaceTabGroup(window);
2265
2266
2267 params[
0] = searchString;
2268 params[
1] = directionArg(direction);
2269 params[
2] = searchTypeArg(searchType);
2270 params[
3] = searchWrapArg(GetPrefSearchWraps());
2271 windowNotToClose = window;
2272 XtCallActionProc(window->lastFocus,
"find", callData->event, params,
4);
2273 windowNotToClose =
NULL;
2274
2275
2276
2277
2278 if (historyIndex(
1) != -
1 &&
2279 !strcmp(SearchHistory[historyIndex(
1)], searchString)) {
2280 NEditFree(ReplaceHistory[historyIndex(
1)]);
2281 ReplaceHistory[historyIndex(
1)] = NEditStrdup(replaceString);
2282 }
2283
2284
2285 if (!XmToggleButtonGetState(window->replaceKeepBtn))
2286 unmanageReplaceDialogs(window);
2287 }
2288
2289 static void replaceFindCB(Widget w, WindowInfo *window, XmAnyCallbackStruct *callData)
2290 {
2291 char searchString[
SEARCHMAX+
1], replaceString[
SEARCHMAX+
1];
2292 int direction, searchType;
2293 char *params[
4];
2294
2295 window = WidgetToWindow(w);
2296
2297
2298 if (!getReplaceDlogInfo(window, &direction, searchString, replaceString,
2299 &searchType))
2300 return;
2301
2302
2303 resetReplaceTabGroup(window);
2304
2305
2306 params[
0] = searchString;
2307 params[
1] = replaceString;
2308 params[
2] = directionArg(direction);
2309 params[
3] = searchTypeArg(searchType);
2310 windowNotToClose = window;
2311 XtCallActionProc(window->lastFocus,
"replace_find", callData->event, params,
4);
2312 windowNotToClose =
NULL;
2313
2314
2315 if (!XmToggleButtonGetState(window->replaceKeepBtn))
2316 unmanageReplaceDialogs(window);
2317 }
2318
2319 static void rSetActionButtons(WindowInfo* window,
2320 int replaceBtn,
2321 int replaceFindBtn,
2322 int replaceAndFindBtn,
2323 #ifndef REPLACE_SCOPE
2324 int replaceInWinBtn,
2325 int replaceInSelBtn,
2326 #endif
2327 int replaceAllBtn)
2328 {
2329 XtSetSensitive(window->replaceBtn, replaceBtn);
2330 XtSetSensitive(window->replaceFindBtn, replaceFindBtn);
2331 XtSetSensitive(window->replaceAndFindBtn, replaceAndFindBtn);
2332 #ifndef REPLACE_SCOPE
2333 XtSetSensitive(window->replaceInWinBtn, replaceInWinBtn);
2334 XtSetSensitive(window->replaceInSelBtn, replaceInSelBtn);
2335 #endif
2336 XtSetSensitive(window->replaceAllBtn, replaceAllBtn);
2337 }
2338
2339 void UpdateReplaceActionButtons(WindowInfo* window)
2340 {
2341
2342 int searchText = textFieldNonEmpty(window->replaceText);
2343 #ifdef REPLACE_SCOPE
2344 switch (window->replaceScope)
2345 {
2346 case REPL_SCOPE_WIN:
2347
2348 rSetActionButtons(window, searchText, searchText, searchText, searchText);
2349 break;
2350
2351 case REPL_SCOPE_SEL:
2352
2353 rSetActionButtons(window, False, False, False, searchText && window->wasSelected);
2354 break;
2355
2356 case REPL_SCOPE_MULTI:
2357
2358 rSetActionButtons(window, False, False, False, searchText);
2359 break;
2360 }
2361 #else
2362 rSetActionButtons(window, searchText, searchText, searchText,
2363 searchText, searchText && window->wasSelected,
2364 searchText && (countWritableWindows() >
1));
2365 #endif
2366 }
2367
2368 #ifdef REPLACE_SCOPE
2369
2370
2371
2372
2373 static void rScopeWinCB(Widget w, WindowInfo *window,
2374 XmAnyCallbackStruct *callData)
2375 {
2376 window = WidgetToWindow(w);
2377 if (XmToggleButtonGetState(window->replaceScopeWinToggle)) {
2378 window->replaceScope =
REPL_SCOPE_WIN;
2379 UpdateReplaceActionButtons(window);
2380 }
2381 }
2382
2383 static void rScopeSelCB(Widget w, WindowInfo *window,
2384 XmAnyCallbackStruct *callData)
2385 {
2386 window = WidgetToWindow(w);
2387 if (XmToggleButtonGetState(window->replaceScopeSelToggle)) {
2388 window->replaceScope =
REPL_SCOPE_SEL;
2389 UpdateReplaceActionButtons(window);
2390 }
2391 }
2392
2393 static void rScopeMultiCB(Widget w, WindowInfo *window,
2394 XmAnyCallbackStruct *callData)
2395 {
2396 window = WidgetToWindow(w);
2397 if (XmToggleButtonGetState(window->replaceScopeMultiToggle)) {
2398 window->replaceScope =
REPL_SCOPE_MULTI;
2399 UpdateReplaceActionButtons(window);
2400 }
2401 }
2402
2403
2404
2405
2406
2407 static void replaceAllScopeCB(Widget w, WindowInfo *window,
2408 XmAnyCallbackStruct *callData)
2409 {
2410 window = WidgetToWindow(w);
2411 switch(window->replaceScope) {
2412 case REPL_SCOPE_WIN:
2413 replaceAllCB(w, window, callData);
2414 break;
2415 case REPL_SCOPE_SEL:
2416 rInSelCB(w, window, callData);
2417 break;
2418 case REPL_SCOPE_MULTI:
2419 replaceMultiFileCB(w, window, callData);
2420 break;
2421 }
2422 }
2423 #endif
2424
2425 static int textFieldNonEmpty(Widget w)
2426 {
2427 char *str = XNETextGetString(w);
2428 int nonEmpty = (str[
0] !=
'\0');
2429 NEditFree(str);
2430 return(nonEmpty);
2431 }
2432
2433 static void rFindTextValueChangedCB(Widget w, WindowInfo *window, XKeyEvent *event)
2434 {
2435 window = WidgetToWindow(w);
2436 UpdateReplaceActionButtons(window);
2437 }
2438
2439 static void rFindArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event)
2440 {
2441 KeySym keysym = XLookupKeysym(event,
0);
2442 int index;
2443 char *searchStr, *replaceStr;
2444 int searchType;
2445
2446 window = WidgetToWindow(w);
2447 index = window->rHistIndex;
2448
2449
2450 if (keysym != XK_Up && keysym != XK_Down)
2451 return;
2452
2453
2454 index += (keysym == XK_Up) ?
1 : -
1;
2455
2456
2457 if (index !=
0 && historyIndex(index) == -
1) {
2458 XBell(TheDisplay,
0);
2459 return;
2460 }
2461
2462 window = WidgetToWindow(w);
2463
2464
2465 if (index ==
0) {
2466 searchStr =
"";
2467 replaceStr =
"";
2468 searchType = GetPrefSearch();
2469 }
else {
2470 searchStr = SearchHistory[historyIndex(index)];
2471 replaceStr = ReplaceHistory[historyIndex(index)];
2472 searchType = SearchTypeHistory[historyIndex(index)];
2473 }
2474
2475
2476 initToggleButtons(searchType, window->replaceRegexToggle,
2477 window->replaceCaseToggle, &window->replaceWordToggle,
2478 &window->replaceLastLiteralCase,
2479 &window->replaceLastRegexCase);
2480
2481 XNETextSetString(window->replaceText, searchStr);
2482 XNETextSetString(window->replaceWithText, replaceStr);
2483
2484
2485 UpdateReplaceActionButtons(window);
2486
2487 window->rHistIndex = index;
2488 }
2489
2490 static void replaceArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event)
2491 {
2492 KeySym keysym = XLookupKeysym(event,
0);
2493 int index;
2494
2495 window = WidgetToWindow(w);
2496 index = window->rHistIndex;
2497
2498
2499 if (keysym != XK_Up && keysym != XK_Down)
2500 return;
2501
2502
2503 index += (keysym == XK_Up) ?
1 : -
1;
2504
2505
2506 if (index !=
0 && historyIndex(index) == -
1) {
2507 XBell(TheDisplay,
0);
2508 return;
2509 }
2510
2511 window = WidgetToWindow(w);
2512
2513
2514 if (index ==
0)
2515 XNETextSetString(window->replaceWithText,
"");
2516 else
2517 XNETextSetString(window->replaceWithText,
2518 ReplaceHistory[historyIndex(index)]);
2519 window->rHistIndex = index;
2520 }
2521
2522 static void fUpdateActionButtons(WindowInfo *window)
2523 {
2524 int buttonState = textFieldNonEmpty(window->findText);
2525 XtSetSensitive(window->findBtn, buttonState);
2526 }
2527
2528 static void findTextValueChangedCB(Widget w, WindowInfo *window, XKeyEvent *event)
2529 {
2530 window = WidgetToWindow(w);
2531 fUpdateActionButtons(window);
2532 }
2533
2534 static void findArrowKeyCB(Widget w, WindowInfo *window, XKeyEvent *event)
2535 {
2536 KeySym keysym = XLookupKeysym(event,
0);
2537 int index;
2538 char *searchStr;
2539 int searchType;
2540
2541 window = WidgetToWindow(w);
2542 index = window->fHistIndex;
2543
2544
2545 if (keysym != XK_Up && keysym != XK_Down)
2546 return;
2547
2548
2549 index += (keysym == XK_Up) ?
1 : -
1;
2550
2551
2552 if (index !=
0 && historyIndex(index) == -
1) {
2553 XBell(TheDisplay,
0);
2554 return;
2555 }
2556
2557
2558
2559 if (index ==
0) {
2560 searchStr =
"";
2561 searchType = GetPrefSearch();
2562 }
else {
2563 searchStr = SearchHistory[historyIndex(index)];
2564 searchType = SearchTypeHistory[historyIndex(index)];
2565 }
2566
2567
2568 initToggleButtons(searchType, window->findRegexToggle,
2569 window->findCaseToggle, &window->findWordToggle,
2570 &window->findLastLiteralCase,
2571 &window->findLastRegexCase);
2572 XNETextSetString(window->findText, searchStr);
2573
2574
2575 fUpdateActionButtons(window);
2576
2577 window->fHistIndex = index;
2578 }
2579
2580 static void findCB(Widget w, WindowInfo *window,XmAnyCallbackStruct *callData)
2581 {
2582 char searchString[
SEARCHMAX];
2583 int direction, searchType;
2584 char *params[
4];
2585
2586 window = WidgetToWindow(w);
2587
2588
2589 if (!getFindDlogInfo(window, &direction, searchString, &searchType))
2590 return;
2591
2592
2593 resetFindTabGroup(window);
2594
2595
2596 params[
0] = searchString;
2597 params[
1] = directionArg(direction);
2598 params[
2] = searchTypeArg(searchType);
2599 params[
3] = searchWrapArg(GetPrefSearchWraps());
2600 windowNotToClose = window;
2601 XtCallActionProc(window->lastFocus,
"find", callData->event, params,
4);
2602 windowNotToClose =
NULL;
2603
2604
2605 if (!XmToggleButtonGetState(window->findKeepBtn))
2606 XtUnmanageChild(window->findDlog);
2607 }
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617 static int getReplaceDlogInfo(WindowInfo *window,
int *direction,
2618 char *searchString,
char *replaceString,
int *searchType)
2619 {
2620 char *replaceText, *replaceWithText;
2621 regexp *compiledRE =
NULL;
2622 char *compileMsg;
2623
2624
2625
2626 replaceText = XNETextGetString(window->replaceText);
2627 replaceWithText = XNETextGetString(window->replaceWithText);
2628
2629 if(XmToggleButtonGetState(window->replaceRegexToggle)) {
2630 int regexDefault;
2631 if(XmToggleButtonGetState(window->replaceCaseToggle)) {
2632 *searchType =
SEARCH_REGEX;
2633 regexDefault =
REDFLT_STANDARD;
2634 }
else {
2635 *searchType =
SEARCH_REGEX_NOCASE;
2636 regexDefault =
REDFLT_CASE_INSENSITIVE;
2637 }
2638
2639
2640 compiledRE = CompileRE(replaceText, &compileMsg, regexDefault);
2641 if (compiledRE ==
NULL) {
2642 DialogF(
DF_WARN, XtParent(window->replaceDlog),
1,
"Search String",
2643 "Please respecify the search string:\n%s",
"OK", compileMsg);
2644 NEditFree(replaceText);
2645 NEditFree(replaceWithText);
2646 return FALSE;
2647 }
2648 NEditFree(compiledRE);
2649 }
else {
2650 if(XmToggleButtonGetState(window->replaceCaseToggle)) {
2651 if(XmToggleButtonGetState(window->replaceWordToggle))
2652 *searchType =
SEARCH_CASE_SENSE_WORD;
2653 else
2654 *searchType =
SEARCH_CASE_SENSE;
2655 }
else {
2656 if(XmToggleButtonGetState(window->replaceWordToggle))
2657 *searchType =
SEARCH_LITERAL_WORD;
2658 else
2659 *searchType =
SEARCH_LITERAL;
2660 }
2661 }
2662
2663 *direction = XmToggleButtonGetState(window->replaceRevToggle) ?
2664 SEARCH_BACKWARD :
SEARCH_FORWARD;
2665
2666
2667 if (strlen(replaceText) >=
SEARCHMAX) {
2668 DialogF(
DF_WARN, XtParent(window->replaceDlog),
1,
"String too long",
2669 "Search string too long.",
"OK");
2670 NEditFree(replaceText);
2671 NEditFree(replaceWithText);
2672 return FALSE;
2673 }
2674 if (strlen(replaceWithText) >=
SEARCHMAX) {
2675 DialogF(
DF_WARN, XtParent(window->replaceDlog),
1,
"String too long",
2676 "Replace string too long.",
"OK");
2677 NEditFree(replaceText);
2678 NEditFree(replaceWithText);
2679 return FALSE;
2680 }
2681 strcpy(searchString, replaceText);
2682 strcpy(replaceString, replaceWithText);
2683 NEditFree(replaceText);
2684 NEditFree(replaceWithText);
2685 return TRUE;
2686 }
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696 static int getFindDlogInfo(WindowInfo *window,
int *direction,
2697 char *searchString,
int *searchType)
2698 {
2699 char *findText;
2700 regexp *compiledRE =
NULL;
2701 char *compileMsg;
2702
2703
2704 findText = XNETextGetString(window->findText);
2705
2706 if(XmToggleButtonGetState(window->findRegexToggle)) {
2707 int regexDefault;
2708 if(XmToggleButtonGetState(window->findCaseToggle)) {
2709 *searchType =
SEARCH_REGEX;
2710 regexDefault =
REDFLT_STANDARD;
2711 }
else {
2712 *searchType =
SEARCH_REGEX_NOCASE;
2713 regexDefault =
REDFLT_CASE_INSENSITIVE;
2714 }
2715
2716
2717 compiledRE = CompileRE(findText, &compileMsg, regexDefault);
2718 if (compiledRE ==
NULL) {
2719 DialogF(
DF_WARN, XtParent(window->findDlog),
1,
"Regex Error",
2720 "Please respecify the search string:\n%s",
"OK", compileMsg);
2721 return FALSE;
2722 }
2723 NEditFree(compiledRE);
2724 }
else {
2725 if(XmToggleButtonGetState(window->findCaseToggle)) {
2726 if(XmToggleButtonGetState(window->findWordToggle))
2727 *searchType =
SEARCH_CASE_SENSE_WORD;
2728 else
2729 *searchType =
SEARCH_CASE_SENSE;
2730 }
else {
2731 if(XmToggleButtonGetState(window->findWordToggle))
2732 *searchType =
SEARCH_LITERAL_WORD;
2733 else
2734 *searchType =
SEARCH_LITERAL;
2735 }
2736 }
2737
2738 *direction = XmToggleButtonGetState(window->findRevToggle) ?
2739 SEARCH_BACKWARD :
SEARCH_FORWARD;
2740
2741 if (isRegexType(*searchType)) {
2742 }
2743
2744
2745 if (strlen(findText) >=
SEARCHMAX) {
2746 DialogF(
DF_WARN, XtParent(window->findDlog),
1,
"String too long",
2747 "Search string too long.",
"OK");
2748 NEditFree(findText);
2749 return FALSE;
2750 }
2751 strcpy(searchString, findText);
2752 NEditFree(findText);
2753 return TRUE;
2754 }
2755
2756 int SearchAndSelectSame(WindowInfo *window,
int direction,
int searchWrap)
2757 {
2758 if (NHist <
1) {
2759 XBell(TheDisplay,
0);
2760 return FALSE;
2761 }
2762
2763 return SearchAndSelect(window, direction, SearchHistory[historyIndex(
1)],
2764 SearchTypeHistory[historyIndex(
1)], searchWrap);
2765 }
2766
2767
2768
2769
2770
2771
2772 int SearchAndSelect(WindowInfo *window,
int direction,
const char *searchString,
2773 int searchType,
int searchWrap)
2774 {
2775 int startPos, endPos;
2776 int beginPos, cursorPos, selStart, selEnd;
2777 int movedFwd =
0;
2778
2779
2780 saveSearchHistory(searchString,
NULL, searchType,
FALSE);
2781
2782
2783
2784 if (searchMatchesSelection(window, searchString, searchType,
2785 &selStart, &selEnd,
NULL,
NULL)) {
2786
2787 if (direction ==
SEARCH_BACKWARD) {
2788 beginPos = selStart -
1;
2789 }
else {
2790 beginPos = selStart +
1;
2791 movedFwd =
1;
2792 }
2793 }
else {
2794 selStart = -
1; selEnd = -
1;
2795
2796 cursorPos = TextGetCursorPos(window->lastFocus);
2797 if (direction ==
SEARCH_BACKWARD) {
2798
2799 beginPos = cursorPos-
1;
2800 }
else {
2801
2802 beginPos = cursorPos;
2803 }
2804 }
2805
2806
2807
2808
2809
2810
2811
2812
2813 iSearchRecordLastBeginPos(window, direction, beginPos);
2814
2815
2816 if (!SearchWindow(window, direction, searchString, searchType, searchWrap,
2817 beginPos, &startPos, &endPos,
NULL,
NULL))
2818 return FALSE;
2819
2820
2821
2822
2823 if (direction==
SEARCH_FORWARD && beginPos==startPos && beginPos==endPos) {
2824 if (!movedFwd &&
2825 !SearchWindow(window, direction, searchString, searchType,
2826 searchWrap, beginPos+
1, &startPos, &endPos,
NULL,
NULL))
2827 return FALSE;
2828 }
2829
2830
2831 if (selStart==startPos && selEnd==endPos) {
2832 XBell(TheDisplay,
0);
2833 return FALSE;
2834 }
2835
2836
2837 BufSelect(window->buffer, startPos, endPos);
2838 MakeSelectionVisible(window, window->lastFocus);
2839 TextSetCursorPos(window->lastFocus, endPos);
2840
2841 return TRUE;
2842 }
2843
2844 void SearchForSelected(WindowInfo *window,
int direction,
int searchType,
2845 int searchWrap, Time time)
2846 {
2847 SearchSelectedCallData *callData = XtNew(SearchSelectedCallData);
2848 callData->direction = direction;
2849 callData->searchType = searchType;
2850 callData->searchWrap = searchWrap;
2851 XtGetSelectionValue(window->textArea,
XA_PRIMARY,
XA_STRING,
2852 selectedSearchCB, callData, time);
2853 }
2854
2855 static void selectedSearchCB(Widget w, XtPointer callData, Atom *selection,
2856 Atom *type, XtPointer v,
unsigned long *length,
int *format)
2857 {
2858 WindowInfo *window = WidgetToWindow(w);
2859 SearchSelectedCallData *callDataItems = (SearchSelectedCallData *)callData;
2860 char *value = v;
2861 int searchType;
2862 char searchString[
SEARCHMAX+
1];
2863
2864 window = WidgetToWindow(w);
2865
2866
2867 if (*type ==
XT_CONVERT_FAIL || value ==
NULL) {
2868 if (GetPrefSearchDlogs())
2869 DialogF(
DF_WARN, window->shell,
1,
"Wrong Selection",
2870 "Selection not appropriate for searching",
"OK");
2871 else
2872 XBell(TheDisplay,
0);
2873 NEditFree(callData);
2874 return;
2875 }
2876 if (*length >
SEARCHMAX) {
2877 if (GetPrefSearchDlogs())
2878 DialogF(
DF_WARN, window->shell,
1,
"Selection too long",
2879 "Selection too long",
"OK");
2880 else
2881 XBell(TheDisplay,
0);
2882 NEditFree(value);
2883 NEditFree(callData);
2884 return;
2885 }
2886 if (*length ==
0) {
2887 XBell(TheDisplay,
0);
2888 NEditFree(value);
2889 NEditFree(callData);
2890 return;
2891 }
2892
2893 if (*format !=
8) {
2894 fprintf(stderr,
"XNEdit: can''t handle non 8-bit text\n");
2895 XBell(TheDisplay,
0);
2896 NEditFree(value);
2897 NEditFree(callData);
2898 return;
2899 }
2900
2901 strncpy(searchString, value, *length);
2902 searchString[*length] =
'\0';
2903 NEditFree(value);
2904
2905
2906
2907 searchType = callDataItems->searchType;
2908 if (searchType ==
SEARCH_REGEX )
2909 searchType =
SEARCH_CASE_SENSE;
2910 else if (searchType ==
SEARCH_REGEX_NOCASE)
2911 searchType =
SEARCH_LITERAL;
2912
2913
2914 SearchAndSelect(window, callDataItems->direction, searchString,
2915 searchType, callDataItems->searchWrap);
2916 NEditFree(callData);
2917 }
2918
2919
2920
2921
2922 void BeginISearch(WindowInfo *window,
int direction)
2923 {
2924
2925
2926 ReadSearchHistory();
2927
2928 window->iSearchStartPos = -
1;
2929 XNETextSetString(window->iSearchText,
"");
2930 XmToggleButtonSetState(window->iSearchRevToggle,
2931 direction ==
SEARCH_BACKWARD,
FALSE);
2932
2933
2934
2935
2936
2937
2938 TempShowISearch(window,
TRUE);
2939 XmProcessTraversal(window->iSearchText, XmTRAVERSE_CURRENT);
2940 }
2941
2942
2943
2944
2945
2946
2947
2948 void EndISearch(WindowInfo *window)
2949 {
2950
2951
2952
2953
2954
2955 window->iSearchStartPos = -
1;
2956
2957
2958 saveSearchHistory(
"",
NULL,
0,
FALSE);
2959
2960
2961 TempShowISearch(window,
FALSE);
2962 }
2963
2964
2965
2966
2967
2968 static void iSearchRecordLastBeginPos(WindowInfo *window,
int direction,
2969 int initPos)
2970 {
2971 window->iSearchLastBeginPos = initPos;
2972 if (direction ==
SEARCH_BACKWARD)
2973 window->iSearchLastBeginPos--;
2974 }
2975
2976
2977
2978
2979
2980
2981
2982
2983 int SearchAndSelectIncremental(WindowInfo *window,
int direction,
2984 const char *searchString,
int searchType,
int searchWrap,
int continued)
2985 {
2986 int beginPos, startPos, endPos;
2987
2988
2989
2990 if (!continued || window->iSearchStartPos == -
1) {
2991 window->iSearchStartPos = TextGetCursorPos(window->lastFocus);
2992 iSearchRecordLastBeginPos(window, direction, window->iSearchStartPos);
2993 }
2994 beginPos = window->iSearchStartPos;
2995
2996
2997
2998
2999
3000 if(searchString[
0] ==
0) {
3001 int beepBeginPos = (direction ==
SEARCH_BACKWARD) ? beginPos-
1:beginPos;
3002 iSearchTryBeepOnWrap(window, direction, beepBeginPos, beepBeginPos);
3003 iSearchRecordLastBeginPos(window, direction, window->iSearchStartPos);
3004 BufUnselect(window->buffer);
3005 TextSetCursorPos(window->lastFocus, beginPos);
3006 return TRUE;
3007 }
3008
3009
3010
3011
3012 if(!(window->iSearchHistIndex >
1 && !strcmp(searchString,
3013 SearchHistory[historyIndex(window->iSearchHistIndex)]))) {
3014 saveSearchHistory(searchString,
NULL, searchType,
TRUE);
3015
3016 window->iSearchHistIndex =
1;
3017 }
3018
3019
3020 if (direction ==
SEARCH_BACKWARD)
3021 beginPos--;
3022
3023
3024 if (!SearchWindow(window, direction, searchString, searchType, searchWrap,
3025 beginPos, &startPos, &endPos,
NULL,
NULL))
3026 return FALSE;
3027
3028 window->iSearchLastBeginPos = startPos;
3029
3030
3031
3032
3033 if (direction==
SEARCH_FORWARD && beginPos==startPos && beginPos==endPos)
3034 if (!SearchWindow(window, direction, searchString, searchType, searchWrap,
3035 beginPos+
1, &startPos, &endPos,
NULL,
NULL))
3036 return FALSE;
3037
3038 window->iSearchLastBeginPos = startPos;
3039
3040
3041 BufSelect(window->buffer, startPos, endPos);
3042 MakeSelectionVisible(window, window->lastFocus);
3043 TextSetCursorPos(window->lastFocus, endPos);
3044
3045 return TRUE;
3046 }
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057 void SetISearchTextCallbacks(WindowInfo *window)
3058 {
3059 static XtTranslations tableText =
NULL;
3060 static char *translationsText =
"Shift<KeyPress>Return: activate()\n";
3061
3062 static XtTranslations tableClear =
NULL;
3063 static char *translationsClear =
3064 "<Btn2Down>:Arm()\n<Btn2Up>: isearch_clear_and_paste() Disarm()\n";
3065
3066 static XtActionsRec actions[] = {
3067 {
"isearch_clear_and_paste", iSearchTextClearAndPasteAP }
3068 };
3069
3070 if (tableText ==
NULL)
3071 tableText = XtParseTranslationTable(translationsText);
3072 XtOverrideTranslations(window->iSearchText, tableText);
3073
3074 if (tableClear ==
NULL) {
3075
3076 XtAppAddActions(XtWidgetToApplicationContext(window->iSearchText),
3077 actions, XtNumber(actions));
3078 tableClear = XtParseTranslationTable(translationsClear);
3079 }
3080 XtOverrideTranslations(window->iSearchClearButton, tableClear);
3081
3082 XtAddCallback(window->iSearchText, XmNactivateCallback,
3083 (XtCallbackProc)iSearchTextActivateCB, window);
3084 XtAddCallback(window->iSearchText, XmNvalueChangedCallback,
3085 (XtCallbackProc)iSearchTextValueChangedCB, window);
3086 XtAddEventHandler(window->iSearchText, KeyPressMask, False,
3087 (XtEventHandler)iSearchTextKeyEH, window);
3088
3089
3090
3091
3092 XtAddCallback(window->iSearchCaseToggle, XmNvalueChangedCallback,
3093 (XtCallbackProc)iSearchCaseToggleCB, window);
3094 XtAddCallback(window->iSearchRegexToggle, XmNvalueChangedCallback,
3095 (XtCallbackProc)iSearchRegExpToggleCB, window);
3096
3097
3098 XtAddCallback(window->iSearchCaseToggle, XmNvalueChangedCallback,
3099 (XtCallbackProc)iSearchTextValueChangedCB, window);
3100 XtAddCallback(window->iSearchRegexToggle, XmNvalueChangedCallback,
3101 (XtCallbackProc)iSearchTextValueChangedCB, window);
3102 XtAddCallback(window->iSearchRevToggle, XmNvalueChangedCallback,
3103 (XtCallbackProc)iSearchTextValueChangedCB, window);
3104
3105
3106 XtAddCallback(window->iSearchFindButton, XmNactivateCallback,
3107 (XtCallbackProc)iSearchTextActivateCB, window);
3108
3109 XtAddCallback(window->iSearchClearButton, XmNactivateCallback,
3110 (XtCallbackProc)iSearchTextClearCB, window);
3111 }
3112
3113
3114
3115
3116
3117 static void iSearchTextSetString(Widget w, WindowInfo *window,
3118 char *str)
3119 {
3120
3121 XtRemoveAllCallbacks(window->iSearchText, XmNvalueChangedCallback);
3122 XtRemoveAllCallbacks(window->iSearchText, XmNactivateCallback);
3123
3124 XNETextSetString(window->iSearchText, str ? str :
"");
3125
3126 XtAddCallback(window->iSearchText, XmNactivateCallback,
3127 (XtCallbackProc)iSearchTextActivateCB, window);
3128 XtAddCallback(window->iSearchText, XmNvalueChangedCallback,
3129 (XtCallbackProc)iSearchTextValueChangedCB, window);
3130 }
3131
3132
3133
3134
3135
3136 static void iSearchTextClearAndPasteAP(Widget w, XEvent *event, String *args,
3137 Cardinal *nArg)
3138 {
3139 WindowInfo *window;
3140 char *selText;
3141 XmAnyCallbackStruct cbdata;
3142
3143 memset(&cbdata,
0,
sizeof (cbdata));
3144 cbdata.event = event;
3145
3146 window = WidgetToWindow(w);
3147
3148 selText = GetAnySelection(window);
3149 iSearchTextSetString(w, window, selText);
3150 if (selText) {
3151 XNETextSetInsertionPosition(window->iSearchText, strlen(selText));
3152 NEditFree(selText);
3153 }
3154 iSearchTextActivateCB(w, window, &cbdata);
3155 }
3156
3157
3158
3159
3160
3161
3162 static void iSearchTextClearCB(Widget w, WindowInfo *window,
3163 XmAnyCallbackStruct *callData)
3164 {
3165 window = WidgetToWindow(w);
3166
3167 iSearchTextSetString(w, window,
NULL);
3168 }
3169
3170
3171
3172
3173
3174
3175 static void iSearchTextActivateCB(Widget w, WindowInfo *window,
3176 XmAnyCallbackStruct *callData)
3177 {
3178 char *params[
4];
3179 char *searchString;
3180 int searchType, direction;
3181
3182 window = WidgetToWindow(w);
3183
3184
3185
3186 searchString = XNETextGetString(window->iSearchText);
3187 if(XmToggleButtonGetState(window->iSearchCaseToggle)) {
3188 if(XmToggleButtonGetState(window->iSearchRegexToggle))
3189 searchType =
SEARCH_REGEX;
3190 else
3191 searchType =
SEARCH_CASE_SENSE;
3192 }
else {
3193 if(XmToggleButtonGetState(window->iSearchRegexToggle))
3194 searchType =
SEARCH_REGEX_NOCASE;
3195 else
3196 searchType =
SEARCH_LITERAL;
3197 }
3198 direction = XmToggleButtonGetState(window->iSearchRevToggle) ?
3199 SEARCH_BACKWARD :
SEARCH_FORWARD;
3200
3201
3202 if (callData->event->xbutton.state & (ShiftMask | ControlMask))
3203 direction = direction ==
SEARCH_FORWARD ?
3204 SEARCH_BACKWARD :
SEARCH_FORWARD;
3205
3206
3207 params[
0] = searchString;
3208 params[
1] = directionArg(direction);
3209 params[
2] = searchTypeArg(searchType);
3210 params[
3] = searchWrapArg(GetPrefSearchWraps());
3211 XtCallActionProc(window->lastFocus,
"find", callData->event, params,
4);
3212 NEditFree(searchString);
3213 }
3214
3215
3216
3217
3218
3219 static void iSearchTextValueChangedCB(Widget w, WindowInfo *window,
3220 XmAnyCallbackStruct *callData)
3221 {
3222 char *params[
5];
3223 char *searchString;
3224 int searchType, direction, nParams;
3225
3226 window = WidgetToWindow(w);
3227
3228
3229
3230 searchString = XNETextGetString(window->iSearchText);
3231 if(XmToggleButtonGetState(window->iSearchCaseToggle)) {
3232 if(XmToggleButtonGetState(window->iSearchRegexToggle))
3233 searchType =
SEARCH_REGEX;
3234 else
3235 searchType =
SEARCH_CASE_SENSE;
3236 }
else {
3237 if(XmToggleButtonGetState(window->iSearchRegexToggle))
3238 searchType =
SEARCH_REGEX_NOCASE;
3239 else
3240 searchType =
SEARCH_LITERAL;
3241 }
3242 direction = XmToggleButtonGetState(window->iSearchRevToggle) ?
3243 SEARCH_BACKWARD :
SEARCH_FORWARD;
3244
3245
3246
3247
3248
3249 if (isRegexType(searchType)) {
3250 regexp *compiledRE =
NULL;
3251 char *compileMsg;
3252 compiledRE = CompileRE(searchString, &compileMsg,
3253 defaultRegexFlags(searchType));
3254 if (compiledRE ==
NULL) {
3255 NEditFree(searchString);
3256 return;
3257 }
3258 NEditFree(compiledRE);
3259 }
3260
3261
3262
3263
3264
3265
3266 nParams =
0;
3267 params[nParams++] = searchString;
3268 params[nParams++] = directionArg(direction);
3269 params[nParams++] = searchTypeArg(searchType);
3270 params[nParams++] = searchWrapArg(GetPrefSearchWraps());
3271 if (window->iSearchStartPos != -
1)
3272 params[nParams++] =
"continued";
3273 XtCallActionProc(window->lastFocus,
"find_incremental",
3274 callData->event, params, nParams);
3275 NEditFree(searchString);
3276 }
3277
3278
3279
3280
3281
3282 static void iSearchTextKeyEH(Widget w, WindowInfo *window,
3283 XKeyEvent *event, Boolean *continueDispatch)
3284 {
3285 KeySym keysym = XLookupKeysym(event,
0);
3286 int index;
3287 char *searchStr;
3288 int searchType;
3289
3290
3291 if (keysym != XK_Up && keysym != XK_Down && keysym != XK_Escape) {
3292 *continueDispatch =
TRUE;
3293 return;
3294 }
3295
3296 window = WidgetToWindow(w);
3297 index = window->iSearchHistIndex;
3298 *continueDispatch =
FALSE;
3299
3300
3301 if (keysym == XK_Escape) {
3302 XmProcessTraversal(window->lastFocus, XmTRAVERSE_CURRENT);
3303 EndISearch(window);
3304 return;
3305 }
3306
3307
3308 index += (keysym == XK_Up) ?
1 : -
1;
3309
3310
3311 if (index !=
0 && historyIndex(index) == -
1) {
3312 XBell(TheDisplay,
0);
3313 return;
3314 }
3315
3316
3317 if (index ==
0) {
3318 searchStr =
"";
3319 searchType = GetPrefSearch();
3320 }
else {
3321 searchStr = SearchHistory[historyIndex(index)];
3322 searchType = SearchTypeHistory[historyIndex(index)];
3323 }
3324
3325
3326
3327 window->iSearchHistIndex = index;
3328 initToggleButtons(searchType, window->iSearchRegexToggle,
3329 window->iSearchCaseToggle,
NULL,
3330 &window->iSearchLastLiteralCase,
3331 &window->iSearchLastRegexCase);
3332
3333
3334 XNETextSetString(window->iSearchText, searchStr);
3335 XNETextSetInsertionPosition(window->iSearchText,
3336 XNETextGetLastPosition(window->iSearchText));
3337 }
3338
3339
3340
3341
3342
3343
3344
3345 void FlashMatching(WindowInfo *window, Widget textW)
3346 {
3347 char c;
3348 void *style;
3349 int pos, matchIndex;
3350 int startPos, endPos, searchPos, matchPos;
3351 int constrain;
3352
3353
3354 if (window->flashTimeoutID !=
0) {
3355 eraseFlash(window);
3356 XtRemoveTimeOut(window->flashTimeoutID);
3357 window->flashTimeoutID =
0;
3358 }
3359
3360
3361 if (window->showMatchingStyle ==
NO_FLASH) {
3362 return;
3363 }
3364
3365
3366 if (window->buffer->primary.selected)
3367 return;
3368
3369
3370 pos = TextGetCursorPos(textW) -
1;
3371 if (pos <
0)
3372 return;
3373 c = BufGetCharacter(window->buffer, pos);
3374 style = GetHighlightInfo(window, pos);
3375
3376
3377 for (matchIndex =
0; matchIndex<
N_FLASH_CHARS; matchIndex++) {
3378 if (MatchingChars[matchIndex].c == c)
3379 break;
3380 }
3381 if (matchIndex ==
N_FLASH_CHARS)
3382 return;
3383
3384
3385
3386 constrain = ((window->nPanes ==
0) &&
3387 (window->showMatchingStyle ==
FLASH_DELIMIT));
3388
3389 if (MatchingChars[matchIndex].direction ==
SEARCH_BACKWARD) {
3390 startPos = constrain ? TextFirstVisiblePos(textW) :
0;
3391 endPos = pos;
3392 searchPos = endPos;
3393 }
else {
3394 startPos = pos;
3395 endPos = constrain ? TextLastVisiblePos(textW) :
3396 window->buffer->length;
3397 searchPos = startPos;
3398 }
3399
3400
3401 if (!findMatchingChar(window, c, style, searchPos, startPos, endPos,
3402 &matchPos))
3403 return;
3404
3405 if (window->showMatchingStyle ==
FLASH_DELIMIT) {
3406
3407 BufHighlight(window->buffer, matchPos, matchPos+
1);
3408 }
else {
3409
3410 if (MatchingChars[matchIndex].direction ==
SEARCH_BACKWARD) {
3411 BufHighlight(window->buffer, matchPos, pos+
1);
3412 }
else {
3413 BufHighlight(window->buffer, matchPos+
1, pos);
3414 }
3415 }
3416
3417
3418 window->flashTimeoutID = XtAppAddTimeOut(
3419 XtWidgetToApplicationContext(window->shell),
1500,
3420 flashTimeoutProc, window);
3421 window->flashPos = matchPos;
3422 }
3423
3424 void SelectToMatchingCharacter(WindowInfo *window)
3425 {
3426 int selStart, selEnd;
3427 int startPos, endPos, matchPos;
3428 textBuffer *buf = window->buffer;
3429
3430
3431
3432
3433 if (!GetSimpleSelection(buf, &selStart, &selEnd)) {
3434 selEnd = TextGetCursorPos(window->lastFocus);
3435 if (window->overstrike)
3436 selEnd +=
1;
3437 selStart = selEnd -
1;
3438 if (selStart <
0) {
3439 XBell(TheDisplay,
0);
3440 return;
3441 }
3442 }
3443 if ((selEnd - selStart) !=
1) {
3444 XBell(TheDisplay,
0);
3445 return;
3446 }
3447
3448
3449 if (!findMatchingChar(window, BufGetCharacter(buf, selStart),
3450 GetHighlightInfo(window, selStart), selStart,
0, buf->length, &matchPos)) {
3451 XBell(TheDisplay,
0);
3452 return;
3453 }
3454 startPos = (matchPos > selStart) ? selStart : matchPos;
3455 endPos = (matchPos > selStart) ? matchPos : selStart;
3456
3457
3458
3459
3460
3461
3462 XtVaSetValues(window->lastFocus, textNautoShowInsertPos, False,
NULL);
3463
3464 BufSelect(buf, startPos, endPos+
1);
3465 MakeSelectionVisible(window, window->lastFocus);
3466 XtVaSetValues(window->lastFocus, textNautoShowInsertPos, True,
NULL);
3467 }
3468
3469 void GotoMatchingCharacter(WindowInfo *window)
3470 {
3471 int selStart, selEnd;
3472 int matchPos;
3473 textBuffer *buf = window->buffer;
3474
3475
3476
3477
3478 if (!GetSimpleSelection(buf, &selStart, &selEnd)) {
3479 selEnd = TextGetCursorPos(window->lastFocus);
3480 if (window->overstrike)
3481 selEnd +=
1;
3482 selStart = selEnd -
1;
3483 if (selStart <
0) {
3484 XBell(TheDisplay,
0);
3485 return;
3486 }
3487 }
3488 if ((selEnd - selStart) !=
1) {
3489 XBell(TheDisplay,
0);
3490 return;
3491 }
3492
3493
3494 if (!findMatchingChar(window, BufGetCharacter(buf, selStart),
3495 GetHighlightInfo(window, selStart), selStart,
0,
3496 buf->length, &matchPos)) {
3497 XBell(TheDisplay,
0);
3498 return;
3499 }
3500
3501
3502
3503
3504
3505
3506 XtVaSetValues(window->lastFocus, textNautoShowInsertPos, False,
NULL);
3507 TextSetCursorPos(window->lastFocus, matchPos+
1);
3508 MakeSelectionVisible(window, window->lastFocus);
3509 XtVaSetValues(window->lastFocus, textNautoShowInsertPos, True,
NULL);
3510 }
3511
3512 static int findMatchingChar(WindowInfo *window,
char toMatch,
3513 void* styleToMatch,
int charPos,
int startLimit,
int endLimit,
3514 int *matchPos)
3515 {
3516 int nestDepth, matchIndex, direction, beginPos, pos;
3517 char matchChar, c;
3518 void *style =
NULL;
3519 textBuffer *buf = window->buffer;
3520 int matchSyntaxBased = window->matchSyntaxBased;
3521
3522
3523 if (!matchSyntaxBased) style = styleToMatch;
3524
3525
3526 for (matchIndex =
0; matchIndex<
N_MATCH_CHARS; matchIndex++) {
3527 if (MatchingChars[matchIndex].c == toMatch)
3528 break;
3529 }
3530 if (matchIndex ==
N_MATCH_CHARS)
3531 return FALSE;
3532 matchChar = MatchingChars[matchIndex].match;
3533 direction = MatchingChars[matchIndex].direction;
3534
3535
3536 beginPos = (direction==
SEARCH_FORWARD) ? charPos+
1 : charPos-
1;
3537 nestDepth =
1;
3538 if (direction ==
SEARCH_FORWARD) {
3539 for (pos=beginPos; pos<endLimit; pos++) {
3540 c=BufGetCharacter(buf, pos);
3541 if (c == matchChar) {
3542 if (matchSyntaxBased) style = GetHighlightInfo(window, pos);
3543 if (style == styleToMatch) {
3544 nestDepth--;
3545 if (nestDepth ==
0) {
3546 *matchPos = pos;
3547 return TRUE;
3548 }
3549 }
3550 }
else if (c == toMatch) {
3551 if (matchSyntaxBased) style = GetHighlightInfo(window, pos);
3552 if (style == styleToMatch)
3553 nestDepth++;
3554 }
3555 }
3556 }
else {
3557 for (pos=beginPos; pos>=startLimit; pos--) {
3558 c=BufGetCharacter(buf, pos);
3559 if (c == matchChar) {
3560 if (matchSyntaxBased) style = GetHighlightInfo(window, pos);
3561 if (style == styleToMatch) {
3562 nestDepth--;
3563 if (nestDepth ==
0) {
3564 *matchPos = pos;
3565 return TRUE;
3566 }
3567 }
3568 }
else if (c == toMatch) {
3569 if (matchSyntaxBased) style = GetHighlightInfo(window, pos);
3570 if (style == styleToMatch)
3571 nestDepth++;
3572 }
3573 }
3574 }
3575 return FALSE;
3576 }
3577
3578
3579
3580
3581 static void flashTimeoutProc(XtPointer clientData, XtIntervalId *id)
3582 {
3583 eraseFlash((WindowInfo *)clientData);
3584 ((WindowInfo *)clientData)->flashTimeoutID =
0;
3585 }
3586
3587
3588
3589
3590
3591 static void eraseFlash(WindowInfo *window)
3592 {
3593 BufUnhighlight(window->buffer);
3594 }
3595
3596
3597
3598
3599
3600 int ReplaceSame(WindowInfo *window,
int direction,
int searchWrap)
3601 {
3602 if (NHist <
1) {
3603 XBell(TheDisplay,
0);
3604 return FALSE;
3605 }
3606
3607 return SearchAndReplace(window, direction, SearchHistory[historyIndex(
1)],
3608 ReplaceHistory[historyIndex(
1)],
3609 SearchTypeHistory[historyIndex(
1)], searchWrap);
3610 }
3611
3612
3613
3614
3615
3616 int ReplaceFindSame(WindowInfo *window,
int direction,
int searchWrap)
3617 {
3618 if (NHist <
1) {
3619 XBell(TheDisplay,
0);
3620 return FALSE;
3621 }
3622
3623 return ReplaceAndSearch(window, direction, SearchHistory[historyIndex(
1)],
3624 ReplaceHistory[historyIndex(
1)],
3625 SearchTypeHistory[historyIndex(
1)], searchWrap);
3626 }
3627
3628
3629
3630
3631
3632 int ReplaceAndSearch(WindowInfo *window,
int direction,
const char *searchString,
3633 const char *replaceString,
int searchType,
int searchWrap)
3634 {
3635 int startPos =
0, endPos =
0, replaceLen =
0;
3636 int searchExtentBW, searchExtentFW;
3637 int replaced;
3638
3639
3640 saveSearchHistory(searchString, replaceString, searchType,
FALSE);
3641
3642 replaced =
0;
3643
3644
3645 if (searchMatchesSelection(window, searchString, searchType,
3646 &startPos, &endPos, &searchExtentBW,
3647 &searchExtentFW)) {
3648
3649 if (isRegexType(searchType)) {
3650 char replaceResult[
SEARCHMAX+
1], *foundString;
3651 foundString = BufGetRange(window->buffer, searchExtentBW,
3652 searchExtentFW+
1);
3653 replaceUsingRE(searchString, replaceString, foundString,
3654 startPos-searchExtentBW,
3655 replaceResult,
SEARCHMAX, startPos ==
0 ?
'\0' :
3656 BufGetCharacter(window->buffer, startPos-
1),
3657 GetWindowDelimiters(window), defaultRegexFlags(searchType));
3658 NEditFree(foundString);
3659 BufReplace(window->buffer, startPos, endPos, replaceResult);
3660 replaceLen = strlen(replaceResult);
3661 }
else {
3662 BufReplace(window->buffer, startPos, endPos, replaceString);
3663 replaceLen = strlen(replaceString);
3664 }
3665
3666
3667
3668 TextSetCursorPos(window->lastFocus, startPos +
3669 ((direction ==
SEARCH_FORWARD) ? replaceLen :
0));
3670 replaced =
1;
3671 }
3672
3673
3674 SearchAndSelect(window, direction, searchString, searchType, searchWrap);
3675
3676 return replaced;
3677 }
3678
3679
3680
3681
3682
3683
3684 int SearchAndReplace(WindowInfo *window,
int direction,
const char *searchString,
3685 const char *replaceString,
int searchType,
int searchWrap)
3686 {
3687 int startPos, endPos, replaceLen, searchExtentBW, searchExtentFW;
3688 int found;
3689 int beginPos, cursorPos;
3690
3691
3692 saveSearchHistory(searchString, replaceString, searchType,
FALSE);
3693
3694
3695
3696
3697
3698 if (!searchMatchesSelection(window, searchString, searchType,
3699 &startPos, &endPos, &searchExtentBW, &searchExtentFW)) {
3700
3701 cursorPos = TextGetCursorPos(window->lastFocus);
3702 if (direction ==
SEARCH_BACKWARD) {
3703
3704 beginPos = cursorPos-
1;
3705 }
else {
3706
3707 beginPos = cursorPos;
3708 }
3709
3710 found = SearchWindow(window, direction, searchString, searchType, searchWrap,
3711 beginPos, &startPos, &endPos, &searchExtentBW, &searchExtentFW);
3712 if (!found)
3713 return FALSE;
3714 }
3715
3716
3717 if (isRegexType(searchType)) {
3718 char replaceResult[
SEARCHMAX], *foundString;
3719 foundString = BufGetRange(window->buffer, searchExtentBW, searchExtentFW+
1);
3720 replaceUsingRE(searchString, replaceString, foundString,
3721 startPos - searchExtentBW,
3722 replaceResult,
SEARCHMAX, startPos ==
0 ?
'\0' :
3723 BufGetCharacter(window->buffer, startPos-
1),
3724 GetWindowDelimiters(window), defaultRegexFlags(searchType));
3725 NEditFree(foundString);
3726 BufReplace(window->buffer, startPos, endPos, replaceResult);
3727 replaceLen = strlen(replaceResult);
3728 }
else {
3729 BufReplace(window->buffer, startPos, endPos, replaceString);
3730 replaceLen = strlen(replaceString);
3731 }
3732
3733
3734
3735
3736 BufUnselect(window->buffer);
3737
3738
3739
3740
3741
3742
3743 XtVaSetValues(window->lastFocus, textNautoShowInsertPos, False,
NULL);
3744 TextSetCursorPos(window->lastFocus, startPos +
3745 ((direction ==
SEARCH_FORWARD) ? replaceLen :
0));
3746 MakeSelectionVisible(window, window->lastFocus);
3747 XtVaSetValues(window->lastFocus, textNautoShowInsertPos, True,
NULL);
3748
3749 return TRUE;
3750 }
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767 static Boolean prefOrUserCancelsSubst(
const Widget parent,
3768 const Display* display)
3769 {
3770 Boolean cancel = True;
3771 unsigned confirmResult =
0;
3772
3773 switch (GetPrefTruncSubstitution()) {
3774 case TRUNCSUBST_SILENT:
3775
3776 cancel = True;
3777 break;
3778
3779 case TRUNCSUBST_FAIL:
3780
3781 XBell((Display*) display,
0);
3782 DialogF(
DF_INF, parent,
1,
"Substitution Failed",
3783 "The result length of the substitution exceeded an internal limit.\n"
3784 "The substitution is canceled.",
3785 "OK");
3786 cancel = True;
3787 break;
3788
3789 case TRUNCSUBST_WARN:
3790
3791 XBell((Display*) display,
0);
3792 confirmResult = DialogF(
DF_WARN, parent,
2,
3793 "Substitution Failed",
3794 "The result length of the substitution exceeded an internal limit.\n"
3795 "Executing the substitution will result in loss of data.",
3796 "Lose Data",
"Cancel");
3797 cancel = (
1 != confirmResult);
3798 break;
3799
3800 case TRUNCSUBST_IGNORE:
3801
3802 cancel = False;
3803 break;
3804 }
3805
3806 return cancel;
3807 }
3808
3809
3810
3811
3812
3813
3814 void ReplaceInSelection(
const WindowInfo* window,
const char* searchString,
3815 const char* replaceString,
int searchType)
3816 {
3817 int selStart, selEnd, beginPos, startPos, endPos, realOffset, replaceLen;
3818 int found, isRect, rectStart, rectEnd, lineStart, cursorPos;
3819 int extentBW, extentFW;
3820 char *fileString;
3821 textBuffer *tempBuf;
3822 Boolean substSuccess = False;
3823 Boolean anyFound = False;
3824 Boolean cancelSubst = True;
3825
3826
3827 saveSearchHistory(searchString, replaceString, searchType,
FALSE);
3828
3829
3830 if (!BufGetSelectionPos(window->buffer, &selStart, &selEnd, &isRect,
3831 &rectStart, &rectEnd))
3832 return;
3833
3834
3835 if (isRect) {
3836 selStart = BufStartOfLine(window->buffer, selStart);
3837 selEnd = BufEndOfLine(window->buffer, selEnd);
3838 fileString = BufGetRange(window->buffer, selStart, selEnd);
3839 }
else
3840 fileString = BufGetSelectionText(window->buffer);
3841
3842
3843
3844
3845 tempBuf = BufCreate();
3846 BufSetAll(tempBuf, fileString);
3847
3848
3849 replaceLen = strlen(replaceString);
3850 found =
TRUE;
3851 beginPos =
0;
3852 cursorPos =
0;
3853 realOffset =
0;
3854 while (found) {
3855 found = SearchString(fileString, searchString,
SEARCH_FORWARD,
3856 searchType,
FALSE, beginPos, &startPos, &endPos, &extentBW,
3857 &extentFW, GetWindowDelimiters(window));
3858 if (!found)
3859 break;
3860
3861 anyFound = True;
3862
3863
3864 if (isRect) {
3865 lineStart = BufStartOfLine(window->buffer, selStart+startPos);
3866 if (BufCountDispChars(window->buffer, lineStart, selStart+startPos) <
3867 rectStart || BufCountDispChars(window->buffer, lineStart,
3868 selStart+endPos) > rectEnd) {
3869 if (fileString[endPos] ==
'\0')
3870 break;
3871
3872
3873
3874
3875
3876 if (BufCountDispChars(window->buffer, lineStart,
3877 selStart+startPos) < rectStart &&
3878 BufCountDispChars(window->buffer, lineStart,
3879 selStart+endPos) > rectStart)
3880 beginPos +=
1;
3881 else
3882 beginPos = (startPos == endPos) ? endPos+
1 : endPos;
3883 continue;
3884 }
3885 }
3886
3887
3888
3889
3890 if (startPos == (selEnd - selStart)) {
3891 found = False;
3892 break;
3893 }
3894
3895
3896 if (isRegexType(searchType)) {
3897 char replaceResult[
SEARCHMAX], *foundString;
3898 foundString = BufGetRange(tempBuf, extentBW+realOffset,
3899 extentFW+realOffset+
1);
3900 substSuccess = replaceUsingRE(searchString, replaceString,
3901 foundString, startPos - extentBW, replaceResult,
SEARCHMAX,
3902 0 == (startPos + realOffset)
3903 ?
'\0'
3904 : BufGetCharacter(tempBuf, startPos + realOffset -
1),
3905 GetWindowDelimiters(window), defaultRegexFlags(searchType));
3906 NEditFree(foundString);
3907
3908 if (!substSuccess) {
3909
3910
3911
3912 cancelSubst = prefOrUserCancelsSubst(window->shell, TheDisplay);
3913
3914 if (cancelSubst) {
3915
3916 break;
3917 }
3918 }
3919
3920 BufReplace(tempBuf, startPos+realOffset, endPos+realOffset,
3921 replaceResult);
3922 replaceLen = strlen(replaceResult);
3923 }
else {
3924
3925 BufReplace(tempBuf, startPos+realOffset, endPos+realOffset,
3926 replaceString);
3927 substSuccess = True;
3928 }
3929
3930 realOffset += replaceLen - (endPos - startPos);
3931
3932 beginPos = (startPos == endPos) ? endPos+
1 : endPos;
3933 cursorPos = endPos;
3934 if (fileString[endPos] ==
'\0')
3935 break;
3936 }
3937 NEditFree(fileString);
3938
3939 if (anyFound) {
3940 if (substSuccess || !cancelSubst) {
3941
3942
3943
3944
3945 BufReplace(window->buffer, selStart, selEnd, BufAsString(tempBuf));
3946
3947
3948 TextSetCursorPos(window->lastFocus, selStart + cursorPos + realOffset);
3949
3950
3951
3952 if (!isRect) {
3953 BufSelect(window->buffer, selStart, selEnd + realOffset);
3954 }
3955 }
3956 }
else {
3957
3958 if (GetPrefSearchDlogs()) {
3959
3960
3961 if (window->findDlog && XtIsManaged(window->findDlog) &&
3962 !XmToggleButtonGetState(window->findKeepBtn))
3963 XtUnmanageChild(window->findDlog);
3964 if (window->replaceDlog && XtIsManaged(window->replaceDlog) &&
3965 !XmToggleButtonGetState(window->replaceKeepBtn))
3966 unmanageReplaceDialogs(window);
3967 DialogF(
DF_INF, window->shell,
1,
"String not found",
3968 "String was not found",
"OK");
3969 }
else
3970 XBell(TheDisplay,
0);
3971 }
3972
3973 BufFree(tempBuf);
3974 return;
3975 }
3976
3977
3978
3979
3980
3981 int ReplaceAll(WindowInfo *window,
const char *searchString,
3982 const char *replaceString,
int searchType)
3983 {
3984 const char *fileString;
3985 char *newFileString;
3986 int copyStart, copyEnd, replacementLen;
3987
3988
3989 if (*searchString ==
'\0')
3990 return FALSE;
3991
3992
3993 saveSearchHistory(searchString, replaceString, searchType,
FALSE);
3994
3995
3996 fileString = BufAsString(window->buffer);
3997
3998 newFileString = ReplaceAllInString(fileString, searchString, replaceString,
3999 searchType, ©Start, ©End, &replacementLen,
4000 GetWindowDelimiters(window));
4001
4002 if (newFileString ==
NULL) {
4003 if (window->multiFileBusy) {
4004 window->replaceFailed =
TRUE;
4005
4006 }
else if (GetPrefSearchDlogs()) {
4007 if (window->findDlog && XtIsManaged(window->findDlog) &&
4008 !XmToggleButtonGetState(window->findKeepBtn))
4009 XtUnmanageChild(window->findDlog);
4010 if (window->replaceDlog && XtIsManaged(window->replaceDlog) &&
4011 !XmToggleButtonGetState(window->replaceKeepBtn))
4012 unmanageReplaceDialogs(window);
4013 DialogF(
DF_INF, window->shell,
1,
"String not found",
4014 "String was not found",
"OK");
4015 }
else
4016 XBell(TheDisplay,
0);
4017 return FALSE;
4018 }
4019
4020
4021 BufReplace(window->buffer, copyStart, copyEnd, newFileString);
4022
4023
4024 TextSetCursorPos(window->lastFocus, copyStart + replacementLen);
4025
4026 NEditFree(newFileString);
4027 return TRUE;
4028 }
4029
4030
4031
4032
4033
4034
4035
4036 char *ReplaceAllInString(
const char *inString,
const char *searchString,
4037 const char *replaceString,
int searchType,
int *copyStart,
4038 int *copyEnd,
int *replacementLength,
const char *delimiters)
4039 {
4040 int beginPos, startPos, endPos, lastEndPos;
4041 int found, nFound, removeLen, replaceLen, copyLen, addLen;
4042 char *outString, *fillPtr;
4043 int searchExtentBW, searchExtentFW;
4044
4045
4046 if (*searchString ==
'\0')
4047 return NULL;
4048
4049
4050
4051 replaceLen = strlen(replaceString);
4052 found =
TRUE;
4053 nFound =
0;
4054 removeLen =
0;
4055 addLen =
0;
4056 beginPos =
0;
4057 *copyStart = -
1;
4058 while (found) {
4059 found = SearchString(inString, searchString,
SEARCH_FORWARD, searchType,
4060 FALSE, beginPos, &startPos, &endPos, &searchExtentBW,
4061 &searchExtentFW, delimiters);
4062 if (found) {
4063 if (*copyStart <
0)
4064 *copyStart = startPos;
4065 *copyEnd = endPos;
4066
4067 beginPos = (startPos == endPos) ? endPos+
1 : endPos;
4068 nFound++;
4069 removeLen += endPos - startPos;
4070 if (isRegexType(searchType)) {
4071 char replaceResult[
SEARCHMAX];
4072 replaceUsingRE(searchString, replaceString, &inString[searchExtentBW],
4073 startPos-searchExtentBW,
4074 replaceResult,
SEARCHMAX, startPos ==
0 ?
'\0' :
4075 inString[startPos-
1], delimiters,
4076 defaultRegexFlags(searchType));
4077 addLen += strlen(replaceResult);
4078 }
else
4079 addLen += replaceLen;
4080 if (inString[endPos] ==
'\0')
4081 break;
4082 }
4083 }
4084 if (nFound ==
0)
4085 return NULL;
4086
4087
4088
4089 copyLen = *copyEnd - *copyStart;
4090 outString = (
char*)NEditMalloc(copyLen - removeLen + addLen +
1);
4091
4092
4093
4094 found =
TRUE;
4095 beginPos =
0;
4096 lastEndPos =
0;
4097 fillPtr = outString;
4098 while (found) {
4099 found = SearchString(inString, searchString,
SEARCH_FORWARD, searchType,
4100 FALSE, beginPos, &startPos, &endPos, &searchExtentBW,
4101 &searchExtentFW, delimiters);
4102 if (found) {
4103 if (beginPos !=
0) {
4104 memcpy(fillPtr, &inString[lastEndPos], startPos - lastEndPos);
4105 fillPtr += startPos - lastEndPos;
4106 }
4107 if (isRegexType(searchType)) {
4108 char replaceResult[
SEARCHMAX];
4109 replaceUsingRE(searchString, replaceString, &inString[searchExtentBW],
4110 startPos-searchExtentBW,
4111 replaceResult,
SEARCHMAX, startPos ==
0 ?
'\0' :
4112 inString[startPos-
1], delimiters,
4113 defaultRegexFlags(searchType));
4114 replaceLen = strlen(replaceResult);
4115 memcpy(fillPtr, replaceResult, replaceLen);
4116 }
else {
4117 memcpy(fillPtr, replaceString, replaceLen);
4118 }
4119 fillPtr += replaceLen;
4120 lastEndPos = endPos;
4121
4122 beginPos = (startPos == endPos) ? endPos+
1 : endPos;
4123 if (inString[endPos] ==
'\0')
4124 break;
4125 }
4126 }
4127 *fillPtr =
'\0';
4128 *replacementLength = fillPtr - outString;
4129 return outString;
4130 }
4131
4132
4133
4134
4135
4136
4137 static void iSearchTryBeepOnWrap(WindowInfo *window,
int direction,
4138 int beginPos,
int startPos)
4139 {
4140 if (GetPrefBeepOnSearchWrap()) {
4141 if (direction ==
SEARCH_FORWARD) {
4142 if ((startPos >= beginPos
4143 && window->iSearchLastBeginPos < beginPos)
4144 ||(startPos < beginPos
4145 && window->iSearchLastBeginPos >= beginPos)) {
4146 XBell(TheDisplay,
0);
4147 }
4148 }
else {
4149 if ((startPos <= beginPos
4150 && window->iSearchLastBeginPos > beginPos)
4151 ||(startPos > beginPos
4152 && window->iSearchLastBeginPos <= beginPos)) {
4153 XBell(TheDisplay,
0);
4154 }
4155 }
4156 }
4157 }
4158
4159
4160
4161
4162 int SearchWindow(WindowInfo *window,
int direction,
const char *searchString,
4163 int searchType,
int searchWrap,
int beginPos,
int *startPos,
4164 int *endPos,
int *extentBW,
int *extentFW)
4165 {
4166 const char *fileString;
4167 int found, resp, fileEnd = window->buffer->length -
1, outsideBounds;
4168
4169
4170 if (*searchString ==
'\0')
4171 return FALSE;
4172
4173
4174 EscSeqArray *esc;
4175 fileString = BufAsStringCleaned(window->buffer, &esc);
4176
4177
4178
4179
4180 if ((direction ==
SEARCH_FORWARD && beginPos > fileEnd +
1)
4181 || (direction ==
SEARCH_BACKWARD && beginPos <
0))
4182 {
4183 outsideBounds =
TRUE;
4184 }
else
4185 {
4186 outsideBounds =
FALSE;
4187 }
4188
4189
4190
4191
4192 if (window->iSearchStartPos == -
1) {
4193 found = !outsideBounds &&
4194 SearchString(fileString, searchString, direction, searchType,
4195 FALSE, beginPos, startPos, endPos, extentBW, extentFW,
4196 GetWindowDelimiters(window));
4197
4198 if (window->findDlog && XtIsManaged(window->findDlog) &&
4199 !XmToggleButtonGetState(window->findKeepBtn))
4200 XtUnmanageChild(window->findDlog);
4201 if (window->replaceDlog && XtIsManaged(window->replaceDlog) &&
4202 !XmToggleButtonGetState(window->replaceKeepBtn))
4203 unmanageReplaceDialogs(window);
4204 if (!found) {
4205 if (searchWrap) {
4206 if (direction ==
SEARCH_FORWARD && beginPos !=
0) {
4207 if(GetPrefBeepOnSearchWrap()) {
4208 XBell(TheDisplay,
0);
4209 }
else if (GetPrefSearchDlogs()) {
4210 resp = DialogF(
DF_QUES, window->shell,
2,
"Wrap Search",
4211 "Continue search from\nbeginning of file?",
4212 "Continue",
"Cancel");
4213 if (resp ==
2) {
4214 translatePosAndRestoreBuf(window->buffer, esc, found, startPos, endPos, extentBW, extentFW);
4215 return False;
4216 }
4217 }
4218 found = SearchString(fileString, searchString, direction,
4219 searchType,
FALSE,
0, startPos, endPos, extentBW,
4220 extentFW, GetWindowDelimiters(window));
4221 }
else if (direction ==
SEARCH_BACKWARD && beginPos != fileEnd) {
4222 if(GetPrefBeepOnSearchWrap()) {
4223 XBell(TheDisplay,
0);
4224 }
else if (GetPrefSearchDlogs()) {
4225 resp = DialogF(
DF_QUES, window->shell,
2,
"Wrap Search",
4226 "Continue search\nfrom end of file?",
"Continue",
4227 "Cancel");
4228 if (resp ==
2) {
4229 translatePosAndRestoreBuf(window->buffer, esc, found, startPos, endPos, extentBW, extentFW);
4230 return False;
4231 }
4232 }
4233 found = SearchString(fileString, searchString, direction,
4234 searchType,
FALSE, fileEnd +
1, startPos, endPos, extentBW,
4235 extentFW, GetWindowDelimiters(window));
4236 }
4237 }
4238 translatePosAndRestoreBuf(window->buffer, esc, found, startPos, endPos, extentBW, extentFW);
4239 esc =
NULL;
4240 if (!found) {
4241 if (GetPrefSearchDlogs()) {
4242 DialogF(
DF_INF, window->shell,
1,
"String not found",
4243 "String was not found",
"OK");
4244 }
else {
4245 XBell(TheDisplay,
0);
4246 }
4247 }
4248 }
4249 }
else {
4250 if (outsideBounds && searchWrap) {
4251 if (direction ==
SEARCH_FORWARD) beginPos =
0;
4252 else beginPos = fileEnd+
1;
4253 outsideBounds =
FALSE;
4254 }
4255 found = !outsideBounds &&
4256 SearchString(fileString, searchString, direction,
4257 searchType, searchWrap, beginPos, startPos, endPos,
4258 extentBW, extentFW, GetWindowDelimiters(window));
4259 if (found) {
4260 iSearchTryBeepOnWrap(window, direction, beginPos, *startPos);
4261 }
else
4262 XBell(TheDisplay,
0);
4263 }
4264
4265 translatePosAndRestoreBuf(window->buffer, esc, found, startPos, endPos, extentBW, extentFW);
4266 return found;
4267 }
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279 int SearchString(
const char *string,
const char *searchString,
int direction,
4280 int searchType,
int wrap,
int beginPos,
int *startPos,
int *endPos,
4281 int *searchExtentBW,
int *searchExtentFW,
const char *delimiters)
4282 {
4283 switch (searchType) {
4284 case SEARCH_CASE_SENSE_WORD:
4285 return searchLiteralWord(string, searchString,
TRUE, direction, wrap,
4286 beginPos, startPos, endPos, delimiters);
4287 case SEARCH_LITERAL_WORD:
4288 return searchLiteralWord(string, searchString,
FALSE, direction, wrap,
4289 beginPos, startPos, endPos, delimiters);
4290 case SEARCH_CASE_SENSE:
4291 return searchLiteral(string, searchString,
TRUE, direction, wrap,
4292 beginPos, startPos, endPos, searchExtentBW,
4293 searchExtentFW);
4294 case SEARCH_LITERAL:
4295 return searchLiteral(string, searchString,
FALSE, direction, wrap,
4296 beginPos, startPos, endPos, searchExtentBW, searchExtentFW);
4297 case SEARCH_REGEX:
4298 return searchRegex(string, searchString, direction, wrap,
4299 beginPos, startPos, endPos, searchExtentBW, searchExtentFW,
4300 delimiters,
REDFLT_STANDARD);
4301 case SEARCH_REGEX_NOCASE:
4302 return searchRegex(string, searchString, direction, wrap,
4303 beginPos, startPos, endPos, searchExtentBW, searchExtentFW,
4304 delimiters,
REDFLT_CASE_INSENSITIVE);
4305 }
4306 return FALSE;
4307 }
4308
4309
4310
4311
4312
4313
4314
4315 int StringToSearchType(
const char * string,
int *searchType)
4316 {
4317 int i;
4318 for (i =
0; searchTypeStrings[i]; i++) {
4319 if (!strcmp(string, searchTypeStrings[i])) {
4320 break;
4321 }
4322 }
4323 if (!searchTypeStrings[i]) {
4324 return FALSE;
4325 }
4326 *searchType = i;
4327 return TRUE;
4328 }
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344 static int searchLiteralWord(
const char *string,
const char *searchString,
int caseSense,
4345 int direction,
int wrap,
int beginPos,
int *startPos,
int *endPos,
4346 const char * delimiters)
4347 {
4348
4349
4350
4351
4352 #define DOSEARCHWORD() \
4353 if (*filePtr == *ucString || *filePtr == *lcString) { \
4354 \
4355 ucPtr = ucString; \
4356 lcPtr = lcString; \
4357 tempPtr = filePtr; \
4358 while (*tempPtr == *ucPtr || *tempPtr == *lcPtr) { \
4359 tempPtr++; ucPtr++; lcPtr++; \
4360 if ( *ucPtr ==
0 \
4361 && (cignore_R ||\
4362 isspace((
unsigned char)*tempPtr) ||\
4363 strchr(delimiters, *tempPtr) ) \
4364 \
4365 && (cignore_L ||\
4366 filePtr==string || \
4367 isspace((
unsigned char)filePtr[-
1]) ||\
4368 strchr(delimiters,filePtr[-
1]) ))\
4369 { \
4370 *startPos = filePtr - string; \
4371 *endPos = tempPtr - string; \
4372 return TRUE; \
4373 } \
4374 } \
4375 }
4376
4377 register const char *filePtr, *tempPtr, *ucPtr, *lcPtr;
4378 char lcString[
SEARCHMAX], ucString[
SEARCHMAX];
4379
4380 int cignore_L=
0, cignore_R=
0;
4381
4382
4383
4384
4385
4386 if (strlen(searchString) >=
SEARCHMAX)
4387 return FALSE;
4388
4389
4390 if (delimiters==
NULL) delimiters = GetPrefDelimiters();
4391
4392 if ( isspace((
unsigned char)*searchString)
4393 || strchr(delimiters, *searchString))
4394 cignore_L=
1;
4395
4396 if ( isspace((
unsigned char)searchString[strlen(searchString)-
1])
4397 || strchr(delimiters, searchString[strlen(searchString)-
1]) )
4398 cignore_R=
1;
4399
4400 if (caseSense) {
4401 strcpy(ucString, searchString);
4402 strcpy(lcString, searchString);
4403 }
else {
4404 UpCaseString(ucString, searchString);
4405 DownCaseString(lcString, searchString);
4406 }
4407
4408 if (direction ==
SEARCH_FORWARD) {
4409
4410 for (filePtr=string+beginPos; *filePtr!=
0; filePtr++) {
4411 DOSEARCHWORD()
4412 }
4413 if (!wrap)
4414 return FALSE;
4415
4416
4417 for (filePtr=string; filePtr<=string+beginPos; filePtr++) {
4418 DOSEARCHWORD()
4419 }
4420 return FALSE;
4421 }
else {
4422
4423
4424
4425 if (beginPos >=
0) {
4426 for (filePtr=string+beginPos; filePtr>=string; filePtr--) {
4427 DOSEARCHWORD()
4428 }
4429 }
4430 if (!wrap)
4431 return FALSE;
4432
4433
4434
4435 for (filePtr=string+strlen(string); filePtr>=string+beginPos; filePtr--) {
4436 DOSEARCHWORD()
4437 }
4438 return FALSE;
4439 }
4440 }
4441
4442
4443 static int searchLiteral(
const char *string,
const char *searchString,
int caseSense,
4444 int direction,
int wrap,
int beginPos,
int *startPos,
int *endPos,
4445 int *searchExtentBW,
int *searchExtentFW)
4446 {
4447
4448
4449
4450
4451 #define DOSEARCH() \
4452 if (*filePtr == *ucString || *filePtr == *lcString) { \
4453 \
4454 ucPtr = ucString; \
4455 lcPtr = lcString; \
4456 tempPtr = filePtr; \
4457 while (*tempPtr == *ucPtr || *tempPtr == *lcPtr) { \
4458 tempPtr++; ucPtr++; lcPtr++; \
4459 if (*ucPtr ==
0) { \
4460 \
4461 *startPos = filePtr - string; \
4462 *endPos = tempPtr - string; \
4463 if (searchExtentBW !=
NULL) \
4464 *searchExtentBW = *startPos; \
4465 if (searchExtentFW !=
NULL) \
4466 *searchExtentFW = *endPos; \
4467 return TRUE; \
4468 } \
4469 } \
4470 } \
4471
4472 register const char *filePtr, *tempPtr, *ucPtr, *lcPtr;
4473 char lcString[
SEARCHMAX], ucString[
SEARCHMAX];
4474
4475
4476
4477
4478 if (strlen(searchString) >=
SEARCHMAX)
4479 return FALSE;
4480
4481 if (caseSense) {
4482 strcpy(ucString, searchString);
4483 strcpy(lcString, searchString);
4484 }
else {
4485 UpCaseString(ucString, searchString);
4486 DownCaseString(lcString, searchString);
4487 }
4488
4489 if (direction ==
SEARCH_FORWARD) {
4490
4491 for (filePtr=string+beginPos; *filePtr!=
0; filePtr++) {
4492 DOSEARCH()
4493 }
4494 if (!wrap)
4495 return FALSE;
4496
4497 for (filePtr=string; filePtr<=string+beginPos; filePtr++) {
4498 DOSEARCH()
4499 }
4500 return FALSE;
4501 }
else {
4502
4503
4504
4505 if (beginPos >=
0) {
4506 for (filePtr=string+beginPos; filePtr>=string; filePtr--) {
4507 DOSEARCH()
4508 }
4509 }
4510 if (!wrap)
4511 return FALSE;
4512
4513
4514
4515 for (filePtr=string+strlen(string);
4516 filePtr>=string+beginPos; filePtr--) {
4517 DOSEARCH()
4518 }
4519 return FALSE;
4520 }
4521 }
4522
4523 static int searchRegex(
const char *string,
const char *searchString,
int direction,
4524 int wrap,
int beginPos,
int *startPos,
int *endPos,
int *searchExtentBW,
4525 int *searchExtentFW,
const char *delimiters,
int defaultFlags)
4526 {
4527 if (direction ==
SEARCH_FORWARD)
4528 return forwardRegexSearch(string, searchString, wrap,
4529 beginPos, startPos, endPos, searchExtentBW, searchExtentFW,
4530 delimiters, defaultFlags);
4531 else
4532 return backwardRegexSearch(string, searchString, wrap,
4533 beginPos, startPos, endPos, searchExtentBW, searchExtentFW,
4534 delimiters, defaultFlags);
4535 }
4536
4537 static int forwardRegexSearch(
const char *string,
const char *searchString,
int wrap,
4538 int beginPos,
int *startPos,
int *endPos,
int *searchExtentBW,
4539 int *searchExtentFW,
const char *delimiters,
int defaultFlags)
4540 {
4541 regexp *compiledRE =
NULL;
4542 char *compileMsg;
4543
4544
4545
4546
4547 compiledRE = CompileRE(searchString, &compileMsg, defaultFlags);
4548 if (compiledRE ==
NULL)
4549 return FALSE;
4550
4551
4552 if (ExecRE(compiledRE, string + beginPos,
NULL,
FALSE,
4553 (beginPos ==
0) ?
'\0' : string[beginPos-
1],
'\0', delimiters,
4554 string,
NULL)) {
4555 *startPos = compiledRE->startp[
0] - string;
4556 *endPos = compiledRE->endp[
0] - string;
4557 if (searchExtentFW !=
NULL)
4558 *searchExtentFW = compiledRE->extentpFW - string;
4559 if (searchExtentBW !=
NULL)
4560 *searchExtentBW = compiledRE->extentpBW - string;
4561 NEditFree(compiledRE);
4562 return TRUE;
4563 }
4564
4565
4566 if (!wrap) {
4567 NEditFree(compiledRE);
4568 return FALSE;
4569 }
4570
4571
4572 if (ExecRE(compiledRE, string, string + beginPos,
FALSE,
'\0',
4573 string[beginPos], delimiters, string,
NULL)) {
4574 *startPos = compiledRE->startp[
0] - string;
4575 *endPos = compiledRE->endp[
0] - string;
4576 if (searchExtentFW !=
NULL)
4577 *searchExtentFW = compiledRE->extentpFW - string;
4578 if (searchExtentBW !=
NULL)
4579 *searchExtentBW = compiledRE->extentpBW - string;
4580 NEditFree(compiledRE);
4581 return TRUE;
4582 }
4583
4584 NEditFree(compiledRE);
4585 return FALSE;
4586 }
4587
4588 static int backwardRegexSearch(
const char *string,
const char *searchString,
int wrap,
4589 int beginPos,
int *startPos,
int *endPos,
int *searchExtentBW,
4590 int *searchExtentFW,
const char *delimiters,
int defaultFlags)
4591 {
4592 regexp *compiledRE =
NULL;
4593 char *compileMsg;
4594 int length;
4595
4596
4597 compiledRE = CompileRE(searchString, &compileMsg, defaultFlags);
4598 if (compiledRE ==
NULL)
4599 return FALSE;
4600
4601
4602
4603 if (beginPos >=
0) {
4604 if (ExecRE(compiledRE, string, string + beginPos,
TRUE,
'\0',
'\0',
4605 delimiters, string,
NULL)) {
4606 *startPos = compiledRE->startp[
0] - string;
4607 *endPos = compiledRE->endp[
0] - string;
4608 if (searchExtentFW !=
NULL)
4609 *searchExtentFW = compiledRE->extentpFW - string;
4610 if (searchExtentBW !=
NULL)
4611 *searchExtentBW = compiledRE->extentpBW - string;
4612 NEditFree(compiledRE);
4613 return TRUE;
4614 }
4615 }
4616
4617
4618 if (!wrap) {
4619 NEditFree(compiledRE);
4620 return FALSE;
4621 }
4622
4623
4624 if (beginPos <
0)
4625 beginPos =
0;
4626 length = strlen(string);
4627 if (ExecRE(compiledRE, string + beginPos, string + length,
TRUE,
4628 (beginPos ==
0) ?
'\0' : string[beginPos-
1],
'\0', delimiters,
4629 string,
NULL)) {
4630 *startPos = compiledRE->startp[
0] - string;
4631 *endPos = compiledRE->endp[
0] - string;
4632 if (searchExtentFW !=
NULL)
4633 *searchExtentFW = compiledRE->extentpFW - string;
4634 if (searchExtentBW !=
NULL)
4635 *searchExtentBW = compiledRE->extentpBW - string;
4636 NEditFree(compiledRE);
4637 return TRUE;
4638 }
4639 NEditFree(compiledRE);
4640 return FALSE;
4641 }
4642
4643 static int check_len(
const char *in,
int len) {
4644 for(
int i=
0;i<len;i++) {
4645 if(in[i] ==
0)
return i;
4646 }
4647 return len;
4648 }
4649
4650 void ChangeCase(
const char *in,
char *out,
int makeUpper,
int *in_len,
int *out_len) {
4651 mbstate_t state;
4652 memset(&state,
0,
sizeof(
mbstate_t));
4653 wchar_t w =
0;
4654
4655 int len = Utf8CharLen((
const unsigned char*)in);
4656 len = check_len(in, len);
4657 *in_len = len;
4658
4659 mbrtowc(&w, in, len, &state);
4660 wchar_t wc = makeUpper ? towupper(w) : towlower(w);
4661 if(wc ==
0) wc = w;
4662 char bufChar[
8];
4663 const char *src_buf = bufChar;
4664 int clen = wctomb(bufChar, wc);
4665 if(clen > len) {
4666 clen = len;
4667 src_buf = in;
4668 }
4669 *out_len = clen;
4670
4671 memcpy(out, src_buf, clen);
4672 }
4673
4674 void UpCaseString(
char *outString,
const char *inString)
4675 {
4676 char *outPtr;
4677 const char *inPtr;
4678
4679 for (outPtr=outString, inPtr=inString; *inPtr!=
0; inPtr++, outPtr++) {
4680 if(*inPtr >=
0) {
4681 *outPtr = toupper((
unsigned char)*inPtr);
4682 }
else {
4683 int in_len, out_len;
4684 ChangeCase(inPtr, outPtr, True, &in_len, &out_len);
4685 inPtr += in_len -
1;
4686 outPtr += out_len -
1;
4687 }
4688
4689 }
4690 *outPtr =
0;
4691 }
4692
4693 void DownCaseString(
char *outString,
const char *inString)
4694 {
4695 char *outPtr;
4696 const char *inPtr;
4697
4698 for (outPtr=outString, inPtr=inString; *inPtr!=
0; inPtr++, outPtr++) {
4699 if(*inPtr >=
0) {
4700 *outPtr = tolower((
unsigned char)*inPtr);
4701 }
else {
4702 int in_len, out_len;
4703 ChangeCase(inPtr, outPtr, False, &in_len, &out_len);
4704 inPtr += in_len -
1;
4705 outPtr += out_len -
1;
4706 }
4707 }
4708 *outPtr =
0;
4709 }
4710
4711
4712
4713
4714
4715
4716
4717 static void resetFindTabGroup(WindowInfo *window)
4718 {
4719 XmProcessTraversal(window->findText, XmTRAVERSE_CURRENT);
4720 }
4721 static void resetReplaceTabGroup(WindowInfo *window)
4722 {
4723 XmProcessTraversal(window->replaceText, XmTRAVERSE_CURRENT);
4724 }
4725
4726
4727
4728
4729
4730
4731 static int searchMatchesSelection(WindowInfo *window,
const char *searchString,
4732 int searchType,
int *left,
int *right,
int *searchExtentBW,
4733 int *searchExtentFW)
4734 {
4735 int selLen, selStart, selEnd, startPos, endPos, extentBW, extentFW, beginPos;
4736 int regexLookContext = isRegexType(searchType) ?
1000 :
0;
4737 char *string;
4738 int found, isRect, rectStart, rectEnd, lineStart =
0;
4739
4740
4741 if (!BufGetEmptySelectionPos(window->buffer, &selStart, &selEnd, &isRect,
4742 &rectStart, &rectEnd))
4743 return FALSE;
4744 if (selEnd - selStart >
SEARCHMAX)
4745 return FALSE;
4746
4747
4748 if (isRect) {
4749 lineStart = BufStartOfLine(window->buffer, selStart);
4750 if (lineStart != BufStartOfLine(window->buffer, selEnd))
4751 return FALSE;
4752 }
4753
4754
4755
4756 if (isRect) {
4757 int stringStart = lineStart + rectStart - regexLookContext;
4758 if (stringStart <
0) stringStart =
0;
4759 string = BufGetRange(window->buffer, stringStart,
4760 lineStart + rectEnd + regexLookContext);
4761 selLen = rectEnd - rectStart;
4762 beginPos = lineStart + rectStart - stringStart;
4763 }
else {
4764 int stringStart = selStart - regexLookContext;
4765 if (stringStart <
0) stringStart =
0;
4766 string = BufGetRange(window->buffer, stringStart,
4767 selEnd + regexLookContext);
4768 selLen = selEnd - selStart;
4769 beginPos = selStart - stringStart;
4770 }
4771 if (*string ==
'\0') {
4772 NEditFree(string);
4773 return FALSE;
4774 }
4775
4776
4777
4778
4779 found = SearchString(string, searchString,
SEARCH_FORWARD, searchType,
4780 FALSE, beginPos, &startPos, &endPos, &extentBW, &extentFW,
4781 GetWindowDelimiters(window));
4782 NEditFree(string);
4783
4784
4785 if (!found)
4786 return FALSE;
4787 if (startPos != beginPos || endPos - beginPos != selLen )
4788 return FALSE;
4789
4790
4791 if (isRect)
4792 GetSimpleSelection(window->buffer, left, right);
4793 else {
4794 *left = selStart;
4795 *right = selEnd;
4796 }
4797 if (searchExtentBW !=
NULL)
4798 *searchExtentBW = *left - (startPos - extentBW);
4799
4800 if (searchExtentFW !=
NULL)
4801 *searchExtentFW = *right + extentFW - endPos;
4802 return TRUE;
4803 }
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815 static Boolean replaceUsingRE(
const char* searchStr,
const char* replaceStr,
4816 const char* sourceStr,
int beginPos,
char* destStr,
4817 int maxDestLen,
int prevChar,
const char* delimiters,
4818 int defaultFlags)
4819 {
4820 regexp *compiledRE;
4821 char *compileMsg;
4822 Boolean substResult = False;
4823
4824 compiledRE = CompileRE(searchStr, &compileMsg, defaultFlags);
4825 ExecRE(compiledRE, sourceStr+beginPos,
NULL, False, prevChar,
'\0',
4826 delimiters, sourceStr,
NULL);
4827 substResult = SubstituteRE(compiledRE, replaceStr, destStr, maxDestLen);
4828 NEditFree(compiledRE);
4829
4830 return substResult;
4831 }
4832
4833
4834
4835
4836 static void enableFindAgainCmds(
void)
4837 {
4838 WindowInfo *w;
4839
4840 for (w=WindowList; w!=
NULL; w=w->next) {
4841 if (!IsTopDocument(w))
4842 continue;
4843 XtSetSensitive(w->findAgainItem, True);
4844 XtSetSensitive(w->replaceFindAgainItem, True);
4845 XtSetSensitive(w->replaceAgainItem, True);
4846 }
4847 }
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862 void WriteSearchHistory(
void)
4863 {
4864 const char *fullName = GetRCFileName(
SEARCH_HISTORY);
4865 const char *searchStr, *replaceStr;
4866 struct stat attribute;
4867 FILE *fp;
4868 int i;
4869
4870
4871 if (!GetPrefSaveSearchHistory())
4872 return;
4873
4874
4875 if ((fp = fopen(fullName,
"w")) ==
NULL) {
4876 #ifdef VMS
4877
4878
4879
4880
4881
4882
4883
4884 if ((fp = fopen(fullName,
"r+")) ==
NULL)
4885 return;
4886 if (ftruncate(fileno(fp),
0) !=
0) {
4887 fclose(fp);
4888 return;
4889 }
4890 #else
4891 return;
4892 #endif
4893 }
4894
4895
4896 for (i = NHist; i >=
1; i--) {
4897 searchStr = SearchHistory[historyIndex(i)];
4898 replaceStr = ReplaceHistory[historyIndex(i)];
4899 fprintf(fp,
"%d:%u:%u\n%s\n%s\n",
4900 SearchTypeHistory[historyIndex(i)],
4901 (
unsigned)strlen(searchStr), (
unsigned)strlen(replaceStr),
4902 searchStr, replaceStr);
4903 }
4904 fclose(fp);
4905
4906
4907 if (
0 == stat(fullName, &attribute)) {
4908
4909 lastSearchdbModTime = attribute.st_mtime;
4910 }
4911 }
4912
4913
4914
4915
4916
4917
4918
4919 void ReadSearchHistory(
void)
4920 {
4921 const char *fullName = GetRCFileName(
SEARCH_HISTORY);
4922 struct stat attribute;
4923 char line[
16];
4924 size_t lineLen;
4925 int type;
4926 unsigned srchLen, replLen;
4927 FILE *fp;
4928
4929
4930 if (!GetPrefSaveSearchHistory())
4931 return;
4932
4933
4934
4935 if (
0 == stat(fullName, &attribute)) {
4936 if (lastSearchdbModTime >= attribute.st_mtime) {
4937
4938 return;
4939 }
else {
4940
4941 lastSearchdbModTime = attribute.st_mtime;
4942 }
4943 }
else {
4944
4945 if (
ENOENT != errno)
4946 fprintf(stderr,
"NEdit: Error reading file %s (%s)\n",
4947 fullName, strerror(errno));
4948 return;
4949 }
4950
4951
4952 if ((fp = fopen(fullName,
"r")) ==
NULL)
4953 return;
4954
4955
4956 while (
0 != NHist) {
4957 XtFree(SearchHistory[historyIndex(NHist)]);
4958 XtFree(ReplaceHistory[historyIndex(NHist)]);
4959 NHist--;
4960 }
4961 HistStart =
0;
4962
4963
4964 while (fgets(line,
sizeof(line), fp) !=
NULL) {
4965 lineLen = strlen(line);
4966 if (lineLen ==
0 || line[
0] ==
'\n' || line[
0] ==
'#') {
4967
4968 continue;
4969 }
4970 if (line[lineLen -
1] !=
'\n') {
4971
4972 fprintf(stderr,
"NEdit: Line too long in file %s\n", fullName);
4973 break;
4974 }
4975 line[--lineLen] =
'\0';
4976
4977 if (sscanf(line,
"%d:%u:%u", &type, &srchLen, &replLen) !=
3) {
4978 fprintf(stderr,
"NEdit: Invalid line in file %s\n", fullName);
4979 break;
4980 }
4981
4982 SearchTypeHistory[HistStart]=type;
4983 if (type <
0 || type >=
N_SEARCH_TYPES
4984 || srchLen >
SEARCHMAX || replLen >
SEARCHMAX) {
4985 fprintf(stderr,
"NEdit: Invalid values in file %s\n", fullName);
4986 break;
4987 }
4988
4989
4990
4991 if (NHist ==
MAX_SEARCH_HISTORY) {
4992 XtFree(SearchHistory[HistStart]);
4993 XtFree(ReplaceHistory[HistStart]);
4994 }
else
4995 NHist++;
4996
4997
4998 SearchHistory[HistStart] = XtMalloc(srchLen+
1);
4999 if (fread(SearchHistory[HistStart],
1, srchLen +
1, fp) != srchLen +
1
5000 || SearchHistory[HistStart][srchLen] !=
'\n') {
5001 fprintf(stderr,
"NEdit: Error reading file %s (%s)\n",
5002 fullName, strerror(errno));
5003 XtFree(SearchHistory[HistStart]);
5004 NHist--;
5005 break;
5006 }
5007 SearchHistory[HistStart][srchLen]=
'\0';
5008
5009
5010 ReplaceHistory[HistStart] = XtMalloc(replLen+
1);
5011 if (fread(ReplaceHistory[HistStart],
1, replLen +
1, fp) != replLen +
1
5012 || ReplaceHistory[HistStart][replLen] !=
'\n') {
5013 fprintf(stderr,
"NEdit: Error reading file %s (%s)\n",
5014 fullName, strerror(errno));
5015 XtFree(SearchHistory[HistStart]);
5016 XtFree(ReplaceHistory[HistStart]);
5017 NHist--;
5018 break;
5019 }
5020 ReplaceHistory[HistStart][replLen]=
'\0';
5021
5022 if (++HistStart >=
MAX_SEARCH_HISTORY)
5023 HistStart =
0;
5024 }
5025 fclose(fp);
5026
5027
5028 if (NHist)
5029 enableFindAgainCmds();
5030 }
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040 static void saveSearchHistory(
const char *searchString,
5041 const char *replaceString,
int searchType,
int isIncremental)
5042 {
5043 char *sStr, *rStr;
5044 static int currentItemIsIncremental =
FALSE;
5045
5046
5047
5048 if (!isIncremental)
5049 currentItemIsIncremental =
FALSE;
5050
5051
5052 if (searchString[
0] ==
'\0')
5053 return;
5054
5055
5056 if (replaceString ==
NULL)
5057 replaceString = NHist >=
1 ? ReplaceHistory[historyIndex(
1)] :
"";
5058
5059
5060
5061 if (NHist >=
1 && searchType == SearchTypeHistory[historyIndex(
1)] &&
5062 !strcmp(SearchHistory[historyIndex(
1)], searchString) &&
5063 !strcmp(ReplaceHistory[historyIndex(
1)], replaceString)) {
5064 return;
5065 }
5066
5067
5068
5069 if (currentItemIsIncremental && isIncremental) {
5070 NEditFree(SearchHistory[historyIndex(
1)]);
5071 SearchHistory[historyIndex(
1)] = NEditStrdup(searchString);
5072 SearchTypeHistory[historyIndex(
1)] = searchType;
5073
5074
5075 WriteSearchHistory();
5076 return;
5077 }
5078 currentItemIsIncremental = isIncremental;
5079
5080
5081 if (NHist ==
0)
5082 enableFindAgainCmds();
5083
5084
5085
5086 ReadSearchHistory();
5087
5088
5089
5090 if (NHist ==
MAX_SEARCH_HISTORY) {
5091 NEditFree(SearchHistory[HistStart]);
5092 NEditFree(ReplaceHistory[HistStart]);
5093 }
else
5094 NHist++;
5095
5096
5097
5098 sStr = NEditStrdup(searchString);
5099 rStr = NEditStrdup(replaceString);
5100 SearchHistory[HistStart] = sStr;
5101 ReplaceHistory[HistStart] = rStr;
5102 SearchTypeHistory[HistStart] = searchType;
5103 HistStart++;
5104 if (HistStart >=
MAX_SEARCH_HISTORY)
5105 HistStart =
0;
5106
5107
5108 WriteSearchHistory();
5109 }
5110
5111
5112
5113
5114
5115
5116 static int historyIndex(
int nCycles)
5117 {
5118 int index;
5119
5120 if (nCycles > NHist || nCycles <=
0)
5121 return -
1;
5122 index = HistStart - nCycles;
5123 if (index <
0)
5124 index =
MAX_SEARCH_HISTORY + index;
5125 return index;
5126 }
5127
5128
5129
5130
5131
5132 static char *searchTypeArg(
int searchType)
5133 {
5134 if (
0 <= searchType && searchType <
N_SEARCH_TYPES) {
5135 return searchTypeStrings[searchType];
5136 }
5137 return searchTypeStrings[
SEARCH_LITERAL];
5138 }
5139
5140
5141
5142
5143
5144 static char *searchWrapArg(
int searchWrap)
5145 {
5146 if (searchWrap) {
5147 return "wrap";
5148 }
5149 return "nowrap";
5150 }
5151
5152
5153
5154
5155
5156 static char *directionArg(
int direction)
5157 {
5158 if (direction ==
SEARCH_BACKWARD)
5159 return "backward";
5160 return "forward";
5161 }
5162
5163
5164
5165
5166 static int isRegexType(
int searchType)
5167 {
5168 return searchType ==
SEARCH_REGEX || searchType ==
SEARCH_REGEX_NOCASE;
5169 }
5170
5171
5172
5173
5174
5175 static int defaultRegexFlags(
int searchType)
5176 {
5177 switch (searchType) {
5178 case SEARCH_REGEX:
5179 return REDFLT_STANDARD;
5180 case SEARCH_REGEX_NOCASE:
5181 return REDFLT_CASE_INSENSITIVE;
5182 default:
5183
5184 return REDFLT_STANDARD;
5185 }
5186 }
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209 static void findRegExpToggleCB(Widget w, XtPointer clientData, XtPointer callData)
5210 {
5211 WindowInfo * window = WidgetToWindow(w);
5212 int searchRegex = XmToggleButtonGetState(w);
5213 int searchCaseSense = XmToggleButtonGetState(window->findCaseToggle);
5214
5215
5216 if(GetPrefStickyCaseSenseBtn()) {
5217 if(searchRegex) {
5218 window->findLastLiteralCase = searchCaseSense;
5219 XmToggleButtonSetState(window->findCaseToggle,
5220 window->findLastRegexCase, False);
5221 }
else {
5222 window->findLastRegexCase = searchCaseSense;
5223 XmToggleButtonSetState(window->findCaseToggle,
5224 window->findLastLiteralCase, False);
5225 }
5226 }
5227
5228 XtSetSensitive(window->findWordToggle, !searchRegex);
5229 }
5230
5231 static void replaceRegExpToggleCB(Widget w, XtPointer clientData, XtPointer callData)
5232 {
5233 WindowInfo * window = WidgetToWindow(w);
5234 int searchRegex = XmToggleButtonGetState(w);
5235 int searchCaseSense = XmToggleButtonGetState(window->replaceCaseToggle);
5236
5237
5238 if(GetPrefStickyCaseSenseBtn()) {
5239 if(searchRegex) {
5240 window->replaceLastLiteralCase = searchCaseSense;
5241 XmToggleButtonSetState(window->replaceCaseToggle,
5242 window->replaceLastRegexCase, False);
5243 }
else {
5244 window->replaceLastRegexCase = searchCaseSense;
5245 XmToggleButtonSetState(window->replaceCaseToggle,
5246 window->replaceLastLiteralCase, False);
5247 }
5248 }
5249
5250 XtSetSensitive(window->replaceWordToggle, !searchRegex);
5251 }
5252
5253 static void iSearchRegExpToggleCB(Widget w, XtPointer clientData, XtPointer callData)
5254 {
5255 WindowInfo * window = WidgetToWindow(w);
5256 int searchRegex = XmToggleButtonGetState(w);
5257 int searchCaseSense = XmToggleButtonGetState(window->iSearchCaseToggle);
5258
5259
5260 if(GetPrefStickyCaseSenseBtn()) {
5261 if(searchRegex) {
5262 window->iSearchLastLiteralCase = searchCaseSense;
5263 XmToggleButtonSetState(window->iSearchCaseToggle,
5264 window->iSearchLastRegexCase, False);
5265 }
else {
5266 window->iSearchLastRegexCase = searchCaseSense;
5267 XmToggleButtonSetState(window->iSearchCaseToggle,
5268 window->iSearchLastLiteralCase, False);
5269 }
5270 }
5271
5272 }
5273 static void findCaseToggleCB(Widget w, XtPointer clientData, XtPointer callData)
5274 {
5275 WindowInfo * window = WidgetToWindow(w);
5276 int searchCaseSense = XmToggleButtonGetState(w);
5277
5278
5279
5280 if(XmToggleButtonGetState(window->findRegexToggle))
5281 window->findLastRegexCase = searchCaseSense;
5282 else
5283 window->findLastLiteralCase = searchCaseSense;
5284 }
5285
5286 static void replaceCaseToggleCB(Widget w, XtPointer clientData, XtPointer callData)
5287 {
5288 WindowInfo * window = WidgetToWindow(w);
5289 int searchCaseSense = XmToggleButtonGetState(w);
5290
5291
5292
5293 if(XmToggleButtonGetState(window->replaceRegexToggle))
5294 window->replaceLastRegexCase = searchCaseSense;
5295 else
5296 window->replaceLastLiteralCase = searchCaseSense;
5297 }
5298
5299 static void iSearchCaseToggleCB(Widget w, XtPointer clientData, XtPointer callData)
5300 {
5301 WindowInfo * window = WidgetToWindow(w);
5302 int searchCaseSense = XmToggleButtonGetState(w);
5303
5304
5305
5306 if(XmToggleButtonGetState(window->iSearchRegexToggle))
5307 window->iSearchLastRegexCase = searchCaseSense;
5308 else
5309 window->iSearchLastLiteralCase = searchCaseSense;
5310 }
5311
5312
5313 static int translateEscPos(EscSeqArray *array,
int pos)
5314 {
5315 int p = pos;
5316 for(
size_t i=
0;i<array->num_esc;i++) {
5317 EscSeqStr e = array->esc[i];
5318 if(e.off_trans < pos)
5319 p += e.len;
5320 else
5321 break;
5322 }
5323 return p;
5324 }
5325
5326 static void translatePosAndRestoreBuf(
5327 textBuffer *buf,
5328 EscSeqArray *array,
5329 int found,
5330 int *begin,
5331 int *end,
5332 int *extentBW,
5333 int *extentFW)
5334 {
5335 if(found && array) {
5336 if(begin) *begin = translateEscPos(array, *begin);
5337 if(end) *end = translateEscPos(array, *end);
5338 if(extentBW) *extentBW = translateEscPos(array, *extentBW);
5339 if(extentFW) *extentFW = translateEscPos(array, *extentFW);
5340 }
5341 BufReintegrateEscSeq(buf, array);
5342 }
5343