Saturday, January 05, 2008

 

Instructive Confusion

The other day, I went so far as to report a bug to Adobe only to discover that I was missing the obvious. It wasn't a bug I was experiencing, but it surely would make a nice feature request. I was working with a book and I had all the documents open. But one of the documents was of primary interest to me at that point in time, and I had two windows open into it, arranged to be side-by-side on my screen.

When I double-clicked that document in the book window, I expected both windows to come to the front. But only one did. And, as luck would have it, it was the one on the left that I had temporarily forgotten about. I was expecting the window on the right to come to the front. When it didn't after repeated tries, I fired off a bug report to Adobe, only to feel rather silly a few minutes later when I realized that the window at left was indeed a window of the document I was trying to wake up. So, I modified my report and made it a feature request instead.

Anyway, it being Saturday evening and I'm sitting here amusing myself messing around with scripts while listening to Mahler's Ninth Symphony, it occurred to me that I could write a script to bring all the windows of the active document to the front. I decided that I wanted them to retain whatever stacking order they already had, so I thought that all that meant was I should cycle through all the active document's windows and bring them to the front starting with the back one.

It came as quite a blow when this script didn't work:
//DESCRIPTION: Bring all Windows of active document to the front

if (app.windows.length > 0) {
bringToFront(app.windows[0].parent);
}

function bringToFront(aDoc) {
var myWindows = aDoc.windows;
for (var j = myWindows.length - 1; j >= 0; j--) {
app.activeWindow = myWindows[j];
}
} // end bringToFront
In as much as it did bring all the active document's windows to the front, you could say it did work, but it reversed the order of the windows. That which was at the back was now at the front (I only had two windows open; with more the result would have been more muddled).

Why is this? Because myWindows is pointing at the collection of windows owned by the active document, so each time I changed the order of the windows, the order of their references in in myWindows also changed. I've fallen into this trap so many times with objects of various sorts, you'd think I'd see it coming. The solution is to deploy getElements() to create an array that captures a snapshot of the order of the windows before we perform the loop, like this:
//DESCRIPTION: Bring all Windows of active document to the front

if (app.windows.length > 0) {
bringToFront(app.windows[0].parent);
}

function bringToFront(aDoc) {
var myWindows = aDoc.windows.everyItem().getElements();
for (var j = myWindows.length - 1; j >= 0; j--) {
app.activeWindow = myWindows[j];
}
} // end bringToFront
Now, the contents of myWindows is not affected by the changes made in the loop and so the windows end up in the order I wanted them, at the front of any other windows that might be open into other documents.

Note: app.windows[0].parent is equivalent to app.documents[0], but this is a script about windows, so I used the window-based construction.

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?