diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | generic/tkText.c | 69 | ||||
-rw-r--r-- | generic/tkText.h | 33 | ||||
-rw-r--r-- | tests/text.test | 14 |
4 files changed, 97 insertions, 24 deletions
@@ -1,5 +1,10 @@ 2009-10-22 Donal K. Fellows <dkf@users.sf.net> + * generic/tkText.c (CreateWidget, TextEditUndo, TextEditRedo) + (TextEditCmd, UpdateDirtyFlag): + * generic/tkText.h: [Patch 1469210]: Corrected handling of marking as + dirty when inserting after an undo from a non-dirty state. + * library/xmfbox.tcl (MotifFDialog_FileTypes) (MotifFDialog_ActivateSEnt): * library/tkfbox.tcl (Done, ::tk::dialog::file::): diff --git a/generic/tkText.c b/generic/tkText.c index 95d91e5..75d253f 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkText.c,v 1.79.2.3 2009/02/06 08:13:23 das Exp $ + * RCS: @(#) $Id: tkText.c,v 1.79.2.4 2009/10/22 21:41:20 dkf Exp $ */ #include "default.h" @@ -529,7 +529,8 @@ CreateWidget( Tcl_InitHashTable(&sharedPtr->imageTable, TCL_STRING_KEYS); sharedPtr->undoStack = TkUndoInitStack(interp,0); sharedPtr->undo = 1; - sharedPtr->isDirtyIncrement = 1; + sharedPtr->isDirty = 0; + sharedPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; sharedPtr->autoSeparators = 1; sharedPtr->lastEditMode = TK_TEXT_EDIT_OTHER; sharedPtr->stateEpoch = 0; @@ -4878,16 +4879,21 @@ TextEditUndo( } /* - * Turn off the undo feature while we revert a compound action. Note that - * the dirty counter counts backwards while we are undoing... + * Turn off the undo feature while we revert a compound action, setting + * the dirty handling mode to undo for the duration (unless it is + * 'fixed'). */ textPtr->sharedTextPtr->undo = 0; - textPtr->sharedTextPtr->isDirtyIncrement = -1; + if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) { + textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_UNDO; + } status = TkUndoRevert(textPtr->sharedTextPtr->undoStack); - textPtr->sharedTextPtr->isDirtyIncrement = 1; + if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) { + textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; + } textPtr->sharedTextPtr->undo = 1; return status; @@ -4922,13 +4928,20 @@ TextEditRedo( /* * Turn off the undo feature temporarily while we revert a previously - * undone compound action. + * undone compound action, setting the dirty handling mode to redo for the + * duration (unless it is 'fixed'). */ textPtr->sharedTextPtr->undo = 0; + if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) { + textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_REDO; + } status = TkUndoApply(textPtr->sharedTextPtr->undoStack); + if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) { + textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; + } textPtr->sharedTextPtr->undo = 1; return status; } @@ -4993,17 +5006,18 @@ TextEditCmd( } /* - * Set or reset the dirty info, but trigger a Modified event only - * if it has changed. Ensure a rationalized value for the bit. + * Set or reset the dirty info, and trigger a Modified event. */ setModified = setModified ? 1 : 0; textPtr->sharedTextPtr->isDirty = setModified; - if (textPtr->sharedTextPtr->modifiedSet != setModified) { - textPtr->sharedTextPtr->modifiedSet = setModified; - GenerateModifiedEvent(textPtr); + if (setModified) { + textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED; + } else { + textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; } + GenerateModifiedEvent(textPtr); } break; case EDIT_REDO: @@ -5171,7 +5185,7 @@ GenerateModifiedEvent( * * UpdateDirtyFlag -- * - * Increases the dirtyness of the text widget + * Updates the dirtyness of the text widget * * Results: * None @@ -5187,14 +5201,37 @@ UpdateDirtyFlag( TkSharedText *sharedTextPtr)/* Information about text widget. */ { int oldDirtyFlag; + TkText *textPtr; + + /* + * If we've been forced to be dirty, we stay dirty (until explicitly + * reset, of course). + */ - if (sharedTextPtr->modifiedSet) { + if (sharedTextPtr->dirtyMode == TK_TEXT_DIRTY_FIXED) { return; } + + if (sharedTextPtr->isDirty < 0 + && sharedTextPtr->dirtyMode == TK_TEXT_DIRTY_NORMAL) { + /* + * If dirty flag is negative, only redo operations can make it zero + * again. If we do a normal operation, it can never become zero any + * more (other than by explicit reset). + */ + + sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED; + return; + } + oldDirtyFlag = sharedTextPtr->isDirty; - sharedTextPtr->isDirty += sharedTextPtr->isDirtyIncrement; + if (sharedTextPtr->dirtyMode == TK_TEXT_DIRTY_UNDO) { + sharedTextPtr->isDirty--; + } else { + sharedTextPtr->isDirty++; + } + if (sharedTextPtr->isDirty == 0 || oldDirtyFlag == 0) { - TkText *textPtr; for (textPtr = sharedTextPtr->peers; textPtr != NULL; textPtr = textPtr->next) { GenerateModifiedEvent(textPtr); diff --git a/generic/tkText.h b/generic/tkText.h index 521d99c..117a717 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkText.h,v 1.34 2007/12/13 15:24:17 dgp Exp $ + * RCS: @(#) $Id: tkText.h,v 1.34.2.1 2009/10/22 21:41:20 dkf Exp $ */ #ifndef _TKTEXT @@ -506,6 +506,19 @@ typedef enum { } TkTextEditMode; /* + * Enumeration defining the ways in which a text widget may be modified (for + * undo/redo handling). + */ + +typedef enum { + TK_TEXT_DIRTY_NORMAL, /* Normal behavior. */ + TK_TEXT_DIRTY_UNDO, /* Reverting a compound action. */ + TK_TEXT_DIRTY_REDO, /* Reapplying a compound action. */ + TK_TEXT_DIRTY_FIXED /* Forced to be dirty; can't be undone/redone + * by normal activity. */ +} TkTextDirtyMode; + +/* * The following enum is used to define a type for the -state option of the * Text widget. */ @@ -555,10 +568,10 @@ typedef struct TkSharedText { * longer valid. */ /* - * Information related to the undo/redo functonality + * Information related to the undo/redo functionality. */ - TkUndoRedoStack *undoStack; /* The undo/redo stack. */ + TkUndoRedoStack *undoStack; /* The undo/redo stack. */ int undo; /* Non-zero means the undo/redo behaviour is * enabled. */ int maxUndo; /* The maximum depth of the undo stack @@ -566,14 +579,12 @@ typedef struct TkSharedText { * statements. */ int autoSeparators; /* Non-zero means the separators will be * inserted automatically. */ - int modifiedSet; /* Flag indicating that the 'dirtyness' of - * the text widget has been explicitly set. */ int isDirty; /* Flag indicating the 'dirtyness' of the * text widget. If the flag is not zero, * unsaved modifications have been applied to * the text widget. */ - int isDirtyIncrement; /* Amount with which the isDirty flag is - * incremented every edit action. */ + TkTextDirtyMode dirtyMode; /* The nature of the dirtyness characterized + * by the isDirty flag. */ TkTextEditMode lastEditMode;/* Keeps track of what the last edit mode * was. */ @@ -1156,3 +1167,11 @@ MODULE_SCOPE void TkTextWinFreeClient(Tcl_HashEntry *hPtr, # define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TKTEXT */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/tests/text.test b/tests/text.test index 273dccd..2d8d916 100644 --- a/tests/text.test +++ b/tests/text.test @@ -6,7 +6,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: text.test,v 1.49.2.1 2008/11/12 22:17:02 patthoyts Exp $ +# RCS: @(#) $Id: text.test,v 1.49.2.2 2009/10/22 21:41:20 dkf Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -3118,6 +3118,18 @@ test text-25.15 {bug fix 1536735 - undo with empty text} { lappend r [catch {.t edit undo}] lappend r [.t edit modified] } {0 0 1 0} +test text-25.18 {patch 1469210 - inserting after undo} -setup { + destroy .t +} -body { + text .t -undo 1 + .t insert end foo + .t edit modified 0 + .t edit undo + .t insert end bar + .t edit modified +} -cleanup { + destroy .t +} -result 1 test text-26.1 {bug fix - 624372, ControlUtfProc long lines} { destroy .t |