A window to display info from all open docs

I’m trying to figure out a way to have a window in my MainMenu.xib that will display info from all the currently open documents in my app. Probably a table that lists the the name of each open document and a value from a text field from each document.

It seems simple, even simple to describe, but I can’t figure out where to start.


Whichever method you use to open a file could call a method on the app delegate, letting it know that it has opened. And if you have a delegate of your document’s window, you could implement -windowWillClose: to call a method letting the app delegate know that. If the text field can change, you’re going to need it to call an app delegate method each time it changes.

Thanks Shane, that should get me in the right direction. I’ll let you know how it goes.

Getting there, slowly. I have a document based app that I built following the “People Docs” app in chapter 22. I figured out how to call a method in the App Delegate from a document window (the “tellMeMore” example), but I can’t figure out how to get values from the document window to the app delegate. The appDelegate script tells me the variables are undefined - of course, because they are defined in the CustomDocument script.

I haven’t gotten to the point of figuring out how to call the method automatically when a file is opened yet. I figured I’d better figure out how to get values across first.

Thanks again-

Progress - I got the values from the document to the AppDelegate using stringValue() of the text fields instead of the variables.

Now I want it to happen automatically when the file is opened. How do I call a method on the AppDelegate script from the file open method on the document script?

You call it on current application’s NSApp’s delegate().

Excellent - works great.

At first I put it in the file open handler:
readFromData_ofType_error_(theData, typeName, outError)

but the first file I opened after launching always gave me this error:
Unrecognized function stringValue. (error -10000)

The error went away with subsequent files, but the second file gave me the string value from the first file, the third gave me the value from the second, etc. When I changed the value of the text field it always gave me the value of the text field from the second to the last opened document window, not the current key window.

I figured it was because it was calling the handler before the window was open so I put it in

windowDidBecomeKey_(aNotification) instead. Now I think I’m getting somewhere.

Thanks for your help!


Wow, I’ve never had this much trouble.

    on fileIsOpen()
        set my theShapeName to stringValue() of theShapeField
        set my theShapeQuan to stringValue() of theQuanField
        set my theShapePrice to stringValue() of thePriceField
        log theShapeName
        log theShapeQuan
        log theShapePrice
    end fileIsOpen

    on theUpdate()
        log theShapeName
        log theShapeQuan
        log theShapePrice

        tell arrayController1
            set theCollection to arrangedObjects() as list
            set theNewData to {theQuan:theShapeQuan, theShape:theShapeName, thePrice:theShapePrice}
            set theCollection to theCollection & {theNewData}
	end tell
    end theUpdate

When I call fileIsOpen() in the MainMenu.xib script from the windowDidBecomeKey_(aNotification) in the document script, the variables log correctly for each open doc. But when I want to populate a table in my window on the MainMenu.xib I get the error “Can’t get arrangedObjects of missing value. (error -1728)”.

If I call theUpdate() from a button on the MainMenu.xib window it logs those variables as (null). It does populate the table but it’s blank.

So I seem to have the variables right but my arrayController doesn’t work, or my arrayController works but my variables are missing value.

How do I communicate between my xibs (am I saying that right)?

Getting closer - I figured out how to reference the variables with “current application’s NSApp’s delegate()'s theShapeName()”

but referencing the array controller that way doesn’t seem to work.

tell current application's NSApp's delegate()'s arrayController1
            set theCollection to arrangedObjects() as list
            set theNewGallery to {theQuan:theShapeQuan, theShape:theShapeName, thePrice:theTotal}
            set theCollection to theCollection & {theNewGallery}
end tell

Before it was “Can’t get arrangedObjects of missing value.”
This gives me “Unrecognized function arrangedObjects.”

Did you try current application’s NSApp’s delegate()'s arrayController1()?

I just tried that and I’m back to “Can’t get arrangedObjects of missing value.”

I also tried

set my arrayController1 to current application’s NSApp’s delegate()'s arrayController1()
tell arrayController1

I also tried accessing the window in the app delegate that has the table on it like this:

current application’s NSApp’s delegate()'s theDataWindow()'s makeKeyAndOrderFront_(me)

and got
Unrecognized function makeKeyAndOrderFront_.

Why do you add the new item to the current list, remove everything from the array controller and and add everything again? This does actually the same thing

