📄 tktext.c
字号:
result = TCL_ERROR; goto done; } relation = TkTextIndexCmp(&index1, &index2); p = argv[3]; if (p[0] == '<') { value = (relation < 0); if ((p[1] == '=') && (p[2] == 0)) { value = (relation <= 0); } else if (p[1] != 0) { compareError: Tcl_AppendResult(interp, "bad comparison operator \"", argv[3], "\": must be <, <=, ==, >=, >, or !=", (char *) NULL); result = TCL_ERROR; goto done; } } else if (p[0] == '>') { value = (relation > 0); if ((p[1] == '=') && (p[2] == 0)) { value = (relation >= 0); } else if (p[1] != 0) { goto compareError; } } else if ((p[0] == '=') && (p[1] == '=') && (p[2] == 0)) { value = (relation == 0); } else if ((p[0] == '!') && (p[1] == '=') && (p[2] == 0)) { value = (relation != 0); } else { goto compareError; } interp->result = (value) ? "1" : "0"; } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) && (length >= 3)) { if (argc == 2) { result = Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs, (char *) textPtr, (char *) NULL, 0); } else if (argc == 3) { result = Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs, (char *) textPtr, argv[2], 0); } else { result = ConfigureText(interp, textPtr, argc-2, argv+2, TK_CONFIG_ARGV_ONLY); } } else if ((c == 'd') && (strncmp(argv[1], "debug", length) == 0) && (length >= 3)) { if (argc > 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " debug boolean\"", (char *) NULL); result = TCL_ERROR; goto done; } if (argc == 2) { interp->result = (tkBTreeDebug) ? "1" : "0"; } else { if (Tcl_GetBoolean(interp, argv[2], &tkBTreeDebug) != TCL_OK) { result = TCL_ERROR; goto done; } tkTextDebug = tkBTreeDebug; } } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0) && (length >= 3)) { if ((argc != 3) && (argc != 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " delete index1 ?index2?\"", (char *) NULL); result = TCL_ERROR; goto done; } if (textPtr->state == tkTextNormalUid) { result = DeleteChars(textPtr, argv[2], (argc == 4) ? argv[3] : (char *) NULL); } } else if ((c == 'd') && (strncmp(argv[1], "dlineinfo", length) == 0) && (length >= 2)) { int x, y, width, height, base; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " dlineinfo index\"", (char *) NULL); result = TCL_ERROR; goto done; } if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) { result = TCL_ERROR; goto done; } if (TkTextDLineInfo(textPtr, &index1, &x, &y, &width, &height, &base) == 0) { sprintf(interp->result, "%d %d %d %d %d", x, y, width, height, base); } } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) { if ((argc != 3) && (argc != 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " get index1 ?index2?\"", (char *) NULL); result = TCL_ERROR; goto done; } if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) { result = TCL_ERROR; goto done; } if (argc == 3) { index2 = index1; TkTextIndexForwChars(&index2, 1, &index2); } else if (TkTextGetIndex(interp, textPtr, argv[3], &index2) != TCL_OK) { result = TCL_ERROR; goto done; } if (TkTextIndexCmp(&index1, &index2) >= 0) { goto done; } while (1) { int offset, last, savedChar; TkTextSegment *segPtr; segPtr = TkTextIndexToSeg(&index1, &offset); last = segPtr->size; if (index1.linePtr == index2.linePtr) { int last2; if (index2.charIndex == index1.charIndex) { break; } last2 = index2.charIndex - index1.charIndex + offset; if (last2 < last) { last = last2; } } if (segPtr->typePtr == &tkTextCharType) { savedChar = segPtr->body.chars[last]; segPtr->body.chars[last] = 0; Tcl_AppendResult(interp, segPtr->body.chars + offset, (char *) NULL); segPtr->body.chars[last] = savedChar; } TkTextIndexForwChars(&index1, last-offset, &index1); } } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0) && (length >= 3)) { if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " index index\"", (char *) NULL); result = TCL_ERROR; goto done; } if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) { result = TCL_ERROR; goto done; } TkTextPrintIndex(&index1, interp->result); } else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0) && (length >= 3)) { int i, j, numTags; char **tagNames; TkTextTag **oldTagArrayPtr; if (argc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " insert index chars ?tagList chars tagList ...?\"", (char *) NULL); result = TCL_ERROR; goto done; } if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) { result = TCL_ERROR; goto done; } if (textPtr->state == tkTextNormalUid) { for (j = 3; j < argc; j += 2) { InsertChars(textPtr, &index1, argv[j]); if (argc > (j+1)) { TkTextIndexForwChars(&index1, (int) strlen(argv[j]), &index2); oldTagArrayPtr = TkBTreeGetTags(&index1, &numTags); if (oldTagArrayPtr != NULL) { for (i = 0; i < numTags; i++) { TkBTreeTag(&index1, &index2, oldTagArrayPtr[i], 0); } ckfree((char *) oldTagArrayPtr); } if (Tcl_SplitList(interp, argv[j+1], &numTags, &tagNames) != TCL_OK) { result = TCL_ERROR; goto done; } for (i = 0; i < numTags; i++) { TkBTreeTag(&index1, &index2, TkTextCreateTag(textPtr, tagNames[i]), 1); } ckfree((char *) tagNames); index1 = index2; } } } } else if ((c == 'd') && (strncmp(argv[1], "dump", length) == 0)) { result = TextDumpCmd(textPtr, interp, argc, argv); } else if ((c == 'i') && (strncmp(argv[1], "image", length) == 0)) { result = TkTextImageCmd(textPtr, interp, argc, argv); } else if ((c == 'm') && (strncmp(argv[1], "mark", length) == 0)) { result = TkTextMarkCmd(textPtr, interp, argc, argv); } else if ((c == 's') && (strcmp(argv[1], "scan") == 0) && (length >= 2)) { result = TkTextScanCmd(textPtr, interp, argc, argv); } else if ((c == 's') && (strcmp(argv[1], "search") == 0) && (length >= 3)) { result = TextSearchCmd(textPtr, interp, argc, argv); } else if ((c == 's') && (strcmp(argv[1], "see") == 0) && (length >= 3)) { result = TkTextSeeCmd(textPtr, interp, argc, argv); } else if ((c == 't') && (strcmp(argv[1], "tag") == 0)) { result = TkTextTagCmd(textPtr, interp, argc, argv); } else if ((c == 'w') && (strncmp(argv[1], "window", length) == 0)) { result = TkTextWindowCmd(textPtr, interp, argc, argv); } else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) { result = TkTextXviewCmd(textPtr, interp, argc, argv); } else if ((c == 'y') && (strncmp(argv[1], "yview", length) == 0) && (length >= 2)) { result = TkTextYviewCmd(textPtr, interp, argc, argv); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be bbox, cget, compare, configure, debug, delete, ", "dlineinfo, get, image, index, insert, mark, scan, search, see, ", "tag, window, xview, or yview", (char *) NULL); result = TCL_ERROR; } done: Tcl_Release((ClientData) textPtr); return result;}/* *---------------------------------------------------------------------- * * DestroyText -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release * to clean up the internal structure of a text at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the text is freed up. * *---------------------------------------------------------------------- */static voidDestroyText(memPtr) char *memPtr; /* Info about text widget. */{ register TkText *textPtr = (TkText *) memPtr; Tcl_HashSearch search; Tcl_HashEntry *hPtr; TkTextTag *tagPtr; /* * Free up all the stuff that requires special handling, then * let Tk_FreeOptions handle all the standard option-related * stuff. Special note: free up display-related information * before deleting the B-tree, since display-related stuff * may refer to stuff in the B-tree. */ TkTextFreeDInfo(textPtr); TkBTreeDestroy(textPtr->tree); for (hPtr = Tcl_FirstHashEntry(&textPtr->tagTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); TkTextFreeTag(textPtr, tagPtr); } Tcl_DeleteHashTable(&textPtr->tagTable); for (hPtr = Tcl_FirstHashEntry(&textPtr->markTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { ckfree((char *) Tcl_GetHashValue(hPtr)); } Tcl_DeleteHashTable(&textPtr->markTable); if (textPtr->tabArrayPtr != NULL) { ckfree((char *) textPtr->tabArrayPtr); } if (textPtr->insertBlinkHandler != NULL) { Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler); } if (textPtr->bindingTable != NULL) { Tk_DeleteBindingTable(textPtr->bindingTable); } /* * NOTE: do NOT free up selBorder, selBdString, or selFgColorPtr: * they are duplicates of information in the "sel" tag, which was * freed up as part of deleting the tags above. */ textPtr->selBorder = NULL; textPtr->selBdString = NULL; textPtr->selFgColorPtr = NULL; Tk_FreeOptions(configSpecs, (char *) textPtr, textPtr->display, 0); ckfree((char *) textPtr);}/* *---------------------------------------------------------------------- * * ConfigureText -- * * This procedure is called to process an argv/argc list, plus * the Tk option database, in order to configure (or * reconfigure) a text widget. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for textPtr; old resources get freed, if there * were any. * *---------------------------------------------------------------------- */static intConfigureText(interp, textPtr, argc, argv, flags) Tcl_Interp *interp; /* Used for error reporting. */ register TkText *textPtr; /* Information about widget; may or may * not already have values for some fields. */ int argc; /* Number of valid entries in argv. */ char **argv; /* Arguments. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */{ int oldExport = textPtr->exportSelection; if (Tk_ConfigureWidget(interp, textPtr->tkwin, configSpecs, argc, argv, (char *) textPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * A few other options also need special processing, such as parsing * the geometry and setting the background from a 3-D border. */ if ((textPtr->state != tkTextNormalUid) && (textPtr->state != tkTextDisabledUid)) { Tcl_AppendResult(interp, "bad state value \"", textPtr->state, "\": must be normal or disabled", (char *) NULL); textPtr->state = tkTextNormalUid; return TCL_ERROR; } if ((textPtr->wrapMode != tkTextCharUid) && (textPtr->wrapMode != tkTextNoneUid) && (textPtr->wrapMode != tkTextWordUid)) { Tcl_AppendResult(interp, "bad wrap mode \"", textPtr->wrapMode, "\": must be char, none, or word", (char *) NULL); textPtr->wrapMode = tkTextCharUid; return TCL_ERROR; } Tk_SetBackgroundFromBorder(textPtr->tkwin, textPtr->border); /* * Don't allow negative spacings. */ if (textPtr->spacing1 < 0) { textPtr->spacing1 = 0; } if (textPtr->spacing2 < 0) { textPtr->spacing2 = 0; } if (textPtr->spacing3 < 0) { textPtr->spacing3 = 0; } /* * Parse tab stops. */ if (textPtr->tabArrayPtr != NULL) { ckfree((char *) textPtr->tabArrayPtr); textPtr->tabArrayPtr = NULL; } if (textPtr->tabOptionString != NULL) { textPtr->tabArrayPtr = TkTextGetTabs(interp, textPtr->tkwin, textPtr->tabOptionString); if (textPtr->tabArrayPtr == NULL) { Tcl_AddErrorInfo(interp,"\n (while processing -tabs option)"); return TCL_ERROR; } } /* * Make sure that configuration options are properly mirrored * between the widget record and the "sel" tags. NOTE: we don't * have to free up information during the mirroring; old * information was freed when it was replaced in the widget * record. */ textPtr->selTagPtr->border = textPtr->selBorder; if (textPtr->selTagPtr->bdString != textPtr->selBdString) { textPtr->selTagPtr->bdString = textPtr->selBdString; if (textPtr->selBdString != NULL) { if (Tk_GetPixels(interp, textPtr->tkwin, textPtr->selBdString, &textPtr->selTagPtr->borderWidth) != TCL_OK) { return TCL_ERROR; } if (textPtr->selTagPtr->borderWidth < 0) { textPtr->selTagPtr->borderWidth = 0; } } } textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr; textPtr->selTagPtr->affectsDisplay = 0; if ((textPtr->selTagPtr->border != NULL) || (textPtr->selTagPtr->bdString != NULL) || (textPtr->selTagPtr->reliefString != NULL) || (textPtr->selTagPtr->bgStipple != None) || (textPtr->selTagPtr->fgColor != NULL) || (textPtr->selTagPtr->tkfont != None) || (textPtr->selTagPtr->fgStipple != None) || (textPtr->selTagPtr->justifyString != NULL) || (textPtr->selTagPtr->lMargin1String != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -