Tk Source Code

Changes On Branch tip-446
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch tip-446 Excluding Merge-Ins

This is equivalent to a diff from ef7364ed to b699eb0e

2016-05-30
18:05
Merged TIP #446 accepted by TCT vote. This fixes [1273358] - Ask a text widget for the depth of its undo and redo stacks. check-in: 85fe3473 user: fvogel tags: core-8-6-branch
2016-05-17
20:00
Took comments from Koen Danckaert into account (with my thanks) to simplify the implementation of TkUndoCanUndo() and TkUndoCanRedo() in tkUndo.c, and in tkText.c to remove direct calls to internals of the undo or redo stack Closed-Leaf check-in: b699eb0e user: fvogel tags: tip-446
2016-05-12
22:21
Unified branched tip-446-undodepth and tip-446-canundo to become branch tip-446 check-in: 2bfc04af user: fvogel tags: tip-446
21:42
Aligned GenerateModifiedEvent() on GenerateUndoStackEvent() regarding generation of the event for each peer Closed-Leaf check-in: ef7364ed user: fvogel tags: tip-446-canundo
21:35
Added test for the <<UndoStack>> event check-in: efe4cb36 user: fvogel tags: tip-446-canundo

Changes to generic/tkText.c.

2766
2767
2768
2769
2770
2771
2772
2773

2774
2775
2776
2777
2778
2779
2780
2766
2767
2768
2769
2770
2771
2772

2773
2774
2775
2776
2777
2778
2779
2780







