Hi,
How can i convert a group into multistate object? Please help.
Thanks,
Vanitha Allwin
Here is the script which i have used:
myDoc=app.activeDocument;
for(myCounter = 0; myCounter < myDoc.pages.length; myCounter++){
cnt=0;
for(counter2=myDoc.pages[myCounter].pageItems.length-1;counter2>=0;co unter2--){
if(myDoc.pages[myCounter].pageItems[counter2].itemLayer.name=="Répons e"){
cnt++;
theAnswer = myDoc.pages[myCounter].pageItems[counter2];
thePageRef=myDoc.pages[myCounter];
var theMSO = thePageRef.multiStateObjects.add({name:"multiState"+cnt, geometricBounds: theAnswer.geometricBounds});
theMSO.states.item(0).name = "m1";
theMSO.states.item(1).name = "m2";
theMSO.states.item(0).pageItems.add({contents:"", geometricBounds:theMSO.geometricBounds});
var myTextFrame = theMSO.states.item(1).addItemsToState(theAnswer) ;
}
}
@Vanitha – I did not test your code, but I can show you an code example that generates an MSO out of a selection. It is working with groups and single objects selected (that is a special case). There are no tests for a valid selection, but I give you hints in the code what is missing:
var d=app.documents[0];
var MSOlength = d.multiStateObjects.length;
if(app.selection.length ===0){alert("You have nothing selected. STOP!"){exit(0)}};
//We have to add some more tests for the validity of a selection:
//Do not add selection to an MSO, if the selection is text, if it is locked, if it is an anchored object
//etc.
var sel = app.selection;
//Adding an default MSO with 2 default states,
//each contain 1 default rectangle
//at position (upper left corner) [0,0]:
var MSO = app.documents[0].multiStateObjects.add({
name:"MSO"+"_"+(MSOlength+1)
});
//Adding all selected objects to a seperate state:
for(var n=0;n<sel.length;n++){
MSO.addItemsAsState(sel[n]);
};
//Special case: selection length = 1:
//We add another state and set the geometric bounds of its default rectangle
//to the geometric bounds of the selected object:
if(sel.length===1){
MSO.states.add();
MSO.states[-1].pageItems[0].geometricBounds = sel[0].geometricBounds;
};
//Cleaning up:
//1. Removing the 2 default states:
MSO.states[0].remove();
MSO.states[0].remove();
//2. Renaming the states:
for(var n=0;n<MSO.states.length;n++){
MSO.states[n].name = "State "+(n+1);
};
Adding objects (also groups) to an already existing state inside an MSO is a different case.
I still don't know if you want to add each object of a group to its own state. Would you please answer that?
Uwe
The requirement is that we already have set of answers in different pages and it should be converted into multistate object. The converted multistate object should be empty in the first state and the second state holds the answer which would be shown on clicking a button lately. I hope you'll understand what i mean. If not, please let me know.
Regards,
Vanitha Allwin
@Vanitha – What kind of object is an "answer"? I guess it could be a text frame or a group. Could it be a couple of objects? If so, do they go all together in one single state?
If so, group all objects that define an "answer", create a new MSO, add that group to the MSO with addItemsAsState().
The MSO now has 3 states. Remove the first state and then set the geometricBounds of the default rectangle of the first state (formerly the second default state) to the geometricBounds of the group.
If the "answer" is a single object (no group) you simply add that single object to a new MSO. Again: remove the first state, set the geometricBounds of the default rectangle of the first state (formerly the second default state) to the geometricBounds of the single object you detect as "answer".
I hope I understood your basic situation.
If not, can you provide a simple sample as an IDML file somewhere to download?
Uwe
@Laubender- The answer can be text or group of objects. Whatever it is, when it's converted into multistate object, the state 0 should be empty and state 1 should have text or group so that the answer won't appear in the beginning but when clicking button. The following code works for every object except group:
myDoc=app.activeDocument;
for(myCounter = 0; myCounter < myDoc.pages.length; myCounter++){
cnt=0;
for(counter2=myDoc.pages[myCounter].pageItems.length-1;counter2>=0;co unter2--){
if(myDoc.pages[myCounter].pageItems[counter2].itemLayer.name=="answer "){
cnt++;
theAnswer = myDoc.pages[myCounter].pageItems[counter2];
thePageRef=myDoc.pages[myCounter];
var theMSO = thePageRef.multiStateObjects.add({name:"multiState"+cnt, geometricBounds: theAnswer.geometricBounds});
theMSO.states.item(0).name = "m1";
theMSO.states.item(1).name = "m2";
theMSO.states.item(0).pageItems.add({contents:"", geometricBounds:theMSO.geometricBounds});
var myTextFrame = theMSO.states.item(1).addItemsToState(theAnswer) ;
}
}
The line which is bold shows error "Unable to set bounding box" for groups. Please help me.
@Vanitha – I can only repeat what I said in my answer #7 in more detail:
0. Store the geometricBounds of "theAnswer" in a variable:
var theAnswerGB = theAnswer.geometricBounds;
1. add a new MSO
1.1 without setting any properties besides "name".
1.2 leave the geometricBounds alone
var theMSO = thePageRef.multiStateObjects.add({name:"multiState"+cnt});
2. then add the "answer" as new state (see my code in #5):
theMSO.addItemsAsState(theAnswer);
3. then get rid of the first default state of the MSO:
theMSO.states[0].remove();
3.1 you now have an MSO with 2 states:
state 1: a default empty rectangle at position [0,0] (upper left corner)
state 2: your "theAnswer" object
4. and now the trick: set the default rectangle of state 1 to the geometricBounds of "theAnswer":
theMSO.states[0].pageItems[0].geometricBounds = theAnswerGB;
5. Finally rename the states of the MSO:
theMSO.states[0].name = "m1";
theMSO.states[1].name = "m2";
I think the core of this is:
1. Do not set the geometricBounds of the MSO during creation of the new MSO
2. Use "addItemsAsState()" instead "addItemsToState()" for adding "theAnswer" to the new MSO
Hope this helps,
Uwe
After investigating the individual original page (thank you, Vanitha, for providing the file), the case seems quite clear to me:
The problem is a tiny group of graphic lines, which is so small, that its geometric bounds cannot be applied to a new MSO (so it seems at least).
Strange enough one could add a new MSO to a page that is 0.01 x 0.01 mm:
var myMSO = app.documents[0].pages[0].multiStateObjects.add();
myMSO.states.everyItem().pageItems.everyItem().geometricBounds = [0,0,"0.01 mm","0.01 mm"];
I have to find out what that means in regards to this individual case here.
Maybe:
1. add a new MSO without setting its geometricBounds and later set the geometricBounds of its default objects to a very small size.
2. then add the geometricBounds of the object on state 2 to the default object on state 1.
I will report here, if I find a conclusion…
Uwe
After inspecting the problem group, I have to tell you, that the height of that group = 0 (when calculated in geometricBounds).
You cannot apply a height of "0" to an MSO.
GeometricBounds of problem group:
45.0541666666667,
17.8809523809524,
45.0541666666667,
19.5178571428571
VisibleBounds of problem group :
45.0333333333333,
17.8809523809524,
45.075,
19.5178571428571
So, instead of using the geometricBounds properties, we should use the visibleBounds properties to determine the size of the MSO (its geometricBounds).
Uwe
North America
Europe, Middle East and Africa
Asia Pacific