• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Display selection on proper page type

Community Expert ,
Dec 11, 2017 Dec 11, 2017

Copy link to clipboard

Copied

Dear experts,

To be able to navigate to any variable in the document (used on any page type) I first collect all information about the variables. The arry elements are built by the prototype function (is this the correct term?)

function oVariable (sName, sContents, oVar, bUsed, bSystem, oTr, sPageType, iPageNr, sPageName) {
  this.Name     =  sName;                         // Name of variable
  this.Contents =  sContents;                     // Contents of variable
  this.VarObj   =  oVar;                          // Var object in document
  this.VarUsed  =  bUsed;                         // User var is used in document
  this.IsSystem =  bSystem;                       // true for system variable
  this.TextRange=  oTr;                           // textrange of this occurance in the doc
  this.PageType =  sPageType;                     // BodyPage or ... where var was found
  this.PageNr   =  iPageNr;                       // for BodyPage
  this.PageName =  sPageName;                     // for the other types
} //--- end oVariable

In a loop through the variables I fill the global array of objects, which works fine.

For the following don't worry about the goFMc prefix: it is the name of the global object holding all stuff.

function GetVarsInDoc (oDoc) { //=== Fill the doc variables array with all found vars in Doc ======
var bIsSystem, bIsUsed, oPage, oTR, oVar, index, iPageType, sPageType, sVarName, sVarContents;
  goFMc.aDocVars.length = 0;                      // clear array for new build up
  oVar = oDoc.FirstVarInDoc;                      // the variable in the text
  while (oVar.ObjectValid()) {
    sVarName = oVar.VarFmt.Name;                  // name of the variable
    sValue   = oVar.VarFmt.Fmt;                   // contents of variable
    oTR      = oVar.TextRange;                    // the text range of the variable
    bIsSystem= (oVar.VarFmt.SystemVar !== Constants.FV_VAR_USER_VARIABLE);
    bIsUsed  = UsrVarIsUsed (oDoc, sVarName);
    goFMc.aDocVars.push (new oVariable (sVarName, sValue, oVar, bIsUsed, bIsSystem, oTr, null, null)); // array element
    oDoc.ScrollToText(oTR);                       // Go there to get page type
    oPage = oDoc.CurrentPage;
    sPageType = oPage.constructor.name;           // BodyPage, MasterPage, RefPage [Rick Quatro]
    index = goFMc.aDocVars.length - 1;            // use current array entry
    goFMc.aDocVars[index].PageType = sPageType;
    if (sPageType == "BodyPage") {
      goFMc.aDocVars[index].PageNr = oPage.PageNum;
    } else if (sPageType == "MasterPage") {
      goFMc.aDocVars[index].PageName = oPage.Name;
    } else if (sPageType == "RefPage") {
      goFMc.aDocVars[index].PageName = oPage.Name;
    }
    oVar = oVar.NextVarInDoc;
  }
  goFMc.nDocVars = goFMc.aDocVars.length;
} //--- end GetVarsInDoc

To get to the first variable in the document I have the following function in the dialogue:

function ButtonFirst () { //=== Go to first variable in document ==================================

var bSystemVar, iVar, jVar, oVar, sName;
  iVar =0;                                        // index in doc variable array
  goFMc.indexDocVars = iVar;                       // keep for other nav buttons
  oVar = goFMc.aDocVars[iVar].VarObj;             // first item in doc variable array
  sName = goFMc.aDocVars[iVar].Name;
  bSystemVar = goFMc.aDocVars[iVar].IsSystem;
  DisplayVariable (goFMc.oCurrentDoc, iVar);      // can be on any page type
// ...

} //---  end ButtonFirst

Relevant data (the ingredients) from goFMc.aDocVars[0] for DisplayVariable is

Name     =  Running H/F 1
Contents =  <$paratext[0chapter-title]>
VarObj   =  // Var object in document
VarUsed  =  false   // User var is used in document
IsSystem =  true
TextRange=  // textrange of this occurance in the doc
PageType =  MasterPage
PageName =  Left

The user normally start on the body pages, while many variables can be on the master pages and even on the reference pages. Hence the display should switch between the various page types. However, in my test case the variable is on the first master page - but the display is still the current body page.

My question now is: why does DisplayVariable not jump to the appropriate page type and show the selected variable?

After executing ButtonFirst I can manually switch to the master pages where I see the variable selected on the very first one.

