TIP 682: Create tmp. widget in "option get" call

Login
Author:         RenĂ© Zaumseil <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Tcl-Version:    8.7

Abstract

This TIP will allow the "option get" call to return option values of not already existing widgets. Only the parent widget of the given widget path should exist.

Rationale

Currently it is not possible to get values of not already existing widgets from the option database. When creating megawidgets or wrapping existing widgets it can be necessary to get option values before creating an widget. Currently this can be done p.e. with creating an frame widget, get option values, and destroy the frame widget.i

The goal of this tip is to extend "option get" for this use case. Alternatively a new method p.e. "option getnext" (the name is open for discussion) could be used.

Examples

    % option add *width 10
    % option get . width Width
    10
    % option get .x width Width
    bad window path name ".x" 
    % option get .x.y width Width
    bad window path name ".x.y" 
    % option add *width 10
    % option get . width Width
    10
    % option get .x width Width
    10
    % option get .x.y width Width
    bad window path name ".x.y" 

Implementation

The following C-code part from tkoOption.c should be changed.

Original code:

    case OPTION_GET: {
        Tk_Window window;
        Tk_Uid value;

        if (objc != 5) {
            Tcl_WrongNumArgs(interp, 2, objv, "window name class");
            return TCL_ERROR;
        }
        window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
        if (window == NULL) {
            return TCL_ERROR;
        }
        value = Tk_GetOption(window, Tcl_GetString(objv[3]),
                Tcl_GetString(objv[4]));
        if (value != NULL) {
            Tcl_SetObjResult(interp, Tcl_NewStringObj(value, -1));
        }
        break;

New version:

    case OPTION_GET: {
        Tk_Window window;
        Tk_Uid value;

        if (objc != 5) {
            Tcl_WrongNumArgs(interp, 2, objv, "window name class");
            return TCL_ERROR;
        }
        window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
        if (window == NULL) {
            Tcl_Obj *res = Tcl_GetObjResult(interp);
            Tcl_IncrRefCount(res);
            window = Tk_CreateWindowFromPath(interp,tkwin,Tcl_GetString(objv[2]),NULL);
            if (window == NULL) {
                Tcl_SetObjResult(interp, res);
                Tcl_DecrRefCount(res);
                return TCL_ERROR;
            }
            Tcl_DecrRefCount(res);
            Tcl_ResetResult(interp);
            value = Tk_GetOption(window, Tcl_GetString(objv[3]),
                Tcl_GetString(objv[4]));
            if (value != NULL) {
                Tcl_SetObjResult(interp, Tcl_NewStringObj(value, -1));
            }
            Tk_DestroyWindow(window);
        } else {
            value = Tk_GetOption(window, Tcl_GetString(objv[3]),
                 Tcl_GetString(objv[4]));
            if (value != NULL) {
                Tcl_SetObjResult(interp, Tcl_NewStringObj(value, -1));
            }
        }
        break;

Copyright

This document has been placed in the public domain.