summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--generic/tkText.c69
-rw-r--r--generic/tkText.h33
-rw-r--r--tests/text.test15
4 files changed, 97 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 542b85b..4fa8ca5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
+
* win/tkWinDialog.c (GetFileNameA): Make the handling of the filter
index the same as in GetFileNameW.
diff --git a/generic/tkText.c b/generic/tkText.c
index 46c2e19..c1cc433 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.91 2009/09/07 07:29:04 das Exp $
+ * RCS: @(#) $Id: tkText.c,v 1.92 2009/10/22 21:36:24 dkf Exp $
*/
#include "default.h"
@@ -543,7 +543,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;
@@ -4899,16 +4900,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;
@@ -4943,13 +4949,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;
}
@@ -5014,17 +5027,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:
@@ -5192,7 +5206,7 @@ GenerateModifiedEvent(
*
* UpdateDirtyFlag --
*
- * Increases the dirtyness of the text widget
+ * Updates the dirtyness of the text widget
*
* Results:
* None
@@ -5208,14 +5222,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 0a97630..6957120 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.36 2008/12/06 10:48:29 dkf Exp $
+ * RCS: @(#) $Id: tkText.h,v 1.37 2009/10/22 21:36:24 dkf Exp $
*/
#ifndef _TKTEXT
@@ -500,6 +500,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.
*/
@@ -549,10 +562,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
@@ -560,14 +573,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. */
@@ -1138,3 +1149,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 8fd077d..5d3060a 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.54 2008/12/19 15:33:40 dgp Exp $
+# RCS: @(#) $Id: text.test,v 1.55 2009/10/22 21:36:24 dkf Exp $
package require tcltest 2.2
eval tcltest::configure $argv
@@ -6079,7 +6079,18 @@ test text-27.17 {bug fix 1536735 - undo with empty text} -body {
} -cleanup {
destroy .t
} -result {0 0 1 0}
-
+test text-27.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-28.1 {bug fix - 624372, ControlUtfProc long lines} -body {
pack [text .t -wrap none]