diff options
author | vincentdarley <vincentdarley> | 2005-10-10 10:36:34 (GMT) |
---|---|---|
committer | vincentdarley <vincentdarley> | 2005-10-10 10:36:34 (GMT) |
commit | 465cf308ea2f63fa388ed9e0e055c82e8e9e3ca3 (patch) | |
tree | ce21d5eee20f7e5c9a628e238ad0a87a0aaeebad | |
parent | ebaf2538558086d8a3749809e5863e1b134f19ab (diff) | |
download | tk-465cf308ea2f63fa388ed9e0e055c82e8e9e3ca3.zip tk-465cf308ea2f63fa388ed9e0e055c82e8e9e3ca3.tar.gz tk-465cf308ea2f63fa388ed9e0e055c82e8e9e3ca3.tar.bz2 |
tip256 implementation
-rw-r--r-- | ChangeLog | 24 | ||||
-rw-r--r-- | doc/text.n | 70 | ||||
-rw-r--r-- | generic/tkText.c | 82 | ||||
-rw-r--r-- | generic/tkText.h | 20 | ||||
-rw-r--r-- | generic/tkTextBTree.c | 14 | ||||
-rw-r--r-- | generic/tkTextDisp.c | 186 | ||||
-rw-r--r-- | generic/tkTextImage.c | 12 | ||||
-rw-r--r-- | generic/tkTextIndex.c | 10 | ||||
-rw-r--r-- | generic/tkTextMark.c | 4 | ||||
-rw-r--r-- | generic/tkTextTag.c | 26 | ||||
-rw-r--r-- | generic/tkTextWind.c | 4 | ||||
-rw-r--r-- | macosx/tkMacOSXDefault.h | 3 | ||||
-rw-r--r-- | tests/text.test | 67 | ||||
-rw-r--r-- | tests/textDisp.test | 148 | ||||
-rw-r--r-- | unix/tkUnixDefault.h | 3 | ||||
-rw-r--r-- | win/tkWinDefault.h | 3 |
16 files changed, 516 insertions, 160 deletions
@@ -1,3 +1,27 @@ +2005-10-10 Vince Darley <vincentdarley@users.sourceforge.net> + + * doc/text.n + * generic/tkText.c + * generic/tkText.h + * generic/tkTextBTree.c + * generic/tkTextDisp.c + * generic/tkTextImage.c + * generic/tkTextIndex.c + * generic/tkTextMark.c + * generic/tkTextTag.c + * generic/tkTextWind.c + * macosx/tkMacOSXDefault.h + * tests/text.test + * tests/textDisp.test + * unix/tkUnixDefault.h + * win/tkWinDefault.h: Implementation of TIP#256, adding a new + text widget configuration option '-tabstyle', with new tests + and documentation. + + Also a fix for [Bug 1281228] (documentation and full implementation + of -strictlimits), and [Bug 1288677] (corrected elide behaviour), + again with more tests. + 2005-10-04 Jeff Hobbs <jeffh@ActiveState.com> * library/dialog.tcl (::tk_dialog): add tkwait visibility before @@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: text.n,v 1.38 2005/08/09 09:46:02 vincentdarley Exp $ +'\" RCS: @(#) $Id: text.n,v 1.39 2005/10/10 10:36:34 vincentdarley Exp $ '\" .so man.macros .TH text n 8.5 Tk "Tk Built-In Commands" @@ -114,13 +114,10 @@ following the tab character is positioned at the tab position, and at the tab position; if there is no decimal point then the least significant digit of the number is positioned just to the left of the tab position; if there is no number in the text then the text is -right-justified at the tab position. +right-justified at the tab position. For example, \fB\-tabs {2c left 4c 6c center}\fR creates three tab stops at two-centimeter intervals; the first two use left -justification and the third uses center justification. Note that -tabs are interpreted as they are encountered in the text. Any tab -character being laid out will use (and be defined by) the first tab stop -to the right of the preceding characters already laid out on that line. +justification and the third uses center justification. If the list of tab stops does not have enough elements to cover all of the tabs in a text line, then Tk extrapolates new tab stops using the spacing and alignment from the last tab stop in the list. Tab @@ -133,6 +130,19 @@ an empty list, then Tk uses default tabs spaced every eight (average size) characters. To achieve a different standard spacing, for example every 4 characters, simply configure the widget with \fB\-tabs "[expr {4 * [font measure $font 0]}] left"\fR. +.OP \-tabstyle tabStyle TabStyle +Specifies how to interpret the relationship between tab stops on a line +and tabs in the text of that line. The value must be \fBtabular\fR (the +default) or \fBwordprocessor\fR. Note that tabs are interpreted as they +are encountered in the text. If the tab style is \fBtabular\fR then the +n'th tab character in the line's text will be associated with the n'th +tab stop defined for that line. If the tab character's x coordinate +falls to the right of the n'th tab stop, then a gap of a single space +will be inserted as a fallback. If the tab style is \fBwordprocessor\fR +then any tab character being laid out will use (and be defined by) the +first tab stop to the right of the preceding characters already laid out +on that line. The value of the \fBtabstyle\fR option may be overridden +by \fB\-tabstyle\fR options in tags. .OP \-undo undo Undo Specifies a boolean that says whether the undo mechanism is active or not. @@ -369,16 +379,16 @@ lines are not wrapped, then these two methods of counting are equivalent. .TP ?\fIsubmodifier\fR? \fBlinestart\fR .VS 8.5 -Adjust the index to refer to the first character on the line. If the -\fBdisplay\fR submodifier is given, this is the first character on the +Adjust the index to refer to the first index on the line. If the +\fBdisplay\fR submodifier is given, this is the first index on the display line, otherwise on the logical line. .VE 8.5 .TP ?\fIsubmodifier\fR? \fBlineend\fR .VS 8.5 -Adjust the index to refer to the last character on the line (the +Adjust the index to refer to the last index on the line (the newline). If the \fBdisplay\fR submodifier is given, this is the last -character on the display line, otherwise on the logical line. +index on the display line, otherwise on the logical line. .VE 8.5 .TP ?\fIsubmodifier\fR? \fBwordstart\fR @@ -468,10 +478,11 @@ option to give a 3-D appearance to the background for characters; it is ignored unless the \fB\-background\fR option has been set for the tag. .TP -\fB\-elide \fIboolean\fR -\fIElide\fR specifies whether the data should be elided. -Elided data is not displayed and takes no space on screen, but further -on behaves just as normal data. +\fB\-elide \fIboolean\fR +\fIElide\fR specifies whether the data should +be elided. Elided data (characters, images, embedded windows, etc) is +not displayed and takes no space on screen, but further on behaves just +as normal data. .TP \fB\-fgstipple \fIbitmap\fR \fIBitmap\fR specifies a bitmap that is used as a stipple pattern @@ -491,15 +502,15 @@ foreground information such as underlines. It may have any of the forms accepted by \fBTk_GetColor\fR. .TP \fB\-justify \fIjustify\fR -If the first character of a display line has a tag for which this +If the first non-elided character of a display line has a tag for which this option has been specified, then \fIjustify\fR determines how to justify the line. It must be one of \fBleft\fR, \fBright\fR, or \fBcenter\fR. If a line wraps, then the justification for each line on the -display is determined by the first character of that display line. +display is determined by the first non-elided character of that display line. .TP \fB\-lmargin1 \fIpixels\fR -If the first character of a text line has a tag for which this +If the first non-elided character of a text line has a tag for which this option has been specified, then \fIpixels\fR specifies how much the line should be indented from the left edge of the window. @@ -510,7 +521,7 @@ first line on the display; the \fB\-lmargin2\fR option controls the indentation for subsequent lines. .TP \fB\-lmargin2 \fIpixels\fR -If the first character of a display line has a tag for which this +If the first non-elided character of a display line has a tag for which this option has been specified, and if the display line is not the first for its text line (i.e., the text line has wrapped), then \fIpixels\fR specifies how much the line should be indented from @@ -543,7 +554,7 @@ it is ignored unless the \fB\-background\fR option has been set for the tag. .TP \fB\-rmargin \fIpixels\fR -If the first character of a display line has a tag for which this +If the first non-elided character of a display line has a tag for which this option has been specified, then \fIpixels\fR specifies how wide a margin to leave between the end of the line and the right edge of the window. @@ -551,7 +562,7 @@ edge of the window. distances. This option is only used when wrapping is enabled. If a text line wraps, the right margin for each line on the -display is determined by the first character of that display +display is determined by the first non-elided character of that display line. .TP \fB\-spacing1 \fIpixels\fR @@ -578,7 +589,7 @@ line on the display. \fITabList\fR specifies a set of tab stops in the same form as for the \fB\-tabs\fR option for the text widget. This option only applies to a display line if it applies to the -first character on that display line. +first non-elided character on that display line. If this option is specified as an empty string, it cancels the option, leaving it unspecified for the tag (the default). If the option is specified as a non-empty string that is @@ -586,6 +597,14 @@ an empty list, such as \fB\-tags\0{\0}\fR, then it requests default 8-character tabs as described for the \fBtags\fR widget option. .TP +\fB\-tabstyle \fIstyle\fR +\fIStyle\fR specifies either the \fItabular\fR or +\fIwordprocessor\fR style of tabbing to use for the text widget. +This option only applies to a display line if it applies to the +first non-elided character on that display line. +If this option is specified as an empty string, it cancels +the option, leaving it unspecified for the tag (the default). +.TP \fB\-underline \fIboolean\fR \fIBoolean\fR specifies whether or not to draw an underline underneath characters. @@ -1553,6 +1572,15 @@ but matching 'Z[a\-z]+Z' against 'ZooZooZoo' will now match twice. An error will be thrown if this switch is used without \fB\-all\fR. .VE 8.5 .TP +\fB\-strictlimits\fR +.VS 8.5 +When performing any search, the normal behaviour is that +the start and stop limits are checked with respect to the +start of the matching text. With the \fB\-strictlimits\fR flag, +the entire matching range must lie inside the start and stop +limits specified for the match to be valid. +.VE 8.5 +.TP \fB\-elide\fR Find elided (hidden) text as well. By default only displayed text is searched. diff --git a/generic/tkText.c b/generic/tkText.c index 7034579..5313ed3 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.59 2005/08/11 01:55:04 dgp Exp $ + * RCS: @(#) $Id: tkText.c,v 1.60 2005/10/10 10:36:35 vincentdarley Exp $ */ #include "default.h" @@ -66,6 +66,16 @@ static char *wrapStrings[] = { }; /* + * The 'TkTextTabStyle' enum in tkText.h is used to define a type for + * the -tabstyle option of the Text widget. These values are used as + * indices into the string table below. + */ + +static char *tabStyleStrings[] = { + "tabular", "wordprocessor", (char *) NULL +}; + +/* * The following functions and custom option type are used to define the * "line" option type, and thereby handle the text widget '-startline', * '-endline' configuration options which are of that type. @@ -214,6 +224,9 @@ static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_STRING, "-tabs", "tabs", "Tabs", DEF_TEXT_TABS, Tk_Offset(TkText, tabOptionPtr), -1, TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_GEOMETRY}, + {TK_OPTION_STRING_TABLE, "-tabstyle", "tabStyle", "TabStyle", + DEF_TEXT_TABSTYLE, -1, Tk_Offset(TkText, tabStyle), + 0, (ClientData) tabStyleStrings, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus), TK_OPTION_NULL_OK, 0, 0}, @@ -323,7 +336,7 @@ int tkTextDebug = 0; static int ConfigureText(Tcl_Interp *interp, TkText *textPtr, int objc, Tcl_Obj *CONST objv[]); -static int DeleteChars(TkSharedText *sharedPtr, TkText *textPtr, +static int DeleteIndexRange(TkSharedText *sharedPtr, TkText *textPtr, CONST TkTextIndex *indexPtr1, CONST TkTextIndex *indexPtr2, int viewUpdate); static int CountIndices(CONST TkText *textPtr, @@ -714,7 +727,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv) result = TCL_ERROR; goto done; } - if (TkTextCharBbox(textPtr, indexPtr, &x, &y, &width, &height, + if (TkTextIndexBbox(textPtr, indexPtr, &x, &y, &width, &height, NULL) == 0) { Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); @@ -1063,7 +1076,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv) } else { indexPtr2 = NULL; } - DeleteChars(NULL, textPtr, indexPtr1, indexPtr2, 1); + DeleteIndexRange(NULL, textPtr, indexPtr1, indexPtr2, 1); } else { /* * Multi-index pair case requires that we prevalidate the @@ -1168,7 +1181,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv) * indices are preparsed above. */ - DeleteChars(NULL, textPtr, &indices[i], &indices[i+1], + DeleteIndexRange(NULL, textPtr, &indices[i], &indices[i+1], 1); } } @@ -1563,9 +1576,9 @@ SharedTextObjCmd(clientData, interp, objc, objv) if (result != TCL_OK) { return result; } - DeleteChars(sharedPtr, NULL, &index1, &index2, 1); + DeleteIndexRange(sharedPtr, NULL, &index1, &index2, 1); } else { - DeleteChars(sharedPtr, NULL, &index1, NULL, 1); + DeleteIndexRange(sharedPtr, NULL, &index1, NULL, 1); } return TCL_OK; } else { @@ -1702,7 +1715,7 @@ TextReplaceCmd(textPtr, interp, indexFromPtr, indexToPtr, objc, objv, /* * Perform the deletion and insertion, but ensure no undo-separator is * placed between the two operations. Since we are using the helper - * functions 'DeleteChars' and 'TextInsertCmd' we have to pretend that the + * functions 'DeleteIndexRange' and 'TextInsertCmd' we have to pretend that the * autoSeparators setting is off, so that we don't get an undo-separator * between the delete and insert. */ @@ -1718,7 +1731,7 @@ TextReplaceCmd(textPtr, interp, indexFromPtr, indexToPtr, objc, objv, } } - DeleteChars(NULL, textPtr, indexFromPtr, indexToPtr, viewUpdate); + DeleteIndexRange(NULL, textPtr, indexFromPtr, indexToPtr, viewUpdate); result = TextInsertCmd(NULL, textPtr, interp, objc-4, objv+4, indexFromPtr, viewUpdate); @@ -2857,7 +2870,7 @@ CountIndices(textPtr, indexPtr1, indexPtr2, type) /* *---------------------------------------------------------------------- * - * DeleteChars -- + * DeleteIndexRange -- * * This function implements most of the functionality of the "delete" * widget command. @@ -2866,7 +2879,8 @@ CountIndices(textPtr, indexPtr1, indexPtr2, type) * Returns a standard Tcl result, currently always TCL_OK. * * Side effects: - * Characters get deleted from the text. + * Characters and other entities (windows, images) get deleted + * from the text. * * If 'viewUpdate' is true, we may adjust the window contents' * y-position, and scrollbar setting. @@ -2882,16 +2896,17 @@ CountIndices(textPtr, indexPtr1, indexPtr2, type) */ static int -DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) +DeleteIndexRange(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) TkSharedText *sharedTextPtr;/* Shared portion of peer widgets. */ TkText *textPtr; /* Overall information about text widget. */ CONST TkTextIndex *indexPtr1; /* Index describing location of first - * character to delete. */ + * character (or other entity) to delete. */ CONST TkTextIndex *indexPtr2; - /* Index describing location of last character - * to delete. NULL means just delete the one - * character given by indexPtr1. */ + /* Index describing location of last + * character (or other entity) to delete. + * NULL means just delete the one character + * given by indexPtr1. */ int viewUpdate; /* Update vertical view if set. */ { int line1, line2; @@ -3086,7 +3101,7 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) sharedTextPtr->stateEpoch++; - TkBTreeDeleteChars(sharedTextPtr->tree, &index1, &index2); + TkBTreeDeleteIndexRange(sharedTextPtr->tree, &index1, &index2); resetViewCount = 0; for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { @@ -3409,7 +3424,7 @@ TextBlinkProc(clientData) } redrawInsert: TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); - if (TkTextCharBbox(textPtr, &index, &x, &y, &w, &h, &charWidth) == 0) { + if (TkTextIndexBbox(textPtr, &index, &x, &y, &w, &h, &charWidth) == 0) { if (textPtr->insertCursorType) { /* Block cursor */ TkTextRedrawRegion(textPtr, x - textPtr->width / 2, y, @@ -4033,6 +4048,18 @@ TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, matchOffset, } /* + * If we're using strict limits checking, ensure that the match with + * its full length fits inside the given range. + */ + + if (searchSpecPtr->strictLimits && lineNum == searchSpecPtr->stopLine) { + if (searchSpecPtr->backwards ^ + ((matchOffset + numChars) > searchSpecPtr->stopOffset)) { + return 0; + } + } + + /* * The index information returned by the regular expression parser only * considers textual information: it doesn't account for embedded windows, * elided text (when we are not searching elided text) or any other @@ -4253,7 +4280,8 @@ TkTextGetTabs(interp, textPtr, stringPtr) tabArrayPtr->numTabs = 0; prevStop = 0.0; lastStop = 0.0; - for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc; i++, tabPtr++) { + for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc; + i++, tabPtr++) { int index; /* @@ -5528,7 +5556,9 @@ SearchCore(interp, searchSpecPtr, patObj) * We've found a multi-line match. */ - extraLinesSearched = extraLines - 1; + if (extraLines > 0) { + extraLinesSearched = extraLines - 1; + } } } @@ -5756,7 +5786,9 @@ SearchCore(interp, searchSpecPtr, patObj) } if (match && ((firstOffset + info.matches[0].end) >= prevFullLine)) { - extraLinesSearched = extraLines - 1; + if (extraLines > 0) { + extraLinesSearched = extraLines - 1; + } lastFullLine = prevFullLine; } @@ -6309,11 +6341,3 @@ ObjectIsEmpty(objPtr) Tcl_GetStringFromObj(objPtr, &length); return (length == 0); } - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/generic/tkText.h b/generic/tkText.h index 5d7ea0f..2ccbfa9 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.26 2005/02/14 23:00:44 vincentdarley Exp $ + * RCS: @(#) $Id: tkText.h,v 1.27 2005/10/10 10:36:35 vincentdarley Exp $ */ #ifndef _TKTEXT @@ -421,6 +421,8 @@ typedef struct TkTextTag { struct TkTextTabArray *tabArrayPtr; /* Info about tabs for tag (malloc-ed) * or NULL. Corresponds to tabString. */ + int tabStyle; /* One of TABULAR or WORDPROCESSOR or + * NONE (if not specified). */ char *underlineString; /* -underline option string (malloc-ed). * NULL means option not specified. */ int underline; /* Non-zero means draw underline underneath @@ -493,6 +495,17 @@ typedef struct TkTextSearch { typedef enum {LEFT, RIGHT, CENTER, NUMERIC} TkTextTabAlign; +/* + * The following are the supported styles of tabbing, used for the + * -tabstyle option of the text widget. The last element is only + * used for tag options. + */ +typedef enum { + TK_TEXT_TABSTYLE_TABULAR, + TK_TEXT_TABSTYLE_WORDPROCESSOR, + TK_TEXT_TABSTYLE_NONE +} TkTextTabStyle; + typedef struct TkTextTab { int location; /* Offset in pixels of this tab stop * from the left margin (lmargin2) of @@ -695,6 +708,7 @@ typedef struct TkText { /* Information about tab stops (malloc'ed). * NULL means perform default tabbing * behavior. */ + int tabStyle; /* One of TABULAR or WORDPROCESSOR. */ /* * Additional information used for displaying: @@ -1014,7 +1028,7 @@ EXTERN void TkBTreeClientRangeChanged _ANSI_ARGS_((TkText *textPtr, EXTERN void TkBTreeRemoveClient _ANSI_ARGS_((TkTextBTree tree, TkText *textPtr)); EXTERN void TkBTreeDestroy _ANSI_ARGS_((TkTextBTree tree)); -EXTERN void TkBTreeDeleteChars _ANSI_ARGS_((TkTextBTree tree, +EXTERN void TkBTreeDeleteIndexRange _ANSI_ARGS_((TkTextBTree tree, TkTextIndex *index1Ptr, TkTextIndex *index2Ptr)); EXTERN TkTextLine * TkBTreeFindLine _ANSI_ARGS_((TkTextBTree tree, CONST TkText *textPtr, int line)); @@ -1058,7 +1072,7 @@ EXTERN void TkTextChanged _ANSI_ARGS_((TkSharedText *sharedTextPtr, TkText *textPtr, CONST TkTextIndex *index1Ptr, CONST TkTextIndex *index2Ptr)); -EXTERN int TkTextCharBbox _ANSI_ARGS_((TkText *textPtr, +EXTERN int TkTextIndexBbox _ANSI_ARGS_((TkText *textPtr, CONST TkTextIndex *indexPtr, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr, int *charWidthPtr)); EXTERN int TkTextCharLayoutProc _ANSI_ARGS_((TkText *textPtr, diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c index f8a682c..30309db 100644 --- a/generic/tkTextBTree.c +++ b/generic/tkTextBTree.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: tkTextBTree.c,v 1.18 2005/07/29 13:43:43 dkf Exp $ + * RCS: @(#) $Id: tkTextBTree.c,v 1.19 2005/10/10 10:36:35 vincentdarley Exp $ */ #include "tkInt.h" @@ -1269,7 +1269,7 @@ CleanupLine(linePtr) /* *---------------------------------------------------------------------- * - * TkBTreeDeleteChars -- + * TkBTreeDeleteIndexRange -- * * Delete a range of characters from a B-tree. The caller must make sure * that the final newline of the B-tree is never deleted. @@ -1287,7 +1287,7 @@ CleanupLine(linePtr) */ void -TkBTreeDeleteChars(tree, index1Ptr, index2Ptr) +TkBTreeDeleteIndexRange(tree, index1Ptr, index2Ptr) TkTextBTree tree; /* Tree to delete from */ register TkTextIndex *index1Ptr; /* Indicates first character that is to be @@ -4832,11 +4832,3 @@ ToggleCheckProc(segPtr, linePtr) } } } - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 5289c94..dfa7dd3 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -12,7 +12,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.52 2005/07/28 17:20:41 dkf Exp $ + * RCS: @(#) $Id: tkTextDisp.c,v 1.53 2005/10/10 10:36:35 vincentdarley Exp $ */ #include "tkPort.h" @@ -100,6 +100,7 @@ typedef struct StyleValues { int spacing3; /* Spacing below last dline in text line. */ TkTextTabArray *tabArrayPtr;/* Locations and types of tab stops (may be * NULL). */ + int tabStyle; /* One of TABULAR or WORDPROCESSOR. */ int underline; /* Non-zero means draw underline underneath * text. */ int elide; /* Zero means draw text, otherwise not */ @@ -482,8 +483,8 @@ static void YScrollByLines _ANSI_ARGS_((TkText *textPtr, static void YScrollByPixels _ANSI_ARGS_((TkText *textPtr, int offset)); static int SizeOfTab _ANSI_ARGS_((TkText *textPtr, - TkTextTabArray *tabArrayPtr, int *indexPtr, - int x, int maxX)); + int tabStyle, TkTextTabArray *tabArrayPtr, + int *indexPtr, int x, int maxX)); static void TextChanged _ANSI_ARGS_((TkText *textPtr, CONST TkTextIndex *index1Ptr, CONST TkTextIndex *index2Ptr)); @@ -685,7 +686,7 @@ GetStyle(textPtr, indexPtr) int underlinePrio, elidePrio, justifyPrio, offsetPrio; int lMargin1Prio, lMargin2Prio, rMarginPrio; int spacing1Prio, spacing2Prio, spacing3Prio; - int overstrikePrio, tabPrio, wrapPrio; + int overstrikePrio, tabPrio, tabStylePrio, wrapPrio; /* * Find out what tags are present for the character, then compute a @@ -699,7 +700,7 @@ GetStyle(textPtr, indexPtr) underlinePrio = elidePrio = justifyPrio = offsetPrio = -1; lMargin1Prio = lMargin2Prio = rMarginPrio = -1; spacing1Prio = spacing2Prio = spacing3Prio = -1; - overstrikePrio = tabPrio = wrapPrio = -1; + overstrikePrio = tabPrio = tabStylePrio = wrapPrio = -1; memset((VOID *) &styleValues, 0, sizeof(StyleValues)); styleValues.relief = TK_RELIEF_FLAT; styleValues.fgColor = textPtr->fgColor; @@ -709,6 +710,7 @@ GetStyle(textPtr, indexPtr) styleValues.spacing2 = textPtr->spacing2; styleValues.spacing3 = textPtr->spacing3; styleValues.tabArrayPtr = textPtr->tabArrayPtr; + styleValues.tabStyle = textPtr->tabStyle; styleValues.wrapMode = textPtr->wrapMode; styleValues.elide = 0; @@ -817,6 +819,11 @@ GetStyle(textPtr, indexPtr) styleValues.tabArrayPtr = tagPtr->tabArrayPtr; tabPrio = tagPtr->priority; } + if ((tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE) + && (tagPtr->priority > tabStylePrio)) { + styleValues.tabStyle = tagPtr->tabStyle; + tabStylePrio = tagPtr->priority; + } if ((tagPtr->underlineString != NULL) && (tagPtr->priority > underlinePrio)) { styleValues.underline = tagPtr->underline; @@ -979,6 +986,10 @@ LayoutDLine(textPtr, indexPtr) int noCharsYet; /* Non-zero means that no characters * have been placed on the line * yet. */ + int paragraphStart; /* Non-zero means that we are + * on the first line of a + * paragraph (Used to choose + * between lmargin1, lmargin2). */ int justify; /* How to justify line: taken from * style for the first character in * line. */ @@ -1001,6 +1012,7 @@ LayoutDLine(textPtr, indexPtr) TkTextTabArray *tabArrayPtr; /* Tab stops for line; taken from * style for the first character on * line. */ + int tabStyle; /* One of TABULAR or WORDPROCESSOR. */ int tabSize; /* Number of pixels consumed by * current tab stop. */ TkTextDispChunk *lastCharChunkPtr; /* Pointer to last chunk in display @@ -1027,12 +1039,19 @@ LayoutDLine(textPtr, indexPtr) dlPtr->flags = NEW_LAYOUT | OLD_Y_INVALID; dlPtr->logicalLinesMerged = 0; + /* + * This is not necessarily totally correct, where we have merged + * logical lines. Fixing this would require a quite significant + * overhaul, though, so currently we make do with this. + */ + paragraphStart = (indexPtr->byteIndex == 0); + /* * Special case entirely elide line as there may be 1000s or more */ elide = TkTextIsElided(textPtr, indexPtr, &info); - if (elide && indexPtr->byteIndex==0) { + if (elide && indexPtr->byteIndex == 0) { maxBytes = 0; for (segPtr = info.segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { if (segPtr->size > 0) { @@ -1141,6 +1160,7 @@ LayoutDLine(textPtr, indexPtr) tabIndex = -1; tabChunkPtr = NULL; tabArrayPtr = NULL; + tabStyle = TK_TEXT_TABSTYLE_TABULAR; rMargin = 0; wrapMode = TEXT_WRAPMODE_CHAR; tabSize = 0; @@ -1194,7 +1214,8 @@ LayoutDLine(textPtr, indexPtr) if (elide && (lastChunkPtr != NULL) && (lastChunkPtr->displayProc == NULL /*ElideDisplayProc*/)) { - if ((elidesize = segPtr->size - byteOffset) > 0) { + elidesize = segPtr->size - byteOffset; + if (elidesize > 0) { curIndex.byteIndex += elidesize; lastChunkPtr->numBytes += elidesize; breakByteOffset = lastChunkPtr->breakIndex @@ -1262,14 +1283,26 @@ LayoutDLine(textPtr, indexPtr) * information for the rest of the line. */ - if (noCharsYet) { + if (!elide && noCharsYet) { tabArrayPtr = chunkPtr->stylePtr->sValuePtr->tabArrayPtr; + tabStyle = chunkPtr->stylePtr->sValuePtr->tabStyle; justify = chunkPtr->stylePtr->sValuePtr->justify; rMargin = chunkPtr->stylePtr->sValuePtr->rMargin; wrapMode = chunkPtr->stylePtr->sValuePtr->wrapMode; - x = ((curIndex.byteIndex == 0) - ? chunkPtr->stylePtr->sValuePtr->lMargin1 - : chunkPtr->stylePtr->sValuePtr->lMargin2); + + /* + * See above - this test may not be entirely correct where + * we have partially elided lines (and therefore merged + * logical lines). In such a case a byteIndex of zero + * doesn't necessarily mean the beginning of a logical line. + */ + if (paragraphStart) { + /* Beginning of logical line */ + x = chunkPtr->stylePtr->sValuePtr->lMargin1; + } else { + /* Beginning of display line */ + x = chunkPtr->stylePtr->sValuePtr->lMargin2; + } if (wrapMode == TEXT_WRAPMODE_NONE) { maxX = -1; } else { @@ -1302,7 +1335,7 @@ LayoutDLine(textPtr, indexPtr) } } chunkPtr->x = x; - if (elide && maxBytes) { + if (elide /*&& maxBytes*/) { /* * Don't free style here, as other code expects to be able to do * that. @@ -1349,6 +1382,16 @@ LayoutDLine(textPtr, indexPtr) } break; } + /* + * We currently say we have some characters (and therefore + * something from which to examine tag values for the first + * character of the line) even if those characters are actually + * elided. This behaviour is not well documented, and it might + * be more consistent to completely ignore such elided + * characters and their tags. To do so change this to: + * + * if (!elide && chunkPtr->numBytes > 0). + */ if (!elide && chunkPtr->numBytes > 0) { noCharsYet = 0; lastCharChunkPtr = chunkPtr; @@ -1382,7 +1425,8 @@ LayoutDLine(textPtr, indexPtr) x = chunkPtr->x + chunkPtr->width; } tabChunkPtr = chunkPtr; - tabSize = SizeOfTab(textPtr, tabArrayPtr, &tabIndex, x, maxX); + tabSize = SizeOfTab(textPtr, tabStyle, tabArrayPtr, + &tabIndex, x, maxX); if ((maxX >= 0) && (tabSize >= maxX - x)) { break; } @@ -6588,15 +6632,15 @@ DlineXOfIndex(textPtr, dlPtr, byteIndex) /* *---------------------------------------------------------------------- * - * TkTextCharBbox -- + * TkTextIndexBbox -- * * Given an index, find the bounding box of the screen area occupied by - * that character. + * the entity (character, window, image) at that index. * * Results: - * Zero is returned if the character is on the screen. -1 means the - * character isn't on the screen. If the return value is 0, then the - * bounding box of the part of the character that's visible on the screen + * Zero is returned if the index is on the screen. -1 means the + * index isn't on the screen. If the return value is 0, then the + * bounding box of the part of the index that's visible on the screen * is returned to *xPtr, *yPtr, *widthPtr, and *heightPtr. * * Side effects: @@ -6606,17 +6650,17 @@ DlineXOfIndex(textPtr, dlPtr, byteIndex) */ int -TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, charWidthPtr) +TkTextIndexBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, charWidthPtr) TkText *textPtr; /* Widget record for text widget. */ - CONST TkTextIndex *indexPtr;/* Index of character whose bounding box is - * desired. */ - int *xPtr, *yPtr; /* Filled with character's upper-left + CONST TkTextIndex *indexPtr;/* Index whose bounding box is desired. */ + int *xPtr, *yPtr; /* Filled with index's upper-left * coordinate. */ - int *widthPtr, *heightPtr; /* Filled in with character's dimensions. */ - int *charWidthPtr; /* If the 'character' isn't really a character - * (e.g. end of a line) and therefore takes up - * a very large width, this is used to return - * a smaller width */ + int *widthPtr, *heightPtr; /* Filled in with index's dimensions. */ + int *charWidthPtr; /* If the 'index' is at the end of + * a display line and therefore takes + * up a very large width, this is + * used to return the smaller width + * actually desired by the index. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; DLine *dlPtr; @@ -6686,8 +6730,19 @@ TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, charWidthPtr) *charWidthPtr = *widthPtr; } } - if ((*xPtr + *widthPtr) <= dInfoPtr->x) { - return -1; + if (*widthPtr == 0) { + /* + * With zero width (e.g. elided text) we just need to + * make sure it is onscreen, where the '=' case here is + * ok. + */ + if (*xPtr < dInfoPtr->x) { + return -1; + } + } else { + if ((*xPtr + *widthPtr) <= dInfoPtr->x) { + return -1; + } } if ((*xPtr + *widthPtr) > dInfoPtr->maxX) { *widthPtr = dInfoPtr->maxX - *xPtr; @@ -7248,19 +7303,31 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr) return; } + x = chunkPtr->nextPtr->x; + /* - * If no tab information has been given, do the usual thing: round up to - * the next boundary of 8 average-sized characters. + * If no tab information has been given, assuming tab stops are + * at 8 average-sized characters. Still ensure we respect the + * tabular versus wordprocessor tab style. */ - x = chunkPtr->nextPtr->x; if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) { /* * No tab information has been given, so use the default * interpretation of tabs. */ - desired = NextTabStop(textPtr->tkfont, x, 0); + if (textPtr->tabStyle == TK_TEXT_TABSTYLE_TABULAR) { + int tabWidth = Tk_TextWidth(textPtr->tkfont, "0", 1) * 8; + if (tabWidth == 0) { + tabWidth = 1; + } + + desired = tabWidth * (index + 1); + } else { + desired = NextTabStop(textPtr->tkfont, x, 0); + } + goto update; } @@ -7399,9 +7466,11 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr) */ static int -SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX) +SizeOfTab(textPtr, tabStyle, tabArrayPtr, indexPtr, x, maxX) TkText *textPtr; /* Information about the text widget as a * whole. */ + int tabStyle; /* One of TK_TEXT_TABSTYLE_TABULAR + * or TK_TEXT_TABSTYLE_WORDPROCESSOR. */ TkTextTabArray *tabArrayPtr;/* Information about the tab stops that apply * to this line. NULL means use default * tabbing (every 8 chars.) */ @@ -7412,29 +7481,33 @@ SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX) int maxX; /* X-location of pixel just past the right * edge of the line. */ { - int tabX, result, index, spaceWidth; + int tabX, result, index, spaceWidth, tabWidth; TkTextTabAlign alignment; index = *indexPtr; if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) { - tabX = NextTabStop(textPtr->tkfont, x, 0); - - /* - * We used up one tab stop. - */ - - *indexPtr = index+1; - return tabX - x; + /* We're using a default tab spacing of 8 characters */ + tabWidth = Tk_TextWidth(textPtr->tkfont, "0", 1) * 8; + if (tabWidth == 0) { + tabWidth = 1; + } + } else { + tabWidth = 0; /* Avoid compiler error */ } - + do { /* * We were given the count before this tab, so increment it first. */ index++; - if (index < tabArrayPtr->numTabs) { + + if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) { + /* We're using a default tab spacing calculated above */ + tabX = tabWidth * (index + 1); + alignment = LEFT; + } else if (index < tabArrayPtr->numTabs) { tabX = tabArrayPtr->tabs[index].location; alignment = tabArrayPtr->tabs[index].alignment; } else { @@ -7449,10 +7522,16 @@ SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX) } /* - * If this tab stop is before the current x position, then we must - * obviously continue until we reach the text tab stop. + * If this tab stop is before the current x position, then we + * have two cases: + * + * With 'wordprocessor' style tabs, we must obviously continue + * until we reach the text tab stop. + * + * With 'tabular' style tabs, we always use the index'th tab + * stop. */ - } while (tabX < x); + } while (tabX < x && (tabStyle == TK_TEXT_TABSTYLE_WORDPROCESSOR)); /* * Inform our caller of how many tab stops we've used up. @@ -7506,7 +7585,8 @@ SizeOfTab(textPtr, tabArrayPtr, indexPtr, x, maxX) * Given the current position, determine where the next default tab stop * would be located. This function is called when the current chunk in * the text has no tabs defined and so the default tab spacing for the - * font should be used. + * font should be used, provided we are using wordprocessor + * style tabs. * * Results: * The location in pixels of the next tab stop. @@ -7733,11 +7813,3 @@ TextGetScrollInfoObj(interp, textPtr, objc, objv, dblPtr, intPtr) "\": must be moveto or scroll", (char *) NULL); return TKTEXT_SCROLL_ERROR; } - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/generic/tkTextImage.c b/generic/tkTextImage.c index fa95e3c..767fef9 100644 --- a/generic/tkTextImage.c +++ b/generic/tkTextImage.c @@ -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: tkTextImage.c,v 1.15 2005/08/10 22:02:22 dkf Exp $ + * RCS: @(#) $Id: tkTextImage.c,v 1.16 2005/10/10 10:36:35 vincentdarley Exp $ */ #include "tk.h" @@ -268,7 +268,7 @@ TkTextImageCmd(textPtr, interp, objc, objv) TkTextIndex index2; TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES); - TkBTreeDeleteChars(textPtr->sharedTextPtr->tree, &index, &index2); + TkBTreeDeleteIndexRange(textPtr->sharedTextPtr->tree, &index, &index2); return TCL_ERROR; } TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL, @@ -834,11 +834,3 @@ EmbImageProc(clientData, x, y, width, height, imgWidth, imgHeight) TkTextInvalidateLineMetrics(eiPtr->body.ei.sharedTextPtr, NULL, index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY); } - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index 127b397..c9ddab3 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -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: tkTextIndex.c,v 1.22 2005/08/10 22:02:22 dkf Exp $ + * RCS: @(#) $Id: tkTextIndex.c,v 1.23 2005/10/10 10:36:35 vincentdarley Exp $ */ #include "default.h" @@ -2303,11 +2303,3 @@ StartEnd(textPtr, string, indexPtr) done: return p; } - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c index 0c56b4a..4354ede 100644 --- a/generic/tkTextMark.c +++ b/generic/tkTextMark.c @@ -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: tkTextMark.c,v 1.14 2005/07/18 22:12:05 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextMark.c,v 1.15 2005/10/10 10:36:35 vincentdarley Exp $ */ #include "tkInt.h" @@ -595,7 +595,7 @@ TkTextInsertDisplayProc(textPtr, chunkPtr, x, y, height, baseline, display, if(textPtr->insertCursorType) { TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); - TkTextCharBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth); + TkTextIndexBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth); rightSideWidth = charWidth + halfWidth; } else { rightSideWidth = halfWidth; diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index 00d350a..540c0af 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.20 2005/08/10 22:02:22 dkf Exp $ + * RCS: @(#) $Id: tkTextTag.c,v 1.21 2005/10/10 10:36:35 vincentdarley Exp $ */ #include "default.h" @@ -30,6 +30,17 @@ static char *wrapStrings[] = { "char", "none", "word", "", (char *) NULL }; +/* + * The 'TkTextTabStyle' enum in tkText.h is used to define a type for + * the -tabstyle option of the Text widget. These values are used as + * indices into the string table below. Tags are allowed an empty wrap + * value, but the widget as a whole is not. + */ + +static char *tabStyleStrings[] = { + "tabular", "wordprocessor", "", (char *) NULL +}; + static Tk_OptionSpec tagOptionSpecs[] = { {TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL, NULL, -1, Tk_Offset(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0}, @@ -70,6 +81,9 @@ static Tk_OptionSpec tagOptionSpecs[] = { NULL, -1, Tk_Offset(TkTextTag, spacing3String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-tabs", (char *) NULL, (char *) NULL, NULL, Tk_Offset(TkTextTag, tabStringPtr), -1, TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING_TABLE, "-tabstyle", (char *) NULL, (char *) NULL, + (char *) NULL, -1, Tk_Offset(TkTextTag, tabStyle), + TK_OPTION_NULL_OK, (ClientData) tabStyleStrings, 0}, {TK_OPTION_STRING, "-underline", (char *) NULL, (char *) NULL, (char *) NULL, -1, Tk_Offset(TkTextTag, underlineString), TK_OPTION_NULL_OK, 0, 0}, @@ -483,6 +497,7 @@ TkTextTagCmd(textPtr, interp, objc, objv) || (tagPtr->spacing2String != NULL) || (tagPtr->spacing3String != NULL) || (tagPtr->tabStringPtr != NULL) + || (tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE) || (tagPtr->wrapMode != TEXT_WRAPMODE_NULL)) { tagPtr->affectsDisplay = 1; tagPtr->affectsDisplayGeometry = 1; @@ -996,6 +1011,7 @@ TkTextCreateTag(textPtr, tagName, newTag) tagPtr->spacing3 = 0; tagPtr->tabStringPtr = NULL; tagPtr->tabArrayPtr = NULL; + tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE; tagPtr->underlineString = NULL; tagPtr->underline = 0; tagPtr->elideString = NULL; @@ -1723,11 +1739,3 @@ TagBindEvent(textPtr, eventPtr, numTags, tagArrayPtr) ckfree((char*)nameArrPtr); } } - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c index 95dcf03..07c4a26 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.14 2004/10/05 01:26:10 hobbs Exp $ + * RCS: @(#) $Id: tkTextWind.c,v 1.15 2005/10/10 10:36:35 vincentdarley Exp $ */ #include "tk.h" @@ -331,7 +331,7 @@ TkTextWindowCmd(textPtr, interp, objc, objv) TkTextIndex index2; TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES); - TkBTreeDeleteChars(textPtr->sharedTextPtr->tree, &index, &index2); + TkBTreeDeleteIndexRange(textPtr->sharedTextPtr->tree, &index, &index2); return TCL_ERROR; } TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL, diff --git a/macosx/tkMacOSXDefault.h b/macosx/tkMacOSXDefault.h index e27e510..14eb937 100644 --- a/macosx/tkMacOSXDefault.h +++ b/macosx/tkMacOSXDefault.h @@ -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: tkMacOSXDefault.h,v 1.8 2005/06/23 20:17:57 das Exp $ + * RCS: @(#) $Id: tkMacOSXDefault.h,v 1.9 2005/10/10 10:36:35 vincentdarley Exp $ */ #ifndef _TKMACDEFAULT @@ -524,6 +524,7 @@ #define DEF_TEXT_SPACING3 "0" #define DEF_TEXT_STATE "normal" #define DEF_TEXT_TABS "" +#define DEF_TEXT_TABSTYLE "tabular" #define DEF_TEXT_TAKE_FOCUS (char *) NULL #define DEF_TEXT_UNDO "0" #define DEF_TEXT_WIDTH "80" diff --git a/tests/text.test b/tests/text.test index e25e71b..17c9488 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.39 2005/08/23 23:04:42 dkf Exp $ +# RCS: @(#) $Id: text.test,v 1.40 2005/10/10 10:36:35 vincentdarley Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -86,6 +86,7 @@ foreach test { {-spacing3 -10 0 bogus} {-state d disabled foo} {-tabs {1i 2i 3i 4i} {1i 2i 3i 4i} bad_tabs} + {-tabstyle wordprocessor wordprocessor garbage} {-undo 1 1 eh} {-width 73 73 2.4} {-wrap w word bad_wrap} @@ -115,7 +116,7 @@ test text-1.[incr i] {text options} { lappend result [lindex $i 4] } set result -} {1 blue {} {} 0 7 watch {} 0 {} fixed #012 5 #123 #234 0 #ffff01234567 green 45 100 47 2 5 3 82 raised #ffff01234567 21 yellow 0 0 0 0 {} disabled {1i 2i 3i 4i} {any old thing} 1 73 word {x scroll command} {test command}} +} {1 blue {} {} 0 7 watch {} 0 {} fixed #012 5 #123 #234 0 #ffff01234567 green 45 100 47 2 5 3 82 raised #ffff01234567 21 yellow 0 0 0 0 {} disabled {1i 2i 3i 4i} wordprocessor {any old thing} 1 73 word {x scroll command} {test command}} test text-2.1 {Tk_TextCmd procedure} { list [catch {text} msg] $msg @@ -1805,6 +1806,13 @@ test text-20.78.5 {TextSearchCmd, hidden text inside match must count in length} list [.t2 search -strict -all -count foo foar 1.3] $foo } {{2.0 3.0} {6 4}} +test text-20.78.6 {TextSearchCmd, single line with -all} { + deleteWindows + pack [text .t2] + .t2 insert end " X\n X\n X\n X\n X\n X\n" + .t2 search -all -regexp { +| *\n} 1.0 end +} {1.0 1.2 2.0 2.2 3.0 3.2 4.0 4.2 5.0 5.2 6.0 6.2 7.0} + test text-20.79 {TextSearchCmd, multiline matching} { deleteWindows pack [text .t2] @@ -2828,6 +2836,61 @@ test text-20.185 {TextSearchCmd, elide up to match} { lappend res [.t2 search -regexp c 1.0] } {{} {} 1.0 2.1 2.0 3.1 2.0 3.0} +test text-20.186 {TextSearchCmd, strict limits} { + deleteWindows + pack [text .t2] + .t2 insert 1.0 "Hello world!\nThis is a test\n" + .t2 search -strictlimits -- "world" 1.3 1.8 +} {} + +test text-20.187 {TextSearchCmd, strict limits} { + deleteWindows + pack [text .t2] + .t2 insert 1.0 "Hello world!\nThis is a test\n" + .t2 search -strictlimits -- "world" 1.3 1.10 +} {} + +test text-20.188 {TextSearchCmd, strict limits} { + deleteWindows + pack [text .t2] + .t2 insert 1.0 "Hello world!\nThis is a test\n" + .t2 search -strictlimits -- "world" 1.3 1.11 +} {1.6} + +test text-20.1189 {TextSearchCmd, strict limits backwards} { + deleteWindows + pack [text .t2] + .t2 insert 1.0 "Hello world!\nThis is a test\n" + .t2 search -strictlimits -backward -- "world" 2.3 1.8 +} {} + +test text-20.190 {TextSearchCmd, strict limits backwards} { + deleteWindows + pack [text .t2] + .t2 insert 1.0 "Hello world!\nThis is a test\n" + .t2 search -strictlimits -backward -- "world" 2.3 1.6 +} {1.6} + +test text-20.191 {TextSearchCmd, strict limits backwards} { + deleteWindows + pack [text .t2] + .t2 insert 1.0 "Hello world!\nThis is a test\n" + .t2 search -strictlimits -backward -- "world" 2.3 1.7 +} {} + +test text-20.188 {TextSearchCmd, strict limits} { + deleteWindows + pack [text .t2] + .t2 insert 1.0 "Hello world!\nThis is a test\n" + .t2 search -regexp -strictlimits -- "world" 1.3 1.8 +} {} + +test text-20.189 {TextSearchCmd, strict limits} { + deleteWindows + pack [text .t2] + .t2 insert 1.0 "Hello world!\nThis is a test\n" + .t2 search -regexp -strictlimits -backward -- "world" 2.3 1.8 +} {} deleteWindows text .t2 -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100 diff --git a/tests/textDisp.test b/tests/textDisp.test index 365dd8d..cd52fe0 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.37 2005/05/10 22:26:16 dgp Exp $ +# RCS: @(#) $Id: textDisp.test,v 1.38 2005/10/10 10:36:35 vincentdarley Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -2992,6 +2992,15 @@ test textDisp-26.1 {AdjustForTab procedure, no tabs} {textfonts} { .t insert 1.0 a\tbcdefghij\tc\td list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.12] 0] \ [lindex [.t bbox 1.14] 0] +} [list 56 126 168] +test textDisp-26.1.2 {AdjustForTab procedure, no tabs} {textfonts} { + .t delete 1.0 end + .t insert 1.0 a\tbcdefghij\tc\td + .t configure -tabstyle wordprocessor + set res [list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.12] 0] \ + [lindex [.t bbox 1.14] 0]] + .t configure -tabstyle tabular + set res } [list 56 168 224] test textDisp-26.2 {AdjustForTab procedure, not enough tabs specified} { .t delete 1.0 end @@ -3111,6 +3120,17 @@ test textDisp-26.13 {AdjustForTab procedure, not enough space} {textfonts} { .t tag add x 1.0 end list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \ [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0] +} [list 28 56 84 120] +test textDisp-26.13.2 {AdjustForTab procedure, not enough space} {textfonts} { + .t delete 1.0 end + .t insert 1.0 "abc\txyz\tqrs\txyz\t0" + .t tag delete x + .t tag configure x -tabs {10 30 center 50 right 120} -tabstyle wordprocessor + .t tag add x 1.0 end + set res [list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \ + [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0]] + .t tag configure x -tabstyle tabular + set res } [list 28 56 120 190] test textDisp-26.14 {AdjustForTab procedure, not enough space} {textfonts} { .t delete 1.0 end @@ -3120,6 +3140,18 @@ test textDisp-26.14 {AdjustForTab procedure, not enough space} {textfonts} { .t insert end "Watch the \tX and the \t\t\tY\n" moop list [lindex [.t bbox 2.11] 0] [lindex [.t bbox 2.24] 0] \ [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0] +} [list 77 224 77 224] +test textDisp-26.14.2 {AdjustForTab procedure, not enough space} {textfonts} { + .t delete 1.0 end + .t configure -tabstyle wordprocessor + .t insert end "a \tb \tc \td \te \tf \tg\n" + .t insert end "Watch the \tX and the \t\t\tY\n" + .t tag configure moop -tabs [expr {8*$fixedWidth}] + .t insert end "Watch the \tX and the \t\t\tY\n" moop + set res [list [lindex [.t bbox 2.11] 0] [lindex [.t bbox 2.24] 0] \ + [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0]] + .t configure -tabstyle tabular + set res } [list 112 56 112 56] .t configure -width 20 -bd 2 -highlightthickness 2 -relief sunken -tabs {} \ @@ -3129,6 +3161,14 @@ test textDisp-27.1 {SizeOfTab procedure, old-style tabs} {textfonts} { .t delete 1.0 end .t insert 1.0 a\tbcdefghij\tc\td list [.t bbox 1.2] [.t bbox 1.10] [.t bbox 1.12] +} [list [list 60 5 7 $fixedHeight] [list 116 5 7 $fixedHeight] [list 130 5 7 $fixedHeight]] +test textDisp-27.1.1 {SizeOfTab procedure, old-style tabs} {textfonts} { + .t delete 1.0 end + .t insert 1.0 a\tbcdefghij\tc\td + .t configure -tabstyle wordprocessor + set res [list [.t bbox 1.2] [.t bbox 1.10] [.t bbox 1.12]] + .t configure -tabstyle tabular + set res } [list [list 60 5 7 $fixedHeight] [list 116 5 7 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]] test textDisp-27.2 {SizeOfTab procedure, choosing tabX and alignment} {textfonts} { .t delete 1.0 end @@ -3189,8 +3229,30 @@ test textDisp-27.7 {SizeOfTab procedure, center alignment, wrap -none (potential set res [.t bbox 2.23] lset res 0 [expr {[lindex $res 0] - $tab}] set res +} [list -28 [expr {$fixedDiff + 18}] 7 $fixedHeight] +test textDisp-27.7.1 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {textfonts} { + .t delete 1.0 end + .t configure -tabstyle wordprocessor + set cm [winfo fpixels .t 1c] + .t configure -tabs {1c 2c center 3c 4c 5c 6c 7c 8c} -wrap none -width 40 + .t insert 1.0 a\tb\tc\td\te\n012345678934567890a\tbb\tcc\tdd + set width [expr {$fixedWidth * 19}] + set tab $cm + while {$tab < $width} { + set tab [expr {$tab + $cm}] + } + # Now we've calculated to the end of the tab after 'a', add one + # more for 'bb\t' and we're there, with 4 for the border. Since + # Tk_GetPixelsFromObj uses the standard 'int(0.5 + float)' rounding, + # so must we. + set tab [expr {4 + int(0.5 + $tab + $cm)}] + update + set res [.t bbox 2.23] + .t configure -tabstyle tabular + lset res 0 [expr {[lindex $res 0] - $tab}] + set res } [list 0 [expr {$fixedDiff + 18}] 7 $fixedHeight] -test textDisp-27.7.1 {SizeOfTab procedure, fractional tab interpolation problem} { +test textDisp-27.7.2 {SizeOfTab procedure, fractional tab interpolation problem} { .t delete 1.0 end set interpolatetab {1c 2c} set precisetab {} @@ -3571,6 +3633,88 @@ test textDisp-32.1 {everything elided} { destroy .tt } {} +test textDisp-32.2 {elide and tags} { + pack [text .tt -height 30 -width 100 -bd 0 \ + -highlightthickness 0 -padx 0] + .tt insert end \ + {test text using tags 1 and 3 } \ + {testtag1 testtag3} \ + {[this bit here uses tags 2 and 3]} \ + {testtag2 testtag3} + update + # indent left margin of tag 1 by 20 pixels + # text should be indented + .tt tag configure testtag1 -lmargin1 20 ; update + #1 + set res {} + lappend res [list [.tt index "1.0 + 0 displaychars"] \ + [lindex [.tt bbox 1.0] 0] \ + [lindex [.tt bbox "1.0 + 0 displaychars"] 0]] + + # hide tag 1, remaining text should not be indented, since + # the indented tag and character is hidden. + .tt tag configure testtag1 -elide 1 ; update + #2 + lappend res [list [.tt index "1.0 + 0 displaychars"] \ + [lindex [.tt bbox 1.0] 0] \ + [lindex [.tt bbox "1.0 + 0 displaychars"] 0]] + + # reset + .tt tag configure testtag1 -lmargin1 0 + .tt tag configure testtag1 -elide 0 + + # indent left margin of tag 2 by 20 pixels + # text should not be indented, since tag1 has lmargin1 of 0. + .tt tag configure testtag2 -lmargin1 20 ; update + #3 + lappend res [list [.tt index "1.0 + 0 displaychars"] \ + [lindex [.tt bbox 1.0] 0] \ + [lindex [.tt bbox "1.0 + 0 displaychars"] 0]] + + # hide tag 1, remaining text should now be indented, but + # the bbox of 1.0 should have zero width and zero indent, + # since it is elided at that position. + .tt tag configure testtag1 -elide 1 ; update + #4 + lappend res [list [.tt index "1.0 + 0 displaychars"] \ + [lindex [.tt bbox 1.0] 0] \ + [lindex [.tt bbox "1.0 + 0 displaychars"] 0]] + + # reset + .tt tag configure testtag2 -lmargin1 {} + .tt tag configure testtag1 -elide 0 + + # indent left margin of tag 3 by 20 pixels + # text should be indented, since this tag takes + # precedence over testtag1, and is applied to the + # start of the text. + .tt tag configure testtag3 -lmargin1 20 ; update + #5 + lappend res [list [.tt index "1.0 + 0 displaychars"] \ + [lindex [.tt bbox 1.0] 0] \ + [lindex [.tt bbox "1.0 + 0 displaychars"] 0]] + + # hide tag 1, remaining text should still be indented, + # since it still has testtag3 on it. Again the + # bbox of 1.0 should have 0. + .tt tag configure testtag1 -elide 1 ; update + #6 + lappend res [list [.tt index "1.0 + 0 displaychars"] \ + [lindex [.tt bbox 1.0] 0] \ + [lindex [.tt bbox "1.0 + 0 displaychars"] 0]] + + .tt tag configure testtag3 -lmargin1 {} -elide 0 + .tt tag configure testtag1 -elide 1 -lmargin1 20 + #7 + lappend res [list [.tt index "1.0 + 0 displaychars"] \ + [lindex [.tt bbox 1.0] 0] \ + [lindex [.tt bbox "1.0 + 0 displaychars"] 0]] + + destroy .tt + set res +} {{1.0 20 20} {1.29 0 0} {1.0 0 0} {1.29 0 20}\ + {1.0 20 20} {1.29 0 20} {1.0 20 20}} + test textDisp-33.0 {one line longer than fits in the widget} { pack [text .tt -wrap char] .tt insert 1.0 [string repeat "more wrap + " 300] diff --git a/unix/tkUnixDefault.h b/unix/tkUnixDefault.h index bfea82b..d47bb0e 100644 --- a/unix/tkUnixDefault.h +++ b/unix/tkUnixDefault.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: tkUnixDefault.h,v 1.21 2004/10/24 17:22:55 dkf Exp $ + * RCS: @(#) $Id: tkUnixDefault.h,v 1.22 2005/10/10 10:36:35 vincentdarley Exp $ */ #ifndef _TKUNIXDEFAULT @@ -515,6 +515,7 @@ #define DEF_TEXT_SPACING3 "0" #define DEF_TEXT_STATE "normal" #define DEF_TEXT_TABS "" +#define DEF_TEXT_TABSTYLE "tabular" #define DEF_TEXT_TAKE_FOCUS (char *) NULL #define DEF_TEXT_UNDO "0" #define DEF_TEXT_WIDTH "80" diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h index 56ee831..3f30f5f 100644 --- a/win/tkWinDefault.h +++ b/win/tkWinDefault.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: tkWinDefault.h,v 1.19 2004/10/24 17:22:55 dkf Exp $ + * RCS: @(#) $Id: tkWinDefault.h,v 1.20 2005/10/10 10:36:35 vincentdarley Exp $ */ #ifndef _TKWINDEFAULT @@ -502,6 +502,7 @@ #define DEF_TEXT_SPACING3 "0" #define DEF_TEXT_STATE "normal" #define DEF_TEXT_TABS "" +#define DEF_TEXT_TABSTYLE "tabular" #define DEF_TEXT_TAKE_FOCUS (char *) NULL #define DEF_TEXT_UNDO "0" #define DEF_TEXT_WIDTH "80" |