From 8c649928f2ff2b219d4165bd5f587526cc870206 Mon Sep 17 00:00:00 2001 From: vincentdarley Date: Sat, 15 Nov 2003 02:33:47 +0000 Subject: fix two more old text widget bugs FossilOrigin-Name: 7975a57e535cb6ca95810430e902417074a0bb2c --- ChangeLog | 12 ++++++ generic/tkText.c | 11 ++--- generic/tkText.h | 4 +- generic/tkTextDisp.c | 115 ++++++++++++++++++++++++++++----------------------- generic/tkTextTag.c | 91 ++++++++++++++++++++++++---------------- generic/tkTextWind.c | 19 +++++---- tests/textDisp.test | 114 ++++++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 252 insertions(+), 114 deletions(-) diff --git a/ChangeLog b/ChangeLog index b56d9ed..7b166cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2003-11-15 Vince Darley + + * generic/tkText.h: + * generic/tkText.c: + * generic/tkTextDisp.c: + * generic/tkTextWind.c: + * generic/tkTextTag.c: + * tests/textDisp.test: fixes to another pair of old Tk bugs + [Bug 220816] (can't scroll horizontally to display all of last + character), [Bug 842498] (xview confused on window creation), + and more efficiency in tag creation. Added new tests. + 2003-11-14 Donal K. Fellows * generic/tkTextDisp.c (TkTextRedrawTag): Get the correct number diff --git a/generic/tkText.c b/generic/tkText.c index dc738a1..133d88d 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.43 2003/11/12 17:38:48 vincentdarley Exp $ + * RCS: @(#) $Id: tkText.c,v 1.44 2003/11/15 02:33:50 vincentdarley Exp $ */ #include "default.h" @@ -451,7 +451,7 @@ Tk_TextObjCmd(clientData, interp, objc, objv) textPtr->selBorderWidth = 0; textPtr->selBorderWidthPtr = NULL; textPtr->selFgColorPtr = NULL; - textPtr->selTagPtr = TkTextCreateTag(textPtr, "sel"); + textPtr->selTagPtr = TkTextCreateTag(textPtr, "sel", NULL); textPtr->selTagPtr->reliefString = (char *) ckalloc(sizeof(DEF_TEXT_SELECT_RELIEF)); strcpy(textPtr->selTagPtr->reliefString, DEF_TEXT_SELECT_RELIEF); @@ -1778,7 +1778,7 @@ TextEventProc(clientData, eventPtr) || (textPtr->prevHeight != Tk_Height(textPtr->tkwin))) { int mask = 0; if (textPtr->prevWidth != Tk_Width(textPtr->tkwin)) { - mask = 1; + mask = TK_TEXT_LINE_GEOMETRY; } TkTextRelayoutWindow(textPtr, mask); textPtr->prevWidth = Tk_Width(textPtr->tkwin); @@ -2690,8 +2690,9 @@ TextInsertCmd(textPtr, interp, objc, objv, indexPtr, noViewUpdate) for (i = 0; i < numTags; i++) { TkBTreeTag(&index1, &index2, - TkTextCreateTag(textPtr, - Tcl_GetString(tagNamePtrs[i])), 1); + TkTextCreateTag(textPtr, + Tcl_GetString(tagNamePtrs[i]), NULL), + 1); } index1 = index2; } diff --git a/generic/tkText.h b/generic/tkText.h index 6ca5084..ee19ad2 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.20 2003/11/12 17:19:18 vincentdarley Exp $ + * RCS: @(#) $Id: tkText.h,v 1.21 2003/11/15 02:33:50 vincentdarley Exp $ */ #ifndef _TKTEXT @@ -951,7 +951,7 @@ EXTERN void TkTextEmbWinDisplayProc _ANSI_ARGS_(( int lineHeight, int baseline, Display *display, Drawable dst, int screenY)); EXTERN TkTextTag * TkTextCreateTag _ANSI_ARGS_((TkText *textPtr, - CONST char *tagName)); + CONST char *tagName, int *newTag)); EXTERN void TkTextFreeDInfo _ANSI_ARGS_((TkText *textPtr)); EXTERN void TkTextFreeTag _ANSI_ARGS_((TkText *textPtr, TkTextTag *tagPtr)); diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index e47a19d..e1a3fee 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.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: tkTextDisp.c,v 1.28 2003/11/14 17:21:03 dkf Exp $ + * RCS: @(#) $Id: tkTextDisp.c,v 1.29 2003/11/15 02:33:50 vincentdarley Exp $ */ #include "tkPort.h" @@ -232,10 +232,9 @@ typedef struct TextDInfo { * Information used for scrolling: */ - int newXByteOffset; /* Desired x scroll position, measured as the - * number of average-size characters off-screen - * to the left for a line with no left - * margin. */ + int newXPixelOffset; /* Desired x scroll position, measured as the + * number of pixels off-screen to the left + * for a line with no left margin. */ int curXPixelOffset; /* Actual x scroll position, measured as the * number of pixels off-screen to the left. */ int maxLength; /* Length in pixels of longest line that's @@ -255,9 +254,8 @@ typedef struct TextDInfo { * The following information is used to implement scanning: */ - int scanMarkIndex; /* Byte index of character that was at the - * left edge of the window when the scan - * started. */ + int scanMarkXPixel; /* Pixel index of left edge of the window + * when the scan started. */ int scanMarkX; /* X-position of mouse at time scan started. */ int scanTotalYScroll; /* Total scrolling (in screen pixels) that has * occurred since scanMarkY was set. */ @@ -495,14 +493,14 @@ TkTextCreateDInfo(textPtr) dInfoPtr->scrollGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures, &gcValues); dInfoPtr->topOfEof = 0; - dInfoPtr->newXByteOffset = 0; + dInfoPtr->newXPixelOffset = 0; dInfoPtr->curXPixelOffset = 0; dInfoPtr->maxLength = 0; dInfoPtr->xScrollFirst = -1; dInfoPtr->xScrollLast = -1; dInfoPtr->yScrollFirst = -1; dInfoPtr->yScrollLast = -1; - dInfoPtr->scanMarkIndex = 0; + dInfoPtr->scanMarkXPixel = 0; dInfoPtr->scanMarkX = 0; dInfoPtr->scanTotalYScroll = 0; dInfoPtr->scanMarkY = 0; @@ -1861,15 +1859,29 @@ UpdateDisplayInfo(textPtr) dInfoPtr->maxLength = dlPtr->length; } } - maxOffset = (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x) - + textPtr->charWidth - 1)/textPtr->charWidth; - if (dInfoPtr->newXByteOffset > maxOffset) { - dInfoPtr->newXByteOffset = maxOffset; + maxOffset = dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x); + + xPixelOffset = dInfoPtr->newXPixelOffset; + if (xPixelOffset > maxOffset) { + xPixelOffset = maxOffset; + } + if (xPixelOffset < 0) { + xPixelOffset = 0; } - if (dInfoPtr->newXByteOffset < 0) { - dInfoPtr->newXByteOffset = 0; + + /* + * Here's a problem: see the tests textDisp-29.2.1-4 + * + * If the widget is being created, but has not yet been configured + * it will have a maxY of 1 above, and we we won't have examined + * all the lines (just the first line, in fact), and so maxOffset + * will not be a true reflection of the widget's lines. Therefore + * we must not overwrite the original newXPixelOffset in this case. + */ + if (!(((Tk_FakeWin *) (textPtr->tkwin))->flags & TK_NEED_CONFIG_NOTIFY)) { + dInfoPtr->newXPixelOffset = xPixelOffset; } - xPixelOffset = dInfoPtr->newXByteOffset * textPtr->charWidth; + if (xPixelOffset != dInfoPtr->curXPixelOffset) { dInfoPtr->curXPixelOffset = xPixelOffset; for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL; @@ -2689,7 +2701,7 @@ TkTextInvalidateLineMetrics(textPtr, linePtr, lineCount, action) fromLine = TkBTreeLineIndex(linePtr); /* - * Invalid the height calculations of each line in the + * Invalidate the height calculations of each line in the * given range. */ linePtr->pixelCalculationEpoch = 0; @@ -3923,7 +3935,7 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag) lineCount -= TkBTreeLineIndex(startLine); } TkTextInvalidateLineMetrics(textPtr, startLine, lineCount, - TK_TEXT_INVALIDATE_ONLY); + TK_TEXT_INVALIDATE_ONLY); } /* @@ -4124,6 +4136,9 @@ TkTextRelayoutWindow(textPtr, mask) if (dInfoPtr->maxX <= dInfoPtr->x) { dInfoPtr->maxX = dInfoPtr->x + 1; } + /* + * This is the only place where dInfoPtr->maxY is set. + */ dInfoPtr->maxY = Tk_Height(textPtr->tkwin) - textPtr->highlightWidth - textPtr->borderWidth - textPtr->padY; if (dInfoPtr->maxY <= dInfoPtr->y) { @@ -4630,21 +4645,17 @@ TkTextSeeCmd(textPtr, interp, objc, objv) oneThird = lineWidth/3; if (delta < 0) { if (delta < -oneThird) { - dInfoPtr->newXByteOffset = (x - lineWidth/2) - / textPtr->charWidth; + dInfoPtr->newXPixelOffset = (x - lineWidth/2); } else { - dInfoPtr->newXByteOffset -= ((-delta) + textPtr->charWidth - 1) - / textPtr->charWidth; + dInfoPtr->newXPixelOffset -= ((-delta) ); } } else { delta -= (lineWidth - width); if (delta > 0) { if (delta > oneThird) { - dInfoPtr->newXByteOffset = (x - lineWidth/2) - / textPtr->charWidth; + dInfoPtr->newXPixelOffset = (x - lineWidth/2); } else { - dInfoPtr->newXByteOffset += - (delta+textPtr->charWidth-1) / textPtr->charWidth; + dInfoPtr->newXPixelOffset += (delta ); } } else { return TCL_OK; @@ -4699,34 +4710,36 @@ TkTextXviewCmd(textPtr, interp, objc, objv) return TCL_OK; } - newOffset = dInfoPtr->newXByteOffset; - type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count); + newOffset = dInfoPtr->newXPixelOffset; + type = TextGetScrollInfoObj(interp, textPtr, objc, objv, + &fraction, &count); switch (type) { - case TK_SCROLL_ERROR: + case TKTEXT_SCROLL_ERROR: return TCL_ERROR; - case TK_SCROLL_MOVETO: + case TKTEXT_SCROLL_MOVETO: if (fraction > 1.0) { fraction = 1.0; } if (fraction < 0) { fraction = 0; } - newOffset = (int) (((fraction * dInfoPtr->maxLength) - / textPtr->charWidth) + 0.5); + newOffset = (int) (fraction * dInfoPtr->maxLength + 0.5); break; - case TK_SCROLL_PAGES: + case TKTEXT_SCROLL_PAGES: charsPerPage = (dInfoPtr->maxX-dInfoPtr->x)/textPtr->charWidth - 2; if (charsPerPage < 1) { charsPerPage = 1; } - newOffset += charsPerPage * count; + newOffset += charsPerPage * count * textPtr->charWidth; + break; + case TKTEXT_SCROLL_UNITS: + newOffset += count * textPtr->charWidth; break; - case TK_SCROLL_UNITS: + case TKTEXT_SCROLL_PIXELS: newOffset += count; break; } - - dInfoPtr->newXByteOffset = newOffset; + dInfoPtr->newXPixelOffset = newOffset; dInfoPtr->flags |= DINFO_OUT_OF_DATE; if (!(dInfoPtr->flags & REDRAW_PENDING)) { dInfoPtr->flags |= REDRAW_PENDING; @@ -5106,7 +5119,7 @@ TkTextScanCmd(textPtr, interp, objc, objv) { TextDInfo *dInfoPtr = textPtr->dInfoPtr; TkTextIndex index; - int c, x, y, totalScroll, newByte, maxByte, gain=10; + int c, x, y, totalScroll, gain=10; size_t length; if ((objc != 5) && (objc != 6)) { @@ -5128,6 +5141,8 @@ TkTextScanCmd(textPtr, interp, objc, objv) c = Tcl_GetString(objv[2])[0]; length = strlen(Tcl_GetString(objv[2])); if (c=='d' && strncmp(Tcl_GetString(objv[2]), "dragto", length)==0) { + int newX, maxX; + /* * Amplify the difference between the current position and the * mark position to compute how much the view should shift, then @@ -5140,20 +5155,18 @@ TkTextScanCmd(textPtr, interp, objc, objv) * moving again). */ - newByte = dInfoPtr->scanMarkIndex + (gain*(dInfoPtr->scanMarkX - x)) - / (textPtr->charWidth); - maxByte = 1 + (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x) - + textPtr->charWidth - 1)/textPtr->charWidth; - if (newByte < 0) { - newByte = 0; - dInfoPtr->scanMarkIndex = 0; + newX = dInfoPtr->scanMarkXPixel + gain*(dInfoPtr->scanMarkX - x); + maxX = 1 + dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x); + if (newX < 0) { + newX = 0; + dInfoPtr->scanMarkXPixel = 0; dInfoPtr->scanMarkX = x; - } else if (newByte > maxByte) { - newByte = maxByte; - dInfoPtr->scanMarkIndex = maxByte; + } else if (newX > maxX) { + newX = maxX; + dInfoPtr->scanMarkXPixel = maxX; dInfoPtr->scanMarkX = x; } - dInfoPtr->newXByteOffset = newByte; + dInfoPtr->newXPixelOffset = newX; totalScroll = gain*(dInfoPtr->scanMarkY - y); if (totalScroll != dInfoPtr->scanTotalYScroll) { @@ -5167,7 +5180,7 @@ TkTextScanCmd(textPtr, interp, objc, objv) } } } else if (c=='m' && strncmp(Tcl_GetString(objv[2]), "mark", length)==0) { - dInfoPtr->scanMarkIndex = dInfoPtr->newXByteOffset; + dInfoPtr->scanMarkXPixel = dInfoPtr->newXPixelOffset; dInfoPtr->scanMarkX = x; dInfoPtr->scanTotalYScroll = 0; dInfoPtr->scanMarkY = y; diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index dc9ae86..c56b217 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextTag.c,v 1.13 2003/11/12 17:19:18 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextTag.c,v 1.14 2003/11/15 02:33:51 vincentdarley Exp $ */ #include "default.h" @@ -160,7 +160,7 @@ TkTextTagCmd(textPtr, interp, objc, objv) "tagName index1 ?index2 index1 index2 ...?"); return TCL_ERROR; } - tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3])); + tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL); for (i = 4; i < objc; i += 2) { if (TkTextGetObjIndex(interp, textPtr, objv[i], &index1) != TCL_OK) { @@ -176,7 +176,8 @@ TkTextTagCmd(textPtr, interp, objc, objv) } } else { index2 = index1; - TkTextIndexForwChars(NULL,&index2, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL,&index2, 1, &index2, + COUNT_INDICES); } if (tagPtr->affectsDisplay) { @@ -208,11 +209,13 @@ TkTextTagCmd(textPtr, interp, objc, objv) memset((VOID *) &event, 0, sizeof(event)); event.xany.type = VirtualEvent; - event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); + event.xany.serial = + NextRequest(Tk_Display(textPtr->tkwin)); event.xany.send_event = False; event.xany.window = Tk_WindowId(textPtr->tkwin); event.xany.display = Tk_Display(textPtr->tkwin); - ((XVirtualEvent *) &event)->name = Tk_GetUid("Selection"); + ((XVirtualEvent *) &event)->name = + Tk_GetUid("Selection"); Tk_HandleEvent(&event); if (addTag && textPtr->exportSelection @@ -229,10 +232,11 @@ TkTextTagCmd(textPtr, interp, objc, objv) } case TAG_BIND: { if ((objc < 4) || (objc > 6)) { - Tcl_WrongNumArgs(interp, 3, objv, "tagName ?sequence? ?command?"); + Tcl_WrongNumArgs(interp, 3, objv, + "tagName ?sequence? ?command?"); return TCL_ERROR; } - tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3])); + tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL); /* * Make a binding table if the widget doesn't already have @@ -271,8 +275,8 @@ TkTextTagCmd(textPtr, interp, objc, objv) (ClientData) tagPtr, Tcl_GetString(objv[4])); Tcl_ResetResult(interp); Tcl_AppendResult(interp, "requested illegal events; ", - "only key, button, motion, enter, leave, and virtual ", - "events may be used", (char *) NULL); + "only key, button, motion, enter, leave, and virtual ", + "events may be used", (char *) NULL); return TCL_ERROR; } } else if (objc == 5) { @@ -315,7 +319,8 @@ TkTextTagCmd(textPtr, interp, objc, objv) return TCL_ERROR; } objPtr = Tk_GetOptionValue(interp, (char *) tagPtr, - tagPtr->optionTable, objv[4], textPtr->tkwin); + tagPtr->optionTable, objv[4], + textPtr->tkwin); if (objPtr == NULL) { return TCL_ERROR; } else { @@ -326,11 +331,13 @@ TkTextTagCmd(textPtr, interp, objc, objv) break; } case TAG_CONFIGURE: { + int newTag; if (objc < 4) { - Tcl_WrongNumArgs(interp, 3, objv, "tagName ?option? ?value? ?option value ...?"); + Tcl_WrongNumArgs(interp, 3, objv, + "tagName ?option? ?value? ?option value ...?"); return TCL_ERROR; } - tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3])); + tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag); if (objc <= 5) { Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char *) tagPtr, tagPtr->optionTable, @@ -373,18 +380,19 @@ TkTextTagCmd(textPtr, interp, objc, objv) } if (tagPtr->lMargin1String != NULL) { if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->lMargin1String, &tagPtr->lMargin1) != TCL_OK) { + tagPtr->lMargin1String, &tagPtr->lMargin1) != TCL_OK) { return TCL_ERROR; } } if (tagPtr->lMargin2String != NULL) { if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->lMargin2String, &tagPtr->lMargin2) != TCL_OK) { + tagPtr->lMargin2String, &tagPtr->lMargin2) != TCL_OK) { return TCL_ERROR; } } if (tagPtr->offsetString != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, tagPtr->offsetString, + if (Tk_GetPixels(interp, textPtr->tkwin, + tagPtr->offsetString, &tagPtr->offset) != TCL_OK) { return TCL_ERROR; } @@ -397,13 +405,13 @@ TkTextTagCmd(textPtr, interp, objc, objv) } if (tagPtr->rMarginString != NULL) { if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->rMarginString, &tagPtr->rMargin) != TCL_OK) { + tagPtr->rMarginString, &tagPtr->rMargin) != TCL_OK) { return TCL_ERROR; } } if (tagPtr->spacing1String != NULL) { if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->spacing1String, &tagPtr->spacing1) != TCL_OK) { + tagPtr->spacing1String, &tagPtr->spacing1) != TCL_OK) { return TCL_ERROR; } if (tagPtr->spacing1 < 0) { @@ -412,7 +420,7 @@ TkTextTagCmd(textPtr, interp, objc, objv) } if (tagPtr->spacing2String != NULL) { if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->spacing2String, &tagPtr->spacing2) != TCL_OK) { + tagPtr->spacing2String, &tagPtr->spacing2) != TCL_OK) { return TCL_ERROR; } if (tagPtr->spacing2 < 0) { @@ -421,7 +429,7 @@ TkTextTagCmd(textPtr, interp, objc, objv) } if (tagPtr->spacing3String != NULL) { if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->spacing3String, &tagPtr->spacing3) != TCL_OK) { + tagPtr->spacing3String, &tagPtr->spacing3) != TCL_OK) { return TCL_ERROR; } if (tagPtr->spacing3 < 0) { @@ -492,14 +500,15 @@ TkTextTagCmd(textPtr, interp, objc, objv) || (tagPtr->underlineString != NULL)) { tagPtr->affectsDisplay = 1; } - /* - * This line is totally unnecessary if this is a new - * tag, since it can't possibly have been applied to - * anything yet. We might wish to test for that - * case specially - */ - TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, - (TkTextIndex *) NULL, tagPtr, 1); + if (!newTag) { + /* + * This line is not necessary if this is a new tag, + * since it can't possibly have been applied to + * anything yet. + */ + TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, + (TkTextIndex *) NULL, tagPtr, 1); + } return result; } break; @@ -512,7 +521,8 @@ TkTextTagCmd(textPtr, interp, objc, objv) return TCL_ERROR; } for (i = 3; i < objc; i++) { - hPtr = Tcl_FindHashEntry(&textPtr->tagTable, Tcl_GetString(objv[i])); + hPtr = Tcl_FindHashEntry(&textPtr->tagTable, + Tcl_GetString(objv[i])); if (hPtr == NULL) { continue; } @@ -525,8 +535,9 @@ TkTextTagCmd(textPtr, interp, objc, objv) (TkTextIndex *) NULL, tagPtr, 1); } TkTextMakeByteIndex(textPtr->tree, 0, 0, &first); - TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), - 0, &last), + TkTextMakeByteIndex(textPtr->tree, + TkBTreeNumLines(textPtr->tree), + 0, &last), TkBTreeTag(&first, &last, tagPtr, 0); if (tagPtr == textPtr->selTagPtr) { @@ -589,8 +600,9 @@ TkTextTagCmd(textPtr, interp, objc, objv) prio = 0; } ChangeTagPriority(textPtr, tagPtr, prio); - TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, (TkTextIndex *) NULL, - tagPtr, 1); + TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, + (TkTextIndex *) NULL, + tagPtr, 1); break; } case TAG_NAMES: { @@ -608,7 +620,8 @@ TkTextTagCmd(textPtr, interp, objc, objv) arrayPtr = (TkTextTag **) ckalloc((unsigned) (textPtr->numTags * sizeof(TkTextTag *))); - for (i = 0, hPtr = Tcl_FirstHashEntry(&textPtr->tagTable, &search); + for (i = 0, hPtr = Tcl_FirstHashEntry(&textPtr->tagTable, + &search); hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { arrayPtr[i] = (TkTextTag *) Tcl_GetHashValue(hPtr); } @@ -747,8 +760,9 @@ TkTextTagCmd(textPtr, interp, objc, objv) } if (tSearch.segPtr->typePtr == &tkTextToggleOnType) { TkTextPrintIndex(&tSearch.curIndex, position1); - TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), - 0, &last); + TkTextMakeByteIndex(textPtr->tree, + TkBTreeNumLines(textPtr->tree), + 0, &last); TkBTreeStartSearch(&tSearch.curIndex, &last, tagPtr, &tSearch); TkBTreeNextTag(&tSearch); TkTextPrintIndex(&tSearch.curIndex, position2); @@ -844,15 +858,20 @@ TkTextTagCmd(textPtr, interp, objc, objv) */ TkTextTag * -TkTextCreateTag(textPtr, tagName) +TkTextCreateTag(textPtr, tagName, newTag) TkText *textPtr; /* Widget in which tag is being used. */ CONST char *tagName; /* Name of desired tag. */ + int *newTag; /* If non-NULL, then return 1 if new, + * or 0 if already exists. */ { register TkTextTag *tagPtr; Tcl_HashEntry *hPtr; int new; hPtr = Tcl_CreateHashEntry(&textPtr->tagTable, tagName, &new); + if (newTag != NULL) { + *newTag = new; + } if (!new) { return (TkTextTag *) Tcl_GetHashValue(hPtr); } diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c index dd829a8..ab0a4e9 100644 --- a/generic/tkTextWind.c +++ b/generic/tkTextWind.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextWind.c,v 1.9 2003/11/07 15:36:27 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextWind.c,v 1.10 2003/11/15 02:33:51 vincentdarley Exp $ */ #include "tk.h" @@ -870,18 +870,21 @@ TkTextEmbWinDisplayProc(chunkPtr, x, y, lineHeight, baseline, TkTextSegment *ewPtr = (TkTextSegment *) chunkPtr->clientData; int lineX, windowX, windowY, width, height; Tk_Window tkwin; - + TkText *textPtr; + tkwin = ewPtr->body.ew.tkwin; if (tkwin == NULL) { return; } + + textPtr = ewPtr->body.ew.textPtr; if ((x + chunkPtr->width) <= 0) { /* * The window is off-screen; just unmap it. */ - if (ewPtr->body.ew.textPtr->tkwin != Tk_Parent(tkwin)) { - Tk_UnmaintainGeometry(tkwin, ewPtr->body.ew.textPtr->tkwin); + if (textPtr->tkwin != Tk_Parent(tkwin)) { + Tk_UnmaintainGeometry(tkwin, textPtr->tkwin); } else { Tk_UnmapWindow(tkwin); } @@ -894,10 +897,10 @@ TkTextEmbWinDisplayProc(chunkPtr, x, y, lineHeight, baseline, */ EmbWinBboxProc(chunkPtr, 0, screenY, lineHeight, baseline, &lineX, - &windowY, &width, &height); + &windowY, &width, &height); windowX = lineX - chunkPtr->x + x; - if (ewPtr->body.ew.textPtr->tkwin == Tk_Parent(tkwin)) { + if (textPtr->tkwin == Tk_Parent(tkwin)) { if ((windowX != Tk_X(tkwin)) || (windowY != Tk_Y(tkwin)) || (Tk_ReqWidth(tkwin) != Tk_Width(tkwin)) || (height != Tk_Height(tkwin))) { @@ -905,8 +908,8 @@ TkTextEmbWinDisplayProc(chunkPtr, x, y, lineHeight, baseline, } Tk_MapWindow(tkwin); } else { - Tk_MaintainGeometry(tkwin, ewPtr->body.ew.textPtr->tkwin, - windowX, windowY, width, height); + Tk_MaintainGeometry(tkwin, textPtr->tkwin, + windowX, windowY, width, height); } /* diff --git a/tests/textDisp.test b/tests/textDisp.test index 9373f1d..30495b8 100644 --- a/tests/textDisp.test +++ b/tests/textDisp.test @@ -6,7 +6,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: textDisp.test,v 1.17 2003/11/13 18:30:42 vincentdarley Exp $ +# RCS: @(#) $Id: textDisp.test,v 1.18 2003/11/15 02:33:51 vincentdarley Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -1582,7 +1582,7 @@ test textDisp-13.9 {TkTextSeeCmd procedure} {textfonts} { lappend x [.t bbox 30.65] .t see 30.90 lappend x [.t bbox 30.90] -} [list [list 80 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 136 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 136 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 80 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight]] +} [list [list 74 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 138 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 138 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 74 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight]] test textDisp-13.10 {TkTextSeeCmd procedure} {} { # SF Bug 641778 set w .tsee @@ -1640,7 +1640,7 @@ test textDisp-14.7 {TkTextXviewCmd procedure} { .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx" .t xview moveto .3 .t xview -} {0.303571428571 0.660714285714} +} {0.301020408163 0.658163265306} test textDisp-14.8 {TkTextXviewCmd procedure} { .t delete 1.0 end .t insert end xxxxxxxxx\n @@ -1659,10 +1659,10 @@ test textDisp-14.9 {TkTextXviewCmd procedure} { } {0.642857142857 1.0} test textDisp-14.10 {TkTextXviewCmd procedure} { list [catch {.t xview scroll a} msg] $msg -} {1 {wrong # args: should be ".t xview scroll number units|pages"}} +} {1 {wrong # args: should be ".t xview scroll number units|pages|pixels"}} test textDisp-14.11 {TkTextXviewCmd procedure} { list [catch {.t xview scroll a b c} msg] $msg -} {1 {wrong # args: should be ".t xview scroll number units|pages"}} +} {1 {wrong # args: should be ".t xview scroll number units|pages|pixels"}} test textDisp-14.12 {TkTextXviewCmd procedure} { list [catch {.t xview scroll gorp units} msg] $msg } {1 {expected integer but got "gorp"}} @@ -1672,9 +1672,9 @@ test textDisp-14.13 {TkTextXviewCmd procedure} { .t insert end "a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9\n" .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx" .t xview moveto 0 - .t xview scroll 2 p + .t xview scroll 2 pa set x [.t index @0,22] - .t xview scroll -1 p + .t xview scroll -1 pa lappend x [.t index @0,22] .t xview scroll -2 pages lappend x [.t index @0,22] @@ -1696,7 +1696,7 @@ test textDisp-14.14 {TkTextXviewCmd procedure} { } {2.21 2.20 2.99 2.84} test textDisp-14.15 {TkTextXviewCmd procedure} { list [catch {.t xview scroll 14 globs} msg] $msg -} {1 {bad argument "globs": must be units or pages}} +} {1 {bad argument "globs": must be units, pages or pixels}} test textDisp-14.16 {TkTextXviewCmd procedure} { list [catch {.t xview flounder} msg] $msg } {1 {unknown option "flounder": must be moveto or scroll}} @@ -2033,7 +2033,7 @@ test textDisp-17.7 {TkTextScanCmd procedure} {textfonts} { set x [.t index @0,0] .t scan dragto 0 [expr {70 + $fixedDiff}] list $x [.t index @0,0] -} {6.13 2.6} +} {6.12 2.5} test textDisp-17.8 {TkTextScanCmd procedure} {textfonts} { .t yview 1.0 .t xview moveto 0 @@ -2048,7 +2048,7 @@ test textDisp-17.9 {TkTextScanCmd procedure} {textfonts} { .t xview scroll 100 units .t scan mark 90 60 .t scan dragto 10 0 - .t scan dragto 15 5 + .t scan dragto 14 5 .t index @0,0 } {18.44} .t configure -wrap word @@ -3230,6 +3230,97 @@ test textDisp-29.2 {miscellaneous: lines wrap but are still too long} {textfonts update list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3] } [list {0.0233333333333 0.49} 300x50+-2+[expr {$fixedDiff + 18}] [list 5 [expr {$fixedDiff + 68}] 7 $fixedHeight]] +test textDisp-29.2.1 {miscellaneous: lines wrap but are still too long} {textfonts} { + catch {destroy .t2} + toplevel .t2 + wm geometry .t2 +0+0 + text .t2.t -width 20 -height 10 -font $fixedFont \ + -wrap none -xscrollcommand ".t2.s set" + pack .t2.t -side top + scrollbar .t2.s -orient horizontal -command ".t2.t xview" + pack .t2.s -side bottom -fill x + .t2.t insert end 1\n + .t2.t insert end [string repeat "abc" 30] + .t2.t xview scroll 5 unit + update + .t2.t xview +} {0.0555555555556 0.277777777778} +test textDisp-29.2.2 {miscellaneous: lines wrap but are still too long} {textfonts} { + catch {destroy .t2} + toplevel .t2 + wm geometry .t2 +0+0 + text .t2.t -width 20 -height 10 -font $fixedFont \ + -wrap char -xscrollcommand ".t2.s set" + pack .t2.t -side top + scrollbar .t2.s -orient horizontal -command ".t2.t xview" + pack .t2.s -side bottom -fill x + .t2.t insert end 123 + frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised + .t2.t window create 1.1 -window .t2.t.f + .t2.t xview scroll 2 unit + update + list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3] +} [list {0.0466666666667 0.513333333333} 300x50+-9+[expr {$fixedDiff + 18}] {}] +test textDisp-29.2.3 {miscellaneous: lines wrap but are still too long} {textfonts} { + catch {destroy .t2} + toplevel .t2 + wm geometry .t2 +0+0 + text .t2.t -width 20 -height 10 -font $fixedFont \ + -wrap char -xscrollcommand ".t2.s set" + pack .t2.t -side top + scrollbar .t2.s -orient horizontal -command ".t2.t xview" + pack .t2.s -side bottom -fill x + .t2.t insert end 123 + frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised + .t2.t window create 1.1 -window .t2.t.f + .t2.t xview scroll 7 pixels + update + list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3] +} [list {0.0233333333333 0.49} 300x50+-2+[expr {$fixedDiff + 18}] [list 5 [expr {$fixedDiff + 68}] 7 $fixedHeight]] +test textDisp-29.2.4 {miscellaneous: lines wrap but are still too long} {textfonts} { + catch {destroy .t2} + toplevel .t2 + wm geometry .t2 +0+0 + text .t2.t -width 20 -height 10 -font $fixedFont \ + -wrap char -xscrollcommand ".t2.s set" + pack .t2.t -side top + scrollbar .t2.s -orient horizontal -command ".t2.t xview" + pack .t2.s -side bottom -fill x + .t2.t insert end 123 + frame .t2.t.f -width 300 -height 50 -bd 2 -relief raised + .t2.t window create 1.1 -window .t2.t.f + .t2.t xview scroll 17 pixels + update + list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3] +} [list {0.0566666666667 0.523333333333} 300x50+-12+[expr {$fixedDiff + 18}] {}] +test textDisp-29.2.5 {miscellaneous: can show last character} { + catch {destroy .t2} + toplevel .t2 + wm geometry .t2 121x141+200+200 + text .t2.t -width 5 -height 5 -font {Arial 10} \ + -wrap none -xscrollcommand ".t2.s set" \ + -bd 2 -highlightthickness 0 -padx 1 + .t2.t insert end "WWWWWWWWWWWWi" + scrollbar .t2.s -orient horizontal -command ".t2.t xview" + grid .t2.t -row 0 -column 0 -sticky nsew + grid .t2.s -row 1 -column 0 -sticky ew + grid columnconfigure .t2 0 -weight 1 + grid rowconfigure .t2 0 -weight 1 + grid rowconfigure .t2 1 -weight 0 + update ; update + set xv [.t2.t xview] + set xd [expr {[lindex $xv 1] - [lindex $xv 0]}] + .t2.t xview moveto [expr {1.0-$xd}] + set iWidth [lindex [.t2.t bbox end-2c] 2] + .t2.t xview scroll 2 units + set iWidth2 [lindex [.t2.t bbox end-2c] 2] + + if {($iWidth == $iWidth2) && $iWidth > 2} { + set result "correct" + } else { + set result "not correct" + } +} {correct} test textDisp-29.3 {miscellaneous: lines wrap but are still too long} {textfonts} { catch {destroy .t2} toplevel .t2 @@ -3246,8 +3337,7 @@ test textDisp-29.3 {miscellaneous: lines wrap but are still too long} {textfonts .t2.t xview scroll 200 units update list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3] -} [list {0.536666666667 1.0} 300x50+-156+[expr {$fixedDiff + 18}] {}] - +} [list {0.533333333333 1.0} 300x50+-155+[expr {$fixedDiff + 18}] {}] test textDisp-30.1 {elidden text complications} {knownBug} { .t2.t delete 1.0 end .t2.t insert 1.0 "1111\n2222\n3333" -- cgit v0.12