Skip navigation
Currently Being Moderated

CS5.5: How do you derive the size of the pasteboard given an ISpread?

Mar 15, 2012 8:32 PM

Basically what I'm doing is programmatically creating a frame on a document and placing the frame anywhere.

This works as long as I create the frame somewhere on the pasteboard.

(I'm defining the pasteboard as that white area on which the pages are positioned.)

 

If I place a frame anywhere fully on the pasteboard then things are all okay.

Even if the new frame slightly overlaps the pasteboard then things are all okay.

However, if I create the new frame so that it is entirely not on the pasteboard then it will crash InDesign.

 

What I need is some way to determine the rectangular bounds of the pasteboard.

This would mean that I could then push the new frames back onto the pasteboard to stop the crash.

However I can't figure out how to get the pasteboard size.

 

Any ideas on how to get a PMRect of the pasteboard bounds when given a ISpread?

 
Replies
  • Currently Being Moderated
    Mar 27, 2012 11:44 PM   in reply to Another Andrew

    Hi,

     

    I think you don't need the size of the pastebord, instead you need the size of the spread in pasteboard coordinates. So you can use the IGeometry interface of the kSpreadBoss to get the bounding box and transform it from inner coordinates to pastebord coordinates.

     

    Markus

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 28, 2012 11:55 PM   in reply to Another Andrew

    Hi,

     

    and what about the pasteboard border values from IPasteboardPrefs added to the page bounds?

     

    Markus

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 29, 2012 12:14 PM   in reply to Another Andrew

    Andrew Andrew,

     

    Do you really need the size of the pasteboard?

     

    Do you want to create frames on the page?

     

    I've hacked some code to create a text frame on all pages in a document. Not saying it is perfect and you should add lots of extra checking. Most of this code has been gleened from the sample in the SDK.

     

    It would be nice if the experts pointed out any short commings.

     

    Here is the code, feel fee to pull it apart. ( it did a rough and dirth job for me ).

     

    ========================================================

     

    #include "ISpreadList.h"

    #include "ISpread.h"

    #include "IGeometry.h"

    #include "ITransform.h"

    #include "TransformUtils.h" // InnerToPasteboard

    #include "SplineID.h"  // kSplineItemBoss

    #include "PreferenceUtils.h"

     

    #include "INewPageItemCmdData.h"

    #include "IMultiColumnItemData.h"

     

    UIDRef CreateTextFrame(const UIDRef& parentUIDRef,

                                                                                                        const PMRect& boundsInParentCoords,

                                                                                                        int32 numberOfColumns,

                                                                                                        bool16 verticalFrame,

                                                                                                        UIDRef* storyUIDRef)

    {

              UIDRef result = UIDRef::gNull;

      do

              {

                        PMPoint topLeft = boundsInParentCoords.LeftTop();

                        PMPoint rightBottom = boundsInParentCoords.RightBottom();

     

                        PMPointList points(2);

                        points.push_back(topLeft);

                        points.push_back(rightBottom);

     

      // Create the command.

      InterfacePtr<ICommand> createTextFrameCmd(CmdUtils::CreateCommand(kCreateMultiColumnItemCmdBoss));

                        ASSERT(createTextFrameCmd);

                        if (createTextFrameCmd == nil) {

      break;

     

                        }

     

      // Set up the INewPageItemCmdData data interface.

                        InterfacePtr<INewPageItemCmdData> newPageItemCmdData(createTextFrameCmd, UseDefaultIID());

                        ASSERT(newPageItemCmdData);

                        if (newPageItemCmdData == nil) {

      break;

                        }

      // ClassID of frame in which kMultiColumnItemBoss will be created.

                        const ClassID graphicFrameClassID = kSplineItemBoss;

                        newPageItemCmdData->Set(parentUIDRef.GetDataBase(), graphicFrameClassID, parentUIDRef.GetUID(), points);

     

      // Set up ICreateMCFrameData.

                        InterfacePtr<ICreateMCFrameData> createFrameData(createTextFrameCmd, UseDefaultIID());

                        ASSERT(createFrameData);

                        if (createFrameData == nil) {

      break;

                        }

      // We recommend you don't activate the text editor via kCreateMultiColumnItemCmdBoss.

      // Under InDesign 3.0 the default value of ICreateMCFrameData::SetActivateTextEditor

      // has changed from kTrue to kFalse because many expensive notifications happen if

      // the text editor is activated.

      //createFrameData->SetActivateTextEditor(nil) ;          // nil to not activate text editor

      // Default is that it isn't activated anyway, this call was bogus (irp)

     

      // Specify the frame orientation

      ICreateMCFrameData::Orientation orientation = ICreateMCFrameData::kHorizontal;

                        if (verticalFrame == kTrue) {

                                  orientation          = ICreateMCFrameData::kVertical;

                        }

                        createFrameData->SetOrientation(orientation);

     

      // Set up IMultiColumnItemData to override defaults.

                        InterfacePtr<IMultiColumnItemData> multiColumnItemData(createTextFrameCmd, UseDefaultIID());

                        ASSERT(multiColumnItemData);

                        if (!multiColumnItemData) {

      break;

                        }

      //          CAlert::InformationAlert( "Hello ");

     

      // 1037710+

      // Under InDesign 4.0 the text frame options such as

      // as insets are now parameters passed to kCreateMultiColumnItemCmdBoss,

      // the command no longer picks up these defaults from the workspace,

      // instead the client code must direct the command at the values to use.

                        InterfacePtr<ITextOptions> textOptions((ITextOptions*)::QueryPreferences(ITextOptions::kDefaultIID, parentUIDRef));

                        if (textOptions) {

                                  multiColumnItemData->SetTextFrameOptionsData(textOptio ns);

                                  InterfacePtr<IBaselineFrameGridData> baselineFrameGridData(textOptions, UseDefaultIID());

                                  if (baselineFrameGridData) {

                                            multiColumnItemData->SetBaselineFrameGridData(bas elineFrameGridData);

                                  }

                        } //1037710+

                        if (numberOfColumns > 0) {

                                  multiColumnItemData->SetNumberOfColumns(numberOfColumn s);

                        }

     

      // Process the command.

                        if (CmdUtils::ProcessCommand(createTextFrameCmd)!=kSuccess) {

      ASSERT_FAIL("kCreateMultiColumnItemCmdBoss failed");

      break;

                        }

     

      // The command returns a reference to the graphic frame, normally a kSplineItemBoss,

      // with which the underlying kMultiColumnItemBoss and kFrameItemBoss objects are

      // associated.

                        const UIDList& outItemList = createTextFrameCmd->GetItemListReference();

                        ASSERT(outItemList.Length() > 0);

                        if (!(outItemList.Length() > 0)) {

      break;

                        }

                        result = outItemList.GetRef(0);;

                        ASSERT(result != UIDRef::gNull);

     

      // If the caller requested it by passing in a pointer return a reference

      // to the story associated with the text frame.

                        if (storyUIDRef) {

                                  *storyUIDRef = UIDRef(parentUIDRef.GetDataBase(), createFrameData->GetStory());

                        }

     

              } while(false);

     

      return result;

    }

     

    #include "ILayerUtils.h"

    #include "ISpreadLayer.h"

     

    UID GetDefaultLayerUID(IDataBase *db, ISpread *spread)

    {

      InterfacePtr<IDocument> doc(db, db->GetRootUID(), UseDefaultIID());

              InterfacePtr<IDocumentLayer> activeDocLayer(Utils<ILayerUtils>()->QueryDocumentActiveLayer(doc));

              InterfacePtr<ISpreadLayer> spreadLayer(spread->QueryLayer(activeDocLayer));

     

              return ::GetUID(spreadLayer);

    }

     

     

    void do_create_stuff ( void )

    {

              IDocument *doc = Utils<ILayoutUIUtils>()->GetFrontDocument ( );

              if ( !doc )

      return;

              do {

     

                        IDataBase* db = ::GetDataBase( doc );

     

      InterfacePtr<ISpreadList> spreadList ( doc, IID_ISPREADLIST );

                        if (spreadList)

                        {

                                  uint32 spreadCount = spreadList->GetSpreadCount ( );

                                  for (uint32 i = 0; i < spreadCount; i++)

                                  {

                                            UID spreadUID = spreadList->GetNthSpreadUID ( i );

                                            InterfacePtr<ISpread> spread(db, spreadUID, UseDefaultIID ( ));

                                            if ( spread )

                                            {

                                                      int32 numPages = spread->GetNumPages ( );

                                                      for ( int32 j = 0; j < numPages; j++ )

                                                      {

                                                                UID pageUID = spread->GetNthPageUID ( j );

                                                                UID layerUID = GetDefaultLayerUID ( db, spread );

                                                                PMRect r(1.0,1.0,20.0,30.0);

                                                                InterfacePtr<IGeometry> pageGeometry ( db, pageUID, UseDefaultIID ( ));

                                                                ::TransformInnerRectToPasteboard ( pageGeometry, &r );

     

                                                                CreateTextFrame ( UIDRef(db, layerUID), r, 1, false, 0L );

                                                      }

                                            }

                                  }

                        }

              } while ( false );

     

    }

     

    ===============================

     

    P.

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 29, 2012 11:55 PM   in reply to Another Andrew

    Another Andrew,

     

    Ah, I miss understood. You could use r.left after the transform for page 0.

     

    P.

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 30, 2012 1:19 AM   in reply to Another Andrew

    Hi Another Andrew,

     

    what do you mean with "all possible pasteboards in a document"? There is only one pasteboard, see programming guide:

     

    ===========================

    ...

    Pasteboard coordinate space

     

    The pasteboard coordinate space is the global coordinate system that encloses all objects in a document,

    as shown in the following figure.

    ...

    All objects in a layout can have their coordinates expressed in pasteboard coordinates. The origin is the

    center of the first spread. The x axis increases from left to right; the y axis decreases from up to down. The

    length along each axis is measured in the PostScript unit of points.

    ...

    ===========================

     

     

     

     

     

    To get size of each spread I use the following code and it works as expected:

     

    ===========================

      IDocument* doc = ac->GetContextDocument();

      if (doc)

        {

        InterfacePtr<ISpreadList> sl(doc, UseDefaultIID());

        if (sl)

          {

          for (int32 i = 0; i < sl->GetSpreadCount(); ++i)

            {

            InterfacePtr<IGeometry> geo(sl->QueryNthSpread(i));

            if (geo)

              {

              PMRect rect = geo->GetPathBoundingBox();

              TransformInnerRectToPasteboard(geo, &rect);

              rect = rect;

              }

            }

          }

        }

    ===========================

     

     

    Markus

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points