Tuesday, October 25, 2011

Grouping Graphics

The following example shows how to group graphic objects within an anchored frame. It works on the selected graphic. If two or more graphics are selected, it asks the user to select just one.

Recall that grouped graphics within FrameMaker can be manipulated as a unit.  While this script works with anchored frames, it could have worked with unanchored frames or both.

For example, assume that the selected graphic contains the following shapes, each ungrouped as indicated by the fact that they can be selected individually.

The script groups them into a graphic that can be worked with as a unit as indicated by the change in the graphic handles.

The script first determines if there is in fact a selected graphic using the document property FirstSelectedGraphicInDoc. If there is indeed such a graphic, it then determines if that graphic is an anchored frame.

Once a selected anchored frame is detected, the script creates a group object using the document method NewGraphicObject(). It passes in the object type and the ID of an anchored frame.

The script them loops through the list of graphics in the frame. Each object found is assigned the group parent just created. When the script completes the graphics within that frame are part of a single group.

doc = app.ActiveDoc;
aFrame = doc.FirstSelectedGraphicInDoc;
   
if (!aFrame.ObjectValid()) {
    Alert("Select an anchored frame and try again.", Constants.FF_ALERT_CONTINUE_WARN);
    }
else if (aFrame.type != Constants.FO_AFrame) {
    Alert("Selected object is not an anchored frame. Adjust your selection and try again.",
    Constants.FF_ALERT_CONTINUE_WARN);
    }
else {  // we have an anchored frame
    group = doc.NewGraphicObject(Constants.FO_Group, aFrame);
    graphic = aFrame.FirstGraphicInFrame;
    while (graphic.ObjectValid()) {
        graphic.GroupParent = group;
        graphic = graphic.NextGraphicInFrame
        }
     Alert("All graphics in this anchored frame have been grouped.",
        Constants.FF_ALERT_CONTINUE_NOTE);
    }

NOTE: If there are already grouped graphics within the anchored frame, they are treated no differently than the rectangle, ellipse or oval. The group becomes a nested group.

NOTE: Although they are graphics, anchored frames cannot be grouped. If there was a nested anchored frame, setting its group parent would have no effect.

2 comments:

  1. If you have one simple object in the Aframe (eg. a rectangle), you are going to build a group made of one object ONLY, that is highly dangerous. FrameMaker will badly crash saving the document.

    ReplyDelete
  2. I have not taken the time to test out this issue so please take that into account in considering my comment.

    In general, the FDK and ExtendScript allow one to automate actions a user might take manually. Clearly, a user cannot create a group with only one graphic object. On the other hand, with ExtendScript, you must first create a group and then add objects to that group. If for some reason, no objects get added to such a group, the group exists in its anchored frame with no graphics inside it. Similarly, one could add just a single object and stop at that point. Do these actions make sense from a practical view point? Likely not. On the other hand, should they crash FrameMaker. I would say no. If they do, I would consider it a bug.

    Further, as anonymous implies, it is best to be careful and think about edge cases.

    ReplyDelete