2010-07-20 20 views
0

Existe-t-il un moyen de faire une copie à distance dans un conteneur à partir de Scripting Bridge? Dans AppleScript, cela ressemble à "copier [élément] de [conteneur] à [emplacement dans le conteneur]". Par exemple, dans le contexte d'un document TellEdit TextEdit, vous pouvez "copier le premier paragraphe de son texte à la fin de son texte" pour copier le premier paragraphe à la fin du document tout en préservant toute la mise en forme.Comment exécuter une commande "copy" AppleScript équivalente à partir de Scripting Bridge?

Est-il possible d'utiliser Objective-C à l'aide de Scripting Bridge?

J'ai essayé quelque chose comme ceci:

SBObject* foo = [container objectAtIndex: 0]; 
[container addObject: foo]; 

et a obtenu un message « ne peut pas ajouter un objet qui existe déjà. » sur la console; il semble que addObject et les diverses méthodes replace* ne fonctionnent que lorsque vous construisez une nouvelle instance SBObject et que vous l'insérez.

Répondre

1

Lorsque le deuxième paramètre de commande d'AppleScript copy intégré est une référence d'application, AppleScript alias « utilement » à une demande ou une commande duplicateset, selon que le premier paramètre est une référence ou non. Pour éviter toute confusion, il est préférable d'utiliser explicitement duplicate ou set lorsque vous traitez des applications scriptables dans AppleScript. Comme pour SB, vous devez rechercher une méthode duplicate... dans le fichier d'en-tête. Sachez que la commande duplicate de SB est semi-invalide (SB has quite a few shortcomings) car elle ne peut traiter qu'un seul objet à la fois. La plupart des applications vous permettront de manipuler plusieurs objets dans une seule commande (attention aux bogues dans leur support de script), par exemple. AppleScript vous laissera dire:

tell application "iTunes" 
    duplicate (every track whose artist is "Foo") to (playlist "Bar") 
end tell 

mais SB ne le fera pas; à la place, vous devez extraire une liste de références uniques et les parcourir en les traitant l'une après l'autre. Rend votre code assez long, et peut être très inefficace si vous avez un grand nombre d'objets ailleurs.

Une autre option est objc-appscript, qui fait tout cela correctement et est moins sujet aux problèmes de compatibilité des applications en général («quirk-for-quirk compatibility», comme le dit Matt Neuburg). De plus, vous obtenez ASTranslate, qui convertit les commandes AppleScript à l'équivalent Python/Ruby/ObjC syntaxe - très pratique au moment de déterminer comment formuler correctement une commande:

#import "ITGlue/ITGlue.h" 
ITApplication *itunes = [ITApplication applicationWithName: @"iTunes"]; 
ITReference *ref = [[itunes tracks] byTest: [[ITIts artist] equals: @"Foo"]]; 
ITDuplicateCommand *cmd = [[ref duplicate] to: [[itunes playlists] byName: @"Bar"]]; 
id result = [cmd send]; 

Une autre option, si vous êtes sur 10.6, serait être d'utiliser le pont AppleScriptObjC, qui vous permet de combiner AS et ObjC dans le même programme sans aucun de ces vilains non-sens NSAppleScript. Cela vous permettrait d'utiliser AppleScript pour ce qu'il fait de mieux (communiquer avec d'autres applications) et ObjC pour tout le reste. La documentation officielle is limited, mais une recherche sur le Web devrait jeter diverses ressources tierces. MacScripter.net pourrait être un bon point de départ - en plus du forum de l'ASOC, Craig Williams a publié une série de tutoriels il y a quelques temps.

(BTW, Craig a également contribué un chapitre sur ASOC à la troisième édition de savoir AppleScript Apress, que je co-écrit, et qui comprend beaucoup d'informations sur les principes et les pratiques de script d'application, y compris la clarification des set/duplicate/copy .)

+0

Merci pour le traitement très complet! J'utilise actuellement un mélange de Scripting Bridge et d'ASOC, et il me semble que je serai capable de le faire. –

+0

J'ai trouvé une méthode '- duplicateTo: (SBObject *) withProperties: (NSDictionary *)', mais comment créer un 'SBObject *' spécifiant "end of [container]" ou un emplacement interstitiel similaire ne contenant pas d'objet réel? –

+0

Tu sais, je ne sais pas. Il est tout à fait possible que les développeurs de SB aient oublié d'ajouter un moyen de le faire, mais il est difficile de le dire sans plus de recherches, étant donné que la documentation est minable et que l'API est opaque et opaque. (SB est la raison pour laquelle j'ai écrit objc-appscript, btw.) Avez-vous essayé de passer une référence au conteneur lui-même, sur le hasard que cela fonctionne? (Certaines applications s'attendent à une référence de conteneur de toute façon.) Si cela échoue, je suggère d'envoyer des messages à des développeurs d'applescript et d'essayer d'attirer l'attention d'un ingénieur AS. Ou utilisez appscript, qui fonctionne simplement. – has