summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2009-10-22 22:10:08 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2009-10-22 22:10:08 (GMT)
commit5969910620bf508843c84476d7ccb60a0e9e8506 (patch)
tree60407ab2b66887151e4c3f098af7fe1538a71b12
parentf70c57e43b0094e798794afa13205580c3113f71 (diff)
downloadtk-5969910620bf508843c84476d7ccb60a0e9e8506.zip
tk-5969910620bf508843c84476d7ccb60a0e9e8506.tar.gz
tk-5969910620bf508843c84476d7ccb60a0e9e8506.tar.bz2
Apply (upgraded) version of [Patch 1469210].
-rw-r--r--ChangeLog7
-rw-r--r--generic/tkText.c78
-rw-r--r--generic/tkText.h56
-rw-r--r--tests/text.test15
4 files changed, 108 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index 53c6407..a8972c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-10-22 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tkText.c (Tk_TextCmd, 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.
+
2009-10-07 Donal K. Fellows <dkf@users.sf.net>
* unix/tkUnixScrlbr.c (TkpComputeScrollbarGeometry): [Patch 2088597]:
diff --git a/generic/tkText.c b/generic/tkText.c
index 6e5cb83..6b24ffa 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -14,7 +14,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.33.2.7 2007/12/13 00:31:33 hobbs Exp $
+ * RCS: @(#) $Id: tkText.c,v 1.33.2.8 2009/10/22 22:10:08 dkf Exp $
*/
#include "default.h"
@@ -415,7 +415,8 @@ Tk_TextCmd(clientData, interp, argc, argv)
textPtr->pickEvent.type = LeaveNotify;
textPtr->undoStack = TkUndoInitStack(interp,0);
textPtr->undo = 1;
- textPtr->isDirtyIncrement = 1;
+ textPtr->isDirty = 0;
+ textPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
textPtr->autoSeparators = 1;
textPtr->lastEditMode = TK_TEXT_EDIT_OTHER;
@@ -2794,25 +2795,29 @@ DumpSegment(interp, key, value, command, index, what)
static int
TextEditUndo(textPtr)
- TkText * textPtr; /* Overall information about text widget. */
+ TkText *textPtr; /* Overall information about text widget. */
{
int status;
if (!textPtr->undo) {
- return TCL_OK;
+ return TCL_OK;
}
/* Turn off the undo feature */
textPtr->undo = 0;
- /* The dirty counter should count downwards as we are undoing things */
- textPtr->isDirtyIncrement = -1;
+ /* Set dirty mode to undo, unless it is fixed */
+ if (textPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
+ textPtr->dirtyMode = TK_TEXT_DIRTY_UNDO;
+ }
/* revert one compound action */
status = TkUndoRevert(textPtr->undoStack);
- /* Restore the isdirty increment */
- textPtr->isDirtyIncrement = 1;
+ /* Restore dirty mode */
+ if (textPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
+ textPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
+ }
/* Turn back on the undo feature */
textPtr->undo = 1;
@@ -2833,20 +2838,30 @@ TextEditUndo(textPtr)
static int
TextEditRedo(textPtr)
- TkText * textPtr; /* Overall information about text widget. */
+ TkText *textPtr; /* Overall information about text widget. */
{
int status;
if (!textPtr->undo) {
- return TCL_OK;
+ return TCL_OK;
}
/* Turn off the undo feature temporarily */
textPtr->undo = 0;
+ /* Set dirty mode to redo, unless it is fixed */
+ if (textPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
+ textPtr->dirtyMode = TK_TEXT_DIRTY_REDO;
+ }
+
/* reapply one compound action */
status = TkUndoApply(textPtr->undoStack);
+ /* Restore dirty mode */
+ if (textPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
+ textPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
+ }
+
/* Turn back on the undo feature */
textPtr->undo = 1;
@@ -2891,22 +2906,25 @@ TextEditCmd(textPtr, interp, argc, argv)
argv[0], " edit modified ?boolean?\"", (char *) NULL);
return TCL_ERROR;
} else {
- int setModified;
+ int setModified, wasModified = textPtr->isDirty;
if (Tcl_GetBoolean(interp, argv[3], &setModified) != TCL_OK) {
return TCL_ERROR;
}
/*
- * 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->isDirty = setModified;
- if (textPtr->modifiedSet != setModified) {
- textPtr->modifiedSet = setModified;
+ if (setModified) {
+ textPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
+ } else {
+ textPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
+ }
+ if ((!wasModified) != (!setModified)) {
GenerateModifiedEvent(textPtr);
}
}
@@ -3041,7 +3059,7 @@ GenerateModifiedEvent(
/*
* updateDirtyFlag --
- * increases the dirtyness of the text widget
+ * updates the dirtyness of the text widget
*
* Results:
* None
@@ -3050,16 +3068,36 @@ GenerateModifiedEvent(
* None.
*/
-static void updateDirtyFlag (textPtr)
+static void
+updateDirtyFlag(textPtr)
TkText *textPtr; /* Information about text widget. */
{
int oldDirtyFlag;
- if (textPtr->modifiedSet) {
- return;
+ if (textPtr->dirtyMode == TK_TEXT_DIRTY_FIXED) {
+ return;
}
+
+ /*
+ * If dirty flag is negative, only redo operations can make it zero again.
+ * If we do a normal operation, it can never become zero anymore.
+ */
+ if (textPtr->isDirty < 0 && textPtr->dirtyMode == TK_TEXT_DIRTY_NORMAL) {
+ textPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
+ return;
+ }
+
oldDirtyFlag = textPtr->isDirty;
- textPtr->isDirty += textPtr->isDirtyIncrement;
+
+ switch (textPtr->dirtyMode) {
+ case TK_TEXT_DIRTY_UNDO:
+ textPtr->isDirty--;
+ break;
+ default:
+ textPtr->isDirty++;
+ break;
+ }
+
if (textPtr->isDirty == 0 || oldDirtyFlag == 0) {
GenerateModifiedEvent(textPtr);
}
diff --git a/generic/tkText.h b/generic/tkText.h
index 7e1f666..77ff926 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -10,7 +10,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.13.2.1 2006/10/17 05:38:48 dgp Exp $
+ * RCS: @(#) $Id: tkText.h,v 1.13.2.2 2009/10/22 22:10:08 dkf Exp $
*/
#ifndef _TKTEXT
@@ -464,6 +464,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;
+
+/*
* A data structure of the following type is kept for each text widget that
* currently exists for this process:
*/
@@ -639,36 +652,25 @@ typedef struct TkText {
* definitions. */
/*
- * Information related to the undo/redo functonality
+ * Information related to the undo/redo funcitonality
*/
- 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 expressed
- * as the maximum number of compound statements */
-
+ * enabled. */
+ int maxUndo; /* The maximum depth of the undo stack
+ * expressed as the maximum number of compound
+ * statements. */
int autoSeparators; /* non zero means the separatorss will be
- * inserted automatically */
-
- int modifiedSet; /* Flag indicating that the 'dirtynesss' of
- * the text widget has been expplicitly set.
- */
-
- int isDirty; /* Flag indicating the 'dirtynesss' 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
- */
-
- TkTextEditMode lastEditMode; /* Keeps track of what the last edit mode was
- */
-
+ * inserted automatically. */
+ int isDirty; /* Flag indicating the 'dirtynesss' of the
+ * text widget. If the flag is not zero,
+ * unsaved modifications have been applied to
+ * the text widget. */
+ TkTextDirtyMode dirtyMode; /* The nature of the dirtyness characterized
+ * by the isDirty flag. */
+ TkTextEditMode lastEditMode;/* Keeps track of what the last edit mode
+ * was. */
} TkText;
/*
diff --git a/tests/text.test b/tests/text.test
index 0158389..f720721 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.19.2.2 2007/12/13 00:31:34 hobbs Exp $
+# RCS: @(#) $Id: text.test,v 1.19.2.3 2009/10/22 22:10:08 dkf Exp $
package require tcltest 2.1
namespace import -force tcltest::configure
@@ -1620,6 +1620,19 @@ test text-25.14 {undo with space-based path} {
$t get 1.0 end
} "line 1\n\n"
+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
pack [text .t -wrap none]