| 001 | #!/usr/bin/env osascript |
| 002 | #coding: utf-8 |
| 003 | ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- |
| 004 | (* |
| 005 | 【留意事項】 |
| 006 | Dockの切り替えをplistを丸ごと入れ替えることで行うので |
| 007 | 連続しての切り替えは反映されない場合があります |
| 008 | いちど切り替えたら、最低でも1分程度経過してから次の切り替えを行わないと |
| 009 | どのPLISTにどの内容が入っているのかわからなくなります。 |
| 010 |
|
| 011 | 注意 |
| 012 | このスクリプトは単体動作しません |
| 013 | 以下からダウンロードして利用してください |
| 014 | https://note.com/quicktimer/n/n8dfec91b687b |
| 015 |
|
| 016 |
|
| 017 | v1 初回作成 macOS26に合わせて作り直した |
| 018 | v1.1 copyItemAtURLでは、うまく反映されないタイミングがあるのでdittoすることにした |
| 019 |
|
| 020 |
|
| 021 | com.cocolog-nifty.quicktimer.icefloe *) |
| 022 | ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- |
| 023 | use AppleScript version "2.8" |
| 024 | use framework "Foundation" |
| 025 | use framework "AppKit" |
| 026 | use scripting additions |
| 027 | property refMe : a reference to current application |
| 028 | ######################################## |
| 029 | #設定項目(バックアップを作成するか) |
| 030 | set boolBackUP to true as boolean |
| 031 |
|
| 032 |
|
| 033 | ######################################## |
| 034 | #初期設定(スクリプトと同じフォルダ内) |
| 035 | set aliasPathToMe to (path to me) as alias |
| 036 | set strPathToMe to (POSIX path of aliasPathToMe) as text |
| 037 | set ocidPathToMeStr to refMe's NSString's stringWithString:(strPathToMe) |
| 038 | set ocidPathToMe to ocidPathToMeStr's stringByStandardizingPath() |
| 039 | set ocidPathToMeURL to refMe's NSURL's alloc()'s initFileURLWithPath:(ocidPathToMe) isDirectory:(false) |
| 040 | set ocidContainerDirPathURL to ocidPathToMeURL's URLByDeletingLastPathComponent() |
| 041 | set ocidDefaultsDirPathURL to ocidContainerDirPathURL's URLByAppendingPathComponent:("Preferences/com.apple.dock") isDirectory:(true) |
| 042 | set ocidDefaultsDirPath to ocidDefaultsDirPathURL's |path|() |
| 043 | set ocidSampleDirPathURL to ocidContainerDirPathURL's URLByAppendingPathComponent:("Preferences/Sample") isDirectory:(true) |
| 044 |
|
| 045 |
|
| 046 | ######################################## |
| 047 | #バックアップ先(初期設定フォルダ内) |
| 048 | set appFileManager to refMe's NSFileManager's defaultManager() |
| 049 | set ocidURLsArray to (appFileManager's URLsForDirectory:(refMe's NSLibraryDirectory) inDomains:(refMe's NSUserDomainMask)) |
| 050 | set ocidLibraryDirPathURL to ocidURLsArray's firstObject() |
| 051 | set ocidPrefDirPathURL to ocidLibraryDirPathURL's URLByAppendingPathComponent:("Preferences") isDirectory:(true) |
| 052 | set ocidSaveDirPathURL to ocidPrefDirPathURL's URLByAppendingPathComponent:("com.apple.dock") isDirectory:(true) |
| 053 | set ocidSaveDirPath to ocidSaveDirPathURL's |path|() |
| 054 | #サンプルインストール |
| 055 | set boolDirExists to (appFileManager's fileExistsAtPath:(ocidSaveDirPath) isDirectory:(true)) |
| 056 | if boolDirExists is false then |
| 057 | set appFileManager to refMe's NSFileManager's defaultManager() |
| 058 | set ocidAttrDict to refMe's NSMutableDictionary's alloc()'s init() |
| 059 | (ocidAttrDict's setValue:(448) forKey:(refMe's NSFilePosixPermissions)) |
| 060 | set listDone to (appFileManager's createDirectoryAtURL:(ocidSaveDirPathURL) withIntermediateDirectories:(true) attributes:(ocidAttrDict) |error|:(reference)) |
| 061 | set listFileName to {"com.apple.dock.Dオフィス.plist", "com.apple.dock.Cアドビ.plist", "com.apple.dock.Bミニ.plist", "com.apple.dock.Aデフォルト.plist"} as list |
| 062 | repeat with itemFileName in listFileName |
| 063 | set ocidSampleFilePathURL to (ocidSampleDirPathURL's URLByAppendingPathComponent:(itemFileName) isDirectory:(true)) |
| 064 | set ocidSampleDistFilePathURL to (ocidSaveDirPathURL's URLByAppendingPathComponent:(itemFileName) isDirectory:(true)) |
| 065 | set listDone to (appFileManager's copyItemAtURL:(ocidSampleFilePathURL) toURL:(ocidSampleDistFilePathURL) |error|:(reference)) |
| 066 | end repeat |
| 067 | end if |
| 068 |
|
| 069 | #バックアップフォルダ |
| 070 | set ocidRecentDirPathURL to ocidSaveDirPathURL's URLByAppendingPathComponent:("Recent") isDirectory:(true) |
| 071 | set ocidPreviousDirPathURL to ocidSaveDirPathURL's URLByAppendingPathComponent:("Previous") isDirectory:(true) |
| 072 |
|
| 073 | set ocidPreviousDirPath to (ocidPreviousDirPathURL's |path|()) |
| 074 | set listDirPathURL to {ocidSaveDirPathURL, ocidRecentDirPathURL, ocidPreviousDirPathURL} as list |
| 075 | repeat with itemDirPathURL in listDirPathURL |
| 076 | set itemDirPath to itemDirPathURL's |path|() |
| 077 | #バックアップ先にcom.apple.dock |
| 078 | set boolDirExists to (appFileManager's fileExistsAtPath:(itemDirPath) isDirectory:(true)) |
| 079 | #フォルダを作っておく |
| 080 | if boolDirExists is false then |
| 081 | set appFileManager to refMe's NSFileManager's defaultManager() |
| 082 | set ocidAttrDict to refMe's NSMutableDictionary's alloc()'s init() |
| 083 | (ocidAttrDict's setValue:(448) forKey:(refMe's NSFilePosixPermissions)) |
| 084 | set listDone to (appFileManager's createDirectoryAtURL:(itemDirPathURL) withIntermediateDirectories:(true) attributes:(ocidAttrDict) |error|:(reference)) |
| 085 | end if |
| 086 | end repeat |
| 087 | set aliasPreviousDirPath to (ocidPreviousDirPathURL's absoluteURL()) as alias |
| 088 | ################################# |
| 089 | # バックアップダイアログ |
| 090 | if boolBackUP is true then |
| 091 | #バックアップ |
| 092 | set strDateNo to doGetDateNo("yyyyMMdd_HHmmSS") as text |
| 093 | set strSaveFileName to ("com.apple.dock." & strDateNo & ".plist") as text |
| 094 | set strTargetExtension to ("plist") as text |
| 095 | #ダイアログ |
| 096 | set strMsg to ("今のDockの設定をバックアップします") as text |
| 097 | set strPrompt to ("今のDock設定のバックアップ" & return & "保存ファイル名を決めてください") as text |
| 098 | try |
| 099 | tell application "SystemUIServer" |
| 100 | activate |
| 101 | set aliasFilePath to (choose file name strMsg with prompt strPrompt default location aliasPreviousDirPath default name strSaveFileName) as «class furl» |
| 102 | end tell |
| 103 | on error strErrMes number numErrNo |
| 104 | log strErrMes & numErrNo |
| 105 | return false |
| 106 | end try |
| 107 | #パス |
| 108 | set strBackupFilePath to (POSIX path of aliasFilePath) as text |
| 109 | set ocidBackupFilePathStr to refMe's NSString's stringWithString:(strBackupFilePath) |
| 110 | set ocidBackupFilePath to ocidBackupFilePathStr's stringByStandardizingPath() |
| 111 | set ocidBackupFilePathURL to refMe's NSURL's alloc()'s initFileURLWithPath:(ocidBackupFilePath) isDirectory:(false) |
| 112 | set ocidContainerDirPathURL to ocidBackupFilePathURL's URLByDeletingLastPathComponent() |
| 113 | |
| 114 | #厳格な比較 |
| 115 | # set listResponse to ocidPreviousDirPathURL's getResourceValue:(reference) forKey:(refMe's NSURLFileResourceIdentifierKey) |error|:(reference) |
| 116 | # set ocidSaveDirID to (2nd item of listResponse) |
| 117 | # set listResponse to ocidContainerDirPathURL's getResourceValue:(reference) forKey:(refMe's NSURLFileResourceIdentifierKey) |error|:(reference) |
| 118 | # set ocidContainerDirID to (2nd item of listResponse) |
| 119 | # set boolIsEq to ocidContainerDirID's isEqual:(ocidSaveDirID) |
| 120 | #保存先フォルダが指定外なら停止 |
| 121 | |
| 122 | |
| 123 | set strBackupExtension to (ocidBackupFilePathURL's pathExtension()) as text |
| 124 | set strBackupFileName to (ocidBackupFilePathURL's lastPathComponent()) as text |
| 125 | #拡張子のつけ忘れ対策 |
| 126 | if strBackupFileName does not contain strTargetExtension then |
| 127 | set strBackupFileName to (strBackupFileName & "." & strTargetExtension) as text |
| 128 | set ocidDistFilePathURL to ocidContainerDirPathURL's URLByAppendingPathComponent:(strBackupFileName) |
| 129 | end if |
| 130 | |
| 131 | set ocidDistFilePathURL to ocidPreviousDirPathURL's URLByAppendingPathComponent:(strBackupFileName) isDirectory:(false) |
| 132 | set ocidOrgFilePathURL to ocidPrefDirPathURL's URLByAppendingPathComponent:("com.apple.dock.plist") isDirectory:(false) |
| 133 | |
| 134 | #NSDATA |
| 135 | set ocidOption to (refMe's NSDataReadingMappedIfSafe) |
| 136 | set listResponse to refMe's NSData's alloc()'s initWithContentsOfURL:(ocidOrgFilePathURL) options:(ocidOption) |error|:(reference) |
| 137 | set ocidPlistData to (first item of listResponse) |
| 138 | if ocidPlistData = (missing value) then |
| 139 | tell application "SystemUIServer" |
| 140 | activate |
| 141 | display alert "PLISTのデータが空でした" |
| 142 | end tell |
| 143 | return false |
| 144 | end if |
| 145 | set ocidOption to (refMe's NSDataWritingAtomic) |
| 146 | set listDone to ocidPlistData's writeToURL:(ocidDistFilePathURL) options:(ocidOption) |error|:(reference) |
| 147 | if (first item of listDone) is false then |
| 148 | |
| 149 | set ocidDistFilePath to ocidDistFilePathURL's |path|() |
| 150 | set ocidOrgFilePath to ocidOrgFilePathURL's |path|() |
| 151 | |
| 152 | set strCmd to ("/usr/bin/ditto '" & ocidOrgFilePath & "' '" & ocidDistFilePath & "'") as text |
| 153 | try |
| 154 | do shell script strCmd |
| 155 | on error strErrMsg number numErrNo |
| 156 | log strErrMsg & numErrNo |
| 157 | return false |
| 158 | end try |
| 159 | end if |
| 160 | end if |
| 161 |
|
| 162 |
|
| 163 | ################################# |
| 164 | #コンテンツの収集 |
| 165 | set ocidOption to (refMe's NSDirectoryEnumerationSkipsHiddenFiles) |
| 166 | set ocidKeyArray to refMe's NSMutableArray's alloc()'s init() |
| 167 | ocidKeyArray's addObject:(refMe's NSURLPathKey) |
| 168 | ocidKeyArray's addObject:(refMe's NSURLNameKey) |
| 169 | set listResponse to (appFileManager's contentsOfDirectoryAtURL:(ocidSaveDirPathURL) includingPropertiesForKeys:(ocidKeyArray) options:(ocidOption) |error|:(reference)) |
| 170 | set ocidFileURLArray to (first item of listResponse) |
| 171 | #ソート |
| 172 | set ocidDescriptor to refMe's NSSortDescriptor's sortDescriptorWithKey:("lastPathComponent") ascending:(yes) selector:("localizedStandardCompare:") |
| 173 | set ocidDescriptorArray to refMe's NSArray's arrayWithObject:(ocidDescriptor) |
| 174 | set ocidSortedArray to ocidFileURLArray's sortedArrayUsingDescriptors:(ocidDescriptorArray) |
| 175 | set listFileName to {} as list |
| 176 | set listExclusion to {"Recent", "Previous"} as list |
| 177 | repeat with itemURL in ocidSortedArray |
| 178 | set strFileName to itemURL's lastPathComponent() as text |
| 179 | if listExclusion does not contain strFileName then |
| 180 | set end of listFileName to strFileName |
| 181 | end if |
| 182 | end repeat |
| 183 | set end of listFileName to "過去の設定から" |
| 184 | ################################# |
| 185 | #ダイアログ |
| 186 | set strLF to ("" & linefeed & "") as text |
| 187 | set strTitle to ("選んでください") as text |
| 188 | set strPrompt to ("ひとつ選んでください" & strLF & "日付無し『com.apple.dock.plist』は" & strLF & "OSデフォルトです" & strLF & "リスト上部が古い設定下が新しい設定") as text |
| 189 | set strOK to ("OK") as text |
| 190 | set strCancel to ("キャンセル") as text |
| 191 | try |
| 192 | tell application "System Events" |
| 193 | activate |
| 194 | set valueResponse to (choose from list listFileName with title strTitle with prompt strPrompt default items (last item of listFileName) OK button name strOK cancel button name strCancel with empty selection allowed without multiple selections allowed) |
| 195 | end tell |
| 196 | on error strErrMes number numErrNo |
| 197 | log strErrMes & numErrNo |
| 198 | return false |
| 199 | end try |
| 200 | if (class of valueResponse) is boolean then |
| 201 | error "ユーザによってキャンセルされました。" number -128 |
| 202 | return false |
| 203 | else if (class of valueResponse) is list then |
| 204 | if valueResponse is {} then |
| 205 | error "Error 何も選んでいません" number -128 |
| 206 | return false |
| 207 | else |
| 208 | tell application "System Events" to quit |
| 209 | set strResponse to (first item of valueResponse) as text |
| 210 | end if |
| 211 | end if |
| 212 | if strResponse is "過去の設定から" then |
| 213 | ################################# |
| 214 | #コンテンツの収集 |
| 215 | set ocidOption to (refMe's NSDirectoryEnumerationSkipsHiddenFiles) |
| 216 | set ocidKeyArray to refMe's NSMutableArray's alloc()'s init() |
| 217 | ocidKeyArray's addObject:(refMe's NSURLPathKey) |
| 218 | ocidKeyArray's addObject:(refMe's NSURLNameKey) |
| 219 | set listResponse to (appFileManager's contentsOfDirectoryAtURL:(ocidPreviousDirPathURL) includingPropertiesForKeys:(ocidKeyArray) options:(ocidOption) |error|:(reference)) |
| 220 | set ocidFileURLArray to (first item of listResponse) |
| 221 | #ソート |
| 222 | set ocidDescriptor to refMe's NSSortDescriptor's sortDescriptorWithKey:("lastPathComponent") ascending:(yes) selector:("localizedStandardCompare:") |
| 223 | set ocidDescriptorArray to refMe's NSArray's arrayWithObject:(ocidDescriptor) |
| 224 | set ocidSortedArray to ocidFileURLArray's sortedArrayUsingDescriptors:(ocidDescriptorArray) |
| 225 | set listFileName to {} as list |
| 226 | set listExclusion to {"Recent", "Previous"} as list |
| 227 | repeat with itemURL in ocidSortedArray |
| 228 | set strFileName to itemURL's lastPathComponent() as text |
| 229 | if listExclusion does not contain strFileName then |
| 230 | set end of listFileName to strFileName |
| 231 | end if |
| 232 | end repeat |
| 233 | try |
| 234 | tell application "System Events" |
| 235 | activate |
| 236 | set valueResponse to (choose from list listFileName with title strTitle with prompt strPrompt default items (last item of listFileName) OK button name strOK cancel button name strCancel with empty selection allowed without multiple selections allowed) |
| 237 | end tell |
| 238 | on error strErrMes number numErrNo |
| 239 | log strErrMes & numErrNo |
| 240 | return false |
| 241 | end try |
| 242 | if (class of valueResponse) is boolean then |
| 243 | error "ユーザによってキャンセルされました。" number -128 |
| 244 | return false |
| 245 | else if (class of valueResponse) is list then |
| 246 | if valueResponse is {} then |
| 247 | error "Error 何も選んでいません" number -128 |
| 248 | return false |
| 249 | else |
| 250 | tell application "System Events" to quit |
| 251 | set strResponse to (first item of valueResponse) as text |
| 252 | end if |
| 253 | end if |
| 254 | set ocidRestoreDirPathURL to ocidPreviousDirPathURL's |copy|() |
| 255 | set ocidRestoreFilePathURL to ocidRestoreDirPathURL's URLByAppendingPathComponent:(strResponse) isDirectory:(false) |
| 256 | else if strResponse is "com.apple.dock.plist" then |
| 257 | set ocidRestoreDirPathURL to ocidDefaultsDirPathURL's |copy|() |
| 258 | set ocidRestoreFilePathURL to ocidRestoreDirPathURL's URLByAppendingPathComponent:(strResponse) isDirectory:(false) |
| 259 | else |
| 260 | set ocidRestoreDirPathURL to ocidSaveDirPathURL's |copy|() |
| 261 | set ocidRestoreFilePathURL to ocidRestoreDirPathURL's URLByAppendingPathComponent:(strResponse) isDirectory:(false) |
| 262 | end if |
| 263 | #################################### |
| 264 | #直近の設定を移動して |
| 265 | set ocidRecentFilePathURL to ocidRecentDirPathURL's URLByAppendingPathComponent:("com.apple.dock.plist") isDirectory:(false) |
| 266 | set strDateNo to doGetDateNo("yyyyMMdd_HHmmSS") as text |
| 267 | set strSaveFileName to ("com.apple.dock." & strDateNo & ".plist") as text |
| 268 | set ocidPreviousFilePathURL to ocidPreviousDirPathURL's URLByAppendingPathComponent:(strSaveFileName) isDirectory:(false) |
| 269 | set listDone to (appFileManager's moveItemAtURL:(ocidRecentFilePathURL) toURL:(ocidPreviousFilePathURL) |error|:(reference)) |
| 270 | #################################### |
| 271 | #今の設定を移動して |
| 272 | set ocidCurrentFilePathURL to ocidPrefDirPathURL's URLByAppendingPathComponent:("com.apple.dock.plist") isDirectory:(false) |
| 273 | set ocidRecentFilePathURL to ocidRecentDirPathURL's URLByAppendingPathComponent:("com.apple.dock.plist") isDirectory:(false) |
| 274 | set listDone to (appFileManager's moveItemAtURL:(ocidCurrentFilePathURL) toURL:(ocidRecentFilePathURL) |error|:(reference)) |
| 275 | #################################### |
| 276 | #設定を戻す |
| 277 | set listDone to (appFileManager's copyItemAtURL:(ocidRestoreFilePathURL) toURL:(ocidCurrentFilePathURL) |error|:(reference)) |
| 278 |
|
| 279 | #結局copyItemAtURLではうまく反映されないタイミングがあるのでDittoすることにした |
| 280 | set ocidRestoreFilePath to ocidRestoreFilePathURL's |path|() |
| 281 | set ocidCurrentFilePath to ocidCurrentFilePathURL's |path|() |
| 282 | set strCmd to ("/usr/bin/ditto \"" & ocidRestoreFilePath & "\" \"" & ocidCurrentFilePath & "\"") as text |
| 283 | try |
| 284 | do shell script strCmd |
| 285 | end try |
| 286 |
|
| 287 | #################################### |
| 288 | #他にいい方法があるとは思うんだけどね |
| 289 | set strCmd to ("/usr/bin/touch \"" & ocidCurrentFilePath & "\"") as text |
| 290 | try |
| 291 | do shell script strCmd |
| 292 | end try |
| 293 | delay 0.25 |
| 294 | set strCmd to ("/usr/bin/killall cfprefsd") as text |
| 295 | try |
| 296 | do shell script strCmd |
| 297 | end try |
| 298 | delay 0.5 |
| 299 | set strCmd to ("/usr/bin/defaults read \"" & ocidCurrentFilePath & "\"") as text |
| 300 | try |
| 301 | do shell script strCmd |
| 302 | end try |
| 303 | delay 0.5 |
| 304 | set strCmd to ("/usr/bin/killall Dock") as text |
| 305 | try |
| 306 | do shell script strCmd |
| 307 | end try |
| 308 | # PLISTを変更しない場合はここまで |
| 309 | return true |
| 310 | #PLISTに変更が入っている間はここで開いてファイル名等を変更する |
| 311 | set appSharedWorkspace to refMe's NSWorkspace's sharedWorkspace() |
| 312 | set boolDone to appSharedWorkspace's openURL:(ocidSaveDirPathURL) |
| 313 | return boolDone |
| 314 | ################################# |
| 315 | #日付 |
| 316 | to doGetDateNo(argFormatStrings) |
| 317 | set ocidDate to refMe's NSDate's |date|() |
| 318 | set ocidNSDateFormatter to refMe's NSDateFormatter's alloc()'s init() |
| 319 | ocidNSDateFormatter's setLocale:(refMe's NSLocale's localeWithLocaleIdentifier:"ja_JP_POSIX") |
| 320 | ocidNSDateFormatter's setDateFormat:(argFormatStrings) |
| 321 | set ocidDateAndTime to ocidNSDateFormatter's stringFromDate:(ocidDate) |
| 322 | set strDateAndTime to ocidDateAndTime as text |
| 323 | return strDateAndTime |
| 324 | end doGetDateNo |