1
/* $XConsortium: TextAction.c,v 1.43 91/07/23 12:23:54 rws Exp $ */
3
/***********************************************************
4
Copyright 1989 by the Massachusetts Institute of Technology,
5
Cambridge, Massachusetts.
9
Permission to use, copy, modify, and distribute this software and its
10
documentation for any purpose and without fee is hereby granted,
11
provided that the above copyright notice appear in all copies and that
12
both that copyright notice and this permission notice appear in
13
supporting documentation, and that the names of Digital or MIT not be
14
used in advertising or publicity pertaining to distribution of the
15
software without specific, written prior permission.
17
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25
******************************************************************/
28
* NOTE: There are some ASCII Dependancies on '\n' and '\0' that I
29
* am not too thrilled with. There is also the implicit assumption
30
* that the individual characters will fit inside a "char".
31
* It would be nice if we could generalize this a but more. If
32
* anyone out there comes up with an implementation of this stuff
33
* that has no dependency on ASCII, please send the code back to us.
39
#include <X11/IntrinsicP.h>
40
#include <X11/StringDefs.h>
41
#include <X11/Xatom.h>
42
#include <X11/Xmu/Misc.h>
43
#include <X11/Xaw/TextP.h>
47
#define SrcScan XawTextSourceScan
48
#define FindDist XawTextSinkFindDistance
49
#define FindPos XawTextSinkFindPosition
52
* These are defined in TextPop.c
55
void _XawTextInsertFileAction(), _XawTextInsertFile(), _XawTextSearch();
56
void _XawTextSearch(), _XawTextDoSearchAction(), _XawTextDoReplaceAction();
57
void _XawTextSetField(), _XawTextPopdownSearchAction();
60
* These are defined in Text.c
63
char * _XawTextGetText();
64
void _XawTextBuildLineTable(), _XawTextAlterSelection(), _XawTextVScroll();
65
void _XawTextSetSelection(), _XawTextCheckResize(), _XawTextExecuteUpdate();
66
void _XawTextSetScrollBars(), _XawTextClearAndCenterDisplay();
67
Atom * _XawTextSelectionList();
70
StartAction(ctx, event)
74
_XawTextPrepareToUpdate(ctx);
76
switch (event->type) {
79
ctx->text.time = event->xbutton.time;
80
ctx->text.ev_x = event->xbutton.x;
81
ctx->text.ev_y = event->xbutton.y;
85
ctx->text.time = event->xkey.time;
86
ctx->text.ev_x = event->xkey.x;
87
ctx->text.ev_y = event->xkey.y;
90
ctx->text.time = event->xmotion.time;
91
ctx->text.ev_x = event->xmotion.x;
92
ctx->text.ev_y = event->xmotion.y;
96
ctx->text.time = event->xcrossing.time;
97
ctx->text.ev_x = event->xcrossing.x;
98
ctx->text.ev_y = event->xcrossing.y;
107
_XawTextCheckResize(ctx);
108
_XawTextExecuteUpdate(ctx);
113
struct _SelectionList {
119
static void GetSelection();
123
_SelectionReceived(w, client_data, selection, type, value, length, format)
125
XtPointer client_data;
126
Atom *selection, *type;
128
unsigned long *length;
131
TextWidget ctx = (TextWidget)w;
134
if (*type == 0 /*XT_CONVERT_FAIL*/ || *length == 0) {
135
struct _SelectionList* list = (struct _SelectionList*)client_data;
137
GetSelection(w, list->time, list->params, list->count);
143
StartAction(ctx, NULL);
144
text.ptr = (char*)value;
146
text.length = *length;
147
text.format = FMT8BIT;
148
if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
149
XBell(XtDisplay(ctx), 0);
152
ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
153
XawstPositions, XawsdRight, text.length, TRUE);
156
_XawTextSetScrollBars(ctx);
158
XFree(value); /* the selection value should be freed with XFree */
162
GetSelection(w, time, params, num_params)
165
String *params; /* selections in precedence order */
171
selection = XInternAtom(XtDisplay(w), *params, False);
173
case XA_CUT_BUFFER0: buffer = 0; break;
174
case XA_CUT_BUFFER1: buffer = 1; break;
175
case XA_CUT_BUFFER2: buffer = 2; break;
176
case XA_CUT_BUFFER3: buffer = 3; break;
177
case XA_CUT_BUFFER4: buffer = 4; break;
178
case XA_CUT_BUFFER5: buffer = 5; break;
179
case XA_CUT_BUFFER6: buffer = 6; break;
180
case XA_CUT_BUFFER7: buffer = 7; break;
181
default: buffer = -1;
185
unsigned long length;
187
Atom type = XA_STRING;
188
char *line = XFetchBuffer(XtDisplay(w), &nbytes, buffer);
190
_SelectionReceived(w, NULL, &selection, &type, (caddr_t)line,
192
else if (num_params > 1)
193
GetSelection(w, time, params+1, num_params-1);
195
struct _SelectionList* list;
197
list = XtNew(struct _SelectionList);
198
list->params = params + 1;
199
list->count = num_params;
202
XtGetSelectionValue(w, selection, XA_STRING, _SelectionReceived,
203
(XtPointer)list, time);
208
InsertSelection(w, event, params, num_params)
211
String *params; /* precedence list of selections to try */
212
Cardinal *num_params;
214
StartAction((TextWidget)w, event); /* Get Time. */
215
GetSelection(w, ((TextWidget)w)->text.time, params, *num_params);
216
EndAction((TextWidget)w);
219
/************************************************************
221
* Routines for Moving Around.
223
************************************************************/
226
Move(ctx, event, dir, type, include)
229
XawTextScanDirection dir;
230
XawTextScanType type;
233
StartAction(ctx, event);
234
ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
235
type, dir, ctx->text.mult, include);
241
MoveForwardChar(w, event, p, n)
247
Move((TextWidget) w, event, XawsdRight, XawstPositions, TRUE);
252
MoveBackwardChar(w, event, p, n)
258
Move((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE);
263
MoveForwardWord(w, event, p, n)
269
Move((TextWidget) w, event, XawsdRight, XawstWhiteSpace, FALSE);
274
MoveBackwardWord(w, event, p, n)
280
Move((TextWidget) w, event, XawsdLeft, XawstWhiteSpace, FALSE);
284
static void MoveForwardParagraph(w, event, p, n)
290
Move((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE);
294
static void MoveBackwardParagraph(w, event, p, n)
300
Move((TextWidget) w, event, XawsdLeft, XawstParagraph, FALSE);
305
MoveToLineEnd(w, event, p, n)
311
Move((TextWidget) w, event, XawsdRight, XawstEOL, FALSE);
316
MoveToLineStart(w, event, p, n)
322
Move((TextWidget) w, event, XawsdLeft, XawstEOL, FALSE);
327
MoveLine(ctx, event, dir)
330
XawTextScanDirection dir;
332
XawTextPosition new, next_line, junk;
333
int from_left, garbage;
335
StartAction(ctx, event);
337
if (dir == XawsdLeft)
340
new = SrcScan(ctx->text.source, ctx->text.insertPos,
341
XawstEOL, XawsdLeft, 1, FALSE);
343
FindDist(ctx->text.sink, new, ctx->text.margin.left, ctx->text.insertPos,
344
&from_left, &junk, &garbage);
346
new = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, dir,
347
ctx->text.mult, (dir == XawsdRight));
349
next_line = SrcScan(ctx->text.source, new, XawstEOL, XawsdRight, 1, FALSE);
351
FindPos(ctx->text.sink, new, ctx->text.margin.left, from_left, FALSE,
352
&(ctx->text.insertPos), &garbage, &garbage);
354
if (ctx->text.insertPos > next_line)
355
ctx->text.insertPos = next_line;
362
MoveNextLine(w, event, p, n)
368
MoveLine( (TextWidget) w, event, XawsdRight);
373
MovePreviousLine(w, event, p, n)
379
MoveLine( (TextWidget) w, event, XawsdLeft);
384
MoveBeginningOfFile(w, event, p, n)
390
Move((TextWidget) w, event, XawsdLeft, XawstAll, TRUE);
395
MoveEndOfFile(w, event, p, n)
401
Move((TextWidget) w, event, XawsdRight, XawstAll, TRUE);
405
Scroll(ctx, event, dir)
408
XawTextScanDirection dir;
410
StartAction(ctx, event);
412
if (dir == XawsdLeft)
413
_XawTextVScroll(ctx, ctx->text.mult);
415
_XawTextVScroll(ctx, -ctx->text.mult);
422
ScrollOneLineUp(w, event, p, n)
428
Scroll( (TextWidget) w, event, XawsdLeft);
433
ScrollOneLineDown(w, event, p, n)
439
Scroll( (TextWidget) w, event, XawsdRight);
443
MovePage(ctx, event, dir)
446
XawTextScanDirection dir;
448
int scroll_val = Max(1, ctx->text.lt.lines - 2);
450
if (dir == XawsdLeft)
451
scroll_val = -scroll_val;
453
StartAction(ctx, event);
454
_XawTextVScroll(ctx, scroll_val);
455
ctx->text.insertPos = ctx->text.lt.top;
461
MoveNextPage(w, event, p, n)
467
MovePage((TextWidget) w, event, XawsdRight);
472
MovePreviousPage(w, event, p, n)
478
MovePage((TextWidget) w, event, XawsdLeft);
481
/************************************************************
485
************************************************************/
488
_DeleteOrKill(ctx, from, to, kill)
490
XawTextPosition from, to;
496
if (kill && from < to) {
497
ptr = _XawTextGetText(ctx, from, to);
498
XStoreBuffer(XtDisplay(ctx), ptr, strlen(ptr), 1);
503
if (_XawTextReplace(ctx, from, to, &text)) {
504
XBell(XtDisplay(ctx), 50);
507
ctx->text.insertPos = from;
508
ctx->text.showposition = TRUE;
512
DeleteOrKill(ctx, event, dir, type, include, kill)
515
XawTextScanDirection dir;
516
XawTextScanType type;
517
Boolean include, kill;
519
XawTextPosition from, to;
521
StartAction(ctx, event);
522
to = SrcScan(ctx->text.source, ctx->text.insertPos,
523
type, dir, ctx->text.mult, include);
526
* If no movement actually happened, then bump the count and try again.
527
* This causes the character position at the very beginning and end of
528
* a boundry to act correctly.
531
if (to == ctx->text.insertPos)
532
to = SrcScan(ctx->text.source, ctx->text.insertPos,
533
type, dir, ctx->text.mult + 1, include);
535
if (dir == XawsdLeft) {
537
to = ctx->text.insertPos;
540
from = ctx->text.insertPos;
542
_DeleteOrKill(ctx, from, to, kill);
543
_XawTextSetScrollBars(ctx);
549
DeleteForwardChar(w, event, p, n)
555
DeleteOrKill((TextWidget) w, event, XawsdRight, XawstPositions, TRUE, FALSE);
560
DeleteBackwardChar(w, event, p, n)
566
DeleteOrKill((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE, FALSE);
571
DeleteForwardWord(w, event, p, n)
577
DeleteOrKill((TextWidget) w, event,
578
XawsdRight, XawstWhiteSpace, FALSE, FALSE);
583
DeleteBackwardWord(w, event, p, n)
589
DeleteOrKill((TextWidget) w, event,
590
XawsdLeft, XawstWhiteSpace, FALSE, FALSE);
595
KillForwardWord(w, event, p, n)
601
DeleteOrKill((TextWidget) w, event,
602
XawsdRight, XawstWhiteSpace, FALSE, TRUE);
607
KillBackwardWord(w, event, p, n)
613
DeleteOrKill((TextWidget) w, event,
614
XawsdLeft, XawstWhiteSpace, FALSE, TRUE);
619
KillToEndOfLine(w, event, p, n)
625
TextWidget ctx = (TextWidget) w;
626
XawTextPosition end_of_line;
628
StartAction(ctx, event);
629
end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL,
630
XawsdRight, ctx->text.mult, FALSE);
631
if (end_of_line == ctx->text.insertPos)
632
end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL,
633
XawsdRight, ctx->text.mult, TRUE);
635
_DeleteOrKill(ctx, ctx->text.insertPos, end_of_line, TRUE);
637
_XawTextSetScrollBars(ctx);
642
KillToEndOfParagraph(w, event, p, n)
648
DeleteOrKill((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE, TRUE);
652
_XawTextZapSelection(ctx, event, kill)
657
StartAction(ctx, event);
658
_DeleteOrKill(ctx, ctx->text.s.left, ctx->text.s.right, kill);
660
_XawTextSetScrollBars(ctx);
665
KillCurrentSelection(w, event, p, n)
671
_XawTextZapSelection( (TextWidget) w, event, TRUE);
676
DeleteCurrentSelection(w, event, p, n)
682
_XawTextZapSelection( (TextWidget) w, event, FALSE);
685
/************************************************************
687
* Insertion Routines.
689
************************************************************/
692
InsertNewLineAndBackupInternal(ctx)
695
int count, error = XawEditDone;
699
ptr = buf = XtMalloc(sizeof(char) * ctx->text.mult);
700
for (count = 0; count < ctx->text.mult; count++, ptr++)
703
text.length = ctx->text.mult;
706
text.format = FMT8BIT;
708
if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
709
XBell( XtDisplay(ctx), 50);
710
error = XawEditError;
713
ctx->text.showposition = TRUE;
721
InsertNewLineAndBackup(w, event, p, n)
727
StartAction( (TextWidget) w, event );
728
(void) InsertNewLineAndBackupInternal( (TextWidget) w );
729
EndAction( (TextWidget) w );
730
_XawTextSetScrollBars( (TextWidget) w);
734
LocalInsertNewLine(ctx, event)
738
StartAction(ctx, event);
739
if (InsertNewLineAndBackupInternal(ctx) == XawEditError)
740
return(XawEditError);
741
ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
742
XawstPositions, XawsdRight, ctx->text.mult, TRUE);
744
_XawTextSetScrollBars(ctx);
750
InsertNewLine(w, event, p, n)
756
(void) LocalInsertNewLine( (TextWidget) w, event);
761
InsertNewLineAndIndent(w, event, p, n)
768
XawTextPosition pos1;
771
TextWidget ctx = (TextWidget) w;
773
StartAction(ctx, event);
774
pos1 = SrcScan(ctx->text.source, ctx->text.insertPos,
775
XawstEOL, XawsdLeft, 1, FALSE);
777
/* Hacked because Ascii Source Object Scan method is permanently broken. */
778
text.ptr = _XawTextGetText(ctx, pos1, ctx->text.insertPos);
779
length = strlen(text.ptr);
780
for (ptr=text.ptr; length && isspace(*ptr); ptr++, length--)
784
text.length = strlen(text.ptr);
785
if (LocalInsertNewLine(ctx, event)) {
790
if (_XawTextReplace(ctx,ctx->text.insertPos, ctx->text.insertPos, &text)) {
791
XBell(XtDisplay(ctx), 50);
796
ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
797
XawstPositions, XawsdRight, text.length, TRUE);
800
_XawTextSetScrollBars(ctx);
803
/************************************************************
805
* Selection Routines.
807
*************************************************************/
810
SelectWord(w, event, params, num_params)
814
Cardinal *num_params;
816
TextWidget ctx = (TextWidget) w;
817
XawTextPosition l, r;
819
StartAction(ctx, event);
820
l = SrcScan(ctx->text.source, ctx->text.insertPos,
821
XawstWhiteSpace, XawsdLeft, 1, FALSE);
822
r = SrcScan(ctx->text.source, l, XawstWhiteSpace, XawsdRight, 1, FALSE);
823
_XawTextSetSelection(ctx, l, r, params, *num_params);
828
SelectAll(w, event, params, num_params)
832
Cardinal *num_params;
834
TextWidget ctx = (TextWidget) w;
836
StartAction(ctx, event);
837
_XawTextSetSelection(ctx,zeroPosition,ctx->text.lastPos,params,*num_params);
842
ModifySelection(ctx, event, mode, action, params, num_params)
845
XawTextSelectionMode mode;
846
XawTextSelectionAction action;
847
String *params; /* unused */
848
Cardinal *num_params; /* unused */
850
StartAction(ctx, event);
851
_XawTextAlterSelection(ctx, mode, action, params, num_params);
857
SelectStart(w, event, params, num_params)
860
String *params; /* unused */
861
Cardinal *num_params; /* unused */
863
ModifySelection((TextWidget) w, event,
864
XawsmTextSelect, XawactionStart, params, num_params);
869
SelectAdjust(w, event, params, num_params)
872
String *params; /* unused */
873
Cardinal *num_params; /* unused */
875
ModifySelection((TextWidget) w, event,
876
XawsmTextSelect, XawactionAdjust, params, num_params);
880
SelectEnd(w, event, params, num_params)
884
Cardinal *num_params;
886
ModifySelection((TextWidget) w, event,
887
XawsmTextSelect, XawactionEnd, params, num_params);
892
ExtendStart(w, event, params, num_params)
895
String *params; /* unused */
896
Cardinal *num_params; /* unused */
898
ModifySelection((TextWidget) w, event,
899
XawsmTextExtend, XawactionStart, params, num_params);
904
ExtendAdjust(w, event, params, num_params)
907
String *params; /* unused */
908
Cardinal *num_params; /* unused */
910
ModifySelection((TextWidget) w, event,
911
XawsmTextExtend, XawactionAdjust, params, num_params);
915
ExtendEnd(w, event, params, num_params)
919
Cardinal *num_params;
921
ModifySelection((TextWidget) w, event,
922
XawsmTextExtend, XawactionEnd, params, num_params);
926
SelectSave(w, event, params, num_params)
930
Cardinal *num_params;
934
Display* dpy = XtDisplay(w);
935
Atom selections[256];
937
StartAction (w, event);
938
num_atoms = *num_params;
941
for (sel=selections; --num_atoms >= 0; sel++, params++)
942
*sel = XInternAtom(dpy, *params, False);
943
num_atoms = *num_params;
944
_XawTextSaltAwaySelection (w, selections, num_atoms);
948
/************************************************************
952
************************************************************/
956
RedrawDisplay(w, event, p, n)
962
StartAction( (TextWidget) w, event);
963
_XawTextClearAndCenterDisplay((TextWidget) w);
964
EndAction( (TextWidget) w);
969
TextFocusIn (w, event, p, n)
975
TextWidget ctx = (TextWidget) w;
977
ctx->text.hasfocus = TRUE;
982
TextFocusOut(w, event, p, n)
988
TextWidget ctx = (TextWidget) w;
990
ctx->text.hasfocus = FALSE;
993
static XComposeStatus compose_status = {NULL, 0};
995
/* Function Name: AutoFill
996
* Description: Breaks the line at the previous word boundry when
997
* called inside InsertChar.
998
* Arguments: ctx - The text widget.
1006
int width, height, x, line_num, max_width;
1007
XawTextPosition ret_pos;
1010
if ( !((ctx->text.auto_fill) && (ctx->text.mult == 1)) )
1013
for ( line_num = 0; line_num < ctx->text.lt.lines ; line_num++)
1014
if ( ctx->text.lt.info[line_num].position >= ctx->text.insertPos )
1016
line_num--; /* backup a line. */
1018
max_width = Max(0, (int)(ctx->core.width - HMargins(ctx)));
1020
x = ctx->text.margin.left;
1021
XawTextSinkFindPosition( ctx->text.sink,ctx->text.lt.info[line_num].position,
1022
x, max_width, TRUE, &ret_pos, &width, &height);
1024
if ( ret_pos >= ctx->text.insertPos )
1030
text.format = FMT8BIT;
1032
if (_XawTextReplace(ctx, ret_pos - 1, ret_pos, &text))
1033
XBell(XtDisplay((Widget) ctx), 0); /* Unable to edit, complain. */
1039
InsertChar(w, event, p, n)
1045
TextWidget ctx = (TextWidget) w;
1046
char *ptr, strbuf[BUFSIZ];
1051
if ( (text.length = XLookupString (&event->xkey, strbuf, BUFSIZ,
1052
&keysym, &compose_status)) == 0) {
1056
text.ptr = ptr = XtMalloc(sizeof(char) * text.length * ctx->text.mult);
1057
for (count = 0 ; count < ctx->text.mult ; count++) {
1058
strncpy(ptr, strbuf, text.length);
1062
text.length = text.length * ctx->text.mult;
1064
text.format = FMT8BIT;
1066
StartAction(ctx, event);
1068
error = _XawTextReplace(ctx, ctx->text.insertPos,ctx->text.insertPos, &text);
1070
if (error == XawEditDone) {
1071
ctx->text.insertPos =
1072
SrcScan(ctx->text.source, ctx->text.insertPos,
1073
XawstPositions, XawsdRight, text.length, TRUE);
1077
XBell(XtDisplay(ctx), 50);
1081
_XawTextSetScrollBars(ctx);
1086
InsertString(w, event, params, num_params)
1090
Cardinal *num_params;
1092
TextWidget ctx = (TextWidget) w;
1097
StartAction(ctx, event);
1098
for (i = *num_params; i; i--, params++) {
1099
unsigned char hexval;
1100
if ((*params)[0] == '0' && (*params)[1] == 'x' && (*params)[2] != '\0') {
1103
for (p = *params+2; (c = *p); p++) {
1105
if (c >= '0' && c <= '9')
1107
else if (c >= 'a' && c <= 'f')
1108
hexval += c - 'a' + 10;
1109
else if (c >= 'A' && c <= 'F')
1110
hexval += c - 'A' + 10;
1114
text.ptr = (char*)&hexval;
1116
} else text.length = strlen(text.ptr = *params);
1117
} else text.length = strlen(text.ptr = *params);
1118
if (text.length == 0) continue;
1119
if (_XawTextReplace(ctx, ctx->text.insertPos,
1120
ctx->text.insertPos, &text)) {
1121
XBell(XtDisplay(ctx), 50);
1125
ctx->text.insertPos =
1126
SrcScan(ctx->text.source, ctx->text.insertPos,
1127
XawstPositions, XawsdRight, text.length, TRUE);
1133
DisplayCaret(w, event, params, num_params)
1135
XEvent *event; /* CrossingNotify special-cased */
1136
String *params; /* Off, False, No, On, True, Yes, etc. */
1137
Cardinal *num_params; /* 0, 1 or 2 */
1139
TextWidget ctx = (TextWidget)w;
1140
Boolean display_caret = True;
1142
if (event->type == EnterNotify || event->type == LeaveNotify) {
1143
/* for Crossing events, the default case is to check the focus
1144
* field and only change the caret when focus==True. A second
1145
* argument of "always" will cause the focus field to be ignored.
1147
Boolean check_focus = True;
1148
if (*num_params == 2 && strcmp(params[1], "always") == 0)
1149
check_focus = False;
1150
if (check_focus && !event->xcrossing.focus) return;
1153
if (*num_params > 0) { /* default arg is "True" */
1155
from.size = strlen(from.addr = params[0]);
1156
XtConvert(w, XtRString, &from, XtRBoolean, &to);
1157
if (to.addr != NULL) display_caret = *(Boolean*)to.addr;
1158
if (ctx->text.display_caret == display_caret) return;
1160
StartAction(ctx, event);
1161
ctx->text.display_caret = display_caret;
1165
/* Function Name: Multiply
1166
* Description: Multiplies the current action by the number passed.
1167
* Arguments: w - the text widget.
1168
* event - ** NOT USED **.
1169
* params, num_params - The parameter list, see below.
1174
* The parameter list may contain either a number or the string 'Reset'.
1176
* A number will multiply the current multiplication factor by that number.
1177
* Many of the text widget actions will will perform n actions, where n is
1178
* the multiplication factor.
1180
* The string reset will reset the mutiplication factor to 1.
1186
Multiply(w, event, params, num_params)
1190
Cardinal * num_params;
1192
TextWidget ctx = (TextWidget) w;
1195
if (*num_params != 1) {
1196
XtAppError(XtWidgetToApplicationContext(w),
1197
"The multiply action takes exactly one argument.");
1198
XBell(XtDisplay(w), 0);
1202
if ( (params[0][0] == 'r') || (params[0][0] == 'R') ) {
1203
XBell(XtDisplay(w), 0);
1208
if ( (mult = atoi(params[0])) == 0 ) {
1210
sprintf(buf, "%s %s", "Text Widget: The multiply action's argument",
1211
"must be a number greater than zero, or 'Reset'.");
1212
XtAppError(XtWidgetToApplicationContext(w), buf);
1213
XBell(XtDisplay(w), 0);
1217
ctx->text.mult *= mult;
1220
/* Function Name: StripOutOldCRs
1221
* Description: strips out the old carrige returns.
1222
* Arguments: ctx - the text widget.
1223
* from - starting point.
1224
* to - the ending point
1225
* Returns: the new ending location (we may add some characters),
1226
* or XawTextReplaceError, which indicates failure.
1229
static XawTextPosition
1230
StripOutOldCRs(ctx, from, to)
1232
XawTextPosition from, to;
1234
XawTextPosition startPos, endPos, eop_begin, eop_end, temp;
1235
Widget src = ctx->text.source;
1241
text.format = FMT8BIT;
1247
eop_begin = eop_end = startPos = endPos = from;
1249
endPos=SrcScan(src, startPos, XawstEOL, XawsdRight, 1, FALSE);
1251
temp=SrcScan(src, endPos, XawstWhiteSpace, XawsdLeft, 1, FALSE);
1252
temp=SrcScan(src, temp, XawstWhiteSpace, XawsdRight, 1, FALSE);
1254
if (temp > startPos)
1260
if (endPos >= eop_begin) {
1262
eop_begin = SrcScan(src, startPos, XawstParagraph, XawsdRight, 1, FALSE);
1263
eop_end = SrcScan(src, startPos, XawstParagraph, XawsdRight, 1, TRUE);
1266
XawTextPosition periodPos, next_word;
1269
periodPos= SrcScan(src, endPos, XawstPositions, XawsdLeft, 1, TRUE);
1270
next_word = SrcScan(src, endPos, XawstWhiteSpace, XawsdRight, 1, FALSE);
1272
len = next_word - periodPos;
1275
buf = _XawTextGetText(ctx, periodPos, next_word);
1276
if ( (periodPos < endPos) && (buf[0] == '.') )
1277
text.length++; /* Put in two spaces. */
1280
* Remove all extra spaces.
1283
for (i = 1 ; i < len; i++)
1284
if ( !isspace(buf[i]) || ((periodPos + i) >= to) ) {
1290
to -= (i - text.length - 1);
1291
startPos = SrcScan(src, periodPos, XawstPositions, XawsdRight, i, TRUE);
1292
if (_XawTextReplace(ctx, endPos, startPos, &text) != XawEditDone)
1293
return XawReplaceError;
1294
startPos -= i - text.length;
1300
/* Function Name: InsertNewCRs
1301
* Description: Inserts the new Carrige Returns.
1302
* Arguments: ctx - the text widget.
1303
* from, to - the ends of the region.
1308
InsertNewCRs(ctx, from, to)
1310
XawTextPosition from, to;
1312
XawTextPosition startPos, endPos, space, eol;
1314
int i, width, height, len;
1320
text.format = FMT8BIT;
1324
XawTextSinkFindPosition( ctx->text.sink, startPos,
1325
(int) ctx->text.margin.left,
1326
(int) (ctx->core.width - HMargins(ctx)),
1327
TRUE, &eol, &width, &height);
1331
eol = SrcScan(ctx->text.source, eol, XawstPositions, XawsdLeft, 1, TRUE);
1332
space= SrcScan(ctx->text.source, eol, XawstWhiteSpace, XawsdRight, 1,TRUE);
1334
startPos = endPos = eol;
1338
len = (int) (space - eol);
1339
buf = _XawTextGetText(ctx, eol, space);
1340
for ( i = 0 ; i < len ; i++)
1341
if (!isspace(buf[i]))
1345
endPos = SrcScan(ctx->text.source, endPos,
1346
XawstPositions, XawsdRight, i, TRUE);
1349
if (_XawTextReplace(ctx, startPos, endPos, &text))
1351
startPos = SrcScan(ctx->text.source, startPos,
1352
XawstPositions, XawsdRight, 1, TRUE);
1356
/* Function Name: FormRegion
1357
* Description: Forms up the region specified.
1358
* Arguments: ctx - the text widget.
1359
* from, to - the ends of the region.
1360
* Returns: XawEditDone if successful, or XawReplaceError.
1364
FormRegion(ctx, from, to)
1366
XawTextPosition from, to;
1368
if (from >= to) return XawEditDone;
1370
if ((to = StripOutOldCRs(ctx, from, to)) == XawReplaceError)
1371
return XawReplaceError;
1372
/* insure that the insertion point is within legal bounds */
1373
if (ctx->text.insertPos >
1374
SrcScan(ctx->text.source, 0, XawstAll, XawsdRight, 1, TRUE))
1375
ctx->text.insertPos = to;
1376
InsertNewCRs(ctx, from, to);
1377
_XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
1381
/* Function Name: FormParagraph.
1382
* Description: reforms up the current paragraph.
1383
* Arguments: w - the text widget.
1384
* event - the X event.
1385
* params, num_params *** NOT USED ***.
1391
FormParagraph(w, event, params, num_params)
1395
Cardinal * num_params;
1397
TextWidget ctx = (TextWidget) w;
1398
XawTextPosition from, to;
1400
StartAction(ctx, event);
1402
from = SrcScan(ctx->text.source, ctx->text.insertPos,
1403
XawstParagraph, XawsdLeft, 1, FALSE);
1404
to = SrcScan(ctx->text.source, from,
1405
XawstParagraph, XawsdRight, 1, FALSE);
1407
if (FormRegion(ctx, from, to) == XawReplaceError)
1408
XBell(XtDisplay(w), 0);
1410
_XawTextSetScrollBars(ctx);
1413
/* Function Name: TransposeCharacters
1414
* Description: Swaps the character to the left of the mark with
1415
* the character to the right of the mark.
1416
* Arguments: w - the text widget.
1417
* event - the event that cause this action.
1418
* params, num_params *** NOT USED ***.
1424
TransposeCharacters(w, event, params, num_params)
1428
Cardinal * num_params;
1430
TextWidget ctx = (TextWidget) w;
1431
XawTextPosition start, end;
1433
unsigned char * buf, c;
1436
StartAction(ctx, event);
1442
start = SrcScan(ctx->text.source, ctx->text.insertPos, XawstPositions,
1443
XawsdLeft, 1, TRUE);
1444
end = SrcScan(ctx->text.source, ctx->text.insertPos, XawstPositions,
1445
XawsdRight, ctx->text.mult, TRUE);
1447
if ( (start == ctx->text.insertPos) || (end == ctx->text.insertPos) )
1448
XBell(XtDisplay(w), 0); /* complain. */
1450
ctx->text.insertPos = end;
1453
* Retrieve text and swap the characters.
1456
buf = (unsigned char *) _XawTextGetText(ctx, start, end);
1457
text.length = strlen((char *)buf);
1459
text.format = FMT8BIT;
1462
for (i = 1 ; i < text.length ; i++)
1463
buf[i - 1] = buf[i];
1467
* Store new text is source.
1470
text.ptr = (char *) buf;
1471
if (_XawTextReplace (ctx, start, end, &text))
1472
XBell(XtDisplay(w), 0); /* Unable to edit, complain. */
1473
XtFree((char *) buf);
1478
/* Function Name: NoOp
1479
* Description: This action performs no action, and allows
1480
* the user or application programmer to unbind a
1482
* Arguments: w - the text widget.
1483
* event - *** UNUSED ***.
1484
* parms and num_params - the action parameters.
1487
* Note: If the parameter list contains the string "RingBell" then
1488
* this action will ring the bell.
1493
NoOp(w, event, params, num_params)
1497
Cardinal *num_params;
1499
if (*num_params != 1)
1502
switch(params[0][0]) {
1505
XBell(XtDisplay(w), 0);
1506
default: /* Fall Through */
1513
XtActionsRec _XawTextActionsTable[] = {
1514
/* motion bindings */
1515
{"forward-character", MoveForwardChar},
1516
{"backward-character", MoveBackwardChar},
1517
{"forward-word", MoveForwardWord},
1518
{"backward-word", MoveBackwardWord},
1519
{"forward-paragraph", MoveForwardParagraph},
1520
{"backward-paragraph", MoveBackwardParagraph},
1521
{"beginning-of-line", MoveToLineStart},
1522
{"end-of-line", MoveToLineEnd},
1523
{"next-line", MoveNextLine},
1524
{"previous-line", MovePreviousLine},
1525
{"next-page", MoveNextPage},
1526
{"previous-page", MovePreviousPage},
1527
{"beginning-of-file", MoveBeginningOfFile},
1528
{"end-of-file", MoveEndOfFile},
1529
{"scroll-one-line-up", ScrollOneLineUp},
1530
{"scroll-one-line-down", ScrollOneLineDown},
1531
/* delete bindings */
1532
{"delete-next-character", DeleteForwardChar},
1533
{"delete-previous-character", DeleteBackwardChar},
1534
{"delete-next-word", DeleteForwardWord},
1535
{"delete-previous-word", DeleteBackwardWord},
1536
{"delete-selection", DeleteCurrentSelection},
1538
{"kill-word", KillForwardWord},
1539
{"backward-kill-word", KillBackwardWord},
1540
{"kill-selection", KillCurrentSelection},
1541
{"kill-to-end-of-line", KillToEndOfLine},
1542
{"kill-to-end-of-paragraph", KillToEndOfParagraph},
1543
/* new line stuff */
1544
{"newline-and-indent", InsertNewLineAndIndent},
1545
{"newline-and-backup", InsertNewLineAndBackup},
1546
{"newline", InsertNewLine},
1547
/* Selection stuff */
1548
{"select-word", SelectWord},
1549
{"select-all", SelectAll},
1550
{"select-start", SelectStart},
1551
{"select-adjust", SelectAdjust},
1552
{"select-end", SelectEnd},
1553
{"select-save", SelectSave},
1554
{"extend-start", ExtendStart},
1555
{"extend-adjust", ExtendAdjust},
1556
{"extend-end", ExtendEnd},
1557
{"insert-selection", InsertSelection},
1559
{"redraw-display", RedrawDisplay},
1560
{"insert-file", _XawTextInsertFile},
1561
{"search", _XawTextSearch},
1562
{"insert-char", InsertChar},
1563
{"insert-string", InsertString},
1564
{"focus-in", TextFocusIn},
1565
{"focus-out", TextFocusOut},
1566
{"display-caret", DisplayCaret},
1567
{"multiply", Multiply},
1568
{"form-paragraph", FormParagraph},
1569
{"transpose-characters", TransposeCharacters},
1571
/* Action to bind special translations for text Dialogs. */
1572
{"InsertFileAction", _XawTextInsertFileAction},
1573
{"DoSearchAction", _XawTextDoSearchAction},
1574
{"DoReplaceAction", _XawTextDoReplaceAction},
1575
{"SetField", _XawTextSetField},
1576
{"PopdownSearchAction", _XawTextPopdownSearchAction},
1579
Cardinal _XawTextActionsTableCount = XtNumber(_XawTextActionsTable);