fl_text_buffer.cxx

来自「SRI international 发布的OAA框架软件」· CXX 代码 · 共 1,884 行 · 第 1/5 页

CXX
1,884
字号
void Fl_Text_Buffer::canUndo(char flag) {
  mCanUndo = flag;
}

/*
** Insert "text" columnwise into buffer starting at displayed character
** position "column" on the line beginning at "startPos".  Opens a rectangular
** space the width and height of "text", by moving all text to the right of
** "column" right.  If charsInserted and charsDeleted are not NULL, the
** number of characters inserted and deleted in the operation (beginning
** at startPos) are returned in these arguments
*/
void Fl_Text_Buffer::insert_column( int column, int startPos, const char *s,
                                    int *charsInserted, int *charsDeleted ) {
  int nLines, lineStartPos, nDeleted, insertDeleted, nInserted;
  const char *deletedText;

  nLines = countLines( s );
  lineStartPos = line_start( startPos );
  nDeleted = line_end( skip_lines( startPos, nLines ) ) -
             lineStartPos;
  call_predelete_callbacks( lineStartPos, nDeleted );
  deletedText = text_range( lineStartPos, lineStartPos + nDeleted );
  insert_column_( column, lineStartPos, s, &insertDeleted, &nInserted,
                  &mCursorPosHint );
  if ( nDeleted != insertDeleted )
    Fl::error("Fl_Text_Buffer::insert_column(): internal consistency check ins1 failed");
  call_modify_callbacks( lineStartPos, nDeleted, nInserted, 0, deletedText );
  free( (void *) deletedText );
  if ( charsInserted != NULL )
    * charsInserted = nInserted;
  if ( charsDeleted != NULL )
    * charsDeleted = nDeleted;
}

/*
** Overlay "text" between displayed character positions "rectStart" and
** "rectEnd" on the line beginning at "startPos".  If charsInserted and
** charsDeleted are not NULL, the number of characters inserted and deleted
** in the operation (beginning at startPos) are returned in these arguments.
*/
void Fl_Text_Buffer::overlay_rectangular( int startPos, int rectStart,
    int rectEnd, const char *s, int *charsInserted, int *charsDeleted ) {
  int nLines, lineStartPos, nDeleted, insertDeleted, nInserted;
  const char *deletedText;

  nLines = countLines( s );
  lineStartPos = line_start( startPos );
  nDeleted = line_end( skip_lines( startPos, nLines ) ) -
             lineStartPos;
  call_predelete_callbacks( lineStartPos, nDeleted );
  deletedText = text_range( lineStartPos, lineStartPos + nDeleted );
  overlay_rectangular_( lineStartPos, rectStart, rectEnd, s, &insertDeleted,
                        &nInserted, &mCursorPosHint );
  if ( nDeleted != insertDeleted )
    Fl::error("Fl_Text_Buffer::overlay_rectangle(): internal consistency check ovly1 failed");
  call_modify_callbacks( lineStartPos, nDeleted, nInserted, 0, deletedText );
  free( (void *) deletedText );
  if ( charsInserted != NULL )
    * charsInserted = nInserted;
  if ( charsDeleted != NULL )
    * charsDeleted = nDeleted;
}

/*
** Replace a rectangular area in buf, given by "start", "end", "rectStart",
** and "rectEnd", with "text".  If "text" is vertically longer than the
** rectangle, add extra lines to make room for it.
*/
void Fl_Text_Buffer::replace_rectangular( int start, int end, int rectStart,
    int rectEnd, const char *s ) {
  char *insPtr;
  const char *deletedText;
  char *insText = (char *)"";
  int i, nInsertedLines, nDeletedLines, insLen, hint;
  int insertDeleted, insertInserted, deleteInserted;
  int linesPadded = 0;

  /* Make sure start and end refer to complete lines, since the
     columnar delete and insert operations will replace whole lines */
  start = line_start( start );
  end = line_end( end );

  call_predelete_callbacks( start, end-start );

  /* If more lines will be deleted than inserted, pad the inserted text
     with newlines to make it as long as the number of deleted lines.  This
     will indent all of the text to the right of the rectangle to the same
     column.  If more lines will be inserted than deleted, insert extra
     lines in the buffer at the end of the rectangle to make room for the
     additional lines in "text" */
  nInsertedLines = countLines( s );
  nDeletedLines = count_lines( start, end );
  if ( nInsertedLines < nDeletedLines ) {
    insLen = strlen( s );
    insText = (char *)malloc( insLen + nDeletedLines - nInsertedLines + 1 );
    strcpy( insText, s );
    insPtr = insText + insLen;
    for ( i = 0; i < nDeletedLines - nInsertedLines; i++ )
      *insPtr++ = '\n';
    *insPtr = '\0';
  } else if ( nDeletedLines < nInsertedLines ) {
    linesPadded = nInsertedLines - nDeletedLines;
    for ( i = 0; i < linesPadded; i++ )
      insert_( end, "\n" );
  } /* else nDeletedLines == nInsertedLines; */

  /* Save a copy of the text which will be modified for the modify CBs */
  deletedText = text_range( start, end );

  /* Delete then insert */
  remove_rectangular_( start, end, rectStart, rectEnd, &deleteInserted, &hint );
  insert_column_( rectStart, start, insText, &insertDeleted, &insertInserted,
                  &mCursorPosHint );

  /* Figure out how many chars were inserted and call modify callbacks */
  if ( insertDeleted != deleteInserted + linesPadded )
    Fl::error("Fl_Text_Buffer::replace_rectangular(): internal consistency check repl1 failed");
  call_modify_callbacks( start, end - start, insertInserted, 0, deletedText );
  free( (void *) deletedText );
  if ( nInsertedLines < nDeletedLines )
    free( (void *) insText );
}

