Is possible to automate this:
- from any application, choose save to pdf (or print to pdf, or print to a pdf printer);
- save the file in the same folder of the original file;
- set password (no copy) of this new file?
Thanks.
Gianluca.
Is possible to automate this:
Thanks.
Gianluca.
You may try this code :
property definePasswordInPrintDialog : true
# false --> define the password at the beginning then everything is automated
# true --> define the password by hand in the print dialog. You will have to click the buttons !
tell application "System Events" -- get frontmost process
set frontmostProcess to first process where it is frontmost -- this will be the script process
if name of frontmostProcess is in {"Script Editor", "AppleScript Editor", "Time Machine", "Finder"} then
set visible of frontmostProcess to false -- hide the script process
repeat while (frontmostProcess is frontmost) -- wait until the script is hiden
delay 0.2
end repeat
set theApp to name of first process where it is frontmost -- get name of frontmost process (ignoring the script process)
set frontmost of frontmostProcess to true -- unhide the script process
else
set theApp to name of frontmostProcess
end if
set fileApp to path of file of process theApp
end tell # System Events
# Get the path to the document to export.
tell application fileApp to set sourcePath to path of document 1
if not definePasswordInPrintDialog then
-- display dialog "Enter your password" default answer "??????" # activate this one if you want to see what you type
display dialog "Enter your password" default answer "??????" with hidden answer # activate this one if you want to hide what you type
set thePassword to text returned of result
end if
tell application "System Events"
tell disk item sourcePath
set {sourceName, sourceFolder, sourceNameExtension} to {its name, path of its container, its name extension}
if sourceNameExtension > "" then
set bareName to text 1 thru -(2 + (count sourceNameExtension)) of sourceName
else
set bareName to sourceName
end if
end tell # disk item
# Builds an unique PDF name
set cnt to 1
set thePDFname to bareName & ".pdf"
repeat
if not (exists disk item (sourceFolder & thePDFname)) then
exit repeat
else
set cnt to cnt + 1
set thePDFname to bareName & "#" & cnt & ".pdf"
end if
end repeat
end tell # System Events
# converts the folder path to a POSIX one to pass it in the dialog
log sourceFolder
set posixFolderPath to POSIX path of sourceFolder
# Code borrowed from Nigel Garvey (http://macscripter.net/viewtopic.php?id=41654)
tell application "System Events"
tell process theApp
set frontmost to true
keystroke "p" using {command down}
tell window 1
repeat until exists sheet 1
delay 0.2
end repeat
tell sheet 1
set PDFButton to first menu button
click PDFButton
-- log (get name of menu items of menu 1 of PDFButton)
--> {"Ouvrir le PDF dans Aperçu", "Enregistrer au format PDF.", "Enregistrer au format PostScript.", "Faxer le document PDF.", missing value, "@ PDF-BAT.qfilter", "@ PDF-prépresse CMJN.qfilter", "@ PDF-web.qfilter", "@ PDFX3-ISO.qfilter", "Add PDF to iTunes", "Envoyer le document PDF par courrier électronique", "Enregistrer le document PDF dans le dossier de reçus web", missing value, "Modifier le menu."}
click menu item 2 of menu 1 of PDFButton
(*
Wait for the availability of the Print sheet *)
repeat
if exists sheet 1 then exit repeat
delay 0.1
end repeat
(*
Set the name of the new PDF *)
tell sheet 1
set value of text field 1 to thePDFname
# Open the pane allowing the setting of destination folder
keystroke "g" using {command down, shift down}
repeat until exists sheet 1
delay 0.02
end repeat
# Set the destination folder
tell sheet 1
set value of text field 1 to posixFolderPath
-- log (get name of buttons) (*Aller, Annuler*)
click button 1
end tell
-- log (get class of UI elements) --> {group, button, button, button, group, checkbox, text field, static text, static text, text field}
tell group 1
-- log (get class of UI elements) --> {text field, static text, button, text field, static text, text field, static text, static text, text field}
click button 1
end tell
end tell # sheet 1 (the Save As one)
end tell -- sheet
end tell -- window
# Wait for the dialog allowing to define password
repeat
delay 0.2
if exists (window 1 whose subrole is "AXDialog") then exit repeat
end repeat
tell (window 1 whose subrole is "AXDialog")
-- log (get properties of UI elements)
(*
Resume of the properties
01 - static text, position:{797, 267}, value:"Mot de passe :" - to Open
01 - text field, position:{896, 411}, subrole:"AXSecureTextField" - to Print or Copy
02 - static text, position:{797, 413}, value:"Mot de passe :" - to Print or Copy
03 - text field, position:{896, 443}, subrole:"AXSecureTextField" - to Print or Copy
04 - text field, position:{896, 265}, subrole:"AXSecureTextField" - to Open
05 - text field, position:{896, 297}, subrole:"AXSecureTextField" - to Open
03 - static text, position:{797, 299}, value:"Confirmation :" - to Open
04 - static text, position:{797, 445}, value:"Confirmation :" - to Print or Copy
01 - checkbox, "Demander un mot de passe pour imprimer le document" - to Print
02 - checkbox, "Exiger un mot de passe pour ouvrir le document" - to Open
03 - checkbox, "Demander un mot de passe pour copier du texte, des
images et tout autre contenu" - to Copy
01 - button, "OK"
02 - button, "Annuler"
05 - static text, "Options de sécurité PDF"
*)
# Here you must be patient, the system take some time before displaying the dialog
click checkbox 3
if not definePasswordInPrintDialog then
set value of text field 1 to thePassword
set value of text field 2 to thePassword
click button 1
end if
end tell # (window 1 whose subrole is "AXDialog")
if not definePasswordInPrintDialog then
tell window 1 to tell sheet 1
tell sheet 1
log (get name of buttons) --> (*Enregistrer, Nouveau dossier, Annuler*)
keystroke return
end tell
log (get name of buttons) --> (*missing value, Masquer les détails, missing value, Annuler, Imprimer*)
keystroke return
end tell
end if
end tell # process
end tell # System Events
Yvan KOENIG running El Capitan 10.11.3 in French (VALLAURIS, France) vendredi 5 février 2016 19:34:56
great! good job, but I can’t use… or… I don’t know how to use.
I did so:
But, when I try, it close immediately…
Save the script as an application.
Open a document. I tested with a rtfd file open in TextEdit.
Double click the script icon or launch it thru a shortcut linked to it with FastScript.
The script will print the open document in a PDF file.
Yvan KOENIG running El Capitan 10.11.3 in French (VALLAURIS, France) vendredi 5 février 2016 22:04:20
thanks! with textedit works! I’ll try with other application (with word and with chrome it doesn’t work)
I’m not a sooth sayer so I have no idea of what your message really means.
Did the script quits ?
Did it issue an error message ?
If it issue an error message, which one is it ?
I can’t test with Word because Merdosoft products aren’t allowed to enter my home and my machines.
I mad a test with LibreOffice. This app has no AppleScript support so the script fails when it’s asked to get the sourcePath of the open document.
I may partially override that extracting the title of the window to get the name of the file but I have no way to get its complete path so I can’t identify the folder in which it is stored.
So I will have to store the PDF without knowing the source folder.
More, LibreOffice doesn’t match the standard behavior of the Print function.
The Print dialog is not a sheet of the document window, it is a window of its own.
I will try to enhance the script according to that.
I’m puzzled about Chrome. As far as I know, it’s a web navigator so I have no idea of what may be the source folder of the displayed window.
Yvan KOENIG running El Capitan 10.11.3 in French (VALLAURIS, France) samedi 6 février 2016 12:36:18
Here is an enhanced version.
I tested it with TextEdit, Numbers and LibreOffice.
property definePasswordInPrintDialogByHand : false
# false --> define the password at the beginning then everything is automated
# true --> define the password by hand in the print dialog. You will have to click the buttons !
property nbTrials : 10
#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
set Print_loc to localized string "Print" in bundle ((path to application id ("com.apple.preview")) as «class furl») --> "Imprimer"
tell application "System Events" -- get frontmost process
set frontmostProcess to first process where it is frontmost -- this will be the script process
if name of frontmostProcess is in {"Script Editor", "AppleScript Editor", "Time Machine"} then
set visible of frontmostProcess to false -- hide the script process
repeat while (frontmostProcess is frontmost) -- wait until the script is hiden
delay 0.2
end repeat
set theProcess to name of first process where it is frontmost -- get name of frontmost process (ignoring the script process)
set frontmost of frontmostProcess to true -- unhide the script process
else
set theProcess to name of frontmostProcess
end if
if theProcess is "Finder" then error "Don't apply upon Finder"
set fileApp to path of file of process theProcess
end tell # System Events
try
# Try to get the path to the document to export if the app behaves like TextEdit.
# It returns a POSIX path
tell application fileApp to set sourcePath to path of document 1
tell application "System Events" to tell disk item sourcePath
set {sourceName, sourceFolder, sourceNameExtension} to {its name, path of its container, its name extension}
end tell
on error
try
# Try to get the path to the document to export if the app behaves like iWork's ones.
# Must coerce the returned file as text.
tell application fileApp to set sourcePath to (file of document 1 as text)
tell application "System Events" to tell disk item sourcePath
set {sourceName, sourceFolder, sourceNameExtension} to {its name, path of its container, its name extension}
end tell
on error
# It seems that the app doesn't support AppleScript.
# Extracts the source name from System Events.
tell application "System Events" to tell process theProcess
set frontmost to true
set sourceName to title of window 1
-- log result --> (*Bon_de_commande.xls*)
end tell
# Defines a fake sourceFolder
set sourceFolder to path to desktop as text
# Extracts the name extension
set maybeList to my decoupe(sourceName, ".")
if (count maybeList) = 1 then
set sourceNameExtension to ""
else
set sourceNameExtension to (maybeList's item -1) as text --> "xls"
end if
end try
end try
if not definePasswordInPrintDialogByHand then
-- tell application "SystemUIServer" todisplay dialog "Enter your password" default answer "??????" # activate this one if you want to see what you type
tell application "SystemUIServer" to display dialog "Enter your password" default answer "??????" with hidden answer # activate this one if you want to hide what you type
set thePassword to text returned of result
end if
tell application "System Events"
if sourceNameExtension > "" then
set bareName to text 1 thru -(2 + (count sourceNameExtension)) of sourceName
else
set bareName to sourceName
end if
# Builds an unique PDF name
set cnt to 1
set thePDFname to bareName & ".pdf"
repeat
if not (exists disk item (sourceFolder & thePDFname)) then
exit repeat
else
set cnt to cnt + 1
set thePDFname to bareName & "#" & cnt & ".pdf"
end if
end repeat
end tell # System Events
# converts the folder path to a POSIX one to pass it in the dialog
-- log sourceFolder
set posixFolderPath to POSIX path of sourceFolder
# Code borrowed from Nigel Garvey (http://macscripter.net/viewtopic.php?id=41654)
tell application "System Events" to tell process theProcess
set frontmost to true
keystroke "p" using {command down}
tell window 1
-- log (get its title) --> (*Imprimer*)
set knt to 0
repeat nbTrials times
set knt to knt + 1
delay 0.2
if exists sheet 1 then exit repeat
end repeat
end tell # window
end tell # process of System Events
if knt < nbTrials then
# Issuing cmd + P opened a sheet.
my useAsheet(theProcess, thePDFname, posixFolderPath, thePassword)
else
tell application "System Events" to tell process theProcess
set frontmost to true
tell window 1 to set itsTitle to its title --> (*Imprimer*)
end tell # process of System Events
if itsTitle is not sourceName then
# issuing cmd + P opened a dialog window.
my useAwindow(theProcess, thePDFname, posixFolderPath, thePassword)
else
# Maybe issuing cmd + P revealed a Page Setup Inspector
tell application "System Events" to tell process theProcess
set frontmost to true
tell window sourceName
-- log (get class of UI elements) --> (*scroll area, button, scroll area, button, button, radio group, scroll area, button, button, static text, radio group, button, button, button, menu button, toolbar, image, static text*)
-- log (get name of buttons) --> (*missing value, missing value, missing value, Terminé, Imprimer., missing value, missing value, missing value*)
try
set printButton to name of first button whose name contains Print_loc
on error errMsg number errNbr
# Maybe it's just that the app isn't localized
set printButton to ""
set theButtons to name of buttons
repeat with aButton in theButtons
if (aButton as text) contains "Print" then
set printButton to aButton as text
exit repeat
end if
end repeat
if printButton = "" then error "Unknown behavior, " & errMsg & ", #" & errNbr
end try
click button printButton
end tell # window sourceName
my useAsheet(theProcess, thePDFname, posixFolderPath, thePassword)
end tell # process of System Events.
end if
end if
#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
on decoupe(t, d)
local oTIDs, l
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
set l to text items of t
set AppleScript's text item delimiters to oTIDs
return l
end decoupe
#=====
on useAsheet(theProcess, thePDFname, posixFolderPath, thePassword)
tell application "System Events"
tell process theProcess
set frontmost to true
# We are here if the Print dialog is a sheet
tell window 1
-- log (get its title) --> (*Paper Sizes.rtfd*)
tell sheet 1
-- log (get its title) --> (*missing value*)
set PDFButton to first menu button
# Reveal the local menu
click PDFButton
-- log (get name of menu items of menu 1 of PDFButton)
--> {"Ouvrir le PDF dans Aperçu", "Enregistrer au format PDF.", "Enregistrer au format PostScript.", "Faxer le document PDF.", missing value, "@ PDF-BAT.qfilter", "@ PDF-prépresse CMJN.qfilter", "@ PDF-web.qfilter", "@ PDFX3-ISO.qfilter", "Add PDF to iTunes", "Envoyer le document PDF par courrier électronique", "Enregistrer le document PDF dans le dossier de reçus web", missing value, "Modifier le menu."}
click menu item 2 of menu 1 of PDFButton
(*
Wait for the availability of the Print sheet *)
set knt to 0
repeat nbTrials times
set knt to knt + 1
delay 0.1
if exists sheet 1 then exit repeat
end repeat
if knt ≥ nbTrials then error number -128
tell sheet 1
-- log (get its title) --> (*missing value*)
set value of text field 1 to thePDFname # Set the name of the new PDF
# Open the pane allowing the setting of destination folder
keystroke "g" using {command down, shift down}
set knt to 0
repeat nbTrials times
set knt to knt + 1
delay 0.2
if exists sheet 1 then exit repeat
end repeat
if knt ≥ nbTrials then error number -128
tell sheet 1
-- log (get its title) --> (*missing value*)
set value of text field 1 to posixFolderPath # Set the destination folder
-- log (get name of buttons) (*Aller, Annuler*)
click button 1
end tell
-- log (get class of UI elements) --> {group, button, button, button, group, checkbox, text field, static text, static text, text field}
tell group 1
-- log (get class of UI elements) --> {text field, static text, button, text field, static text, text field, static text, static text, text field}
click button 1
end tell
end tell # the «Save As» sheet
end tell -- the «Print» sheet
end tell -- the document window
# Wait for the dialog allowing to define password
set knt to 0
repeat nbTrials times
set knt to knt + 1
delay 0.2
if exists (window 1 whose subrole is "AXDialog") then exit repeat
end repeat
if knt ≥ nbTrials then error number -128
tell (window 1 whose subrole is "AXDialog")
-- log (get its title) --> (*Options de sécurité PDF*)
-- log (get properties of UI elements)
(*
Resume of the properties
static text 1, position:{797, 267}, value:"Mot de passe :" - to Open
text field 1, position:{896, 411}, subrole:"AXSecureTextField" - to Print or Copy
static text 2, position:{797, 413}, value:"Mot de passe :" - to Print or Copy
text field 3, position:{896, 443}, subrole:"AXSecureTextField" - to Print or Copy
text field 4, position:{896, 265}, subrole:"AXSecureTextField" - to Open
text field 5, position:{896, 297}, subrole:"AXSecureTextField" - to Open
static text 3, position:{797, 299}, value:"Confirmation :" - to Open
static text 4, position:{797, 445}, value:"Confirmation :" - to Print or Copy
checkbox 1, "Demander un mot de passe pour imprimer le document" - to Print
checkbox 2, "Exiger un mot de passe pour ouvrir le document" - to Open
checkbox 3, "Demander un mot de passe pour copier du texte, des
images et tout autre contenu" - to Copy
button 1, "OK"
button 2, "Annuler"
static text 5, "Options de sécurité PDF"
*)
# Here you must be patient, the system take some time before displaying the dialog
click checkbox 3
if not definePasswordInPrintDialogByHand then
set value of text field 1 to thePassword
set value of text field 2 to thePassword
click button 1
end if
end tell # (window 1 whose subrole is "AXDialog")
if not definePasswordInPrintDialogByHand then
tell window 1 to tell sheet 1
-- log (get its title) --> (*Imprimer*)
tell sheet 1
-- log (get its title) --> (*missing value*)
-- log (get name of buttons) --> (*Enregistrer, Nouveau dossier, Annuler*)
click button 1 # idem keystroke return
end tell
-- log (get name of buttons) --> (*missing value, Masquer les détails, missing value, Annuler, Imprimer*)
keystroke return
end tell
end if
end tell # process
end tell # System Events
end useAsheet
#=====
on useAwindow(theProcess, thePDFname, posixFolderPath, thePassword)
tell application "System Events"
tell process theProcess
# We are here if the Print dialog is a window
-- log (get subrole of windows) --> (*AXDialog, AXStandardWindow*)
tell window 1
-- log (get its title) --> (*Imprimer*)
set PDFButton to first menu button
# Reveal the local menu
click PDFButton
-- log (get name of menu items of menu 1 of PDFButton)
--> {"Ouvrir le PDF dans Aperçu", "Enregistrer au format PDF.", "Enregistrer au format PostScript.", "Faxer le document PDF.", missing value, "@ PDF-BAT.qfilter", "@ PDF-prépresse CMJN.qfilter", "@ PDF-web.qfilter", "@ PDFX3-ISO.qfilter", "Add PDF to iTunes", "Envoyer le document PDF par courrier électronique", "Enregistrer le document PDF dans le dossier de reçus web", missing value, "Modifier le menu."}
click menu item 2 of menu 1 of PDFButton
(*
Wait for the availability of the Print sheet *)
set knt to 0
repeat nbTrials times
set knt to knt + 1
delay 0.1
if exists sheet 1 then exit repeat
end repeat
if knt ≥ nbTrials then error number -128
tell sheet 1
-- log (get its title) --> (*missing value*)
set value of text field 1 to thePDFname # Set the name of the new PDF
# Open the pane allowing the setting of destination folder
keystroke "g" using {command down, shift down}
set knt to 0
repeat nbTrials times
set knt to knt + 1
delay 0.2
if exists sheet 1 then exit repeat
end repeat
if knt ≥ nbTrials then error number -128
tell sheet 1
-- log (get its title) --> (*missing value*)
set value of text field 1 to posixFolderPath # Set the destination folder
-- log (get name of buttons) (*Aller, Annuler*)
click button 1
end tell
-- log (get class of UI elements) --> {group, button, button, button, group, checkbox, text field, static text, static text, text field}
tell group 1
-- log (get class of UI elements) --> {text field, static text, button, text field, static text, text field, static text, static text, text field}
click button 1
end tell
end tell # the «Save As» sheet
end tell -- the document window
# Wait for the dialog allowing to define password
set knt to 0
repeat nbTrials times
set knt to knt + 1
delay 0.2
if exists (window 1 whose subrole is "AXDialog") then exit repeat
end repeat
if knt ≥ nbTrials then error number -128
tell (window 1 whose subrole is "AXDialog")
-- log (get its title) --> (*Options de sécurité PDF*)
-- log (get properties of UI elements)
(*
Resume of the properties
static text 1, position:{797, 267}, value:"Mot de passe :" - to Open
text field 1, position:{896, 411}, subrole:"AXSecureTextField" - to Print or Copy
static text 2, position:{797, 413}, value:"Mot de passe :" - to Print or Copy
text field 3, position:{896, 443}, subrole:"AXSecureTextField" - to Print or Copy
text field 4, position:{896, 265}, subrole:"AXSecureTextField" - to Open
text field 5, position:{896, 297}, subrole:"AXSecureTextField" - to Open
static text 3, position:{797, 299}, value:"Confirmation :" - to Open
static text 4, position:{797, 445}, value:"Confirmation :" - to Print or Copy
checkbox 1, "Demander un mot de passe pour imprimer le document" - to Print
checkbox 2, "Exiger un mot de passe pour ouvrir le document" - to Open
checkbox 3, "Demander un mot de passe pour copier du texte, des
images et tout autre contenu" - to Copy
button 1, "OK"
button 2, "Annuler"
static text 5, "Options de sécurité PDF"
*)
# Here you must be patient, the system take some time before displaying the dialog
click checkbox 3
if not definePasswordInPrintDialogByHand then
set value of text field 1 to thePassword
set value of text field 2 to thePassword
click button 1
end if
end tell # (window 1 whose subrole is "AXDialog")
if not definePasswordInPrintDialogByHand then
tell window 1
-- log (get its title) --> (*Imprimer*)
tell sheet 1
-- log (get its title) --> (*missing value*)
-- log (get name of buttons) --> (*Enregistrer, Nouveau dossier, Annuler*)
click button 1 # keystroke return
end tell # sheet
end tell # window Imprimer
end if
end tell # process
end tell # System Events
end useAwindow
I left numerous log instructions (disabled) which were useful during the building process.
I guess that they would be useful if you use the script as the beginning of an other one triggering the same dialogs.
Yvan KOENIG running El Capitan 10.11.3 in French (VALLAURIS, France) samedi 6 février 2016 20:24:08