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 + -
显示快捷键?