/*
** Remove a rectangular swath of characters between character positions start
** and end and horizontal displayed-character offsets rectStart and rectEnd.
*/
void Fl_Text_Buffer::remove_rectangular( int start, int end, int rectStart,
    int rectEnd ) {
  const char * deletedText;
  int nInserted;

  start = line_start( start );
  end = line_end( end );
  call_predelete_callbacks( start, end-start );
  deletedText = text_range( start, end );
  remove_rectangular_( start, end, rectStart, rectEnd, &nInserted,
                       &mCursorPosHint );
  call_modify_callbacks( start, end - start, nInserted, 0, deletedText );
  free( (void *) deletedText );
}

/*
** Clear a rectangular "hole" out of the buffer between character positions
** start and end and horizontal displayed-character offsets rectStart and
** rectEnd.
*/
void Fl_Text_Buffer::clear_rectangular( int start, int end, int rectStart,
                                        int rectEnd ) {
  int i, nLines;
  char *newlineString;

  nLines = count_lines( start, end );
  newlineString = (char *)malloc( nLines + 1 );
  for ( i = 0; i < nLines; i++ )
    newlineString[ i ] = '\n';
  newlineString[ i ] = '\0';
  overlay_rectangular( start, rectStart, rectEnd, newlineString,
                       NULL, NULL );
  free( (void *) newlineString );
}

char * Fl_Text_Buffer::text_in_rectangle( int start, int end,
    int rectStart, int rectEnd ) {
  int lineStart, selLeft, selRight, len;
  char *textOut, *outPtr, *retabbedStr;
  const char *textIn;

  start = line_start( start );
  end = line_end( end );
  textOut = (char *)malloc( ( end - start ) + 1 );
  lineStart = start;
  outPtr = textOut;
  while ( lineStart <= end ) {
    rectangular_selection_boundaries( lineStart, rectStart, rectEnd,
                                      &selLeft, &selRight );
    textIn = text_range( selLeft, selRight );
    len = selRight - selLeft;
    memcpy( outPtr, textIn, len );
    free( (void *) textIn );
    outPtr += len;
    lineStart = line_end( selRight ) + 1;
    *outPtr++ = '\n';
  }
  if ( outPtr != textOut )
    outPtr--;    /* don't leave trailing newline */
  *outPtr = '\0';

  /* If necessary, realign the tabs in the selection as if the text were
     positioned at the left margin */
  retabbedStr = realignTabs( textOut, rectStart, 0, mTabDist,
                             mUseTabs, mNullSubsChar, &len );
  free( (void *) textOut );
  return retabbedStr;
}

/*
** Set the hardware tab distance used by all displays for this buffer,
** and used in computing offsets for rectangular selection operations.
*/
void Fl_Text_Buffer::tab_distance( int tabDist ) {
  const char * deletedText;

    /* First call the pre-delete callbacks with the previous tab setting 
       still active. */
  call_predelete_callbacks( 0, mLength );
    
  /* Change the tab setting */
  mTabDist = tabDist;

  /* Force any display routines to redisplay everything (unfortunately,
     this means copying the whole buffer contents to provide "deletedText" */
  deletedText = text();
  call_modify_callbacks( 0, mLength, mLength, 0, deletedText );
  free( (void *) deletedText );
}

void Fl_Text_Buffer::select( int start, int end ) {
  Fl_Text_Selection oldSelection = mPrimary;

  mPrimary.set( start, end );
  redisplay_selection( &oldSelection, &mPrimary );
}

void Fl_Text_Buffer::unselect() {
  Fl_Text_Selection oldSelection = mPrimary;

  mPrimary.mSelected = 0;
  redisplay_selection( &oldSelection, &mPrimary );
}

void Fl_Text_Buffer::select_rectangular( int start, int end, int rectStart,
    int rectEnd ) {
  Fl_Text_Selection oldSelection = mPrimary;

  mPrimary.set_rectangular( start, end, rectStart, rectEnd );
  redisplay_selection( &oldSelection, &mPrimary );
}

