AppleScript: encore plus loin dans le script de fermeture des applis !
Par Didier Pulicani - Publié le
Ce que nous voulons faire...
Ce script a pour but de quitter tout simplement toutes les applications.Seulement nous allons l' enrichir un peu ou ce serait l' affaire de quelques lignes de code et ne nécessiterait pas un article complet.Rajoutons donc un dialogue de confirmation et un système permettant de définir les applications à garder (dont le Finder devra faire partie !)
Le script se composera donc de deux parties, une permettant de définir les options et l' autre quittant les applications.
Nous aurons besoin des Osax "Sändi's Additions", "Dialog Director" et "AkuaSweets" (que je vous invite fortement à utiliser pour vos propres scripts, car il est excellent, soit dit en passant...)
Le Script
Comme le script est relativement long, je vous conseille d'utiliser un format AppleScript coloré pour mieux s'y retrouver.Voici les détails du format:
(police - taille - style - couleur)
texte non compilé: Courier - 10 - normal - noir
texte normal: Geneva - 10 - gras -noir
mots clés: Geneva - 10 - gras - rouge
terme des applications: Geneva - 10 - normal - bleu clair
commentaires: Geneva - 9 - italique - noir
valeurs: Helvetica - 10 - normal - noir
variables: Geneva - 10 - normal - bleu foncé
références: Geneva - 10 - normal - noir
Et voilà le script :
property Apps_a_garder : {"Finder"}
property AskBeforeQuit : true
on run
if (CommandIsDown) is true then set AskBeforeQuit to true
set TheProcesses to (all processes without background only)
set |app| to ((all processes with currency) as text)
if AskBeforeQuit is true then
set |Dialog| to {size:{378, 120}, style:standard dialog, default item:3, contents:{¬
{class:icon, bounds:{16, 8, 48, 40}, contents:1}, ¬
{class:static text, bounds:{64, 8, 364, 40}, contents:"Êtes-vous sur de vouloir quitter toutes les applications lancées ?"}, ¬
{class:push button, bounds:{292, 88, 362, 108}, name:"OK"}, ¬
{class:push button, bounds:{212, 88, 282, 108}, name:"Annuler"}, ¬
{class:push button, bounds:{50, 88, 202, 108}, name:"Applications à garder"}, ¬
{class:check box, bounds:{64, 60, 200, 76}, name:"Ne plus afficher", value:false, font:{name:"Geneva", size:10}}}}
dd auto dialog |Dialog| with fonts {name:"Charcoal", size:12} with grayscale
set {OK, Annuler, DefApps, NoAsk} to (items 3 thru 6 of the result)
if Annuler is true then
return
else if OK is true then
if NoAsk is true then set AskBeforeQuit to false
else if DefApps is true then
--afficher le dialogue de définition des apps à garder
set theDialog to {size:{303, 182}, style:movable dialog, name:"Applications à garder", default item:7, contents:{¬
{class:icon, bounds:{16, 8, 48, 40}, contents:1}, ¬
{class:static text, bounds:{60, 8, 260, 40}, contents:"Ces applications ne seront pas quittées par le script:"}, ¬
{class:list box, bounds:{48, 60, 180, 135}, contents:Apps_a_garder}, ¬
{class:push button, bounds:{204, 60, 284, 80}, name:"Ajouter"}, ¬
{class:push button, bounds:{204, 92, 284, 112}, name:"Supprimer", enabled:3}, ¬
{class:push button, bounds:{114, 153, 194, 173}, name:"Annuler"}, ¬
{class:push button, bounds:{204, 153, 284, 173}, name:"OK"}}}
dd install with fonts {name:"Charcoal", size:12} with grayscale
set d to dd make dialog theDialog
repeat
set i to dd interact with user
if i = 4 then
set PList to collect items of TheProcesses that match |app| with just contents and negation
set dlog to {size:[220, 220], name:"Ajouter Application", style:movable dialog, contents:{¬
{class:static text, bounds:{10, 5, 210, 26}, contents:"Applications lancées :"}, ¬
{class:list box, bounds:[10, 30, 210, 172], contents:PList}, ¬
{class:push button, bounds:[150, 190, 210, 210], name:"Ajouter", enabled:2}, ¬
{class:push button, bounds:{20, 190, 140, 210}, name:"Autre application"}}}
set {LApp, Add, CApp} to (items 2 thru 4 of (dd auto dialog dlog with fonts {name:"Charcoal", size:12} with grayscale))
if CApp is true then --on fait choisir une application
repeat
set LeFile to (choose file with prompt "Choisissez une application :")
tell application "Finder"
if LeFile's original item exists then
set LeFile to LeFile's original item
end if
try
get suggested size of LeFile
set AppleScript's text item delimiters to ":"
set theApp to (last text item of (LeFile as text))
set AppleScript's text item delimiters to " "
exit repeat
on error number ErrNumber
if ErrNumber = -1728 then
display dialog "Le Fichier choisi n' est pas une application" with icon caution buttons {"OK"} default button 1
end if
end try
end tell
end repeat
else if Add is true then
set theApp to item LApp of PList
end if
if theApp is not in Apps_a_garder then
set Apps_a_garder to Apps_a_garder & theApp
dd set contents of item 3 of d to Apps_a_garder
end if
else if i = 5 then
set theApp to item (dd get value of item 3 of d) of Apps_a_garder
set Apps_a_garder to (collect items of Apps_a_garder that match theApp with just contents and negation)
dd set contents of item 3 of d to Apps_a_garder
else if i = 6 then
return
else if i = 7 then
exit repeat
end if
end repeat
dd delete d
dd uninstall
end if
end if
repeat with |process| in TheProcesses
if |process| is not in Apps_a_garder and |process| != |app| then
tell application |process|
activate
quit
end tell
end if
end repeat
end run
L' Explication !
Les deux property définissent, pour la première, les applications qui ne seront pas quittées par le script et pour la deuxième, l' affichage ou non du dialogue de confirmation.Si vous ne mettez aucune application dans la première, elles seront toutes quittées puis le Finder sera relançé.
Ensuite, il nous faut un dialogue de confirmation pour éviter de tout quitter par inadvertance, tout en laissant une option pour ne plus afficher le dialogue.Seulement quand on a demandé à ce qu' il ne s' affiche plus et qu' on veut le rafficher,il faut prévoir quelquechose pour qu' il s' affiche quand même (relisez cette phrase lentement si vous n' avez pas tout compris...)
C' est le role du CommandIsDown.Concrétement si vous appuyez sur commande, le dialogue s' affichera (par l' intermédiaire de la variable AskBeforeQuit).
Les deux premières lignes servent à définir deux variables qui serviront pour tout le script, contenant respectivement la liste des applications lancées et le nom du script grace à une commande d' AkuaSweets:
all processes: Check for a running process by name or creator - or get a list of all processes.
all processes
[named string] -- Filter processes with this name.
[whose creators are string] -- Four letter creator
[background only boolean] -- Include background (default is TRUE). Specify TRUE to get only background apps.
[pending notifications boolean] -- Only return process with a notification pending.
[as type class] -- The kind of result you want. You can use string (names of apps), integer (process numbers), file (paths to the apps), aliases (ditto), applications or Process Infos.
[currency boolean] -- Just return the current process.
Result: a list of string -- A list of processes that match your criteria.
Après vient toute une grosse partie qui sert à afficher le dialogue de confirmation et à définir les applications à garder sans mettre les mains dans le cambouis.Pour y voir plus clair, la structure du script est très simple:
--properties
on run
--3 lignes de commandes vues plus haut
if AskBeforeQuit is true then
--partie de définition des applications
end if
--partie quittant les applications
end run
Entrons dans la grosse partie...
On commence par définir un dialogue avec DialogDirector.Si vous n' êtes pas familier de cet Osax (j' essaierai de faire un article dessus), sachez juste qu' il permet de faire des dialogues complexes et que la variable theDialog est tout simplement un record qui contient les propriétés du dialogue.Je vous laisse aller voir son dictionnaire pour plus de précisions et pour toutes les autres commandes dont nous aurons besoin.
Puis on affiche ce dialogue avec dd auto dialog:
Cette commande renvoie une liste comme résultat dans laquelle nous prennons ce qui nous intéresse (Bouton choisi et checkbox cochée ou pas)
Là on arrive dans un grand if qui dépend du bouton choisi.Les deux cas les plus simples sont les premiers:
Si on a choisi "Annuler", on ... annule ! (le script s' arrête donc)
Si on a choisi "OK" et que la checkbox est cochée, on met la variable d' affichage du dialogue à false et on continue.
Si on a choisi "Applications à garder", là c' est plus compliqué, il faut afficher des dialogues:
On définit le dialogue comme tout à l' heure mais on va utiliser une méthode différente pour l' afficher: les trois commandes dd install, dd make dialog et dd interact with user.
La première initialise l' environnement.
La deuxième crée le dialogue (la variable d est la référence à ce dialogue)
La troisième permet à l' utilisateur d' interagir avec le dialogue (i désigne l' action effectuée)
Cette méthode est légèrement différent de dd auto dialog car elle permet plus d' interaction.Voici son résultat:
La commande d' interacton nécessite plus d' attention que les autres car elle est plus complexe.Nous allons l' examiner rapidement.
Tout d' abord, il faut l' encapsuler dans un repeat pour pouvoir interagir plusieurs fois !
La variable i contiendra un entier désignant l' élément du dialogue sur lequel on a cliqué (ou autre)
Nous n' allons définir le comportement à suivre que pour les quatres boutons (c' est inutile pour les autres éléments)
Le plus compliqué étant le bouton ajouter (i=4), nous le verrons en dernier.
Si on clique sur "Supprimer" (possible seulement si un élément de la liste est séléctionné grace au enabled:3 dans la description du bouton), il faut enlever l' élément de la liste à la fois sur l' écran et en property.
La commande dd get value permet de savoir quel élément est séléctionné et on le met dans la variable theApp.
Ensuite on va l' enlever de la liste Apps_a_garder grace à une autre commmande d' AkuaSweets: collect items.Cette commande permet d' enlever un élément d' une liste par son contenu ou au contraire de ne garder que lui.Pour la syntaxe exacte, voilà le dictionnaire:
collect items of: Get item offsets and contents that match an expression.
collect items of a list of string -- A list of text items to search.
that match string -- A string (or list of strings to be “OR’d”) that defines what to find.
% Toggles case
$ Toggles early-end-allow
+ Any one character
[c n chars until c
/c Absolute c comparison
(cde) Any of c, d or e
&xcyd Where x & y are one of (>,<,=,#) matches range e.g.
[in position small integer] -- In a list of lists, this causes a search of the specified sublist item.
[in subfield anything] -- The property you wish to search in subrecords.
[in user property string] -- The name of the field you wish to search in subrecords.
[from point] -- The first/last items to be searched. Default is {1, -1}.
[item contents boolean] -- Return a list of {{item Number, item Data}...} instead of just item numbers.
[just contents boolean] -- Return only the item contents, no reference to position.
[negation boolean] -- Return the opposite (the items that don't match).
[expression evaluation boolean] -- I
Result: a list of integer -- List of item numbers that matched.
enfin on affiche la nouvelle liste avec dd set contents.
Si on clique sur "Annuler", comme pour tout à l' heure ça se passe de commentaires...
Si on clique sur "OK", on quitte la boucle repeat car on en a fini avec ce dialogue.
Maintenant examinons le bouton "Ajouter".
Nous allons commencer par proposer un choix avec les applications lancées après avoir enlevé l' application courante de la liste grace à la commande décrite plus haut:
Ce dialogue nous renverra trois variables qui contiendront le numéro de l' application séléctionnée, et le bouton choisi pour les deux dernières ce qui nous amène à un if et à un dernier dialogue au cas où on aurait choisi "Autre Application".
Dans ce cas, on choisit l' application avec un choose file basique.Seulement nous devons vérifier que le fichier choisi est bien une application.C' est le rôle du bloc tell "Finder".
Tout d' abord si on a choisi un alias, on prend l' original à sa place.(Vous remarquerez l' emploi du cas possessif)
Ensuite, dans le bloc try, on essaie d' obtenir la mémoire attribuée à l' application.Si on a pas séléctionné une application l' erreur renvoyée est -1728 et on affiche un message d' erreur approprié.
Par contre, si on a bien une application, on extrait son nom du chemin d' accès par la méthode "set AppleScript' s text item delimiters to ...", fort utile, puis on sort du repeat.
Si on a choisi "Ajouter", on définit la variable theApp.
Ensuite, si l' application n' y est pas déjà, on l' ajoute à la liste puis on affiche celle-ci à l' écran.
A la sortie du grand repeat, on efface le dialogue et on désinstalle l' environnement.
Enfin, nous arrivons à la partie qui quitte véritablement les applications et c' est à la fois la plus courte et la plus simple du script:
On utilise un banal repeat dans lequel on quitte l' application après avoir vérifié qu' elle ne fait pas partie des applications à gerder et qu' elle n' est pas l' application courante (c' est à dire le script)
Le mot de la fin...
Et voilà !Vous vous doutez bien que le but de cet article n' était pas de vous apprendre à quitter une application mais de vous faire un aperçu des possibilités offertes par la création de dialogues multiples et complexes...
Si vous avez des questions, vous savez quoi faire...
Article entièrement rédigé par Coco.