8 Replies Latest reply on Nov 26, 2015 1:33 AM by Vamitul

    C#/JavaScript How to Set Primary Text Frame?

    michaelt5330502 Level 1

      Hi,

       

      I'm trying to work with InDesign scripting API with C# for my work. I'm new to both the InDesign scripting API, and using InDesign as well.

      I'm trying to construct a master spread, with text frames in such a way that the text frame on the left page of the spready would flow into the text frame on the right page.


      I've read there is the Primary Text Frame option for the master spread, but I can't seem to figure out how to use it.

      Is there anyone who could show me an example scripting code to set the primary text frame for a master spread/page?


      Here's the code I have so far.

      The issue I have is in line 53, where when I try to run it, it gives me the very generic error "Invalid object for this request.", which leads me to believe I'm doing it wrong.

       

              public static byte[] CreatePageBasedOnCreatedMasterSpread(string savePath)
              {
                  Application application = ActivateInDesign();
      
      
                  // Create new document
                  application.Documents.Add(true, application.DocumentPresets.FirstItem());
      
      
                  // Get active document and change some settings
                  Document document = application.ActiveDocument;
                  document.DocumentPreferences.FacingPages = true;
                  document.DocumentPreferences.PageWidth = 210;
                  document.DocumentPreferences.PageHeight = 297;
      
      
                  document.DocumentPreferences.CreatePrimaryTextFrame = true;
                  document.TextPreferences.SmartTextReflow = true;
      
      
                  MasterSpread masterSpread = document.MasterSpreads.Add();
                  masterSpread.BaseName = "CustomMasterSpread";
                  masterSpread.NamePrefix = "AC";
      
      
                  //Set the document's ruler origin to page origin. This is very important
                  //--if you don't do this, getting objects to the correct position on the
                  //page is much more difficult.
                  document.ViewPreferences.RulerOrigin = idRulerOrigin.idPageOrigin;
      
      
                  Page leftPage = masterSpread.Pages.FirstItem();
                  Page rightPage = masterSpread.Pages.LastItem();
      
      
                  leftPage.MarginPreferences.Top = rightPage.MarginPreferences.Top = 10;
                  leftPage.MarginPreferences.Bottom = rightPage.MarginPreferences.Bottom = 10;
                  leftPage.MarginPreferences.Left = rightPage.MarginPreferences.Left = 30;
                  leftPage.MarginPreferences.Right = rightPage.MarginPreferences.Right = 20;
      
      
                  // Create a text frame. Do not add text to this, as this is a master spread text frame.
                  // Link their flow together
                  TextFrame primaryFirstPageTextFrame = leftPage.TextFrames.Add(document.Layers.FirstItem(), idLocationOptions.idUnknown, leftPage);
                  TextFrame primarySecondPageTextFrame = rightPage.TextFrames.Add(document.Layers.FirstItem(), idLocationOptions.idUnknown, rightPage);
                  primaryFirstPageTextFrame.NextTextFrame = primarySecondPageTextFrame;
                  //Set primary text frame of master spread to be the two linked textframes
      
      
                  primaryFirstPageTextFrame.GeometricBounds = GetPageBoundsWithMargin(leftPage, document);
                  primarySecondPageTextFrame.GeometricBounds = GetPageBoundsWithMargin(rightPage, document);
               
                  masterSpread.PrimaryTextFrame = primaryFirstPageTextFrame; //This causes the error
               
                  return GetFileData(document, savePath);
              }
      
      

       

      I notice JavaScript API is very similar to C# as well, so it'd also help if I get a JavaScript answer.

        • 1. Re: C#/JavaScript How to Set Primary Text Frame?
          Jump_Over Level 5

          Hi,

           

          Never met such property for Spread  like primaryTextFrame in javascript.

           

          There is "startTextFrame" property as a first text frame in the thread, but

          you did set an order of frames while applying "nextTextFrame" property, so there is a proper order set inside a Spread, I guess.

           

          At least involving "autoflow" utility while placing a Story ==> this order should be used.

           

          Am I miss something?

           

          Jarek

          • 2. Re: C#/JavaScript How to Set Primary Text Frame?
            Harbs. Level 6

            @Jarek, primaryTextFrame is a property of MasterSpread. (not Spread)

             

            @Michael, I've never used primary text frames, so I can't help with that.

            • 3. Re: C#/JavaScript How to Set Primary Text Frame?
              Laubender Adobe Community Professional & MVP

              Hi Michael,

              basically you can do something like that (in ExtendScript) :

               

              //Store value:
              var storedPreset = app.documentPresets[0].createPrimaryTextFrame;
              
              //Let's set it to true:
              app.documentPresets[0].createPrimaryTextFrame = true;
              
              //Add the document, name the master as you wish etc.pp. :
              app.documents.add
              (
              
                  {
                      documentPrefreneces :
                          {
                              facingPages : true
                              ,
                              pageWidth : "210 mm"
                              ,
                              pageHeight : "297 mm"
                             
                          }
                  }
              
              );
              //Reset to stored value:
              app.documentPresets[0].createPrimaryTextFrame = storedPreset;
              

               

              Uwe

              • 4. Re: C#/JavaScript How to Set Primary Text Frame?
                Laubender Adobe Community Professional & MVP

                The added document will automatically contain a primary text frame on the left and the right page of the master spread "A" threaded together.

                I don't think you can add a primary text frame after you added a document in asigning a text frame on the page of a master spread.

                (I get the same error message as you if I tried, because my app.documentPresets[0].createPrimarytextFrame was initally set to false.)

                 

                Uwe

                 

                Note: In the script above:

                documentPrefreneces

                should be:

                documentPreferences

                 

                (a typo)

                • 5. Re: C#/JavaScript How to Set Primary Text Frame?
                  michaelt5330502 Level 1

                  Thanks Laubender,

                   

                  I got around the issue by using document presets to create a default masterspread (i.e. "A-Master") to use primary text frames.

                  And I just had to use that "A-Master" masterspread as a base for my own masterspread.

                   

                  I included my final code for anyone having a similar issue.

                          public static byte[] CreatePageBasedOnCreatedMasterSpread(string savePath)
                          {
                              Application application = ActivateInDesign();
                  
                  
                              //Change preset settings.
                              DocumentPreset defaultPreset = application.DocumentPresets.FirstItem();
                              defaultPreset.CreatePrimaryTextFrame = true;
                  
                  
                              // Create new document, and change some settings
                              Document document = application.Documents.Add(true, defaultPreset);
                              document.DocumentPreferences.FacingPages = true;
                              document.DocumentPreferences.PageWidth = 210;
                              document.DocumentPreferences.PageHeight = 297;
                              document.TextPreferences.SmartTextReflow = true;
                  
                  
                              MasterSpread masterSpread = document.MasterSpreads.Add();
                              //Base the master spread to the first default masterspready A-Master
                              //This already have text frames set to be primary text frames.
                              masterSpread.AppliedMaster = document.MasterSpreads.FirstItem();
                  
                  
                              masterSpread.BaseName = "CustomMasterSpread";
                              masterSpread.NamePrefix = "AC";
                  
                  
                              //Set the document's ruler origin to page origin. This is very important
                              //--if you don't do this, getting objects to the correct position on the
                              //page is much more difficult.
                              document.ViewPreferences.RulerOrigin = idRulerOrigin.idPageOrigin;
                  
                  
                              Page leftPage = masterSpread.Pages.FirstItem();
                              Page rightPage = masterSpread.Pages.LastItem();
                  
                  
                              leftPage.MarginPreferences.Top = rightPage.MarginPreferences.Top = 10;
                              leftPage.MarginPreferences.Bottom = rightPage.MarginPreferences.Bottom = 10;
                              leftPage.MarginPreferences.Left = rightPage.MarginPreferences.Left = 30;
                              leftPage.MarginPreferences.Right = rightPage.MarginPreferences.Right = 20;
                  
                  
                              // Do not add text to this, as this is a master spread text frame.
                              // Link their flow together
                              TextFrame primaryFirstPageTextFrame = leftPage.TextFrames.FirstItem();
                              TextFrame primarySecondPageTextFrame = rightPage.TextFrames.FirstItem();
                  
                  
                              primaryFirstPageTextFrame.GeometricBounds = GetPageBoundsWithMargin(leftPage, document);
                              primarySecondPageTextFrame.GeometricBounds = GetPageBoundsWithMargin(rightPage, document);
                  
                  
                              //Doesn't work...for some reason?
                              //masterSpread.PrimaryTextFrame = primaryFirstPageTextFrame;
                              //masterSpread.PrimaryTextFrame = masterSpread.PrimaryTextFrame;
                              //masterSpread.PrimaryTextFrame = idNothingEnum.idNothing;
                          
                              return GetFileData(document, savePath);
                          }
                  
                  
                  
                  
                  

                   

                  Post-Investigation

                  After setting up a working masterspread with primary text frames, I break-pointed with Visual Studio and checked to see what valid values the "masterSpread.PrimaryTextFrame" has (see line 56 of below code).
                  It has all properties and values of a TextFrame in the MasterSpread....
                  The "id" property matches my left masterspread left page's TextFrame too, so I'm thinking it must it must be set to a TextFrame.

                  I had tried to set it as:

                  • "masterSpread.PrimaryTextFrame = primaryFirstPageTextFrame;"
                  • "masterSpread.PrimaryTextFrame = masterSpread.PrimaryTextFrame;"
                  • "masterSpread.PrimaryTextFrame = idNothingEnum.idNothing;"

                  However all wouldn't work and have the same error as my original post.
                  So I could only conclude either:

                  • There is some other way to set the PrimaryTextFrame for a masterspread, or
                  • Adobe CS6 scripting and lower doesn't fully support PrimaryTextFrame property for master spread yet (a bug), or
                  • PrimaryTextFrame wasn't supposed to be set, and is read-only.
                  • 6. Re: C#/JavaScript How to Set Primary Text Frame?
                    Laubender Adobe Community Professional & MVP

                    Michael, I'm not surprised at all.

                     

                    If you have a document open and looking at document preferences in the UI, the option for "PrimaryTextFrame" is always grayed out.

                    Whether "PrimaryTextFrame" was set or not by adding the document.

                     

                    However, working with the UI you are able to transform a text frame on the master spread to a primary one.

                    This is not working with ExtendScript, if you assign a text frame (or a pageItem, documentation explicitly says pageItem; I wonder why it does not say textFrame) to the property primaryTextFrame of object masterSpread.

                     

                    Just an idea:

                    1. You can duplicate a master spread with a "PrimaryTextFrame" from document A to a document B where no "PrimaryTextFrame" was defined initally.

                    The "PrimaryTextFrame" of A is preserved in document B. By script and also through the UI.

                     

                    var docAsource = app.documents[0]; // Contains the master spead A with a primary text frame
                    var docBtarget = app.documents[1]; // Does not contain a primary text frame and was not built with a primary text frame initally
                    docAsource.masterSpreads[0].duplicate(LocationOptions.AFTER,docBtarget.masterSpreads[0]);
                    


                    What is not working:

                    2. You can move or duplicate a "PrimaryTextFrame" from doc A to doc B where no "PrimaryTextFrame" was defined initally.

                    The "PrimaryTextFrame" of A is not preserved as primary in document B. It's just a text frame on the master after moving or duplicating.

                    (Copy/paste (paste in place) does the same; it's not working as expected)

                     

                    Uwe

                    • 7. Re: C#/JavaScript How to Set Primary Text Frame?
                      Laubender Adobe Community Professional & MVP

                      And the r/w in the documentation is a bit misleading. Perhaps.

                      In fact once having access to a primary text frame, you can change its properties, it is simply a text frame tied to a specific master spread.

                       

                      Uwe

                      • 8. Re: C#/JavaScript How to Set Primary Text Frame?
                        Vamitul Level 4

                        I ran into this issue also. Based on the error message i would say it is a bug in the script bindings (it expects an actual textframe object, but remember that ExtendScript actually works - behind the scene - with id's and commands).