int Fl_Text_Buffer::selection_position( int *start, int *end
                                      ) {
  return mPrimary.position( start, end );
}

int Fl_Text_Buffer::selection_position( int *start, int *end,
                                        int *isRect, int *rectStart, int *rectEnd ) {
  return mPrimary.position( start, end, isRect, rectStart,
                            rectEnd );
}

char * Fl_Text_Buffer::selection_text() {
  return selection_text_( &mPrimary );
}

void Fl_Text_Buffer::remove_selection() {
  remove_selection_( &mPrimary );
}

void Fl_Text_Buffer::replace_selection( const char *s ) {
  replace_selection_( &mPrimary, s );
}

void Fl_Text_Buffer::secondary_select( int start, int end ) {
  Fl_Text_Selection oldSelection = mSecondary;

  mSecondary.set( start, end );
  redisplay_selection( &oldSelection, &mSecondary );
}

void Fl_Text_Buffer::secondary_unselect() {
  Fl_Text_Selection oldSelection = mSecondary;

  mSecondary.mSelected = 0;
  redisplay_selection( &oldSelection, &mSecondary );
}

void Fl_Text_Buffer::secondary_select_rectangular( int start, int end,
    int rectStart, int rectEnd ) {
  Fl_Text_Selection oldSelection = mSecondary;

  mSecondary.set_rectangular( start, end, rectStart, rectEnd );
  redisplay_selection( &oldSelection, &mSecondary );
}

int Fl_Text_Buffer::secondary_selection_position( int *start, int *end,
    int *isRect, int *rectStart, int *rectEnd ) {
  return mSecondary.position( start, end, isRect, rectStart,
                              rectEnd );
}

char * Fl_Text_Buffer::secondary_selection_text() {
  return selection_text_( &mSecondary );
}

void Fl_Text_Buffer::remove_secondary_selection() {
  remove_selection_( &mSecondary );
}

void Fl_Text_Buffer::replace_secondary_selection( const char *s ) {
  replace_selection_( &mSecondary, s );
}

void Fl_Text_Buffer::highlight( int start, int end ) {
  Fl_Text_Selection oldSelection = mHighlight;

  mHighlight.set( start, end );
  redisplay_selection( &oldSelection, &mHighlight );
}

void Fl_Text_Buffer::unhighlight() {
  Fl_Text_Selection oldSelection = mHighlight;

  mHighlight.mSelected = 0;
  redisplay_selection( &oldSelection, &mHighlight );
}

void Fl_Text_Buffer::highlight_rectangular( int start, int end,
    int rectStart, int rectEnd ) {
  Fl_Text_Selection oldSelection = mHighlight;

  mHighlight.set_rectangular( start, end, rectStart, rectEnd );
  redisplay_selection( &oldSelection, &mHighlight );
}

int Fl_Text_Buffer::highlight_position( int *start, int *end,
                                        int *isRect, int *rectStart, int *rectEnd ) {
  return mHighlight.position( start, end, isRect, rectStart,
                              rectEnd );
}

char * Fl_Text_Buffer::highlight_text() {
  return selection_text_( &mHighlight );
}

/*
** Add a callback routine to be called when the buffer is modified
*/
void Fl_Text_Buffer::add_modify_callback( Fl_Text_Modify_Cb bufModifiedCB,
    void *cbArg ) {
  Fl_Text_Modify_Cb * newModifyProcs;
  void **newCBArgs;
  int i;

  newModifyProcs = new Fl_Text_Modify_Cb [ mNModifyProcs + 1 ];
  newCBArgs = new void * [ mNModifyProcs + 1 ];
  for ( i = 0; i < mNModifyProcs; i++ ) {
    newModifyProcs[ i + 1 ] = mNodifyProcs[ i ];
    newCBArgs[ i + 1 ] = mCbArgs[ i ];
  }
  if ( mNModifyProcs != 0 ) {
    delete [] mNodifyProcs;
    delete [] mCbArgs;
  }
  newModifyProcs[ 0 ] = bufModifiedCB;
  newCBArgs[ 0 ] = cbArg;
  mNModifyProcs++;
  mNodifyProcs = newModifyProcs;
  mCbArgs = newCBArgs;
}

void Fl_Text_Buffer::remove_modify_callback( Fl_Text_Modify_Cb bufModifiedCB,
    void *cbArg ) {
  int i, toRemove = -1;
  Fl_Text_Modify_Cb *newModifyProcs;
  void **newCBArgs;

  /* find the matching callback to remove */
  for ( i = 0; i < mNModifyProcs; i++ ) {
    if ( mNodifyProcs[ i ] == bufModifiedCB && mCbArgs[ i ] == cbArg ) {
      toRemove = i;
      break;
    }
  }
  if ( toRemove == -1 ) {
    Fl::error("Fl_Text_Buffer::remove_modify_callback(): Can't find modify CB to remove");
    return;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?