Ruler reset for notebooks

Posted in response to a discussion on the wish-list

27 Aug 2011: Updated to accommodate notebooks as subwindows. Igor packs the winrecreation data in a private format, which is base-85 encoded at the recreation level, but some compression? binary under that. In any case recreating the notebook as a standalone temporarily allows the usual winRecreation data to be extracted, and the ruler reset then proceeds in the old way.

Thanks to Ulrich Froebe for pointing this out and his patience while I stumbled a bit getting it to work.

//====================================================================================================================================
// ResetRuler
// ----------
//  * SUMMARY: 'ResetRuler' resets all of the settable parameters in a notebook to the original settings determined at the time
//              of the original creation of the ruler.  This is useful because subsequent changes in settings are added on top
//              of the ruler's defaults, and do not get reset when a line such as:
//
//                  notebook notebook0,ruler="Normal"
//
//              is executed.  This function allows all settings to be returned to the original ruler's defaults, including the
//              vOffset, textRGB, font, margins, justification, tabs, fStyle, fSize, and spacing commands.  The command also
//              sets the 'ruler' as the current ruler for the notebook, and can therefore be used as the ruler command for
//              programatic notebook creation, setting the conditions back to a known state, without the programmer needing
//              to know anything about the ruler being set (except its name...).
//
//  * ARGUMENTS:
//      - nb:           Notebook to set ruler defaults.  An error is raised if the notebook does not exist.  If the notebook is
//                      a subwindow the full '#' separated window path should be passed.
//
//      - ruler:        Name of the ruler to set.  An error is raised if the ruler does not exist for the named notebook.
//
//      - [instance]:   Optional variable. Use this instance of the notebook name (only useful if there is more than one subwindow
//                      with an embedded notebook, whence more than one notebook can legally have the same name).  
//                      Zero based for the first notebook created.  Default 0.
//
//      - [errMsg]:     Optional pass-by-reference string to receive error message.  If present the function will not abort.
//
//  * RETURNS:  V_AbortCode (zero for no error).
//
//  * ON ERROR:
//      If 'errMsg' is passed: sets 'errMsg'=<error string>, returns V_AbortCode.  ('errMsg' is "" for no error.)
//      If 'errMsg' is not a parameter: aborts with error message.
//
//  * SOURCE:   Patrick Groenestein, 2010
//
//  * UPDATES:  20110515 Created from PG61_NotebookUtils.
//              20110821 Added support for notebooks in subwindows.
//
//------------------------------+---------------------------------------------------------------+-------------------------------------
FUNCTION ResetRuler(nb,ruler [,instance,errMsg])
    variable                    instance;
    string                      nb,ruler,&errMsg;

    variable                    err,i,n,pos,len;
    variable                    isSW=itemsInList(nb,"#")-1;
    string                      s0,nbStr,cmd,rgb,nbRef,zd;

    TRY
        if( !strlen(ruler))
            ruler = "Normal";
        endif;

        if( !strlen(nb))
            nb = winName(0,16);  abortOnValue !strlen(nb),5;
            isSW = 0;
        endif;
       
        abortOnValue !winType(nb),6;

        if(isSW)
            nbStr = winRecreation(stringFromList(0,nb,"#"),0);  abortOnRTE;
            nbRef = stringFromList(isSW,nb,"#");
            for(i=0,cmd="",n=itemsInList(nbStr,"\r") ; i<n ; i+=1)
                s0 = stringFromList(i,nbStr,"\r")
                if(stringMatch(s0,"\tNewNotebook *") && strSearch(s0,"/N="+nbRef+" ",0,2)>=0)
                    if(instance>0)
                        instance -= 1;
                    else
                                // Found the required notebook; extract its data into 'cmd', minus the 'NewNotebook' line
                                //
                        for(i+=1,s0=stringFromList(i,nbStr,"\r") ; stringMatch(s0,"\tNotebook *") ; i+=1,s0=stringFromList(i,nbStr,"\r"))
                            cmd += s0+"\r";
                        endfor;
                       
                                // Could use UniqueName here
                                //
                        for(i=0,zd="PG62_NBTmp_0" ; winType(zd) ; i+=1,zd="PG62_NBTmp_"+num2iStr(i))
                        endfor;
                       
                                // Create an invisible, temporary, stand-alone notebook to extract commands from
                                // Needs the loop to avoid command buffer overflow
                                //
                        cmd[0] = "newNotebook/V=0/F=1/N="+zd+"\r";
                        for(i=0,n=itemsInList(cmd,"\r") ; i<n ; i+=1)
                            s0 = stringFromList(i,cmd,"\r");
                            s0 = replaceString("kwTopWin",s0,zd,0,1);
                            execute/Z/Q s0;  abortOnRTE; abortOnValue V_Flag,2;
                        endfor;
                       
                                // Extract the 'winRecreation()', now free of 'zdata' lines
                                //
                        cmd = winRecreation(zd,0);
                        doWindow/K $zd;
                        break;
                    endif;
                endif;
            endfor;
            nbStr = cmd;
            cmd = "";
        else
            nbStr = winRecreation(nb,0);  abortOnRTE;   // Normal standalone notebook
        endif;

        nbRef = "$nb";
        nbStr = stringFromList(0,listMatch(nbStr,"\tNotebook "+nbRef+" newRuler="+ruler+", *","\r"),"\r");  abortOnValue !strlen(nbStr),3;
        nbStr = replaceString("newRuler=",replaceString(nbRef,nbStr,nb,0,1),"ruler=",0,1);
       
        pos = strSearch(nbStr,"rulerDefaults=",0,2);  abortOnValue pos<0,4;
        len = strlen(nbStr)-1;
        cmd = nbStr[pos,len];

        nbStr[pos,len] = "";
        pos -= 1;
        nbStr[pos,pos] = "";    // trailing space
        nbStr[0,0] = "";        // leading tab
        sscanf cmd,"rulerDefaults={\"%*[^\"]\",%*d,%*d,(%[^)])",rgb;  abortOnRTE;

        notebook $nb,Ruler=$ruler,vOffset=0,font="default",fSize= -1,fStyle= -1;  abortOnRTE;
        execute/Q/Z nbStr+"textRGB=("+rgb+")";  abortOnValue V_Flag,2;
        abortOnRTE;

    CATCH
       
        variable                ev;
        string                  es="";

        if(V_AbortCode<0)
            es = getRTErrMessage();
            ev = getRTError(1);
        elseif(V_AbortCode>1)
            es  = "Error 0. {BUG}\n";                               // V_AbortCode 0 (not used)
            es += "Error 1. {BUG}\n";                               // V_AbortCode 1 (error passing up the line)
            es += "Igor error: {"+GetErrMessage(V_Flag,2)+"}.\n";   // V_AbortCode 2
            es += "Cannot find 'newRuler' command for the ruler \""+ruler+"\".\n";              // V_AbortCode 3
            es += "Cannot find 'rulerDefaults' command for the ruler \""+ruler+"\".\n";         // V_AbortCode 4
            es += "No notebook windows found.\n";                                               // V_AbortCode 5
            es += "Notebook window '"+nb+"' not found.\n";                                      // V_AbortCode 6
            es += "<Undocumented error> {BUG}\n";                                               // V_AbortCode <undocumented>
           
            ev = min(V_AbortCode,itemsInList(es,"\n")-1);
            es = stringFromList(ev,es,"\n");
        endif;
    ENDTRY;

                                // Add cleanup here
                                // <none>
                               
    if(V_AbortCode)
                                // This function's error: set the error environment for this error.
                                // Otherwise just pass the error received from some other function back up the line.
                                //
        es[0] = getRTStackInfo(1)+" error <"+num2iStr(V_AbortCode)+">: ";
        if(paramIsDefault(errMsg))
 
            variable/G          V_Error=V_AbortCode;
            string/G            S_Error=es;
 
            print es;
            abort es;
        else
            errMsg = es;
        endif;
    endif;

    return(V_AbortCode);
END
the zip xop offers deflate and inflate algorithms if the compression is in that format.

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More