-
+







    int insert,			/* 1 if insert, else delete. */
    const TkTextIndex *index1Ptr,
				/* Index describing first location. */
    const TkTextIndex *index2Ptr)
				/* Index describing second location. */
{
    TkUndoSubAtom *iAtom, *dAtom;
    TkUndoAtom *redoElem, *undoElem;
    int canUndo, canRedo;

    /*
     * Create the helpers.
     */

    Tcl_Obj *seeInsertObj = Tcl_NewObj();
    Tcl_Obj *markSet1InsertObj = Tcl_NewObj();
2853
2854
2855
2856
2857
2858
2859
2860
2861


2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875

2876
2877
2878
2879
2880
2881
2882
2853
2854
2855
2856
2857
2858
2859


2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874

2875
2876
2877
2878
2879
2880
2881
2882







-
-
+
+













-
+







    TkUndoMakeCmdSubAtom(NULL, markSet1InsertObj, dAtom);
    TkUndoMakeCmdSubAtom(NULL, seeInsertObj, dAtom);

    Tcl_DecrRefCount(seeInsertObj);
    Tcl_DecrRefCount(index1Obj);
    Tcl_DecrRefCount(index2Obj);

    undoElem = textPtr->sharedTextPtr->undoStack->undoStack;
    redoElem = textPtr->sharedTextPtr->undoStack->redoStack;
    canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
    canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);

    /*
     * Depending whether the action is to insert or delete, we provide the
     * appropriate second and third arguments to TkUndoPushAction. (The first
     * is the 'actionCommand', and the second the 'revertCommand').
     */

    if (insert) {
	TkUndoPushAction(textPtr->sharedTextPtr->undoStack, iAtom, dAtom);
    } else {
	TkUndoPushAction(textPtr->sharedTextPtr->undoStack, dAtom, iAtom);
    }

    if (undoElem == NULL || redoElem != NULL) {
    if (!canUndo || canRedo) {
        GenerateUndoStackEvent(textPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5162
5163
5164
5165
5166
5167
5168

5169
5170
5171
5172
5173
5174
5175







-







    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int index, setModified, oldModified;
    int canRedo = 0;
    int canUndo = 0;
    TkUndoAtom *redoElem, *undoElem;

    static const char *const editOptionStrings[] = {
	"canundo", "canredo", "modified", "redo", "reset", "separator",
        "undo", NULL
    };
    enum editOptions {
	EDIT_CANUNDO, EDIT_CANREDO, EDIT_MODIFIED, EDIT_REDO, EDIT_RESET,
5245
5246
5247
5248
5249
5250
5251
5252

5253
5254
5255
5256
5257
5258
5259


5260
5261
5262
5263
5264
5265
5266
5267
5268
5269


5270
5271

5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287

5288
5289
5290
5291
5292
5293
5294


5295
5296
5297
5298
5299
5300
5301
5244
5245
5246
5247
5248
5249
5250

5251
5252
5253
5254
5255
5256


5257
5258
5259
5260
5261
5262
5263
5264
5265
5266


5267
5268
5269

5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285

5286
5287
5288
5289
5290
5291


5292
5293
5294
5295
5296
5297
5298
5299
5300







-
+





-
-
+
+








-
-
+
+

-
+















-
+





-
-
+
+







	}
	break;
    case EDIT_REDO:
        if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	undoElem = textPtr->sharedTextPtr->undoStack->undoStack;
	canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
        if (TextEditRedo(textPtr)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to redo", -1));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_REDO", NULL);
	    return TCL_ERROR;
	}
        redoElem = textPtr->sharedTextPtr->undoStack->redoStack;
        if (undoElem == NULL || redoElem == NULL) {
        canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
        if (!canUndo || !canRedo) {
            GenerateUndoStackEvent(textPtr);
        }
	break;
    case EDIT_RESET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
        undoElem = textPtr->sharedTextPtr->undoStack->undoStack;
        redoElem = textPtr->sharedTextPtr->undoStack->redoStack;
        canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
        canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
	TkUndoClearStacks(textPtr->sharedTextPtr->undoStack);
        if (undoElem != NULL || redoElem != NULL) {
        if (canUndo || canRedo) {
            GenerateUndoStackEvent(textPtr);
        }
	break;
    case EDIT_SEPARATOR:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
	TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack);
	break;
    case EDIT_UNDO:
        if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}
        redoElem = textPtr->sharedTextPtr->undoStack->redoStack;
        canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
	if (TextEditUndo(textPtr)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to undo", -1));
	    Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_UNDO", NULL);
	    return TCL_ERROR;
	}
        undoElem = textPtr->sharedTextPtr->undoStack->undoStack;
        if (redoElem == NULL || undoElem == NULL) {
        canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
        if (!canRedo || !canUndo) {
            GenerateUndoStackEvent(textPtr);
        }
	break;
    }
    return TCL_OK;
}


Changes to generic/tkUndo.c.

491
492
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
491
492
493
494
495
496
497


498









499
500
501
502
503
504
505







-
-
+
-
-
-
-
-
-
-
-
-







 *----------------------------------------------------------------------
 */

int
TkUndoCanRedo(
    TkUndoRedoStack *stack)	/* An Undo/Redo stack */
{
    int canRedo = 0;
    TkUndoAtom *elem = stack->redoStack;
    return stack->redoStack != NULL;

    while (elem != NULL) {
        if (elem->type != TK_UNDO_SEPARATOR) {
            canRedo = 1;
            break;
        }
        elem = elem->next;
    }
    return canRedo;
}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoCanUndo --
 *
524
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
514
515
516
517
518
519
520


521









522
523
524
525
526
527
528







-
-
+
-
-
-
-
-
-
-
-
-







 *----------------------------------------------------------------------
 */

int
TkUndoCanUndo(
    TkUndoRedoStack *stack)	/* An Undo/Redo stack */
{
    int canUndo = 0;
    TkUndoAtom *elem = stack->undoStack;
    return stack->undoStack != NULL;

    while (elem != NULL) {
        if (elem->type != TK_UNDO_SEPARATOR) {
            canUndo = 1;
            break;
        }
        elem = elem->next;
    }
    return canUndo;
}

/*
 *----------------------------------------------------------------------
 *
 * TkUndoInsertUndoSeparator --
 *