fl_text_buffer.cxx
来自「SRI international 发布的OAA框架软件」· CXX 代码 · 共 1,884 行 · 第 1/5 页
CXX
1,884 行
}
/* Allocate new lists for remaining callback procs and args (if
any are left) */
mNModifyProcs--;
if ( mNModifyProcs == 0 ) {
mNModifyProcs = 0;
delete[] mNodifyProcs;
mNodifyProcs = NULL;
delete[] mCbArgs;
mCbArgs = NULL;
return;
}
newModifyProcs = new Fl_Text_Modify_Cb [ mNModifyProcs ];
newCBArgs = new void * [ mNModifyProcs ];
/* copy out the remaining members and free the old lists */
for ( i = 0; i < toRemove; i++ ) {
newModifyProcs[ i ] = mNodifyProcs[ i ];
newCBArgs[ i ] = mCbArgs[ i ];
}
for ( ; i < mNModifyProcs; i++ ) {
newModifyProcs[ i ] = mNodifyProcs[ i + 1 ];
newCBArgs[ i ] = mCbArgs[ i + 1 ];
}
delete[] mNodifyProcs;
delete[] mCbArgs;
mNodifyProcs = newModifyProcs;
mCbArgs = newCBArgs;
}
/*
** Add a callback routine to be called before text is deleted from the buffer.
*/
void Fl_Text_Buffer::add_predelete_callback(Fl_Text_Predelete_Cb bufPreDeleteCB,
void *cbArg) {
Fl_Text_Predelete_Cb *newPreDeleteProcs;
void **newCBArgs;
int i;
newPreDeleteProcs = new Fl_Text_Predelete_Cb[ mNPredeleteProcs + 1 ];
newCBArgs = new void * [ mNPredeleteProcs + 1 ];
for ( i = 0; i < mNPredeleteProcs; i++ ) {
newPreDeleteProcs[i + 1] = mPredeleteProcs[i];
newCBArgs[i + 1] = mPredeleteCbArgs[i];
}
if (! mNPredeleteProcs != 0) {
delete [] mPredeleteProcs;
delete [] mPredeleteCbArgs;
}
newPreDeleteProcs[0] = bufPreDeleteCB;
newCBArgs[0] = cbArg;
mNPredeleteProcs++;
mPredeleteProcs = newPreDeleteProcs;
mPredeleteCbArgs = newCBArgs;
}
void Fl_Text_Buffer::remove_predelete_callback(
Fl_Text_Predelete_Cb bufPreDeleteCB, void *cbArg) {
int i, toRemove = -1;
Fl_Text_Predelete_Cb *newPreDeleteProcs;
void **newCBArgs;
/* find the matching callback to remove */
for ( i = 0; i < mNPredeleteProcs; i++) {
if (mPredeleteProcs[i] == bufPreDeleteCB &&
mPredeleteCbArgs[i] == cbArg) {
toRemove = i;
break;
}
}
if (toRemove == -1) {
Fl::error("Fl_Text_Buffer::remove_predelete_callback(): Can't find pre-delete CB to remove");
return;
}
/* Allocate new lists for remaining callback procs and args (if
any are left) */
mNPredeleteProcs--;
if (mNPredeleteProcs == 0) {
mNPredeleteProcs = 0;
delete[] mPredeleteProcs;
mPredeleteProcs = NULL;
delete[] mPredeleteCbArgs;
mPredeleteCbArgs = NULL;
return;
}
newPreDeleteProcs = new Fl_Text_Predelete_Cb [ mNPredeleteProcs ];
newCBArgs = new void * [ mNPredeleteProcs ];
/* copy out the remaining members and free the old lists */
for ( i = 0; i < toRemove; i++) {
newPreDeleteProcs[i] = mPredeleteProcs[i];
newCBArgs[i] = mPredeleteCbArgs[i];
}
for ( ; i < mNPredeleteProcs; i++) {
newPreDeleteProcs[i] = mPredeleteProcs[i+1];
newCBArgs[i] = mPredeleteCbArgs[i+1];
}
delete[] mPredeleteProcs;
delete[] mPredeleteCbArgs;
mPredeleteProcs = newPreDeleteProcs;
mPredeleteCbArgs = newCBArgs;
}
/*
** Return the text from the entire line containing position "pos"
*/
char * Fl_Text_Buffer::line_text( int pos ) {
return text_range( line_start( pos ), line_end( pos ) );
}
/*
** Find the position of the start of the line containing position "pos"
*/
int Fl_Text_Buffer::line_start( int pos ) {
if ( !findchar_backward( pos, '\n', &pos ) )
return 0;
return pos + 1;
}
/*
** Find the position of the end of the line containing position "pos"
** (which is either a pointer to the newline character ending the line,
** or a pointer to one character beyond the end of the buffer)
*/
int Fl_Text_Buffer::line_end( int pos ) {
if ( !findchar_forward( pos, '\n', &pos ) )
pos = mLength;
return pos;
}
int Fl_Text_Buffer::word_start( int pos ) {
while ( pos && ( isalnum( character( pos ) ) || character( pos ) == '_' ) ) {
pos--;
}
if ( !( isalnum( character( pos ) ) || character( pos ) == '_' ) ) pos++;
return pos;
}
int Fl_Text_Buffer::word_end( int pos ) {
while (pos < length() && (isalnum(character(pos)) || character(pos) == '_' )) {
pos++;
}
return pos;
}
/*
** Get a character from the text buffer expanded into it's screen
** representation (which may be several characters for a tab or a
** control code). Returns the number of characters written to "outStr".
** "indent" is the number of characters from the start of the line
** for figuring tabs. Output string is guranteed to be shorter or
** equal in length to FL_TEXT_MAX_EXP_CHAR_LEN
*/
int Fl_Text_Buffer::expand_character( int pos, int indent, char *outStr ) {
return expand_character( character( pos ), indent, outStr,
mTabDist, mNullSubsChar );
}
/*
** Expand a single character from the text buffer into it's screen
** representation (which may be several characters for a tab or a
** control code). Returns the number of characters added to "outStr".
** "indent" is the number of characters from the start of the line
** for figuring tabs. Output string is guranteed to be shorter or
** equal in length to FL_TEXT_MAX_EXP_CHAR_LEN
*/
int Fl_Text_Buffer::expand_character( char c, int indent, char *outStr, int tabDist,
char nullSubsChar ) {
int i, nSpaces;
/* Convert tabs to spaces */
if ( c == '\t' ) {
nSpaces = tabDist - ( indent % tabDist );
for ( i = 0; i < nSpaces; i++ )
outStr[ i ] = ' ';
return nSpaces;
}
/* Convert control codes to readable character sequences */
/*... is this safe with international character sets? */
if ( ( ( unsigned char ) c ) <= 31 ) {
sprintf( outStr, "<%s>", ControlCodeTable[ c ] );
return strlen( outStr );
} else if ( c == 127 ) {
sprintf( outStr, "<del>" );
return 5;
} else if ( c == nullSubsChar ) {
sprintf( outStr, "<nul>" );
return 5;
}
/* Otherwise, just return the character */
*outStr = c;
return 1;
}
/*
** Return the length in displayed characters of character "c" expanded
** for display (as discussed above in BufGetExpandedChar). If the
** buffer for which the character width is being measured is doing null
** substitution, nullSubsChar should be passed as that character (or nul
** to ignore).
*/
int Fl_Text_Buffer::character_width( char c, int indent, int tabDist, char nullSubsChar ) {
/* Note, this code must parallel that in Fl_Text_Buffer::ExpandCharacter */
if ( c == '\t' )
return tabDist - ( indent % tabDist );
else if ( ( ( unsigned char ) c ) <= 31 )
return strlen( ControlCodeTable[ c ] ) + 2;
else if ( c == 127 )
return 5;
else if ( c == nullSubsChar )
return 5;
return 1;
}
/*
** Count the number of displayed characters between buffer position
** "lineStartPos" and "targetPos". (displayed characters are the characters
** shown on the screen to represent characters in the buffer, where tabs and
** control characters are expanded)
*/
int Fl_Text_Buffer::count_displayed_characters( int lineStartPos, int targetPos ) {
int pos, charCount = 0;
char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ];
pos = lineStartPos;
while ( pos < targetPos )
charCount += expand_character( pos++, charCount, expandedChar );
return charCount;
}
/*
** Count forward from buffer position "startPos" in displayed characters
** (displayed characters are the characters shown on the screen to represent
** characters in the buffer, where tabs and control characters are expanded)
*/
int Fl_Text_Buffer::skip_displayed_characters( int lineStartPos, int nChars ) {
int pos, charCount = 0;
char c;
pos = lineStartPos;
while ( charCount < nChars && pos < mLength ) {
c = character( pos );
if ( c == '\n' )
return pos;
charCount += character_width( c, charCount, mTabDist, mNullSubsChar );
pos++;
}
return pos;
}
/*
** Count the number of newlines between startPos and endPos in buffer "buf".
** The character at position "endPos" is not counted.
*/
int Fl_Text_Buffer::count_lines( int startPos, int endPos ) {
int pos, gapLen = mGapEnd - mGapStart;
int lineCount = 0;
pos = startPos;
while ( pos < mGapStart ) {
if ( pos == endPos )
return lineCount;
if ( mBuf[ pos++ ] == '\n' )
lineCount++;
}
while ( pos < mLength ) {
if ( pos == endPos )
return lineCount;
if ( mBuf[ pos++ + gapLen ] == '\n' )
lineCount++;
}
return lineCount;
}
/*
** Find the first character of the line "nLines" forward from "startPos"
** in "buf" and return its position
*/
int Fl_Text_Buffer::skip_lines( int startPos, int nLines ) {
int pos, gapLen = mGapEnd - mGapStart;
int lineCount = 0;
if ( nLines == 0 )
return startPos;
pos = startPos;
while ( pos < mGapStart ) {
if ( mBuf[ pos++ ] == '\n' ) {
lineCount++;
if ( lineCount == nLines )
return pos;
}
}
while ( pos < mLength ) {
if ( mBuf[ pos++ + gapLen ] == '\n' ) {
lineCount++;
if ( lineCount >= nLines )
return pos;
}
}
return pos;
}
/*
** Find the position of the first character of the line "nLines" backwards
** from "startPos" (not counting the character pointed to by "startpos" if
** that is a newline) in "buf". nLines == 0 means find the beginning of
** the line
*/
int Fl_Text_Buffer::rewind_lines( int startPos, int nLines ) {
int pos, gapLen = mGapEnd - mGapStart;
int lineCount = -1;
pos = startPos - 1;
if ( pos <= 0 )
return 0;
while ( pos >= mGapStart ) {
if ( mBuf[ pos + gapLen ] == '\n' ) {
if ( ++lineCount >= nLines )
return pos + 1;
}
pos--;
}
while ( pos >= 0 ) {
if ( mBuf[ pos ] == '\n' ) {
if ( ++lineCount >= nLines )
return pos + 1;
}
pos--;
}
return 0;
}
/*
** Search forwards in buffer for string "searchString", starting with the
** character "startPos", and returning the result in "foundPos"
** returns 1 if found, 0 if not.
*/
int Fl_Text_Buffer::search_forward( int startPos, const char *searchString,
int *foundPos, int matchCase )
{
if (!searchString) return 0;
int bp;
const char* sp;
while (startPos < length()) {
bp = startPos;
sp = searchString;
do {
if (!*sp) { *foundPos = startPos; return 1; }
} while ((matchCase ? character(bp++) == *sp++ :
toupper(character(bp++)) == toupper(*sp++))
&& bp < length());
startPos++;
}
return 0;
}
/*
** Search backwards in buffer for string "searchString", starting with the
** character BEFORE "startPos", returning the result in "foundPos"
** returns 1 if found, 0 if not.
*/
int Fl_Text_Buffer::search_backward( int startPos, const char *searchString,
int *foundPos, int matchCase )
{
if (!searchString) return 0;
int bp;
const char* sp;
while (startPos > 0) {
bp = startPos-1;
sp = searchString+strlen(searchString)-1;
do {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?