summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tkText.c217
-rw-r--r--tests/text.test14
2 files changed, 130 insertions, 101 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index 6bed713..f1fb16d 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 2003/02/18 21:53:59 hobbs Exp $
+ * RCS: @(#) $Id: tkText.c,v 1.33.2.1 2006/04/05 19:48:43 hobbs Exp $
*/
#include "default.h"
@@ -1367,6 +1367,14 @@ InsertChars(textPtr, indexPtr, string)
char indexBuffer[TK_POS_CHARS];
/*
+ * Don't do anything for an empty string [Bug 1275237]
+ */
+
+ if (*string == '\0') {
+ return;
+ }
+
+ /*
* Don't allow insertions on the last (dummy) line of the text.
*/
@@ -1398,60 +1406,60 @@ InsertChars(textPtr, indexPtr, string)
* Push the insertion on the undo stack
*/
- if ( textPtr->undo ) {
- TkTextIndex toIndex;
-
- Tcl_DString actionCommand;
- Tcl_DString revertCommand;
-
- if (textPtr->autoSeparators &&
- textPtr->lastEditMode != TK_TEXT_EDIT_INSERT) {
- TkUndoInsertUndoSeparator(textPtr->undoStack);
- }
-
- textPtr->lastEditMode = TK_TEXT_EDIT_INSERT;
-
- Tcl_DStringInit(&actionCommand);
- Tcl_DStringInit(&revertCommand);
-
- Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&actionCommand," insert ",-1);
- TkTextPrintIndex(indexPtr,indexBuffer);
- Tcl_DStringAppend(&actionCommand,indexBuffer,-1);
- Tcl_DStringAppend(&actionCommand," ",-1);
- Tcl_DStringAppendElement(&actionCommand,string);
- Tcl_DStringAppend(&actionCommand,";",-1);
- Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&actionCommand," mark set insert ",-1);
- TkTextIndexForwBytes(indexPtr, (int) strlen(string),
- &toIndex);
- TkTextPrintIndex(&toIndex, indexBuffer);
- Tcl_DStringAppend(&actionCommand,indexBuffer,-1);
- Tcl_DStringAppend(&actionCommand,"; ",-1);
- Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&actionCommand," see insert",-1);
-
- Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&revertCommand," delete ",-1);
- TkTextPrintIndex(indexPtr,indexBuffer);
- Tcl_DStringAppend(&revertCommand,indexBuffer,-1);
- Tcl_DStringAppend(&revertCommand," ",-1);
- TkTextPrintIndex(&toIndex, indexBuffer);
- Tcl_DStringAppend(&revertCommand,indexBuffer,-1);
- Tcl_DStringAppend(&revertCommand," ;",-1);
- Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&revertCommand," mark set insert ",-1);
- TkTextPrintIndex(indexPtr,indexBuffer);
- Tcl_DStringAppend(&revertCommand,indexBuffer,-1);
- Tcl_DStringAppend(&revertCommand,"; ",-1);
- Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&revertCommand," see insert",-1);
-
- TkUndoPushAction(textPtr->undoStack,&actionCommand, &revertCommand);
-
- Tcl_DStringFree(&actionCommand);
- Tcl_DStringFree(&revertCommand);
-
+ if (textPtr->undo) {
+ CONST char *cmdName;
+ TkTextIndex toIndex;
+
+ Tcl_DString actionCommand;
+ Tcl_DString revertCommand;
+
+ if (textPtr->autoSeparators &&
+ textPtr->lastEditMode != TK_TEXT_EDIT_INSERT) {
+ TkUndoInsertUndoSeparator(textPtr->undoStack);
+ }
+
+ textPtr->lastEditMode = TK_TEXT_EDIT_INSERT;
+ cmdName = Tcl_GetCommandName(textPtr->interp, textPtr->widgetCmd);
+
+ Tcl_DStringInit(&actionCommand);
+ Tcl_DStringInit(&revertCommand);
+
+ Tcl_DStringAppendElement(&actionCommand, cmdName);
+ Tcl_DStringAppend(&actionCommand, " insert ", -1);
+ TkTextPrintIndex(indexPtr,indexBuffer);
+ Tcl_DStringAppend(&actionCommand, indexBuffer, -1);
+ Tcl_DStringAppend(&actionCommand, " ", -1);
+ Tcl_DStringAppendElement(&actionCommand, string);
+ Tcl_DStringAppend(&actionCommand, ";", -1);
+ Tcl_DStringAppendElement(&actionCommand, cmdName);
+ Tcl_DStringAppend(&actionCommand, " mark set insert ", -1);
+ TkTextIndexForwBytes(indexPtr, (int) strlen(string), &toIndex);
+ TkTextPrintIndex(&toIndex, indexBuffer);
+ Tcl_DStringAppend(&actionCommand, indexBuffer,-1);
+ Tcl_DStringAppend(&actionCommand, "; ", -1);
+ Tcl_DStringAppendElement(&actionCommand, cmdName);
+ Tcl_DStringAppend(&actionCommand, " see insert", -1);
+
+ Tcl_DStringAppendElement(&revertCommand, cmdName);
+ Tcl_DStringAppend(&revertCommand, " delete ", -1);
+ TkTextPrintIndex(indexPtr, indexBuffer);
+ Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
+ Tcl_DStringAppend(&revertCommand, " ", -1);
+ TkTextPrintIndex(&toIndex, indexBuffer);
+ Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
+ Tcl_DStringAppend(&revertCommand, " ;", -1);
+ Tcl_DStringAppendElement(&revertCommand, cmdName);
+ Tcl_DStringAppend(&revertCommand, " mark set insert ", -1);
+ TkTextPrintIndex(indexPtr,indexBuffer);
+ Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
+ Tcl_DStringAppend(&revertCommand, "; ", -1);
+ Tcl_DStringAppendElement(&revertCommand, cmdName);
+ Tcl_DStringAppend(&revertCommand," see insert", -1);
+
+ TkUndoPushAction(textPtr->undoStack, &actionCommand, &revertCommand);
+
+ Tcl_DStringFree(&actionCommand);
+ Tcl_DStringFree(&revertCommand);
}
updateDirtyFlag(textPtr);
@@ -1632,59 +1640,60 @@ DeleteChars(textPtr, index1String, index2String, indexPtr1, indexPtr2)
*/
if (textPtr->undo) {
+ CONST char *cmdName;
Tcl_DString ds;
- Tcl_DString actionCommand;
- Tcl_DString revertCommand;
-
+ Tcl_DString actionCommand;
+ Tcl_DString revertCommand;
+
if (textPtr->autoSeparators
&& (textPtr->lastEditMode != TK_TEXT_EDIT_DELETE)) {
TkUndoInsertUndoSeparator(textPtr->undoStack);
}
textPtr->lastEditMode = TK_TEXT_EDIT_DELETE;
-
- Tcl_DStringInit(&actionCommand);
- Tcl_DStringInit(&revertCommand);
-
- Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&actionCommand," delete ",-1);
- TkTextPrintIndex(&index1,indexBuffer);
- Tcl_DStringAppend(&actionCommand,indexBuffer,-1);
- Tcl_DStringAppend(&actionCommand," ",-1);
- TkTextPrintIndex(&index2, indexBuffer);
- Tcl_DStringAppend(&actionCommand,indexBuffer,-1);
- Tcl_DStringAppend(&actionCommand,"; ",-1);
- Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&actionCommand," mark set insert ",-1);
- TkTextPrintIndex(&index1,indexBuffer);
- Tcl_DStringAppend(&actionCommand,indexBuffer,-1);
-
- Tcl_DStringAppend(&actionCommand,"; ",-1);
- Tcl_DStringAppend(&actionCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&actionCommand," see insert",-1);
+ cmdName = Tcl_GetCommandName(textPtr->interp, textPtr->widgetCmd);
+
+ Tcl_DStringInit(&actionCommand);
+ Tcl_DStringInit(&revertCommand);
+
+ Tcl_DStringAppendElement(&actionCommand, cmdName);
+ Tcl_DStringAppend(&actionCommand, " delete ", -1);
+ TkTextPrintIndex(&index1, indexBuffer);
+ Tcl_DStringAppend(&actionCommand, indexBuffer, -1);
+ Tcl_DStringAppend(&actionCommand, " ", -1);
+ TkTextPrintIndex(&index2, indexBuffer);
+ Tcl_DStringAppend(&actionCommand, indexBuffer, -1);
+ Tcl_DStringAppend(&actionCommand, "; ", -1);
+ Tcl_DStringAppendElement(&actionCommand, cmdName);
+ Tcl_DStringAppend(&actionCommand, " mark set insert ", -1);
+ TkTextPrintIndex(&index1, indexBuffer);
+ Tcl_DStringAppend(&actionCommand,indexBuffer, -1);
+
+ Tcl_DStringAppend(&actionCommand, "; ", -1);
+ Tcl_DStringAppendElement(&actionCommand, cmdName);
+ Tcl_DStringAppend(&actionCommand, " see insert", -1);
TextGetText(&index1, &index2, &ds);
- Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&revertCommand," insert ",-1);
- TkTextPrintIndex(&index1,indexBuffer);
- Tcl_DStringAppend(&revertCommand,indexBuffer,-1);
- Tcl_DStringAppend(&revertCommand," ",-1);
- Tcl_DStringAppendElement(&revertCommand,Tcl_DStringValue(&ds));
- Tcl_DStringAppend(&revertCommand,"; ",-1);
- Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&revertCommand," mark set insert ",-1);
- TkTextPrintIndex(&index2, indexBuffer);
- Tcl_DStringAppend(&revertCommand,indexBuffer,-1);
- Tcl_DStringAppend(&revertCommand,"; ",-1);
- Tcl_DStringAppend(&revertCommand,Tcl_GetCommandName(textPtr->interp,textPtr->widgetCmd),-1);
- Tcl_DStringAppend(&revertCommand," see insert",-1);
-
- TkUndoPushAction(textPtr->undoStack,&actionCommand, &revertCommand);
-
- Tcl_DStringFree(&actionCommand);
- Tcl_DStringFree(&revertCommand);
-
+ Tcl_DStringAppendElement(&revertCommand, cmdName);
+ Tcl_DStringAppend(&revertCommand, " insert ", -1);
+ TkTextPrintIndex(&index1, indexBuffer);
+ Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
+ Tcl_DStringAppend(&revertCommand, " ", -1);
+ Tcl_DStringAppendElement(&revertCommand, Tcl_DStringValue(&ds));
+ Tcl_DStringAppend(&revertCommand, "; ", -1);
+ Tcl_DStringAppendElement(&revertCommand, cmdName);
+ Tcl_DStringAppend(&revertCommand, " mark set insert ", -1);
+ TkTextPrintIndex(&index2, indexBuffer);
+ Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
+ Tcl_DStringAppend(&revertCommand, "; ", -1);
+ Tcl_DStringAppendElement(&revertCommand, cmdName);
+ Tcl_DStringAppend(&revertCommand, " see insert", -1);
+
+ TkUndoPushAction(textPtr->undoStack, &actionCommand, &revertCommand);
+
+ Tcl_DStringFree(&actionCommand);
+ Tcl_DStringFree(&revertCommand);
}
updateDirtyFlag(textPtr);
@@ -2618,7 +2627,7 @@ DumpLine(interp, textPtr, what, linePtr, startByte, endByte, lineno, command)
CONST char *command; /* Script to apply to the segment */
{
int offset;
- TkTextSegment *segPtr;
+ TkTextSegment *segPtr, *nextPtr;
TkTextIndex index;
/*
* Must loop through line looking at its segments.
@@ -2631,7 +2640,8 @@ DumpLine(interp, textPtr, what, linePtr, startByte, endByte, lineno, command)
for (offset = 0, segPtr = linePtr->segPtr ;
(offset < endByte) && (segPtr != (TkTextSegment *)NULL) ;
- offset += segPtr->size, segPtr = segPtr->nextPtr) {
+ offset += segPtr->size, segPtr = nextPtr) {
+ nextPtr = segPtr->nextPtr;
if ((what & TK_DUMP_TEXT) && (segPtr->typePtr == &tkTextCharType) &&
(offset + segPtr->size > startByte)) {
char savedChar; /* Last char used in the seg */
@@ -2690,6 +2700,13 @@ DumpLine(interp, textPtr, what, linePtr, startByte, endByte, lineno, command)
command, &index, what);
}
}
+ if (nextPtr != segPtr->nextPtr) {
+ /*
+ * Someone modified the text widget while we were dumping.
+ * Just stop dumping. [Bug 1414171]
+ */
+ break;
+ }
}
}
diff --git a/tests/text.test b/tests/text.test
index 1c21d21..a5cdfbe 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 2002/10/17 23:38:01 hobbs Exp $
+# RCS: @(#) $Id: text.test,v 1.19.2.1 2006/04/05 19:48:44 hobbs Exp $
package require tcltest 2.1
namespace import -force tcltest::configure
@@ -1573,6 +1573,18 @@ test text-25.13 {-maxundo configuration option} {
.t get 1.0 end
} "line 1\n\n"
+test text-25.14 {undo with space-based path} {
+ set t {.t e x t}
+ destroy $t
+ text $t -undo 1
+ $t insert end "line 1\n"
+ $t delete 1.4 1.6
+ $t insert end "line 2\n"
+ $t edit undo
+ $t edit undo
+ $t get 1.0 end
+} "line 1\n\n"
+
test text-26.1 {bug fix - 624372, ControlUtfProc long lines} {
destroy .t
pack [text .t -wrap none]