Index: doc/entry.n ================================================================== --- doc/entry.n +++ doc/entry.n @@ -13,19 +13,19 @@ .SH NAME entry \- Create and manipulate 'entry' one-line text entry widgets .SH SYNOPSIS \fBentry\fI pathName \fR?\fIoptions\fR? .SO -\-background \-highlightthickness \-selectbackground -\-borderwidth \-insertbackground \-selectborderwidth -\-cursor \-insertborderwidth \-selectforeground -\-exportselection \-insertofftime \-takefocus -\-font \-insertontime \-textvariable -\-foreground \-insertwidth \-xscrollcommand -\-highlightbackground \-justify -\-highlightcolor \-relief -\-placeholder \-placeholderforeground +\-background \-insertbackground \-relief +\-borderwidth \-insertborderwidth \-selectbackground +\-cursor \-insertofftime \-selectborderwidth +\-exportselection \-insertontime \-selectforeground +\-font \-insertwidth \-takefocus +\-foreground \-justify \-textvariable +\-highlightbackground \-locale \-xscrollcommand +\-highlightcolor \-placeholder +\-highlightthickness \-placeholderforeground .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-disabledbackground disabledBackground DisabledBackground Specifies the background color to use when the entry is disabled. If this option is the empty string, the normal background color is used. Index: doc/spinbox.n ================================================================== --- doc/spinbox.n +++ doc/spinbox.n @@ -12,20 +12,20 @@ .SH NAME spinbox \- Create and manipulate 'spinbox' value spinner widgets .SH SYNOPSIS \fBspinbox\fI pathName \fR?\fIoptions\fR? .SO -\-activebackground \-highlightthickness \-repeatinterval -\-background \-insertbackground \-selectbackground -\-borderwidth \-insertborderwidth \-selectborderwidth -\-cursor \-insertontime \-selectforeground -\-exportselection \-insertwidth \-takefocus -\-font \-insertofftime \-textvariable -\-foreground \-justify \-xscrollcommand -\-highlightbackground \-relief -\-highlightcolor \-repeatdelay -\-placeholder \-placeholderforeground +\-activebackground \-insertbackground \-repeatdelay +\-background \-insertborderwidth \-repeatinterval +\-borderwidth \-insertontime \-selectbackground +\-cursor \-insertwidth \-selectborderwidth +\-exportselection \-insertofftime \-selectforeground +\-font \-justify \-takefocus +\-foreground \-locale \-textvariable +\-highlightbackground \-placeholder \-xscrollcommand +\-highlightcolor \-placeholderforeground +\-highlightthickness \-relief .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-buttonbackground buttonBackground Background The background color to be used for the spin buttons. .OP \-buttoncursor buttonCursor Cursor Index: doc/text.n ================================================================== --- doc/text.n +++ doc/text.n @@ -506,10 +506,18 @@ \fB\-lmargin2\fR. It may have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not been specified, or if it is specified as an empty string, then the color used is specified by the \fB\-background\fR tag option (or, if this is also unspecified, by the \fB\-background\fR widget option). +.\" OPTION: -locale +.TP +\fB\-locale \fIlocale\fR +. +The locale which is used for determining word and character +boundaries within the text. The special value \fIregexp\fR can +be used to select a locale-independent algorithm, based on the +presence of (Unicode) word characters only. .\" OPTION: -offset .TP \fB\-offset \fIpixels\fR . \fIPixels\fR specifies an amount by which the text's baseline should be offset @@ -1477,10 +1485,15 @@ of the tags present around the insertion point. If multiple \fIchars\fR\-\fItagList\fR argument pairs are present, they produce the same effect as if a separate \fIpathName \fBinsert\fR widget command had been issued for each pair, in order. The last \fItagList\fR argument may be omitted. +.\" METHOD: locale +.TP +\fIpathName \fBlocale \fIindex\fR +. +Returns the locale belonging to this \fIindex\fR. .\" METHOD: mark .TP \fIpathName \fBmark \fIoption \fR?\fIarg ...\fR? . This command is used to manipulate marks. The exact behavior of the command Index: doc/ttk_combobox.n ================================================================== --- doc/ttk_combobox.n +++ doc/ttk_combobox.n @@ -27,10 +27,12 @@ Boolean value. If set, the widget selection is linked to the X selection. .OP \-justify justify Justify Specifies how the text is aligned within the widget. Must be one of \fBleft\fR, \fBcenter\fR, or \fBright\fR. +.OP \-locale locale Locale +Specifies which locale is used for determining character or word boundaries. .OP \-height height Height Specifies the height of the pop-down listbox, in rows. .OP \-postcommand postCommand PostCommand A Tcl script to evaluate immediately before displaying the listbox. The \fB\-postcommand\fR script may specify the \fB\-values\fR to display. Index: doc/ttk_entry.n ================================================================== --- doc/ttk_entry.n +++ doc/ttk_entry.n @@ -45,10 +45,12 @@ Specifies how the text is aligned within the entry widget. One of \fBleft\fR, \fBcenter\fR, or \fBright\fR. .\" MAYBE: .OP \-selectbackground selectBackground Foreground .\" MAYBE: .OP \-selectborderwidth selectBorderWidth BorderWidth .\" MAYBE: .OP \-selectforeground selectForeground Background +.OP \-locale locale Locale +Specifies which locale is used for determining character or word boundaries. .OP \-show show Show If this option is specified, then the true contents of the entry are not displayed in the window. Instead, each character in the entry's value will be displayed as the first character in the value of this option, such as Index: doc/ttk_widget.n ================================================================== --- doc/ttk_widget.n +++ doc/ttk_widget.n @@ -115,10 +115,12 @@ .OP \-justify justify Justify If there are multiple lines of text, specifies how the lines are laid out relative to one another. One of \fBleft\fR, \fBcenter\fR, or \fBright\fR. See also \fB\-anchor\fR (for widgets supporting this option). +.OP \-locale locale Locale +Specifies which locale is used for determining character or word boundaries. .OP \-padding padding Padding Specifies the internal padding for the widget. The padding is a list of up to four length specifications \fIleft top right bottom\fR. If fewer than four elements are specified, Index: generic/tkEntry.c ================================================================== --- generic/tkEntry.c +++ generic/tkEntry.c @@ -120,10 +120,13 @@ TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), TK_OPTION_ENUM_VAR, 0, 0}, + {TK_OPTION_STRING, "-locale", "locale", "Locale", + NULL, offsetof(Entry, localeObj), TCL_INDEX_NONE, + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder", DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground", "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE, @@ -266,10 +269,13 @@ TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), TK_OPTION_ENUM_VAR, 0, 0}, + {TK_OPTION_STRING, "-locale", "locale", "Locale", + NULL, offsetof(Entry, localeObj), TCL_INDEX_NONE, + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder", DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground", "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE, Index: generic/tkEntry.h ================================================================== --- generic/tkEntry.h +++ generic/tkEntry.h @@ -184,10 +184,11 @@ char *validateCmd; /* Command prefix to use when invoking * validate command. NULL means don't invoke * commands. Malloc'ed. */ char *invalidCmd; /* Command called when a validation returns 0 * (successfully fails), defaults to {}. */ + Tcl_Obj *localeObj; /* locale, defaults to {}. */ } Entry; /* * A data structure of the following type is kept for each spinbox widget * managed by this file: Index: generic/tkIcu.c ================================================================== --- generic/tkIcu.c +++ generic/tkIcu.c @@ -58,10 +58,29 @@ #define icu_previous icu_fns.previous #define icu_next icu_fns.next #define icu_setText icu_fns.setText TCL_DECLARE_MUTEX(icu_mutex); + +const char *compatFunctions[] = { + NULL, + "tcl_startOfPreviousWord", + NULL, + NULL, + NULL, + "tcl_startOfNextWord", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "tcl_endOfWord", + NULL, + NULL, +}; static int startEndOfCmd( void *clientData, Tcl_Interp *interp, @@ -83,10 +102,19 @@ return TCL_ERROR; } if (objc > 3) { locale = Tcl_GetString(objv[3]); if (!*locale) { + locale = NULL; + } else if (!strcmp(locale, "regexp")) { + if (compatFunctions[flags]) { + Tcl_Obj *args[3]; + args[0] = Tcl_NewStringObj(compatFunctions[flags], -1); + args[1] = objv[1]; + args[2] = objv[2]; + return Tcl_EvalObjv(interp, 3, args, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT); + } locale = NULL; } } Tcl_DStringInit(&ds); str = Tcl_GetStringFromObj(objv[1], &len); Index: generic/tkText.c ================================================================== --- generic/tkText.c +++ generic/tkText.c @@ -175,10 +175,13 @@ DEF_TEXT_INSERT_UNFOCUSSED, TCL_INDEX_NONE, offsetof(TkText, insertUnfocussed), TK_OPTION_ENUM_VAR, insertUnfocussedStrings, 0}, {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", DEF_TEXT_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(TkText, insertWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-locale", "locale", "Locale", + NULL, offsetof(TkText, localeObj), TCL_INDEX_NONE, + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo", DEF_TEXT_MAX_UNDO, TCL_INDEX_NONE, offsetof(TkText, maxUndo), TK_OPTION_DONT_SET_DEFAULT, 0, 0}, {TK_OPTION_PIXELS, "-padx", "padX", "Pad", DEF_TEXT_PADX, TCL_INDEX_NONE, offsetof(TkText, padX), 0, 0, @@ -682,18 +685,18 @@ int idx; static const char *const optionStrings[] = { "bbox", "cget", "compare", "configure", "count", "debug", "delete", "dlineinfo", "dump", "edit", "get", "image", "index", "insert", - "mark", "peer", "pendingsync", "replace", "scan", "search", + "locale", "mark", "peer", "pendingsync", "replace", "scan", "search", "see", "sync", "tag", "window", "xview", "yview", NULL }; enum options { TEXT_BBOX, TEXT_CGET, TEXT_COMPARE, TEXT_CONFIGURE, TEXT_COUNT, TEXT_DEBUG, TEXT_DELETE, TEXT_DLINEINFO, TEXT_DUMP, TEXT_EDIT, - TEXT_GET, TEXT_IMAGE, TEXT_INDEX, TEXT_INSERT, TEXT_MARK, - TEXT_PEER, TEXT_PENDINGSYNC, TEXT_REPLACE, TEXT_SCAN, + TEXT_GET, TEXT_IMAGE, TEXT_INDEX, TEXT_INSERT, TEXT_LOCALE, + TEXT_MARK, TEXT_PEER, TEXT_PENDINGSYNC, TEXT_REPLACE, TEXT_SCAN, TEXT_SEARCH, TEXT_SEE, TEXT_SYNC, TEXT_TAG, TEXT_WINDOW, TEXT_XVIEW, TEXT_YVIEW }; if (objc < 2) { @@ -1365,10 +1368,30 @@ } if (textPtr->state != TK_TEXT_STATE_DISABLED) { result = TextInsertCmd(NULL, textPtr, interp, objc-3, objv+3, indexPtr, 1); } + break; + } + case TEXT_LOCALE: { + Tcl_Obj *localeObj; + const TkTextIndex *indexPtr; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index"); + result = TCL_ERROR; + goto done; + } + indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); + if (indexPtr == NULL) { + result = TCL_ERROR; + goto done; + } + localeObj = TkTextIndexLocale(textPtr, indexPtr); + if (localeObj) { + Tcl_SetObjResult(interp, localeObj); + } break; } case TEXT_MARK: result = TkTextMarkCmd(textPtr, interp, objc, objv); break; Index: generic/tkText.h ================================================================== --- generic/tkText.h +++ generic/tkText.h @@ -476,10 +476,11 @@ * specifications. */ int affectsDisplayGeometry; /* Non-zero means that this tag affects the * size with which information is displayed on * the screen (so need to recalculate line * dimensions if tag changes). */ + Tcl_Obj *localeObj; /* locale */ } TkTextTag; #define TK_TAG_AFFECTS_DISPLAY 0x1 #define TK_TAG_UNDERLINE 0x2 #define TK_TAG_JUSTIFY 0x4 @@ -856,10 +857,11 @@ * statements. */ int autoSeparators; /* Non-zero means the separators will be * inserted automatically. */ Tcl_Obj *afterSyncCmd; /* Command to be executed when lines are up to * date */ + Tcl_Obj *localeObj; /* locale */ } TkText; /* * Flag values for TkText records: * @@ -1106,10 +1108,12 @@ XEvent *eventPtr); MODULE_SCOPE void TkTextSelectionEvent(TkText *textPtr); MODULE_SCOPE int TkTextIndexBbox(TkText *textPtr, const TkTextIndex *indexPtr, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr, int *charWidthPtr); +MODULE_SCOPE Tcl_Obj *TkTextIndexLocale(TkText *textPtr, + const TkTextIndex *indexPtr); MODULE_SCOPE int TkTextCharLayoutProc(TkText *textPtr, TkTextIndex *indexPtr, TkTextSegment *segPtr, Tcl_Size offset, int maxX, Tcl_Size maxChars, int noBreakYet, TkWrapMode wrapMode, TkTextDispChunk *chunkPtr); MODULE_SCOPE void TkTextCreateDInfo(TkText *textPtr); Index: generic/tkTextDisp.c ================================================================== --- generic/tkTextDisp.c +++ generic/tkTextDisp.c @@ -158,10 +158,11 @@ * text. */ int elide; /* Zero means draw text, otherwise not. */ TkWrapMode wrapMode; /* How to handle wrap-around for this tag. * One of TEXT_WRAPMODE_CHAR, * TEXT_WRAPMODE_NONE or TEXT_WRAPMODE_WORD.*/ + char locale[24]; } StyleValues; /* * The following structure extends the StyleValues structure above with * graphics contexts used to actually draw the characters. The entries in @@ -786,11 +787,11 @@ */ Tcl_Size borderPrio, borderWidthPrio, reliefPrio, bgStipplePrio; Tcl_Size fgPrio, fontPrio, fgStipplePrio; Tcl_Size underlinePrio, elidePrio, justifyPrio, offsetPrio; Tcl_Size lMargin1Prio, lMargin2Prio, rMarginPrio; - Tcl_Size lMarginColorPrio, rMarginColorPrio; + Tcl_Size lMarginColorPrio, rMarginColorPrio, localePrio; Tcl_Size spacing1Prio, spacing2Prio, spacing3Prio; Tcl_Size overstrikePrio, tabPrio, tabStylePrio, wrapPrio; /* * Find out what tags are present for the character, then compute a @@ -801,11 +802,11 @@ tagPtrs = TkBTreeGetTags(indexPtr, textPtr, &numTags); borderPrio = borderWidthPrio = reliefPrio = bgStipplePrio = -1; fgPrio = fontPrio = fgStipplePrio = -1; underlinePrio = elidePrio = justifyPrio = offsetPrio = -1; lMargin1Prio = lMargin2Prio = rMarginPrio = -1; - lMarginColorPrio = rMarginColorPrio = -1; + lMarginColorPrio = rMarginColorPrio = localePrio = -1; spacing1Prio = spacing2Prio = spacing3Prio = -1; overstrikePrio = tabPrio = tabStylePrio = wrapPrio = -1; memset(&styleValues, 0, sizeof(StyleValues)); styleValues.relief = TK_RELIEF_FLAT; styleValues.fgColor = textPtr->fgColor; @@ -818,10 +819,13 @@ styleValues.spacing3 = textPtr->spacing3; styleValues.tabArrayPtr = textPtr->tabArrayPtr; styleValues.tabStyle = textPtr->tabStyle; styleValues.wrapMode = textPtr->wrapMode; styleValues.elide = 0; + if (textPtr->localeObj) { + strncpy(styleValues.locale, Tcl_GetString(textPtr->localeObj), sizeof(styleValues.locale)-1); + } isSelected = 0; for (i = 0 ; i < numTags; i++) { if (textPtr->selTagPtr == tagPtrs[i]) { isSelected = 1; @@ -988,10 +992,15 @@ if ((tagPtr->wrapMode != TEXT_WRAPMODE_NULL) && (tagPtr->priority > wrapPrio)) { styleValues.wrapMode = tagPtr->wrapMode; wrapPrio = tagPtr->priority; } + if ((tagPtr->localeObj != NULL) + && (tagPtr->priority > localePrio)) { + strncpy(styleValues.locale, Tcl_GetString(tagPtr->localeObj), sizeof(styleValues.locale)-1); + localePrio = tagPtr->priority; + } } if (tagPtrs != NULL) { ckfree(tagPtrs); } @@ -7474,10 +7483,88 @@ } } return 0; } +/* + *---------------------------------------------------------------------- + * + * TkTextIndexLocale -- + * + * Given an index, find the locale of the screen area occupied by + * the entity (character, window, image) at that index. + * + * Results: + * *locale will be filled with the locale. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TkTextIndexLocale( + TkText *textPtr, /* Widget record for text widget. */ + const TkTextIndex *indexPtr)/* Index whose locale is desired. */ +{ + TextDInfo *dInfoPtr = textPtr->dInfoPtr; + DLine *dlPtr; + TkTextDispChunk *chunkPtr; + int byteCount; + + /* + * Make sure that all of the screen layout information is up to date. + */ + + if (dInfoPtr->flags & DINFO_OUT_OF_DATE) { + UpdateDisplayInfo(textPtr); + } + + /* + * Find the display line containing the desired index. + */ + + dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr); + + /* + * Two cases shall be trapped here because the logic later really + * needs dlPtr to be the display line containing indexPtr: + * 1. if no display line contains the desired index (NULL dlPtr) + * 2. if indexPtr is before the first display line, in which case + * dlPtr currently points to the first display line + */ + + if ((dlPtr == NULL) || (TkTextIndexCmp(&dlPtr->index, indexPtr) > 0)) { + return textPtr->localeObj; + } + + /* + * Find the chunk within the display line that contains the desired + * index. The chunks making the display line are skipped up to but not + * including the one crossing indexPtr. Skipping is done based on + * a byteCount offset possibly spanning several logical lines in case + * they are elided. + */ + + byteCount = TkTextIndexCountBytes(textPtr, &dlPtr->index, indexPtr); + for (chunkPtr = dlPtr->chunkPtr; ; chunkPtr = chunkPtr->nextPtr) { + if (chunkPtr == NULL) { + return textPtr->localeObj; + } + if (byteCount < chunkPtr->numBytes) { + break; + } + byteCount -= chunkPtr->numBytes; + } + + if (!chunkPtr->stylePtr->sValuePtr->locale[0]) { + return NULL; + } + return Tcl_NewStringObj(chunkPtr->stylePtr->sValuePtr->locale, TCL_INDEX_NONE); +} + /* *---------------------------------------------------------------------- * * TkTextDLineInfo -- * Index: generic/tkTextTag.c ================================================================== --- generic/tkTextTag.c +++ generic/tkTextTag.c @@ -39,10 +39,12 @@ NULL, offsetof(TkTextTag, lMargin1Obj), offsetof(TkTextTag, lMargin1), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_PIXELS, "-lmargin2", NULL, NULL, NULL, offsetof(TkTextTag, lMargin2Obj), offsetof(TkTextTag, lMargin2), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_BORDER, "-lmargincolor", NULL, NULL, NULL, TCL_INDEX_NONE, offsetof(TkTextTag, lMarginColor), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-locale", NULL, NULL, + NULL, offsetof(TkTextTag, localeObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_PIXELS, "-offset", NULL, NULL, NULL, offsetof(TkTextTag, offsetObj), offsetof(TkTextTag, offset), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BOOLEAN, "-overstrike", NULL, NULL, NULL, TCL_INDEX_NONE, offsetof(TkTextTag, overstrike), TK_OPTION_NULL_OK, 0, 0}, @@ -975,10 +977,11 @@ tagPtr->elide = -1; tagPtr->wrapMode = TEXT_WRAPMODE_NULL; tagPtr->affectsDisplay = 0; tagPtr->affectsDisplayGeometry = 0; textPtr->sharedTextPtr->numTags++; + tagPtr->localeObj = NULL; if (!strcmp(tagName, "sel")) { tagPtr->textPtr = textPtr; textPtr->refCount++; } else { CLANG_ASSERT(hPtr); Index: generic/ttk/ttkEntry.c ================================================================== --- generic/ttk/ttkEntry.c +++ generic/ttk/ttkEntry.c @@ -119,10 +119,12 @@ Tcl_Obj *stateObj; /* Compatibility option -- see CheckStateObj */ Tcl_Obj *placeholderObj; /* Text to display for placeholder text */ + Tcl_Obj *localeObj; /* locale */ + /* * Derived resources: */ Ttk_TraceHandle *textVariableTrace; @@ -169,10 +171,13 @@ NULL, TCL_INDEX_NONE, offsetof(Entry, entry.invalidCmd), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", "left", TCL_INDEX_NONE, offsetof(Entry, entry.justify), TK_OPTION_ENUM_VAR, 0, GEOMETRY_CHANGED}, + {TK_OPTION_STRING, "-locale", "locale", "Locale", + NULL, offsetof(Entry, entry.localeObj), TCL_INDEX_NONE, + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder", NULL, offsetof(Entry, entry.placeholderObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-show", "show", "Show", NULL, TCL_INDEX_NONE, offsetof(Entry, entry.showChar), Index: library/entry.tcl ================================================================== --- library/entry.tcl +++ library/entry.tcl @@ -163,12 +163,12 @@ bind Entry { if {[%W selection present]} { %W delete sel.first sel.last } else { - %W delete [tk::startOfCluster [%W get] [%W index insert]] \ - [tk::endOfCluster [%W get] [%W index insert]] + %W delete [tk::startOfCluster [%W get] [%W index insert] [$w cget -locale]] \ + [tk::endOfCluster [%W get] [%W index insert] [$w cget -locale]] } } bind Entry { tk::EntryBackspace %W } @@ -388,21 +388,21 @@ } } } word { if {$cur < $anchor} { - set before [tk::wordBreakBefore [$w get] $cur] - set after [tk::wordBreakAfter [$w get] $anchor-1] + set before [tk::wordBreakBefore [$w get] $cur [$w cget -locale]] + set after [tk::wordBreakAfter [$w get] $anchor-1 [$w cget -locale]] } elseif {$cur > $anchor} { - set before [tk::wordBreakBefore [$w get] $anchor] - set after [tk::wordBreakAfter [$w get] $cur-1] + set before [tk::wordBreakBefore [$w get] $anchor [$w cget -locale]] + set after [tk::wordBreakAfter [$w get] $cur-1 [$w cget -locale]] } else { if {[$w index @$Priv(pressX)] < $anchor} { incr anchor -1 } - set before [tk::wordBreakBefore [$w get] $anchor] - set after [tk::wordBreakAfter [$w get] $anchor] + set before [tk::wordBreakBefore [$w get] $anchor [$w cget -locale]] + set after [tk::wordBreakAfter [$w get] $anchor [$w cget -locale]] } if {$before < 0} { set before 0 } if {$after < 0} { @@ -518,12 +518,12 @@ if {[$w selection present]} { $w delete sel.first sel.last } else { set x [expr {[$w index insert] - 1}] if {$x >= 0} { - $w delete [tk::startOfCluster [$w get] $x] \ - [tk::endOfCluster [$w get] $x] + $w delete [tk::startOfCluster [$w get] $x [$w cget -locale]] \ + [tk::endOfCluster [$w get] $x [$w cget -locale]] } if {[$w index @0] >= [$w index insert]} { set range [$w xview] set left [lindex $range 0] set right [lindex $range 1] @@ -598,13 +598,13 @@ proc ::tk::EntryNextWord {w start} { # the check on [winfo class] is because the spinbox also uses this proc if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} { return end } - set pos [tk::endOfWord [$w get] [$w index $start]] + set pos [tk::endOfWord [$w get] [$w index $start] [$w cget -locale]] if {$pos >= 0} { - set pos [tk::startOfNextWord [$w get] $pos] + set pos [tk::startOfNextWord [$w get] $pos [$w cget -locale]] } if {$pos < 0} { return end } return $pos @@ -621,11 +621,11 @@ proc ::tk::EntrySelectNextWord {w start} { # the check on [winfo class] is because the spinbox also uses this proc if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} { return end } - set pos [tk::endOfWord [$w get] [$w index $start]] + set pos [tk::endOfWord [$w get] [$w index $start] [$w cget -locale]] if {$pos < 0} { return end } return $pos } @@ -642,27 +642,27 @@ proc ::tk::EntryPreviousWord {w start} { # the check on [winfo class] is because the spinbox also uses this proc if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} { return 0 } - set pos [tk::startOfPreviousWord [$w get] [$w index $start]] + set pos [tk::startOfPreviousWord [$w get] [$w index $start] [$w cget -locale]] if {$pos < 0} { return 0 } return $pos } proc ::tk::EntryNextChar {w start} { - set pos [tk::endOfCluster [$w get] [$w index $start]] + set pos [tk::endOfCluster [$w get] [$w index $start] [$w cget -locale]] if {$pos < 0} { return end } return $pos } proc ::tk::EntryPreviousChar {w start} { - set pos [tk::startOfCluster [$w get] [expr {[$w index $start]-1}]] + set pos [tk::startOfCluster [$w get] [expr {[$w index $start]-1}] [$w cget -locale]] if {$pos < 0} { return 0 } return $pos } Index: library/spinbox.tcl ================================================================== --- library/spinbox.tcl +++ library/spinbox.tcl @@ -173,12 +173,12 @@ bind Spinbox { if {[%W selection present]} { %W delete sel.first sel.last } else { - %W delete [tk::startOfCluster [%W get] [%W index insert]] \ - [tk::endOfCluster [%W get] [%W index insert]] + %W delete [tk::startOfCluster [%W get] [%W index insert] [$w cget -locale]] \ + [tk::endOfCluster [%W get] [%W index insert] [$w cget -locale]] } } bind Spinbox { ::tk::EntryBackspace %W } @@ -467,15 +467,15 @@ } } } word { if {$cur < [$w index anchor]} { - set before [tk::wordBreakBefore [$w get] $cur] - set after [tk::wordBreakAfter [$w get] $anchor-1] + set before [tk::wordBreakBefore [$w get] $cur [$w cget -locale]] + set after [tk::wordBreakAfter [$w get] $anchor-1 [$w cget -locale]] } else { - set before [tk::wordBreakBefore [$w get] $anchor] - set after [tk::wordBreakAfter [$w get] $cur-1] + set before [tk::wordBreakBefore [$w get] $anchor [$w cget -locale]] + set after [tk::wordBreakAfter [$w get] $cur-1 [$w cget -locale]] } if {$before < 0} { set before 0 } if {$after < 0} { Index: library/text.tcl ================================================================== --- library/text.tcl +++ library/text.tcl @@ -1123,11 +1123,11 @@ proc ::tk::TextNextPos {w start op} { set text "" set cur $start while {[$w compare $cur < end]} { set text $text[$w get -displaychars $cur "$cur lineend + 1c"] - set pos [$op $text 0] + set pos [$op $text 0 [$w locale $cur]] if {$pos >= 0} { return [$w index "$start + $pos display chars"] } set cur [$w index "$cur lineend +1c"] } @@ -1146,11 +1146,11 @@ proc ::tk::TextPrevPos {w start op} { set text "" set cur $start while {[$w compare $cur > 0.0]} { set text [$w get -displaychars "$cur linestart - 1c" $cur]$text - set pos [$op $text end] + set pos [$op $text end [$w locale $cur]] if {$pos >= 0} { return [$w index "$cur linestart - 1c + $pos display chars"] } set cur [$w index "$cur linestart - 1c"] } Index: library/ttk/entry.tcl ================================================================== --- library/ttk/entry.tcl +++ library/ttk/entry.tcl @@ -255,13 +255,13 @@ proc ttk::entry::NextWord {w start} { # the check on [winfo class] is because the spinbox and combobox also use this proc if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} { return end } - set pos [tk::endOfWord [$w get] [$w index $start]] + set pos [tk::endOfWord [$w get] [$w index $start] [$w cget -locale]] if {$pos >= 0} { - set pos [tk::startOfNextWord [$w get] $pos] + set pos [tk::startOfNextWord [$w get] $pos [$w cget -locale]] } if {$pos < 0} { return end } return $pos @@ -274,11 +274,11 @@ proc ttk::entry::SelectNextWord {w start} { # the check on [winfo class] is because the spinbox and combobox also use this proc if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} { return end } - set pos [tk::endOfWord [$w get] [$w index $start]] + set pos [tk::endOfWord [$w get] [$w index $start] [$w cget -locale]] if {$pos < 0} { return end } return $pos } @@ -288,11 +288,11 @@ proc ttk::entry::PrevWord {w start} { # the check on [winfo class] is because the spinbox and combobox also use this proc if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} { return 0 } - set pos [tk::startOfPreviousWord [$w get] [$w index $start]] + set pos [tk::startOfPreviousWord [$w get] [$w index $start] [$w cget -locale]] if {$pos < 0} { return 0 } return $pos } @@ -299,21 +299,21 @@ ## NextChar -- Find the next char position. # proc ttk::entry::NextChar {w start} { variable State - set pos [tk::endOfCluster [$w get] [$w index $start]] + set pos [tk::endOfCluster [$w get] [$w index $start] [$w cget -locale]] if {$pos < 0} { return end } return $pos } ## PrevChar -- Find the previous char position. # proc ttk::entry::PrevChar {w start} { - set pos [tk::startOfCluster [$w get] [expr {[$w index $start]-1}]] + set pos [tk::startOfCluster [$w get] [expr {[$w index $start]-1}] [$w cget -locale]] if {$pos < 0} { return 0 } return $pos } @@ -534,16 +534,16 @@ ## WordSelect -- Select whole words between index $from and $to # proc ttk::entry::WordSelect {w from to} { if {$to < $from} { - set first [WordBack [$w get] $to] - set last [WordForward [$w get] $from] + set first [WordBack [$w get] $to [$w cget -locale]] + set last [WordForward [$w get] $from [$w cget -locale]] $w icursor $first } else { - set first [WordBack [$w get] $from] - set last [WordForward [$w get] $to] + set first [WordBack [$w get] $from [$w cget -locale]] + set last [WordForward [$w get] $to [$w cget -locale]] $w icursor $last } $w selection range $first $last } @@ -653,11 +653,11 @@ return } set x [expr {[$w index insert] - 1}] if {$x < 0} { return } - $w delete [tk::startOfCluster [$w get] $x] [tk::endOfCluster [$w get] $x] + $w delete [tk::startOfCluster [$w get] $x [$w cget -locale]] [tk::endOfCluster [$w get] $x [$w cget -locale]] if {[$w index @0] >= [$w index insert]} { set range [$w xview] set left [lindex $range 0] set right [lindex $range 1] @@ -668,11 +668,11 @@ ## Delete -- Delete the character after the insert cursor. # If there is a selection, delete that instead. # proc ttk::entry::Delete {w} { if {![PendingDelete $w]} { - $w delete [tk::startOfCluster [$w get] [$w index insert]] \ - [tk::endOfCluster [$w get] [$w index insert]] + $w delete [tk::startOfCluster [$w get] [$w index insert] [$w cget -locale]] \ + [tk::endOfCluster [$w get] [$w index insert] [$w cget -locale]] } } #*EOF* Index: tests/entry.test ================================================================== --- tests/entry.test +++ tests/entry.test @@ -824,11 +824,11 @@ update } -body { llength [.e configure] } -cleanup { destroy .e -} -result 38 +} -result 39 test entry-3.16 {EntryWidgetCmd procedure, "configure" widget command} -setup { entry .e } -body { .e configure -foo } -cleanup { Index: tests/spinbox.test ================================================================== --- tests/spinbox.test +++ tests/spinbox.test @@ -1162,11 +1162,11 @@ update } -body { llength [.e configure] } -cleanup { destroy .e -} -result 51 +} -result 52 test spinbox-3.16 {SpinboxWidgetCmd procedure, "configure" widget command} -setup { spinbox .e } -body { .e configure -foo } -cleanup { Index: tests/text.test ================================================================== --- tests/text.test +++ tests/text.test @@ -950,11 +950,11 @@ text .t } -body { .t gorp 1.0 z 1.2 } -cleanup { destroy .t -} -returnCodes {error} -result {bad option "gorp": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview} +} -returnCodes {error} -result {bad option "gorp": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, locale, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview} test text-4.1 {TextWidgetCmd procedure, "bbox" option} -setup { text .t } -body { .t bbox @@ -1172,11 +1172,11 @@ !@#$% Line 7" .t co 1.0 z 1.2 } -cleanup { destroy .t -} -returnCodes {error} -result {ambiguous option "co": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview} +} -returnCodes {error} -result {ambiguous option "co": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, locale, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview} # "configure" option is already covered above test text-7.1 {TextWidgetCmd procedure, "debug" option} -setup { text .t } -body { @@ -1188,11 +1188,11 @@ text .t } -body { .t de 0 1 } -cleanup { destroy .t -} -returnCodes {error} -result {ambiguous option "de": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview} +} -returnCodes {error} -result {ambiguous option "de": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, locale, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview} test text-7.3 {TextWidgetCmd procedure, "debug" option} -setup { text .t } -body { .t debug true .t deb @@ -3160,11 +3160,11 @@ text .t } -body { .t in a b } -cleanup { destroy .t -} -returnCodes {error} -result {ambiguous option "in": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview} +} -returnCodes {error} -result {ambiguous option "in": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, locale, mark, peer, pendingsync, replace, scan, search, see, sync, tag, window, xview, or yview} test text-12.4 {TextWidgetCmd procedure, "index" option} -setup { text .t } -body { .t index @xyz } -cleanup { Index: tests/textTag.test ================================================================== --- tests/textTag.test +++ tests/textTag.test @@ -306,10 +306,24 @@ test textTag-1.37 {configuration options} -body { .t tag configure x -underlinefg stupid } -cleanup { .t tag configure x -underlinefg [lindex [.t tag configure x -underlinefg] 3] } -returnCodes error -result {unknown color name "stupid"} +test textTag-1.38 {configuration options, -locale} -body { + .t tag configure x -locale regexp + .t tag add x 1.0 1.3 + list [.t locale 1.0] [.t locale 1.2] [.t locale 1.3] +} -cleanup { + .t tag configure x -locale {} +} -result {regexp regexp {}} +test textTag-1.39 {configuration options, -locale} -body { + .t configure -locale regexp + .t tag configure x -locale abc + list [.t locale 1.0] [.t locale 1.2] [.t locale 1.3] +} -cleanup { + .t tag configure x -locale {} +} -result {abc abc regexp} test textTag-2.1 {TkTextTagCmd - "add" option} -body { .t tag } -returnCodes error -result {wrong # args: should be ".t tag option ?arg ...?"}