tell arrayController1 to addObject:{theQuan:theShapeQuan, theShape:theShapeName, thePrice:theShapePrice}

Hi Stefan - Thanks. I got that from a tutorial somewhere and it’s always worked so I never looked for a way to shorten it.

There must be some fundamental concept I’m not understanding. When I call a method on the app delegate script from the application script, I can set the properties contained in the app delegate script. They aren’t declared in the document script so I know I’m setting the right variables.

property theShapeName : missing value

on methodCalledFromDoc()
set my theShapeName to "Something"
log theShapeName
end methodCalledFromDoc

Log shows “Something”, but the text field on the main menu window that is bound to that property stays blank.
This tells me I haven’t really set the value, even though the log tells me I did.

on methodCalledFromMainMenu()
log theShapeName
end methodCalledFromMainMenu

Log shows “(null)”
This confirms that I haven’t really set the value.

So then I have to

on methodCalledFromMainMenu()
set my theShapeName to current application's NSApp's delegate()'s theShapeName()
log theShapeName
end methodCalledFromMainMenu

Log shows “Something”.

So I have to physically click a button on the app delegate window to force the properties to set? Why can’t I set the properties and populate the app delegate window from the document window?

What am I not understanding?

FWIW, I opened a copy of People Docs, added a window to MainMenu.xib with a text field bound to theShapeName, added your handler and property to the app delegate, then added a button to the document window calling this:

    on doIt_(sender)
        current application's NSApp's delegate()'s methodCalledFromDoc()
        current application's NSLog("%@","called")
    end doIt:

And it worked fine. So you might check your code and connections.

Alright, so you’re saying it should work, so I must have some wires crossed. I think I need to start over. It’s a real mess now after all my trials and errors.

Thanks for your help


Ok, here’s my progress:

I tried exactly what you did with the People Docs and I was able to call the method and it did set the property and the text field bound to it, like you said it would and like it should.

So I started a new document based project and built it, very carefully, to do nothing but call a method on MainMenu script from the CustomDocument script to set the value of a property declared in the MainMenu script. According to the log it worked. Then I made a window in the MainMenu.xib, added a text field bound to that property, and it STILL didn’t change when I set the property! Log says the property is set, text field bound to that property says it isn’t.

So I disconnected everything and reconnected them again exactly as they were… and it DID work! Jeez!

But I still couldn’t set the value of the property in the MainMenu.xib to the value of a property in the document.xib. I finally figured out how to declare a property in the MainMenu script that refers to the other script like this:

property theTextIWantToReplace : missing value
property theDocScript : missing value
on transferIt()
set my theDocScript to current application's CustomDocument's alloc()'s init() --(CustomDocument is name of the document script minus .applescript)
set my theTextIWantToReplace to theDocScript's theTextFromTheDoc() as text
end transferIt

so I can refer to the properties in the other script. That was really hard to find an example of, so hopefully this will help someone else in my boat.

Now I have to see if I can talk to an array controller in the other script.

Thanks again


Wow, I hope I’m not being a pest.
Here’s my latest glitch:

The Document script:

property theTextFromTheDoc : "I Like Turtles"

on transferFromHere_(sender)
set my theTextFromTheDoc to "I Like Cows"
current application's NSApp's delegate()'s transferToHere()
end transferFromHere_

The MainMenu script:

property theTextIWantToReplace : missing value

on transferToHere()
set my theTextIWantToReplace to theDocScript's theTextFromTheDoc()
log theTextIWantToReplace
end transferToHere

the result is “I Like Turtles”, not “I like Cows”. How can this be? I set the value of the property before I passed it. If I log it before calling the script in the MainMenu the value is “I Like Cows”, but when I refer to it from the other script it’s the original value.

What should I do differently?

I like them both by the way.

Don’t do that. You’re creating a new window-less (and otherwise problematic) document.

Write a method in your app delegate that sets your property, and call that method from your document.

I had no idea I was doing that. That sounds bad.

That’s what I’m trying to do. The only problem is that the value I want to set the app delegate property to is contained in the document. How do I get that value over to the app delegate? Am I making any sense?

You pass it as the parameter of a method call. Your app delegate contains:

on doItWith_(someThing)
-- do something with someThing here, coercing it an AS class if required
end doItWith_

And your document contains:

current application's NSApp's delegate()'s doItWith_(someThing)

where someThing is what you want to pass.