Added 'Undo' to Fl_Text_Editor by reusing some of the Fl_Input_ code. I tried many cases and it seems to work fine.

Matthias


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@2825 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher 2002-11-05 19:53:50 +00:00
parent 66dabdb8f5
commit 3473297741
4 changed files with 123 additions and 13 deletions

View File

@ -1,5 +1,5 @@
// //
// "$Id: Fl_Text_Buffer.H,v 1.3.2.5 2002/09/20 19:59:45 easysw Exp $" // "$Id: Fl_Text_Buffer.H,v 1.3.2.6 2002/11/05 19:53:50 matthiaswm Exp $"
// //
// Header file for Fl_Text_Buffer class. // Header file for Fl_Text_Buffer class.
// //
@ -83,6 +83,7 @@ class FL_EXPORT Fl_Text_Buffer {
void remove(int start, int end); void remove(int start, int end);
void replace(int start, int end, const char *text); void replace(int start, int end, const char *text);
void copy(Fl_Text_Buffer* fromBuf, int fromStart, int fromEnd, int toPos); void copy(Fl_Text_Buffer* fromBuf, int fromStart, int fromEnd, int toPos);
int undo(int *cp=0);
int insertfile(const char *file, int pos, int buflen = 128*1024); int insertfile(const char *file, int pos, int buflen = 128*1024);
int appendfile(const char *file, int buflen = 128*1024) int appendfile(const char *file, int buflen = 128*1024)
{ return insertfile(file, length(), buflen); } { return insertfile(file, length(), buflen); }
@ -249,5 +250,5 @@ class FL_EXPORT Fl_Text_Buffer {
#endif #endif
// //
// End of "$Id: Fl_Text_Buffer.H,v 1.3.2.5 2002/09/20 19:59:45 easysw Exp $". // End of "$Id: Fl_Text_Buffer.H,v 1.3.2.6 2002/11/05 19:53:50 matthiaswm Exp $".
// //

View File

@ -1,5 +1,5 @@
// //
// "$Id: Fl_Text_Editor.H,v 1.1.2.5 2002/11/05 06:45:40 matthiaswm Exp $" // "$Id: Fl_Text_Editor.H,v 1.1.2.6 2002/11/05 19:53:50 matthiaswm Exp $"
// //
// Header file for Fl_Text_Editor class. // Header file for Fl_Text_Editor class.
// //
@ -88,6 +88,7 @@ class FL_EXPORT Fl_Text_Editor : public Fl_Text_Display {
static int kf_cut(int c, Fl_Text_Editor* e); static int kf_cut(int c, Fl_Text_Editor* e);
static int kf_paste(int c, Fl_Text_Editor* e); static int kf_paste(int c, Fl_Text_Editor* e);
static int kf_select_all(int c, Fl_Text_Editor* e); static int kf_select_all(int c, Fl_Text_Editor* e);
static int kf_undo(int c, Fl_Text_Editor* e);
protected: protected:
int handle_key(); int handle_key();
@ -102,6 +103,6 @@ class FL_EXPORT Fl_Text_Editor : public Fl_Text_Display {
#endif #endif
// //
// End of "$Id: Fl_Text_Editor.H,v 1.1.2.5 2002/11/05 06:45:40 matthiaswm Exp $". // End of "$Id: Fl_Text_Editor.H,v 1.1.2.6 2002/11/05 19:53:50 matthiaswm Exp $".
// //

View File

@ -1,5 +1,5 @@
// //
// "$Id: Fl_Text_Buffer.cxx,v 1.9.2.12 2002/09/20 19:59:45 easysw Exp $" // "$Id: Fl_Text_Buffer.cxx,v 1.9.2.13 2002/11/05 19:53:50 matthiaswm Exp $"
// //
// Copyright 2001-2002 by Bill Spitzak and others. // Copyright 2001-2002 by Bill Spitzak and others.
// Original code Copyright Mark Edel. Permission to distribute under // Original code Copyright Mark Edel. Permission to distribute under
@ -69,6 +69,26 @@ static const char *ControlCodeTable[ 32 ] = {
"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
"can", "em", "sub", "esc", "fs", "gs", "rs", "us"}; "can", "em", "sub", "esc", "fs", "gs", "rs", "us"};
static char* undobuffer;
static int undobufferlength;
static Fl_Text_Buffer* undowidget;
static int undoat; // points after insertion
static int undocut; // number of characters deleted there
static int undoinsert; // number of characters inserted
static int undoyankcut; // length of valid contents of buffer, even if undocut=0
static void undobuffersize(int n) {
if (n > undobufferlength) {
if (undobuffer) {
do {undobufferlength *= 2;} while (undobufferlength < n);
undobuffer = (char*)realloc(undobuffer, undobufferlength);
} else {
undobufferlength = n+9;
undobuffer = (char*)malloc(undobufferlength);
}
}
}
/* /*
** Create an empty text buffer of a pre-determined size (use this to ** Create an empty text buffer of a pre-determined size (use this to
** avoid unnecessary re-allocation if you know exactly how much the buffer ** avoid unnecessary re-allocation if you know exactly how much the buffer
@ -249,6 +269,7 @@ void Fl_Text_Buffer::replace( int start, int end, const char *s ) {
call_predelete_callbacks( start, end-start ); call_predelete_callbacks( start, end-start );
deletedText = text_range( start, end ); deletedText = text_range( start, end );
remove_( start, end ); remove_( start, end );
//undoyankcut = undocut;
nInserted = insert_( start, s ); nInserted = insert_( start, s );
mCursorPosHint = start + nInserted; mCursorPosHint = start + nInserted;
call_modify_callbacks( start, end - start, nInserted, 0, deletedText ); call_modify_callbacks( start, end - start, nInserted, 0, deletedText );
@ -311,6 +332,45 @@ void Fl_Text_Buffer::copy( Fl_Text_Buffer *fromBuf, int fromStart,
update_selections( toPos, 0, copiedLength ); update_selections( toPos, 0, copiedLength );
} }
/*
** remove text according to the undo variables or insert text
** from the undo buffer
*/
int Fl_Text_Buffer::undo(int *cursorPos) {
if (undowidget != this || !undocut && !undoinsert) return 0;
int ilen = undocut;
int xlen = undoinsert;
int b = undoat-xlen;
if (xlen && undoyankcut && !ilen) {
ilen = undoyankcut;
}
if (xlen && ilen) {
undobuffersize(ilen+1);
undobuffer[ilen] = 0;
char *tmp = strdup(undobuffer);
int at = undoat;
replace(b, undoat, tmp);
if (cursorPos) *cursorPos = mCursorPosHint;
free(tmp);
}
else if (xlen) {
remove(b, undoat);
if (cursorPos) *cursorPos = mCursorPosHint;
}
else if (ilen) {
undobuffersize(ilen+1);
undobuffer[ilen] = 0;
insert(undoat, undobuffer);
if (cursorPos) *cursorPos = mCursorPosHint;
undoyankcut = 0;
}
return 1;
}
/* /*
** Insert "text" columnwise into buffer starting at displayed character ** Insert "text" columnwise into buffer starting at displayed character
** position "column" on the line beginning at "startPos". Opens a rectangular ** position "column" on the line beginning at "startPos". Opens a rectangular
@ -1279,6 +1339,17 @@ int Fl_Text_Buffer::insert_( int pos, const char *s ) {
mLength += insertedLength; mLength += insertedLength;
update_selections( pos, 0, insertedLength ); update_selections( pos, 0, insertedLength );
if ( undowidget==this && undoat==pos && undoinsert ) {
undoinsert += insertedLength;
}
else {
undoinsert = insertedLength;
undoyankcut = (undoat==pos) ? undocut : 0 ;
}
undoat = pos+insertedLength;
undocut = 0;
undowidget = this;
return insertedLength; return insertedLength;
} }
@ -1289,10 +1360,34 @@ int Fl_Text_Buffer::insert_( int pos, const char *s ) {
*/ */
void Fl_Text_Buffer::remove_( int start, int end ) { void Fl_Text_Buffer::remove_( int start, int end ) {
/* if the gap is not contiguous to the area to remove, move it there */ /* if the gap is not contiguous to the area to remove, move it there */
if ( start > mGapStart )
if ( undowidget==this && undoat==end && undocut ) {
undobuffersize( undocut+end-start+1 );
memmove( undobuffer+end-start, undobuffer, undocut );
undocut += end-start;
}
else {
undocut = end-start;
undobuffersize(undocut);
}
undoat = start;
undoinsert = 0;
undoyankcut = 0;
undowidget = this;
if ( start > mGapStart ) {
memcpy( undobuffer, mBuf+(mGapEnd-mGapStart)+start, end-start );
move_gap( start ); move_gap( start );
else if ( end < mGapStart ) }
else if ( end < mGapStart ) {
memcpy( undobuffer, mBuf+start, end-start );
move_gap( end ); move_gap( end );
}
else {
int prelen = mGapStart - start;
memcpy( undobuffer, mBuf+start, prelen );
memcpy( undobuffer+prelen, mBuf+mGapEnd, end-start-prelen);
}
/* expand the gap to encompass the deleted characters */ /* expand the gap to encompass the deleted characters */
mGapEnd += end - mGapStart; mGapEnd += end - mGapStart;
@ -1843,8 +1938,10 @@ void Fl_Text_Buffer::remove_selection_( Fl_Text_Selection *sel ) {
return; return;
if ( isRect ) if ( isRect )
remove_rectangular( start, end, rectStart, rectEnd ); remove_rectangular( start, end, rectStart, rectEnd );
else else {
remove( start, end ); remove( start, end );
//undoyankcut = undocut;
}
} }
void Fl_Text_Buffer::replace_selection_( Fl_Text_Selection *sel, const char *s ) { void Fl_Text_Buffer::replace_selection_( Fl_Text_Selection *sel, const char *s ) {
@ -2397,5 +2494,5 @@ Fl_Text_Buffer::outputfile(const char *file, int start, int end, int buflen) {
// //
// End of "$Id: Fl_Text_Buffer.cxx,v 1.9.2.12 2002/09/20 19:59:45 easysw Exp $". // End of "$Id: Fl_Text_Buffer.cxx,v 1.9.2.13 2002/11/05 19:53:50 matthiaswm Exp $".
// //

View File

@ -1,5 +1,5 @@
// //
// "$Id: Fl_Text_Editor.cxx,v 1.9.2.11 2002/11/05 06:45:40 matthiaswm Exp $" // "$Id: Fl_Text_Editor.cxx,v 1.9.2.12 2002/11/05 19:53:50 matthiaswm Exp $"
// //
// Copyright 2001-2002 by Bill Spitzak and others. // Copyright 2001-2002 by Bill Spitzak and others.
// Original code Copyright Mark Edel. Permission to distribute under // Original code Copyright Mark Edel. Permission to distribute under
@ -93,8 +93,8 @@ static struct {
{ FL_Page_Up, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, { FL_Page_Up, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
{ FL_Page_Down, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, { FL_Page_Down, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
//{ FL_Clear, 0, Fl_Text_Editor::delete_to_eol }, //{ FL_Clear, 0, Fl_Text_Editor::delete_to_eol },
//{ 'z', FL_CTRL, Fl_Text_Editor::undo }, { 'z', FL_CTRL, Fl_Text_Editor::kf_undo },
//{ '/', FL_CTRL, Fl_Text_Editor::undo }, { '/', FL_CTRL, Fl_Text_Editor::kf_undo },
{ 'x', FL_CTRL, Fl_Text_Editor::kf_cut }, { 'x', FL_CTRL, Fl_Text_Editor::kf_cut },
{ FL_Delete, FL_SHIFT, Fl_Text_Editor::kf_cut }, { FL_Delete, FL_SHIFT, Fl_Text_Editor::kf_cut },
{ 'c', FL_CTRL, Fl_Text_Editor::kf_copy }, { 'c', FL_CTRL, Fl_Text_Editor::kf_copy },
@ -105,6 +105,7 @@ static struct {
#ifdef __APPLE__ #ifdef __APPLE__
// Define CMD+key accelerators... // Define CMD+key accelerators...
{ 'z', FL_COMMAND, Fl_Text_Editor::kf_undo },
{ 'x', FL_COMMAND, Fl_Text_Editor::kf_cut }, { 'x', FL_COMMAND, Fl_Text_Editor::kf_cut },
{ 'c', FL_COMMAND, Fl_Text_Editor::kf_copy }, { 'c', FL_COMMAND, Fl_Text_Editor::kf_copy },
{ 'v', FL_COMMAND, Fl_Text_Editor::kf_paste }, { 'v', FL_COMMAND, Fl_Text_Editor::kf_paste },
@ -386,6 +387,16 @@ int Fl_Text_Editor::kf_select_all(int, Fl_Text_Editor* e) {
return 1; return 1;
} }
int Fl_Text_Editor::kf_undo(int , Fl_Text_Editor* e) {
e->buffer()->unselect();
int crsr;
int ret = e->buffer()->undo(&crsr);
e->insert_position(crsr);
e->show_insert_position();
if (e->when()&FL_WHEN_CHANGED) e->do_callback(); else e->set_changed();
return ret;
}
int Fl_Text_Editor::handle_key() { int Fl_Text_Editor::handle_key() {
// Call fltk's rules to try to turn this into a printing character. // Call fltk's rules to try to turn this into a printing character.
@ -466,5 +477,5 @@ int Fl_Text_Editor::handle(int event) {
} }
// //
// End of "$Id: Fl_Text_Editor.cxx,v 1.9.2.11 2002/11/05 06:45:40 matthiaswm Exp $". // End of "$Id: Fl_Text_Editor.cxx,v 1.9.2.12 2002/11/05 19:53:50 matthiaswm Exp $".
// //