/**************************************************************************** ** *W gaptext.c XGAP source Frank Celler ** ** *Y Copyright 1995-1997, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany *Y Copyright 1997, Frank Celler, Huerth, Germany ** ** The GapTextWidget is intended to be used as a simple front end to the ** text widget with a gap text source and an ascii sink attached to it. It ** is a subclass of the standard text widget supplied with X11R4 and should ** work with X11R5 and X11R6.
*/ #include"utils.h" #include"gaptext.h"
*F GapTextInsertSelection( <w>, <evt>, <parms>, <nums> ) . . . . insert text ** ** DESCRIPTION ** Handle a selection insert event. 'GapTextInsertSelection' calls the ** input callback method with the selected string.
*/ #define CTR(a) ( a & 0x1f )
staticvoid GetSelection ( Widget, Time, String *, Cardinal );
staticvoid GapTextInsertSelection (
Widget w,
XEvent * evt,
String * parms,
Cardinal * nums )
{
Time time = 0;
/* get the time of the event */ if ( evt != NULL ) switch ( evt->type )
{ case ButtonPress: case ButtonRelease:
time = evt->xbutton.time; break; case KeyPress: case KeyRelease:
time = evt->xkey.time; break; default:
time = CurrentTime; break;
}
/* and insert the selection */
GetSelection( w, time, parms, *nums );
}
/* free the output buffer */
XtFree( src->gap_src.buffer );
}
/**************************************************************************** ** *F GapSrcReadText( <w>, <pos>, <text>, <len> ) . . . get a piece of our text ** ** DESCRIPTION ** 'GapSrcReadText' sets the pointer <text>.ptr to the text of <w> ** starting at position <pos> and length <len>. ** ** RETURNS ** 'GapSrcReadText' returns the position relative to the beginning of text ** of <w> of the last character in <text>.
*/ static XawTextPosition GapSrcReadText (
Widget w,
XawTextPosition pos,
XawTextBlock * text, Int length )
{
GapSrcObject src = (GapSrcObject) w;
/**************************************************************************** ** *F GapSrcReplaceText( <w>, <start>, <end>, <text> ) . replace a text piece ** ** DESCRIPTION ** Replace the text of <w> starting with <start> and ending before <end> ** with the text given in <text>. ** ** RETURNS ** Either 'XawEditDone' or 'XawPositionError'.
*/ staticint GapSrcReplaceText (
Widget w,
XawTextPosition start,
XawTextPosition end,
XawTextBlock * text )
{
GapSrcObject src = (GapSrcObject) w;
String p;
String q;
String e;
/* remove text from <start> to end */
p = src->gap_src.buffer + start;
q = src->gap_src.buffer + end;
e = src->gap_src.buffer + src->gap_src.length; while ( p < e )
*p++ = *q++;
src->gap_src.length += start - end;
/* now insert the new text */ if ( 0 < text->length )
{ if ( src->gap_src.size < src->gap_src.length + text->length )
{
src->gap_src.size += 16*1024 + text->length;
src->gap_src.buffer = XtRealloc( src->gap_src.buffer,
src->gap_src.size );
}
p = ( src->gap_src.buffer + src->gap_src.length ) - 1;
q = p + text->length;
e = src->gap_src.buffer + start; while ( e <= p )
*q-- = *p--;
q = text->ptr;
p = e;
e = p + text->length; while ( p < e )
*p++ = *q++;
src->gap_src.length += text->length;
} return XawEditDone;
}
/**************************************************************************** ** *F GapSrcScan( <w>, <pos>, <type>, <dir>, <cnt>, <inc> ) . . . . . scan text ** ** DESCRIPTION ** Scan the text in <w>.buffer for the <cnt>.th occurrence of a boundary of ** type <type>. Start the scan at position <pos>. If <include> is true ** include the boundary in the returned position. ** ** RETURNS ** 'Scan' returns the position of the boundary.
*/ static XawTextPosition GapSrcScan (
Widget w,
XawTextPosition pos,
XawTextScanType type,
XawTextScanDirection dir, int cnt, int ind )
{
GapSrcObject src = (GapSrcObject) w; Int inc;
String p;
/* first or last position in our text */ if ( type == XawstAll ) return (dir == XawsdRight) ? src->gap_src.length : 0;
/* set <pos> to a sensible value */ if ( pos > src->gap_src.length )
pos = src->gap_src.length;
/* we cannot scan left of position 0 or right of the text end */ if ( dir == XawsdRight && pos == src->gap_src.length ) return src->gap_src.length; elseif ( dir == XawsdLeft && pos == 0 ) return 0; elseif ( dir == XawsdLeft )
pos--;
/* <inc> is used to increment (decrement) <p> and <pos> */
inc = (dir == XawsdRight) ? 1 : -1;
/* handle different types of boundaries <cnt> times */ switch ( type )
{ case XawstAll: /* is not possible */ return (dir == XawsdRight) ? src->gap_src.length : 0; break;
case XawstEOL: case XawstParagraph: if ( dir == XawsdRight )
{ for ( ; 0 < cnt; cnt-- )
{
p = src->gap_src.buffer + pos; while ( pos < src->gap_src.length )
{ if ( *p == '\n' ) break;
pos++; p++;
} if ( src->gap_src.length < pos ) return src->gap_src.length;
pos++;
}
} else
{ for ( ; 0 < cnt; cnt-- )
{
p = src->gap_src.buffer + pos; while ( 0 <= pos )
{ if ( *p == '\n' ) break;
pos--; p--;
} if ( pos < 0 ) return 0;
pos--;
}
} if ( !ind )
pos -= inc; break;
case XawstWhiteSpace: for ( ; 0 < cnt; cnt-- )
{
Boolean nonSpace = FALSE;
p = src->gap_src.buffer + pos; while ( 0 <= pos && pos < src->gap_src.length )
{ if ( *p == ' ' || *p == '\t' || *p == '\n' )
{ if ( nonSpace ) break;
} else
nonSpace = TRUE;
pos += inc;
p += inc;
} if ( pos < 0 ) return 0; if ( src->gap_src.length < pos ) return src->gap_src.length;
pos += inc;
} if ( !ind )
pos -= inc; break;
case XawstPositions:
pos += cnt * inc; break;
default: break;
} if ( dir == XawsdLeft )
pos++;
/* set <pos> to a sensible value and return */ if ( pos >= src->gap_src.length ) return src->gap_src.length; elseif ( pos < 0 ) return 0; else return pos;
}
/**************************************************************************** ** *F GTDelete( <w>, <dir>, <type> ) . . . . . . . . . delete a piece of text
*/ void GTDelete ( Widget w, XawTextScanDirection dir, XawTextScanType type )
{
GapTextWidget gap = (GapTextWidget) w;
XawTextBlock text; Int to; Int from;
/* prepare text for update */
_XawTextPrepareToUpdate((TextWidget)gap);
gap->text.time = CurrentTime;
/* find <to> and <from> */
to = GapSrcScan(gap->text.source,gap->text.insertPos,type,dir,1,TRUE);
if ( to == gap->text.insertPos )
to = GapSrcScan(gap->text.source,gap->text.insertPos,type,dir,2,TRUE); if (dir == XawsdLeft)
{
from = to;
to = gap->text.insertPos;
} else
from = gap->text.insertPos;
/**************************************************************************** ** *F GTInsertText( <w>, <str>, <len> ) . . . . . insert <str> into a gap text ** ** DESCRIPTION ** This functions insert the text pointed to by <str> of length <len> in ** the gap text widget at the current position. It is the responsibility ** of the caller to set the current insertion position.
*/ void GTInsertText ( Widget w, String str, Int len )
{
GapTextWidget gap = (GapTextWidget) w;
XawTextBlock block;
/* convert text into a text block */
block.firstPos = 0;
block.ptr = (char*) str;
block.format = FMT8BIT;
block.length = len; #if 0
CheckTextBlock(&block); #endif
/* insert text at current position */
XawTextReplace( w, gap->text.insertPos, gap->text.insertPos, &block );
/* move insertion position */
XawTextSetInsertionPoint( w, gap->text.insertPos+len );
}
/**************************************************************************** ** *F GTReplaceText( <w>, <str>, <len> ) . . . . . replace last line by <str> ** ** DESCRIPTION ** This functions replaces the text right of the insert point by the text ** pointed to by <str> of length <len>. It is the responsibility of the ** caller to set the current insertion position.
*/ void GTReplaceText ( Widget w, String str, Int len )
{
GapTextWidget gap = (GapTextWidget) w;
XawTextBlock block;
/* convert text into a text block */
block.firstPos = 0;
block.ptr = (char*) str;
block.format = FMT8BIT;
block.length = len; #if 0
CheckTextBlock(&block); #endif
/* insert text at current position */
XawTextReplace(w,gap->text.insertPos,gap->text.insertPos+len,&block);
/* move insertion position */
XawTextSetInsertionPoint( w, gap->text.insertPos+len );
}
/**************************************************************************** ** *F GTMoveCaret( <w>, <rpos> ) . . . move caret relative to current position
*/ void GTMoveCaret ( Widget w, Int rpos )
{
GapTextWidget gap = (GapTextWidget) w; Int pos;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.