Xcode Applescript create list of results - xcode

I have been trying to work out the best way to accomplish this and every time I think I am on to something it doesn't seem to work in my situation.
If someone could point me in the right direction to an existing example or the correct google term I would be very grateful.
I am creating a Cocoa - Applescript Application in Xcode 5.
I have the basics in already, which so far prompts the user to select an audio track, the track is then played back in Quick Time and I have a button to return the current play time of the track, as it stands at the moment this returns the time to a variable of SMPTE ala.
tell application "QuickTime Player"
set SMPTE to get current time of document 1
end tell
My problem is what to do with the result of "SMPTE"
I would like to generate a list in a separate window with each button press updating a new row with the new returned value.
I have tried using a NSTableColumn but can't work out how to "auto fill" with each subsequent button press.

A very simplistic way.
Add an NSArrayController to the IB Objects.
Connect it to an outlet.
Select the TableView's TableColumn and go to it Bindings Inspector.
Bind it's Value to Array Controller
And name it's model key path as 'time'
In the TableColumn's Attributes Inspector. Set it's Title to 'time'
The code would be like this:
property ArrayController :missing value
on addTime_(sender) --clicked to add time
tell application "QuickTime Player"
set SMPTE to get current time of document 1
end tell
ArrayController's addObject:{|time|:SMPTE}
end addTime_
The Button would need to be connected to the Action: addTime:
To remove an item:
Simply add a new button and connect it to the ArrayController's Remove Action method.
( By dragging the button's connection to the ArrayController object in IB and selecting remove: )
To Save the data to be able to see it on relaunch:
Select the ArrayController object in IB and go to it's bindings inspector.
Bind it's Control Content's content Array to the 'Shared user defaults Controller'
And name it's model key path as 'theValues'
There is a very good intro tutorial here
And NSArrayController's Docs

Related

How to create multiple windows using "command + n" in non document based application

Is there a way to create/enable having multiple windows using "command + n" in a non document based application? I want to have unlimited instance of that window (not actually unlimited, but might be 6-7 instances) using command + n
Or I have to create a document based app and port all my code in new project template is the only solution?
I can see the menu button for "New" is disabled right now.
A few ways to do this.
First connect the New menu item to an IBAction method.
Name the method whatever makes sense to you.
Next, you will want to add some kind of property to your controller ( app delegate for simplicity ) that is basically a window stack only storing a reference to each window or window controller. NSMutableArray should do nicely.
Now you can do the next part a few ways, but I would recommend creating an NSWindowController subclass with a nib/xib (especially if these windows will have the same basic things in them).
Do what you want in the nib file.
Now in your IBAction method, create a new instance of your window controller class, add it to your mutable array. Tell it to load its window.
You only have to decide if the controller should be removed from the stack and set to nil if its window is closed.
Many ways to handle that, and up to your design to know what is correct.
Try this :-
NSWindowController *yourWindow=[[[[yourWindowController alloc]init]retain]autorelease];
[yourWindow loadWindow];

How do I populate a popup button with AppleScript?

I've found this snippet of code in various place around the 'net:
tell window 1
tell menu of popup button 1
delete every menu item
repeat with catListItem in catList
make new menu item at end of menu items with properties {title:catListItem}
end repeat
end tell
end tell
When I use it in my AppDelegate script in a Cocoa-AppleScript Application, Xcode gives me an error: *t2t_AppDelegate.applescript:25: error: Expected end of line but found identifier. (-2741)* (Line 25 is "tell menu...")
I'm not sure what I'm missing that would allow me to dynamically populate the popup button with a list of terms (catList) that I'm drawing from another application. Any suggestions?
Unless you are running something earlier than Snow Leopard, It looks like you are using AppleScript Studio terminology (which was deprecated in Snow Leopard). Using the current AppleScriptObjC framework, the user interface items are referenced via outlet properties, for example:
property myPopUp : missing value
From the Interface Editor, this property is connected to your popup button, which allows you to use it with various methods in the NSPopupButton class and its parents, such as addItemsWithTitles. Once everything is defined and connected, you would use something like:
set catList to {"next item", "another item", "Items added"}
myPopUp's addItemsWithTitles_(catList)

Applescript and Microsoft Word

I'm working on a applescript to update the content of a document in Microsoft Word. The updating process is quite long (might take more than 5s). So I want to prevent users to change anything during the updating. Do you know whether Microsoft or Applescript a function like that?
In Windows, I can just display a User Form (which is a dialog telling that "we are updating... ") and close that form when it's done. However, I don't know whether I can do the same in Mac (with Applescript alone).
When you say "applescript", I don't know if you mean "plain" applescript or the AppleScriptObjC version. If you mean the latter, then I know ways to do it.
One way I've used during slow processes is to put an overlay view over the whole content view of the window. I make it translucent white to partially obscure the window, and put some kind of message (and maybe a progress indicator) on it. You can just use an NSBox (of the custom type) in IB to make this, and then make a subclass of NSBox to color the view and override mouseDown:. MouseDown:, doesn't need to have any code in it, just by overriding it, you capture any key and mouse events so they don't accumulate on the event queue, and get used by the view below after your overlay goes away. Here's code I've used:
script Overlay
property parent : class "NSBox"
on awakeFromNib()
set overlayColor to current application's NSColor's colorWithCalibratedWhite_alpha_(1,.8)
setFillColor_(overlayColor)
end
on mouseDown_(theEvent)
--log "mouseDown"
end
end script
I have this view as the top most view in the view hierarchy, and set its hidden property to true until I want to show it.

Define the class of the sender when making an IBAction connection in Xcode 4,2.1

In Xcode 4 or above, it has a handy function allowing us to CTRL + drag an object from the interface to the .h file to quickly connect the object with an event method (assume the Assistant Editor is enabled).
Say we have an UIButton in the interface, and we want to add an IBAction for its "touch up inside", we enable the assistant window and press/hold CTRL + Drag the button to the .h file to quickly generate the necessary codes.
In the popup prompt box, say we set "connection" as "Action".
In the "Type" drop-down, we can select "id" or "UIButton". <--- this is where my problem is.
The strange thing in Xcode 4.2.1 is: no matter what I select, it always generates code: "(id)sender" as the argument.
I know it is easy to manually change it to "(UIButton *) sender", but what is the point of this drop-down when it always generates "(id)"?
Is this is a bug of Xcode or am I missing something to make it directly generate the code "(UIButton *) sender" when I select "UIButton" in this drop-down?
Edited on 27/Feb/2012: This is confirmed solved in Xcode 4.3
- (void)action:(id)sender is just the way actions are defined. you can, in theory, connect different UI elements to the same action. after you've created the connection, you can manually change id to whatever class you want, or just do a cast inside the method.

What's a good way to bind from a shared utility window and the frontmost document window?

I have an application which allows for multiple NSDocuments to be open. In this application is a single utility window that contains some functionality that I want to apply to the frontmost document.
I am trying to use bindings here, so the trick is how to cleanly bind the user interface of the utility window to the frontmost document. The goal is that then switching the frontmost document window will update the view in the utility window; controls that are bound to properties of the frontmost document's model would be updated appropriately when state changes in the document's model, etc.
For sending actions from such a window, it's easy to just use first responder; the document object can intercept actions via the responder chain. But I want more than this, and of course you can't bind to the first responder.
A few ideas that I have:
put an object controller in my nib for the shared window. When a document window changes frontmost status, change the content of that binding. A disadvantage of this is that if I were to have another kind of utility window, I'd have to remember to hook up the bindings from the document window to that utility window too!
Make an accessor in the application delegate that gets the frontmost document window by traversing the window list. My utility window would just bind through the application delegate's method. A disadvantage here is that it's not KVO compliant
Have a getter and setter in the application delegate to determine (and perhaps set to be KVO-compliant? would that make sense?) the frontmost document. Perhaps use window notifications set an ivar to the appropriate value when a window loses main status. Update: I'm using this for now, and it actually seems pretty clean. I set the value from the windowDidBecomeMain notification of my doc window and clear it (if it's the current value) in windowWillClose. Unless there is any major objection, this is probably the approach I'll use.
One idea was to bind to mainWindow.windowController.document ... this comes close, except that when my shared window becomes main, then this binding goes away. So really I need to find the frontmost document window's controller (and of the right class).
None of these seem quite right. Is there a better way to do this that I'm missing?
I’ve always bound through Shared Application, mainWindow.document, which works fine. if you have windows w/o documents, you may want to add a mainYourKindOfWindow key that is implemented by watching mainWindow and updating the value based on some filter criteria.
Leopard's TextEdit does this for its inspector. Check it out in file:///Developer/Examples/AppKit/TextEdit.
put an object controller in my nib for the shared window. When a document window changes frontmost status, change the content of that binding.
That makes the most sense to me. You'd change the content to the document instance ([NSDocumentController currentDocument]).
A disadvantage of this is that if I were to have another kind of utility window, I'd have to remember to hook up the bindings from the document window to that utility window too!
Huh? I don't understand this.
Leopard's TextEdit does this for its inspector. Check it out in >file:///Developer/Examples/AppKit/TextEdit.
In TextEdit, inspector values are bound via an intermediate object controller. The controller content object is bound to the shared application mainWindow.
You may bind the content to mainWindow.firstResponder and uncheck "Raises for not applicable keys".
Use the key window, not the main window. KVO might not be supported for NSApplication's keyWindow property, but you can still use NSNotifications if it doesn't work. The reason for this is that NSDocumentController's currentDocument uses the keyWindow, so it better represents the built in functionality. Also, panels can be set to avoid becoming key window.

Resources