Hello everyone,
I’m not very good at English, so please forgive any strange wording.
While I was localizing l008com’s disk-image-creation script the other day
I suddenly wondered:
“Is it possible to make this dialog multilingual?”
After looking into it, I realized that if you want to show very specific messages,
you do need to prepare your own dictionary.
But then I thought, can’t I reuse some of the dictionaries already provided by the system?
So I tried it.
I made a small script that exports previous file versions from DocumentRevision, and I added multilingual support for the file-selection dialog and the alert shown when the selected file has no revision history.
Of course, the exact messages and button labels depend on the macOS version, but it seems that to some extent you can build simple multilingual messages by reusing existing system dictionaries.
If people think,
“Ah, this is kind of interesting,”
then I’ll be happy — that’s the only reason I’m posting this.
The script is quite verbose and definitely not “modern,” and yes, I’m fully aware of that already—
so please don’t point that part out… ![]()
Note
If you want to try displaying messages in other languages, please be aware that changing the system language in System Settings may cause FSeventsd to run heavily for a while.
I have prepared some test inputs.
If there is a language you want to try, please modify the script in the section marked “FOR TEST” and run it with your desired settings.
#言語判定 追加事項(Additional items for language)
If you have any advice for better language detection regarding this section, I would be very grateful.
Please feel free to share your suggestions.
#!/usr/bin/osascript
#coding: utf-8
----+----1----+----2----+-----3----+----4----+----5----+----6----+----7--
(*
doGetDocumentRevisions-V100.appliscript
DocumentRevisions-V100に保存されている履歴を参照して
ファイルのバージョンの取得して
取得できれば
過去のバージョンを全て保存します
Refer to the history stored in DocumentRevisions-V100 to get the version of the file.
If you can get it,
save all past versions.
こちらの記事を参考にしました(I referred to this article)
https://www.macscripter.net/t/deleted-by-mistake-files-recovery-script-needed/68078/8
https://eclecticlight.co/?s=DocumentRevisions-V100
Shane StanleyとHoward Oakleyに感謝します
Thanks to Shane Stanley and Howard Oakley
制限事項
ダイアログメッセージはマルチリンガル対応になっていますが
内容ははmacOS26.1の内容を参照して作成しました
OSのバージョンによっては正しく表示されない可能性があります
Restrictions
The dialog message is multilingual
but the content was created by referring
to the contents of macOS 26.1. Depending on the OS version
it is likely not to be displayed correctly.
保存先(Save destination)
保存先は書類フォルダ
The destination is the document folder
Restore『復元』フォルダには全てのバージョン
Keep『残す』フォルダには最新か削除出来ないisDiscardableがFALSEの復元結果が保存されます
In the "Restore" folder, all versions of the "Keep" folder, the latest or undeleteable isDiscardable is TRUE recovery results are saved.
v1初回作成
v1.1 マルチリンガル対応
License Notice
CC0 1.0 Universal (Public Domain Dedication)
com.cocolog-nifty.quicktimer.icefloe *)
----+----1----+----2----+-----3----+----4----+----5----+----6----+----7--
use AppleScript version "2.8"
use framework "Foundation"
use framework "AppKit"
use scripting additions
property refMe : a reference to current application
property appLocale : (missing value)
####################
#地域と言語(Region and language)
set appLocale to refMe's NSLocale's currentLocale()
set ocidLocaleID to appLocale's objectForKey:(refMe's NSLocaleIdentifier)
set strLocaleID to ocidLocaleID as text
#ダイアログ用のメッセージ辞書の取得
#(Get a message dictionary for dialogs)
set ocidMsgDict to doGetDialogMsg(appLocale)
####################
#ダイアログ用のメッセージ(Messages for dialogs)
set strNoprevious to (ocidMsgDict's objectForKey:("No previous versions available")) as text
set strOK to (ocidMsgDict's objectForKey:("OK")) as text
set strCancel to (ocidMsgDict's objectForKey:("Cancel")) as text
set strChooseaFile to (ocidMsgDict's objectForKey:("Choose a File")) as text
set strNoResults to (ocidMsgDict's objectForKey:("No Results")) as text
set strChoose to (ocidMsgDict's objectForKey:("Choose")) as text
set strLoadversion to (ocidMsgDict's objectForKey:("Load version")) as text
set strUnable to (ocidMsgDict's objectForKey:("Unable to open version")) as text
set strRestore to (ocidMsgDict's objectForKey:("Restore")) as text
set strKeep to (ocidMsgDict's objectForKey:("Keep")) as text
# log ocidMsgDict's allKeys() as list
####################
#ダイアログ(Dialogue)
tell application "Finder"
set aliasDefaultLocation to (path to desktop folder from user domain) as alias
end tell
set listUTI to {"public.item"} as list
set strPrompt to ("" & return & strChoose & return & strLoadversion & strChooseaFile & return & "") as text
try
tell application "SystemUIServer"
activate
set aliasFilePath to (choose file strChoose with prompt strPrompt default location (aliasDefaultLocation) of type listUTI with invisibles and showing package contents without multiple selections allowed) as alias
end tell
on error strErrMes number numErrNo
log strErrMes & numErrNo
return false
end try
#パス
set strFilePath to (POSIX path of aliasFilePath) as text
set ocidFilePathStr to refMe's NSString's stringWithString:(strFilePath)
set ocidFilePath to ocidFilePathStr's stringByStandardizingPath()
set ocidFilePathURL to refMe's NSURL's fileURLWithPath:(ocidFilePath) isDirectory:(false)
#拡張子やファイル名
# set ocidExtensionName to ocidFilePathURL's pathExtension()
set ocidFileName to ocidFilePathURL's lastPathComponent()
set ocidBaseFileName to ocidFileName's stringByDeletingPathExtension()
####################
#保存先は書類フォルダ(The destination is the document folder)
set appFileManager to refMe's NSFileManager's defaultManager()
set ocidURLsArray to (appFileManager's URLsForDirectory:(refMe's NSDocumentDirectory) inDomains:(refMe's NSUserDomainMask))
set ocidDocumentDirPathURL to ocidURLsArray's firstObject()
#フォルダ作成オプションchmod=700(make dir option)
set ocidAttrDict to refMe's NSMutableDictionary's alloc()'s init()
ocidAttrDict's setValue:(448) forKey:(refMe's NSFilePosixPermissions)
####################
#バージョン取得(Version acquisition)
set ocidVerSionArray to refMe's NSFileVersion's otherVersionsOfItemAtURL:(ocidFilePathURL)
#数を数えて(Count the number)
set numCntArray to ocidVerSionArray's |count|()
#取得できなければアラート出して終了(If you can't get it, send an alert and end it.)
if numCntArray = 0 or ocidVerSionArray = (missing value) then
set strMsg to ("" & strNoprevious & return & strUnable & "") as text
tell application "System Events"
activate
display alert strMsg buttons {strCancel} default button strCancel cancel button strCancel as critical giving up after 5
return strMsg
end tell
end if
####################
#取得できたバージョンを順番に(The versions data that were acquired in order)
repeat with ocidVerSionItem in ocidVerSionArray
#各種値をとって(Take various values)
set ocidItemURL to ocidVerSionItem's |URL|()
set ocidItemName to ocidVerSionItem's |localizedName|()
set ocidItemPID to ocidVerSionItem's |persistentIdentifier|()
set ocidItemDeviceName to ocidVerSionItem's |localizedNameOfSavingComputer|()
set ocidItemModDate to ocidVerSionItem's |modificationDate|()
#保存先フォルダ名用の日付時間 (Date and time for the destination folder name)
set strFormatStrings to ("yyyyMMdd_hhmmss") as text
set strDateNo to doGetDateNo(ocidItemModDate, strFormatStrings)
#履歴の廃棄可能判断(Evaluation of the history’s deletability)
set boolDiscard to ocidVerSionItem's isDiscardable() as boolean
#保存先フォルダ作成(Create a destination folder)
if boolDiscard is true then
set strSaveDir to ("FileVersion/" & ocidBaseFileName & "/" & strRestore & "/" & strDateNo & "") as text
else if boolDiscard is false then
set strSaveDir to ("FileVersion/" & ocidBaseFileName & "/" & strKeep & "/" & strDateNo & "") as text
end if
set ocidSaveDirPathURL to (ocidDocumentDirPathURL's URLByAppendingPathComponent:(strSaveDir) isDirectory:(true))
set listDone to (appFileManager's createDirectoryAtURL:(ocidSaveDirPathURL) withIntermediateDirectories:(true) attributes:(ocidAttrDict) |error|:(reference))
#ファイル保存先(File dist path)
set ocidSaveFilePathURL to (ocidSaveDirPathURL's URLByAppendingPathComponent:(ocidItemName) isDirectory:(false))
#コピー(Copy)
set listDone to (appFileManager's copyItemAtURL:(ocidItemURL) toURL:(ocidSaveFilePathURL) |error|:(reference))
end repeat
####################
#終了時に(To open at the end)
set ocidSaveDirPathURL to ocidDocumentDirPathURL's URLByAppendingPathComponent:("FileVersion/" & ocidBaseFileName & "") isDirectory:(true)
#保存先を開く(Open the save destination)
set appWorkspace to refMe's NSWorkspace's sharedWorkspace()
set boolDone to appWorkspace's openURL:(ocidSaveDirPathURL)
return boolDone
####################
#修正日を日付時間数字にする(Set the revision date to the date and time number)
to doGetDateNo(argDateData, argFormatStrings)
#日付のフォーマットを定義(Define the date format)
set appFormatter to refMe's NSDateFormatter's alloc()'s init()
appFormatter's setLocale:(appLocale)
appFormatter's setDateFormat:(argFormatStrings)
set ocidDateAndTime to appFormatter's stringFromDate:(argDateData)
set strDateAndTime to ocidDateAndTime as text
#テキスト形式で戻す(Return to text format)
return strDateAndTime
end doGetDateNo
####################
#ローカライズメッセージ取得(Get Localize message)
to doGetDialogMsg(argLocale)
set ocidLanguageCode to argLocale's objectForKey:(refMe's NSLocaleLanguageCode)
set strLanguageCode to ocidLanguageCode as text
set ocidLocaleID to argLocale's objectForKey:(refMe's NSLocaleIdentifier)
set strLocaleID to ocidLocaleID as text
log strLocaleID
log strLanguageCode
#LPROJフォルダ名(LPROJ name)
set listLproj to {"ar", "ca", "cs", "da", "de", "el", "en_AU", "en_GB", "en", "es_419", "es", "fi", "fr_CA", "fr", "he", "hi", "hr", "hu", "id", "it", "ja", "ko", "ms", "nl", "no", "pl", "pt_BR", "pt_PT", "ro", "ru", "sk", "sl", "sv", "th", "tr", "uk", "vi", "zh_CN", "zh_HK", "zh_TW"} as list
#その中でラングエージコードになっている言語(使ってないけど)
set listLangID to {"ar", "ca", "cs", "da", "de", "el", "en", "es", "fi", "fr", "he", "hi", "hr", "hu", "id", "it", "ja", "ko", "ms", "nl", "no", "pl", "ro", "ru", "sk", "sl", "sv", "th", "tr", "uk", "vi"} as list
#その中でロケールIDになっている言語(Among them, the language that is the locale ID)
set listLocalID_Lproj to {"zh_CN", "zh_HK", "zh_TW", "pt_BR", "pt_PT", "en_AU", "en_GB", "fr_CA", "es_419"} as list
########
#FOR TEST
# set strLanguageCode to ("nn") as text
# set strLanguageCode to ("cy") as text
# set strLanguageCode to ("fr") as text
# set strLanguageCode to ("pt") as text
# set strLanguageCode to ("rm") as text
# set strLanguageCode to ("zh") as text
# set strLanguageCode to ("zh_TW") as text
# set strLocaleID to ("zh_Hant") as text
# set strLanguageCode to ("zh") as text
# set strLocaleID to ("no_NO") as text
# set strLanguageCode to ("nn") as text
#言語判定 追加事項(Additional items for language)
if listLproj does not contain strLanguageCode then
#ランゲージCodeがLPROJのフォルダ名に含まれていない場合
#If the language Code is not included in the folder name of LPROJ
if strLanguageCode is "br" then
set strSetUIlangID to ("fr") as text
else if strLanguageCode is "pt" then
set strSetUIlangID to ("pt_PT") as text
else if strLanguageCode is "gd" or strLanguageCode is "cy" then
set strSetUIlangID to ("en_GB") as text
else if strLanguageCode is "gl" or strLanguageCode is "eu" then
set strSetUIlangID to ("en_GB") as text
else if strLanguageCode is "ga" then
set strSetUIlangID to ("en_GB") as text
else if strLanguageCode is "nb" or strLanguageCode is "nn" then
set strSetUIlangID to ("no") as text
else if strLanguageCode is "is" then
set strSetUIlangID to ("sv") as text
else if strLanguageCode is "mt" then
set strSetUIlangID to ("it") as text
else if strLanguageCode is "tl" then
set strSetUIlangID to ("es") as text
else if strLanguageCode is "lo" then
set strSetUIlangID to ("th") as text
else if strLanguageCode is "rm" then
set strSetUIlangID to ("de") as text
else if strLanguageCode is "zh" then
if strLocaleID contains "zh_Hans" then
set strSetUIlangID to ("zh_CN") as text
else if strLocaleID contains "zh_CN" then
set strSetUIlangID to ("zh_CN") as text
else if strLocaleID contains "zh_Hant" then
set strSetUIlangID to ("zh_TW") as text
else if strLocaleID contains "zh_TW" then
set strSetUIlangID to ("zh_TW") as text
else if strLocaleID contains "zh_HK" then
set strSetUIlangID to ("zh_HK") as text
end if
else
#ロケールIDがLPROJのフォルダ名の場合
#If the locale ID is the folder name of LPROJ
if listLocalID_Lproj contains strLocaleID then
set strSetUIlangID to (strLocaleID) as text
else
#追加判定にない場合はen表示
#If there is no additional judgment, there is a fallover to en
set strSetUIlangID to ("en") as text
end if
end if
else
if listLocalID_Lproj contains strLocaleID then
set strSetUIlangID to (strLocaleID) as text
else
set strSetUIlangID to (strLanguageCode) as text
end if
end if
#辞書のマージ用(For dictionary merge)
set ocidMergeDict to refMe's NSMutableDictionary's alloc()'s init()
#翻訳辞書を開く(Open the translation dictionary)
#ScriptingAdditionsの辞書を使用(Use the dictionary of ScriptingAdditions)
set strFilePath to ("/System/Library/ScriptingAdditions/StandardAdditions.osax/Contents/Resources/Localizable.loctable") as text
set ocidFilePathStr to refMe's NSString's stringWithString:(strFilePath)
set ocidFilePath to ocidFilePathStr's stringByStandardizingPath()
set ocidFilePathURL to refMe's NSURL's fileURLWithPath:(ocidFilePath) isDirectory:(false)
#loctableを開く(Open loctable file)
set listResponse to refMe's NSMutableDictionary's alloc()'s initWithContentsOfURL:(ocidFilePathURL) |error|:(reference)
set ocidLocTableDict to (first item of listResponse)
#対象の言語の翻訳を取得(Get the translation of the target language)
set ocidStandardAdditionsDict to ocidLocTableDict's objectForKey:(strSetUIlangID)
#マージ merge
ocidMergeDict's addEntriesFromDictionary:(ocidStandardAdditionsDict)
#翻訳辞書を開く(Open the translation dictionary)
#AppKit.frameworkの辞書を使用(Use the dictionary of AppKit.framework)
set strFilePath to ("/System/Library/Frameworks/AppKit.framework/Versions/C/Resources/Revisions.loctable") as text
set ocidFilePathStr to refMe's NSString's stringWithString:(strFilePath)
set ocidFilePath to ocidFilePathStr's stringByStandardizingPath()
set ocidFilePathURL to refMe's NSURL's fileURLWithPath:(ocidFilePath) isDirectory:(false)
#loctableを開く(Open loctable file)
set listResponse to refMe's NSMutableDictionary's alloc()'s initWithContentsOfURL:(ocidFilePathURL) |error|:(reference)
set ocidLocTableDict to (first item of listResponse)
#対象の言語の翻訳を取得(Get the translation of the target language)
set ocidSpotlightDict to ocidLocTableDict's objectForKey:(strSetUIlangID)
#マージ merge
ocidMergeDict's addEntriesFromDictionary:(ocidSpotlightDict)
return ocidMergeDict
end doGetDialogMsg