function DisplayVariable (oDoc, iVar) { //=== display the indexed variable ========================
var oTR;
  oTR = goFMc.aDocVars[iVar].TextRange;
  oDoc.TextSelection = oTR;
  oDoc.ScrollToText(oTR);
} //--- end DisplayVariable

When switching manually to the last master page before I use the button then the display is correct.

But how can I make the function automatically go to the relvant page type?

I have the necessary ingredients, but no recipe...

Any ideas are welcome

Klaus

TOPICS
Scripting

Views

422

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Dec 11, 2017 Dec 11, 2017

Hi Klaus, You can set the current page to the page containing the variable by using line 15. I think this is what you are trying to do. -Rick

#target framemaker

var doc = app.ActiveDoc;

showVariables (doc);

function showVariables (doc) {

   

    var variable, page, result;

   

    variable = doc.FirstVarInDoc;

    while (variable.ObjectValid () === 1) {

        page = getPage (variable, doc);

        if (page.ObjectValid () === 1) {

            // Go to the page containing the variable.

            doc.Cur

...

Votes

Translate

Translate
Community Expert ,
Dec 11, 2017 Dec 11, 2017

Copy link to clipboard

Copied

Hi Klaus, You can set the current page to the page containing the variable by using line 15. I think this is what you are trying to do. -Rick

#target framemaker

var doc = app.ActiveDoc;

showVariables (doc);

function showVariables (doc) {

   

    var variable, page, result;

   

    variable = doc.FirstVarInDoc;

    while (variable.ObjectValid () === 1) {

        page = getPage (variable, doc);

        if (page.ObjectValid () === 1) {

            // Go to the page containing the variable.

            doc.CurrentPage = page;

        }

        variable = variable.NextVarInDoc;

    }

}

function getPage (obj,doc) {

   

    var frame = 0, cell = 0;

    var objType = "", prop = 0;

   

    while (obj) {

       

        frame = obj;

        objType = obj.constructor.name;

       

        switch (objType) {

            case "SubCol" :

                obj = obj.ParentTextFrame;

                break;

            case "Tbl" :

                obj = obj.FirstRowInTbl.FirstCellInRow;

                break;

            case "Row" :

                obj = obj.FirstCellInRow;

                break;

            case "Cell" :

            case "Pgf" :

            case "AFrame" :

                obj = obj.InTextFrame;

                break;

            case "TextLine" :

            case "TextFrame" :

            case "UnanchoredFrame" :

            case "Arc" :

            case "Ellipse" :

            case "Group" :

            case "Inset" :

            case "Line" :

            case "Math" :

            case "Polygon" :

            case "Polyline" :

            case "Rectangle" :

            case "RoundRect" :

                if (obj.FrameParent.ObjectValid()) {

                    obj = obj.FrameParent;

                } else {

                    obj = 0;

                }

                break;

            case "XRef" :

            case "Var" :

                prop = doc.GetTextPropVal (obj.TextRange.beg, Constants.FP_InTextObj);

                var obj = prop.propVal.obj;

                break;           

            default:

                // Prevent endless loop if unknown object type is found.

                obj = 0;

                break;

        }

    }

    if (frame) {

        return frame.PageFramePage;

    } else {

        return 0;

    }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 12, 2017 Dec 12, 2017

Copy link to clipboard

Copied

LATEST

Thank You, Rick - I feared that I will need such an elaborate process you provide with function GetPage.

Now my function DisplayVariable became very simple:

function DisplayVariable (oDoc, iVar) { //=== display the indexed variable ========================
//           Select variable to visualize the location of it
// Arguments oDoc: current document
//           iVar: index in array of variable objects
// Called by
// Reference GetPage by Rick Quatro, https://forums.adobe.com/thread/2424187
var oPage, oTR;
  if (settings.bIsDebug) {ZTrace ();} 
  oPage = GetPage (goFMc.aDocVars[iVar].VarObj, oDoc); 
  if (oPage.ObjectValid () === 1) { 
    oDoc.CurrentPage = oPage;                     // Go to the page containing the variable. 
  } 
  oTR = goFMc.aDocVars[iVar].TextRange;
  oDoc.TextSelection = oTR;                       // Variable is selected
  oDoc.ScrollToText(oTR);                         // Selection is viewed
} //--- end DisplayVariable


... and it works like a charm. Later I will insert here and there "display on/off" to avoid flicker of the window.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines