| 001 | #!/usr/bin/env osascript |
| 002 | #coding: utf-8 |
| 003 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7 |
| 004 | (* |
| 005 |
|
| 006 | スクリプトメニュー用 |
| 007 |
|
| 008 | macOS26で新しくなった |
| 009 | アイコン(文字)付き+色付きフォルダを作成します |
| 010 |
|
| 011 | 各処理に1秒の待ち時間をつけているので |
| 012 | 比較的時間がかかります |
| 013 |
|
| 014 | v4からこのスクリプトだけで |
| 015 | SF Symbols、絵文字、通常の文字が入力できます |
| 016 |
|
| 017 | SF Symbols.appでシンボル名は調べることができます |
| 018 | https://developer.apple.com/sf-symbols/ |
| 019 | または を参照してください |
| 020 | https://github.com/andrewtavis/sf-symbols-online |
| 021 |
|
| 022 | 実験中 |
| 023 | ダイアログをcurrent applicationで別にしたのは |
| 024 | 新しい試みで、スクリプトメニューからの実行を考慮してみた |
| 025 | 文字の場合(not SF Symbols)は10文字までの制限を入れた |
| 026 |
|
| 027 | メッセージやログの2ヶ国語対応に初挑戦 |
| 028 |
|
| 029 | 制限事項 |
| 030 | すでにタグが設定してあるフォルダを処理する場合 |
| 031 | ラベル無しを選択すると、設定済みのタグを削除してカラーを無しにします |
| 032 |
|
| 033 | v1 初回作成 |
| 034 | v1.1 20251017 複数文字入力に対応 グリーンの設定間違いを修正 |
| 035 | v2 20251017 メッセージやダイアログを2ヶ国語対応にしてみた |
| 036 | v3 20251022 タグの名称をcom.apple.LSSharedFileList.ProjectsItemsから取得するように変更 |
| 037 | v3.1 20251022 フォルダをタグに基づいて色合い調整を有効にするようにした |
| 038 | v3.1.1 20251025 OSバージョン取得のところを少し治した |
| 039 | v3.2 20251025 UIプロセスが残ってしまうので プロセスのクリーニングを入れた |
| 040 | v3.2.1 20251026 ProjectsItemsのインデックス指定のないタグに対応した |
| 041 | v3.2.2 20251026 NSUserDefaultsの設定誤りを修正 |
| 042 | v3.3 20251026 Symbols名のチェックを入れた |
| 043 | v4 20251026 文字もSF Symbolsも両方対応するようにした |
| 044 | v4.0.1 20251115 文字数の最大を10文字にした |
| 045 | v4.0.2 20251115 UIプロセスクリーニングを少し改良 |
| 046 | v4.1 20251115 インデクスとタグを逆順にしたら良くなったので様子見ることにした |
| 047 | v4.2 20251122 タグ名部分だけマルチリンガル対応にしたテスト版 |
| 048 | v4.3 20251123 タグ名の取得を見直し修正した |
| 049 | v.4.4 20251123 カントリーコードと国旗の対応をした |
| 050 | v.4.4.1 20251203 一部ダイアログをマルチリンガル対応した |
| 051 | v.4.5 20260408 今日の日付合字版を選択リストに入るようにした |
| 052 |
|
| 053 | このスクリプトのライセンス |
| 054 | CC0 1.0 全世界 (CC0 1.0) |
| 055 | https://quicktimer.cocolog-nifty.com/icefloe/2011/01/readme.html#licenseJA |
| 056 |
|
| 057 | こちらの記事を参考にしました |
| 058 | https://eclecticlight.co/2025/09/18/customising-folders-in-tahoe/ |
| 059 | Mr. Howardに感謝 |
| 060 |
|
| 061 | Creates a new color folder feature introduced in macOS 26 |
| 062 |
|
| 063 | 1-second delay is added between each process, |
| 064 | so it may take a little time to complete. |
| 065 |
|
| 066 | SF Symbols version: you can enter a Symbol Name text. |
| 067 | Although not fully verified, characters included in one of macOS’s default fonts, |
| 068 | SF Pro, should generally work fine. |
| 069 |
|
| 070 | SF You can check the symbol name on Symbols.app |
| 071 | https://developer.apple.com/sf-symbols/ |
| 072 | Or please refer to the following |
| 073 | https://github.com/andrewtavis/sf-symbols-online |
| 074 |
|
| 075 | During the experiment |
| 076 | The dialog is separated using "current application" ― |
| 077 | this is an experimental approach for running from the Script Menu. |
| 078 | In the case of characters (not SF Symbols), it is limited to 10 characters. |
| 079 |
|
| 080 | First attempt at bilingual (English/Japanese) messages and logs. |
| 081 |
|
| 082 | Limitations |
| 083 | When processing a folder that already has tags assigned, |
| 084 | Label selecting “None” will remove the existing tags and clear the color setting. |
| 085 |
|
| 086 | v1 Initial version |
| 087 | v1.1 20251017 Added support for multi-character input |
| 088 | v2 20251017 First attempt at bilingual messages and logs. |
| 089 | v3 20251022 Change tag names to be retrieved from com.apple.LSSharedFileList.ProjectsItems |
| 090 | v3.1 20251022 Enabled color adjustment for folders based on tags |
| 091 | v3.2 20251025 UI process will remain, so I cleaned the process. |
| 092 | v3.2.1 20251026 ProjectsItems Corresponded to tags without indexing |
| 093 | v3.2.2 20251026 NSUserDefaults's Fixed the setting error |
| 094 | v3.3 20251026 checked the name of Symbols |
| 095 | v4 20251026 Both letters and SF Symbols are supported. |
| 096 | v4.0.1 20251115 The maximum number of characters is set to 10 characters |
| 097 | v4.1 20251115 If I put the index and tag in reverse order, it got better, so I decided to wait and see. |
| 098 | v4.3 20251123 The acquisition of the tag name has been reviewed and corrected |
| 099 | v.4.4 20251123 Country code and national flag correspondence |
| 100 |
|
| 101 |
|
| 102 | License of this script |
| 103 | CC0 1.0 Universal (Public Domain Dedication). |
| 104 | https://quicktimer.cocolog-nifty.com/icefloe/2011/01/readme.html#licenseEN |
| 105 |
|
| 106 | I referred to this article |
| 107 | https://eclecticlight.co/2025/09/18/customising-folders-in-tahoe/ |
| 108 | Thanks to Mr. Howard |
| 109 |
|
| 110 | com.cocolog-nifty.quicktimer.icefloe *) |
| 111 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7 |
| 112 | use AppleScript version "2.8" |
| 113 | use framework "Foundation" |
| 114 | use framework "AppKit" |
| 115 | use scripting additions |
| 116 | property refMe : a reference to current application |
| 117 | ############ |
| 118 | #設定項目 |
| 119 | #処理間待ち時間 デフォルト1秒 |
| 120 | #Waiting time between processing Default 1 second |
| 121 | property numMagicTime : 1.0 as number |
| 122 |
|
| 123 |
|
| 124 | on run |
| 125 | |
| 126 | |
| 127 | ############################# |
| 128 | #ダイアログ |
| 129 | set strAppFilePath to ("/System/Library/ScriptingAdditions/StandardAdditions.osax") as text |
| 130 | set ocidAppFilePathStr to refMe's NSString's stringWithString:(strAppFilePath) |
| 131 | set ocidAppFilePath to ocidAppFilePathStr's stringByStandardizingPath() |
| 132 | set ocidAppFilePathURL to refMe's NSURL's fileURLWithPath:(ocidAppFilePath) isDirectory:(true) |
| 133 | set appBundle to refMe's NSBundle's bundleWithURL:(ocidAppFilePathURL) |
| 134 | set strChooseAFolder to (appBundle's localizedStringForKey:("Choose a Folder") value:("Choose a Folder") table:("Localizable")) as text |
| 135 | # |
| 136 | set strAppFilePath to "/System/Library/CoreServices/Finder.app" as text |
| 137 | set ocidAppFilePathStr to refMe's NSString's stringWithString:(strAppFilePath) |
| 138 | set ocidAppFilePath to ocidAppFilePathStr's stringByStandardizingPath() |
| 139 | set ocidAppFilePathURL to refMe's NSURL's fileURLWithPath:(ocidAppFilePath) isDirectory:(true) |
| 140 | set appBundle to refMe's NSBundle's bundleWithURL:(ocidAppFilePathURL) |
| 141 | set strFolder to (appBundle's localizedStringForKey:("NE89") value:("Folder") table:("LocalizableMerged")) as text |
| 142 | set strCustomizeFolder to (appBundle's localizedStringForKey:("N160.2") value:("Customize Folder…") table:("LocalizableMerged")) as text |
| 143 | # |
| 144 | set strAppFilePath to "/System/Library/Frameworks/AppKit.framework" as text |
| 145 | set ocidAppFilePathStr to refMe's NSString's stringWithString:(strAppFilePath) |
| 146 | set ocidAppFilePath to ocidAppFilePathStr's stringByStandardizingPath() |
| 147 | set ocidAppFilePathURL to refMe's NSURL's fileURLWithPath:(ocidAppFilePath) isDirectory:(true) |
| 148 | set appBundle to refMe's NSBundle's bundleWithURL:(ocidAppFilePathURL) |
| 149 | set strMultiple to (appBundle's localizedStringForKey:("Multiple Selection") value:("Multiple Selection") table:("Placeholders")) as text |
| 150 | # |
| 151 | set strMsg to ("" & strCustomizeFolder & return & strChooseAFolder & return & strMultiple & "") as text |
| 152 | set strPrompt to ("" & strCustomizeFolder & return & strChooseAFolder & return & strMultiple & "") as text |
| 153 | ############ |
| 154 | set appFileManager to refMe's NSFileManager's defaultManager() |
| 155 | set ocidURLsArray to (appFileManager's URLsForDirectory:(refMe's NSDesktopDirectory) inDomains:(refMe's NSUserDomainMask)) |
| 156 | set ocidDesktopDirPathURL to ocidURLsArray's firstObject() |
| 157 | set aliasDefaultLocation to (ocidDesktopDirPathURL's absoluteURL()) as alias |
| 158 | ############ |
| 159 | tell application "SystemUIServer" |
| 160 | activate |
| 161 | set listAliasFolderPath to (choose folder strMsg with prompt strPrompt default location aliasDefaultLocation with multiple selections allowed without invisibles and showing package contents) as list |
| 162 | end tell |
| 163 | |
| 164 | |
| 165 | |
| 166 | set boolDone to (open listAliasFolderPath) as boolean |
| 167 | try |
| 168 | tell application "System Events" to quit |
| 169 | end try |
| 170 | return boolDone |
| 171 | end run |
| 172 |
|
| 173 |
|
| 174 | on open listAliasFolderPath |
| 175 | ###################### |
| 176 | set ocidFolderURLArray to refMe's NSMutableArray's alloc()'s init() |
| 177 | #フォルダだけを次工程に回す |
| 178 | set appFileManager to refMe's NSFileManager's defaultManager() |
| 179 | repeat with itemAliasFolderPath in listAliasFolderPath |
| 180 | set aliasFolderPath to itemAliasFolderPath as alias |
| 181 | set strDirPath to (POSIX path of aliasFolderPath) as text |
| 182 | set ocidDirPathStr to (refMe's NSString's stringWithString:(strDirPath)) |
| 183 | set ocidDirPath to ocidDirPathStr's stringByStandardizingPath() |
| 184 | set ocidDirPathURL to (refMe's NSURL's alloc()'s initFileURLWithPath:(ocidDirPath) isDirectory:(true)) |
| 185 | # |
| 186 | set listResponse to (ocidDirPathURL's getResourceValue:(reference) forKey:(refMe's NSURLIsDirectoryKey) |error|:(reference)) |
| 187 | set boolIsDir to (item 2 of listResponse) as boolean |
| 188 | if boolIsDir is true then |
| 189 | (ocidFolderURLArray's addObject:(ocidDirPathURL)) |
| 190 | end if |
| 191 | end repeat |
| 192 | |
| 193 | ###################### |
| 194 | #【設定項目】 Setting items |
| 195 | #SF Symbolsのプリセットリスト よく使うものを登録して利用します |
| 196 | #Preset list of SF Symbols Register and use frequently used items |
| 197 | #ご自分でカスタマイズしてください |
| 198 | #Please customize it yourself |
| 199 | set listSymbolName to {"applescript.fill", "apple.logo", "apple.classical.pages.fill", "gear", "gearshape.2.fill", "globe.badge.chevron.backward", "icloud.and.arrow.down.fill", "icloud.and.arrow.up.fill", "finder", "lock.badge.checkmark.fill", "receipt.fill", "envelope.open.fill", "printer.filled.and.paper", "wrench.and.screwdriver.fill", "square.2.layers.3d.fill"} as list |
| 200 | ##今日の日付合字版 |
| 201 | set listResponse to doGetTodayString() |
| 202 | set beginning of listSymbolName to (first item of listResponse) |
| 203 | set beginning of listSymbolName to (last item of listResponse) |
| 204 | |
| 205 | ###################### |
| 206 | #フォルダをタグに基づいて色合い調整 設定を有効にする |
| 207 | #Disable Tag Based Icon Tinting をFalseにして設定を有効にする |
| 208 | set ocidGlobalDomain to refMe's NSUserDefaults's alloc()'s initWithSuiteName:(".GlobalPreferences") |
| 209 | set ocidGlobalDomainDict to ocidGlobalDomain's dictionaryRepresentation() |
| 210 | set ocidKeyArray to ocidGlobalDomainDict's allKeys() |
| 211 | set boolContain to ocidKeyArray's containsObject:("AppleDisableTagBasedIconTinting") |
| 212 | #分岐は不要だったけどせっかく書いたので残す |
| 213 | #I didn't need a branch, but I wrote it, so I'll leave it. |
| 214 | if (boolContain as boolean) is false then |
| 215 | #設定済みなので何もしない |
| 216 | #I don't do anything because it's already set up |
| 217 | set boolDidChange to false as boolean |
| 218 | else if boolContain is true then |
| 219 | ocidGlobalDomain's removeObjectForKey:("AppleDisableTagBasedIconTinting") |
| 220 | ocidGlobalDomain's synchronize() |
| 221 | set boolDidChange to true as boolean |
| 222 | end if |
| 223 | |
| 224 | ###################### |
| 225 | #ロケールの値でメッセージを分岐する |
| 226 | set appLocale to refMe's NSLocale's currentLocale() |
| 227 | set ocidLocaleID to appLocale's objectForKey:(refMe's NSLocaleIdentifier) |
| 228 | set ocidCountryCode to appLocale's objectForKey:(refMe's NSLocaleCountryCode) |
| 229 | set ocidLanguageCode to appLocale's objectForKey:(refMe's NSLocaleLanguageCode) |
| 230 | set strLocaleID to ocidLocaleID as text |
| 231 | set strCountryCode to ocidCountryCode as text |
| 232 | set strLanguageCode to ocidLanguageCode as text |
| 233 | #国旗絵文字取得 |
| 234 | #Get the national flag emoji |
| 235 | set ocidFlagEmoji to doGetCountryCode2EmojiFlag(ocidCountryCode) |
| 236 | |
| 237 | |
| 238 | ################################ |
| 239 | #【1】OSのデフォルトタグ名を収集する |
| 240 | # 各国語でのタグ名のデフォルト値の取得 |
| 241 | set strAppFilePath to "/System/Library/CoreServices/Finder.app" as text |
| 242 | set ocidAppFilePathStr to refMe's NSString's stringWithString:(strAppFilePath) |
| 243 | set ocidAppFilePath to ocidAppFilePathStr's stringByStandardizingPath() |
| 244 | set ocidAppFilePathURL to refMe's NSURL's fileURLWithPath:(ocidAppFilePath) isDirectory:(true) |
| 245 | set appFineder to refMe's NSBundle's bundleWithURL:(ocidAppFilePathURL) |
| 246 | #localizedStringForKeyは |
| 247 | #en英語のLPROJのキーと値を入れます |
| 248 | set ocidNoColor to appFineder's localizedStringForKey:("TG_COLOR_0") value:("No Color") table:("LocalizableMerged") |
| 249 | set ocidGray to appFineder's localizedStringForKey:("TG_COLOR_1") value:("Gray") table:("LocalizableMerged") |
| 250 | set ocidGreen to appFineder's localizedStringForKey:("TG_COLOR_2") value:("Green") table:("LocalizableMerged") |
| 251 | set ocidPurple to appFineder's localizedStringForKey:("TG_COLOR_3") value:("Purple") table:("LocalizableMerged") |
| 252 | set ocidBlue to appFineder's localizedStringForKey:("TG_COLOR_4") value:("Blue") table:("LocalizableMerged") |
| 253 | set ocidYellow to appFineder's localizedStringForKey:("TG_COLOR_5") value:("Yellow") table:("LocalizableMerged") |
| 254 | set ocidRed to appFineder's localizedStringForKey:("TG_COLOR_6") value:("Red") table:("LocalizableMerged") |
| 255 | set ocidOrange to appFineder's localizedStringForKey:("TG_COLOR_7") value:("Orange") table:("LocalizableMerged") |
| 256 | #カラー無し |
| 257 | set strIndex0 to ocidNoColor as text |
| 258 | #グレイ |
| 259 | set strIndex1 to ocidGray as text |
| 260 | #グリーン |
| 261 | set strIndex2 to ocidGreen as text |
| 262 | #パープル |
| 263 | set strIndex3 to ocidPurple as text |
| 264 | #ブルー |
| 265 | set strIndex4 to ocidBlue as text |
| 266 | #イエロー |
| 267 | set strIndex5 to ocidYellow as text |
| 268 | #レッド |
| 269 | set strIndex6 to ocidRed as text |
| 270 | #オレンジ |
| 271 | set strIndex7 to ocidOrange as text |
| 272 | #ラベル無しの場合 |
| 273 | set strSetNoSelect to (strIndex0) as text |
| 274 | |
| 275 | ################################ |
| 276 | #【2】com.apple.sharedfilelistの値を収集する |
| 277 | set ocidURLsArray to appFileManager's URLsForDirectory:(refMe's NSApplicationSupportDirectory) inDomains:(refMe's NSUserDomainMask) |
| 278 | set ocidApplicatioocidupportDirPathURL to ocidURLsArray's firstObject() |
| 279 | set ocidContainerPathURL to ocidApplicatioocidupportDirPathURL's URLByAppendingPathComponent:("com.apple.sharedfilelist") isDirectory:(true) |
| 280 | set strFileName to ("com.apple.LSSharedFileList.ProjectsItems.sfl4") as text |
| 281 | set ocidSharedFileListURL to ocidContainerPathURL's URLByAppendingPathComponent:(strFileName) isDirectory:(false) |
| 282 | #osascriptからアクセスするためにまずコピーする |
| 283 | set appFileManager to refMe's NSFileManager's defaultManager() |
| 284 | set ocidTempDirURL to appFileManager's temporaryDirectory() |
| 285 | set ocidUUID to refMe's NSUUID's alloc()'s init() |
| 286 | set ocidUUIDString to ocidUUID's UUIDString |
| 287 | set ocidSaveDirPathURL to ocidTempDirURL's URLByAppendingPathComponent:(ocidUUIDString) isDirectory:(true) |
| 288 | #コピー先フォルダを作成して |
| 289 | set ocidAttrDict to refMe's NSMutableDictionary's alloc()'s init() |
| 290 | ocidAttrDict's setValue:(511) forKey:(refMe's NSFilePosixPermissions) |
| 291 | set listDone to appFileManager's createDirectoryAtURL:(ocidSaveDirPathURL) withIntermediateDirectories:(true) attributes:(ocidAttrDict) |error|:(reference) |
| 292 | #パスを定義 |
| 293 | set strFileName to "com.apple.LSSharedFileList.ProjectsItems.sfl4" as text |
| 294 | set ocidTempFilePathURL to ocidSaveDirPathURL's URLByAppendingPathComponent:(strFileName) isDirectory:false |
| 295 | #コピー |
| 296 | set listDone to (appFileManager's copyItemAtURL:(ocidSharedFileListURL) toURL:(ocidTempFilePathURL) |error|:(reference)) |
| 297 | |
| 298 | #NSKeyedUnarchiver |
| 299 | #この方法が正しいのか?わからないが取得できているので良しとする |
| 300 | set ocidOption to (refMe's NSDataReadingMappedIfSafe) |
| 301 | set listResponse to refMe's NSData's alloc()'s initWithContentsOfURL:(ocidTempFilePathURL) options:(ocidOption) |error|:(reference) |
| 302 | set ocidReadData to (first item of listResponse) |
| 303 | |
| 304 | ###################### |
| 305 | #ProjectsItemsから値が取れなかった場合 |
| 306 | #稀だけどファイル自体がない場合がある |
| 307 | if ocidReadData = (missing value) then |
| 308 | |
| 309 | set listIndex to {strIndex0, strIndex1, strIndex2, strIndex3, strIndex4, strIndex5, strIndex6, strIndex7} as list |
| 310 | set ocidNameArray to refMe's NSArray's arrayWithArray:(listIndex) |
| 311 | set ocidIndexDict to refMe's NSMutableDictionary's alloc()'s init() |
| 312 | ocidIndexDict's setObject:(0) forKey:(strIndex0) |
| 313 | ocidIndexDict's setObject:(1) forKey:(strIndex1) |
| 314 | ocidIndexDict's setObject:(2) forKey:(strIndex2) |
| 315 | ocidIndexDict's setObject:(3) forKey:(strIndex3) |
| 316 | ocidIndexDict's setObject:(4) forKey:(strIndex4) |
| 317 | ocidIndexDict's setObject:(5) forKey:(strIndex5) |
| 318 | ocidIndexDict's setObject:(6) forKey:(strIndex6) |
| 319 | ocidIndexDict's setObject:(7) forKey:(strIndex7) |
| 320 | |
| 321 | ###################### |
| 322 | #com.apple.sharedfilelistからタグ名を収集できた場合 |
| 323 | else if ocidReadData ≠ (missing value) then |
| 324 | set ocidSetArray to refMe's NSMutableArray's alloc()'s init() |
| 325 | ocidSetArray's addObject:(refMe's NSObject's class) |
| 326 | ocidSetArray's addObject:(refMe's NSKeyedArchiver's class) |
| 327 | ocidSetArray's addObject:(refMe's NSArray's class) |
| 328 | set ocidClassSet to refMe's NSSet's setWithArray:(ocidSetArray) |
| 329 | set listResponse to refMe's NSKeyedUnarchiver's unarchivedObjectOfClasses:(ocidClassSet) fromData:(ocidReadData) |error|:(reference) |
| 330 | set ocidSharedfilelistDict to (first item of listResponse) |
| 331 | #LocalizableMergedから収集した形式と同じになるようにする |
| 332 | set ocidItemsArray to ocidSharedfilelistDict's objectForKey:("items") |
| 333 | set ocidIndexDict to refMe's NSMutableDictionary's alloc()'s init() |
| 334 | repeat with itemTagDict in ocidItemsArray |
| 335 | set ocidItemName to (itemTagDict's objectForKey:("Name")) |
| 336 | set ocidItemIndex to (itemTagDict's valueForKeyPath:("CustomItemProperties.kLSSharedTagFileListItemLabel")) |
| 337 | if ocidItemIndex = (missing value) then |
| 338 | set ocidItemIndex to 0 as integer |
| 339 | end if |
| 340 | (ocidIndexDict's setObject:(ocidItemIndex) forKey:(ocidItemName)) |
| 341 | end repeat |
| 342 | set ocidNameArray to (ocidSharedfilelistDict's valueForKeyPath:("items.Name")) |
| 343 | set listIndex to ocidNameArray as list |
| 344 | end if |
| 345 | |
| 346 | |
| 347 | |
| 348 | set strLF to ("" & linefeed & "") as text |
| 349 | set strCR to ("" & return & "") as text |
| 350 | set strCRLF to ("" & return & linefeed & "") as text |
| 351 | set strSpace to ("" & space & "") as text |
| 352 | set strTab to ("" & tab & "") as text |
| 353 | #日本語のメッセージ |
| 354 | #Message in Japanese |
| 355 | if strLocaleID is "ja_JP" then |
| 356 | set strMes1 to ("フォルダを選んでください" & ocidFlagEmoji & "") as text |
| 357 | set strPrompt1 to ("" & strCR & strCR & ocidFlagEmoji & "アイコン設定をするフォルダを選んでください" & strCR & strCR & "") as text |
| 358 | set strTitle2 to ("選んでください") as text |
| 359 | set strPrompt2 to ("フォルダにセットする" & strCR & "ラベル色" & strCR & "または" & strCR & "タグ名を" & strCR & "ひとつ選んでください") as text |
| 360 | set strCancelButton to ("キャンセル") as text |
| 361 | set strTitle3 to ("文字入力") as text |
| 362 | set strTimeUP to ("時間切れですやりなおしてください") as text |
| 363 | set strUserCancel to ("ユーザによってキャンセルされました。") as text |
| 364 | set strReturn to ("処理終了") as text |
| 365 | set strOsMes to ("macOS26以下では結果が反映されませんが実行できます。" & strCR & "OKで処理を継続します") as text |
| 366 | set strListButton to ("リストから選ぶ") as text |
| 367 | set strPrompt3 to ("SF Symbolの『シンボル名』か『文字』を入力してください" & strCR & "シンボル名は1つかリストから選択できます" & strCR & "文字の場合は絵文字または通常の文字が入力できます" & strCR & "通常の文字の場合、文字数が多くなると文字サイズが小さくなります" & strCR & "例" & strCR & ocidFlagEmoji & ocidCountryCode & strCR & "applescript.fill" & strCR & "✈️羽田") as text |
| 368 | set strTitle4 to ("選んでください") as text |
| 369 | set strPrompt4 to ("フォルダにセットするSymbolsの名称をえらんでください") as text |
| 370 | else |
| 371 | #英語のメッセージ |
| 372 | #English message |
| 373 | set strMes1 to ("Choose Folder" & ocidFlagEmoji & "") as text |
| 374 | set strPrompt1 to ("" & strCR & strCR & ocidFlagEmoji & "Select the folder to apply the icon setting" & strCR & strCR & "") as text |
| 375 | set strTitle2 to ("Choose Color") as text |
| 376 | set strPrompt2 to ("Choose one color" & strCR & "tag Name" & strCR & " to apply to the folder") as text |
| 377 | set strCancelButton to ("Cancel") as text |
| 378 | set strTitle3 to ("Text Input") as text |
| 379 | set strTimeUP to ("Timeout ― please try again") as text |
| 380 | set strUserCancel to ("Canceled by user") as text |
| 381 | set strReturn to ("Done") as text |
| 382 | set strOsMes to ("The result is not reflected on macOS 26 or earlier.") as text |
| 383 | set strListButton to ("Choose List") as text |
| 384 | set strTitle4 to ("Choose one symbol name") as text |
| 385 | set strPrompt3 to ("Enter an SF Symbol Name or a Character" & strCR & "SF Symbol: You can select a symbol name from a list or enter a single one" & strCR & "Character: An emoji or regular text. Longer regular text input will result in a smaller character size." & strCR & "Example" & strCR & ocidFlagEmoji & ocidCountryCode & strCR & "applescript.fill" & strCR & "🇺🇸IA") as text |
| 386 | #🇺🇸IA because I am a fan of Caitlin Clark , Go! Caitlin Go!22 |
| 387 | set strPrompt4 to ("Select Symbol" & strCR & "Please choose the SF Symbol to apply to the folder.") as text |
| 388 | end if |
| 389 | ############################# |
| 390 | # OSのバージョン |
| 391 | # version of macOS |
| 392 | set ocidProcessInfo to refMe's NSProcessInfo's processInfo() |
| 393 | set listOsVersion to ocidProcessInfo's operatingSystemVersion() |
| 394 | set numMajorVersion to (first item of listOsVersion) as integer |
| 395 | set numMinorVersion to (2nd item of listOsVersion) as integer |
| 396 | set numPatchVersion to (last item of listOsVersion) as integer |
| 397 | if numMajorVersion < 26 then |
| 398 | try |
| 399 | tell application "System Events" |
| 400 | activate |
| 401 | set recordResponse to (display alert strOsMes buttons {"OK"} default button "OK" as critical giving up after 10) as record |
| 402 | end tell |
| 403 | on error strErrMes number numErrNo |
| 404 | log doUiCleaning() |
| 405 | log strErrMes |
| 406 | return false |
| 407 | end try |
| 408 | # return false |
| 409 | end if |
| 410 | ############################# |
| 411 | #ラベルインデックスの色を選ぶ |
| 412 | # Choose the label index color |
| 413 | try |
| 414 | tell application "System Events" |
| 415 | activate |
| 416 | set valueResponse to (choose from list listIndex with title strTitle2 with prompt strPrompt2 default items (last item of listIndex) OK button name "OK" cancel button name strCancelButton with empty selection allowed without multiple selections allowed) |
| 417 | end tell |
| 418 | on error strErrMes number numErrNo |
| 419 | #プロセスクリーニングしてから終了 |
| 420 | #Finish after process cleaning |
| 421 | log doUiCleaning() |
| 422 | log strErrMes |
| 423 | return false |
| 424 | end try |
| 425 | if (class of valueResponse) is boolean then |
| 426 | #プロセスクリーニングしてから終了 |
| 427 | #Finish after process cleaning |
| 428 | log doUiCleaning() |
| 429 | log strUserCancel |
| 430 | return false |
| 431 | else if (class of valueResponse) is list then |
| 432 | #戻り値が空の場合はラベルインデックスは0を設定する |
| 433 | #If the return value is empty, set the label index to 0 |
| 434 | if valueResponse is {} then |
| 435 | set strIndexName to strSetNoSelect as text |
| 436 | else |
| 437 | set strIndexName to (first item of valueResponse) as text |
| 438 | end if |
| 439 | end if |
| 440 | #インデックスの番号 |
| 441 | # Index number |
| 442 | set ocidIndexNO to ocidIndexDict's valueForKey:(strIndexName) |
| 443 | #基本的には発生しないはずだけどエラーよけに残す |
| 444 | #ラベル番号がない場合はラベルインデックス0を指定する |
| 445 | if ocidIndexNO = (refMe's NSNull's |null|) then |
| 446 | set numIndexNO to 0 as integer |
| 447 | else if ocidIndexNO = (missing value) then |
| 448 | set numIndexNO to 0 as integer |
| 449 | else |
| 450 | set numIndexNO to ocidIndexNO as integer |
| 451 | end if |
| 452 | log numIndexNO as text |
| 453 | ############################# |
| 454 | #文字を入力 ダイアログ |
| 455 | # Text input dialog |
| 456 | set appPasteboard to refMe's NSPasteboard's generalPasteboard() |
| 457 | set ocidValue to appPasteboard's stringForType:(refMe's NSPasteboardTypeString) |
| 458 | if ocidValue = (missing value) then |
| 459 | set strDefaultAnswer to ("applescript.fill") as text |
| 460 | else |
| 461 | set strDefaultAnswer to ocidValue as text |
| 462 | end if |
| 463 | #ダイアログ |
| 464 | #display dialog |
| 465 | set aliasIconPath to (POSIX file "/System/Library/PrivateFrameworks/StorageManagement.framework/PlugIns/AppleInternalStorageExtension.appex/Contents/Resources/AppleInternalIcon.icns") as alias |
| 466 | try |
| 467 | tell application "System Events" |
| 468 | activate |
| 469 | set recordResponse to (display dialog strPrompt3 with title strTitle3 default answer strDefaultAnswer buttons {"OK", strCancelButton, strListButton} default button "OK" cancel button strCancelButton with icon aliasIconPath giving up after 120 without hidden answer) |
| 470 | end tell |
| 471 | on error strErrMes number numErrNo |
| 472 | #プロセスクリーニングしてから終了 |
| 473 | #Finish after process cleaning |
| 474 | log doUiCleaning() |
| 475 | log strErrMes |
| 476 | return false |
| 477 | end try |
| 478 | if true is equal to (gave up of recordResponse) then |
| 479 | #プロセスクリーニングしてから終了 |
| 480 | #Finish after process cleaning |
| 481 | log doUiCleaning() |
| 482 | log strTimeUP |
| 483 | return false |
| 484 | end if |
| 485 | if "OK" is equal to (button returned of recordResponse) then |
| 486 | set strResponse to (text returned of recordResponse) as text |
| 487 | #SF Symbolsの名称をリストから選択 |
| 488 | #Select the name of SF Symbols from the list |
| 489 | else if strListButton is equal to (button returned of recordResponse) then |
| 490 | try |
| 491 | tell application "System Events" |
| 492 | activate |
| 493 | set valueResponse to (choose from list listSymbolName with title strTitle4 with prompt strPrompt4 default items (last item of listSymbolName) OK button name "OK" cancel button name strCancelButton with empty selection allowed without multiple selections allowed) |
| 494 | end tell |
| 495 | on error strErrMes number numErrNo |
| 496 | #プロセスクリーニングしてから終了 |
| 497 | #Finish after process cleaning |
| 498 | log doUiCleaning() |
| 499 | log strErrMes |
| 500 | return false |
| 501 | end try |
| 502 | if (class of valueResponse) is boolean then |
| 503 | #プロセスクリーニングしてから終了 |
| 504 | #Finish after process cleaning |
| 505 | log doUiCleaning() |
| 506 | log strUserCancel |
| 507 | return false |
| 508 | else if (class of valueResponse) is list then |
| 509 | #文字を入力しない シンボル名も選択しない =文字不要 |
| 510 | #Do not enter characters Do not select symbol names = no characters required |
| 511 | if valueResponse is {} then |
| 512 | set strResponse to "" as text |
| 513 | else |
| 514 | set strResponse to (first item of valueResponse) as text |
| 515 | end if |
| 516 | end if |
| 517 | else |
| 518 | #プロセスクリーニングしてから終了 |
| 519 | #Finish after process cleaning |
| 520 | log doUiCleaning() |
| 521 | log strUserCancel |
| 522 | return false |
| 523 | end if |
| 524 | #タブと改行とスペースを除去しておきます |
| 525 | # Remove tabs and newlines |
| 526 | set ocidSetChar to refMe's NSString's stringWithString:(strResponse) |
| 527 | set ocidSetChar to (ocidSetChar's stringByReplacingOccurrencesOfString:(strCR) withString:("")) |
| 528 | set ocidSetChar to (ocidSetChar's stringByReplacingOccurrencesOfString:(strLF) withString:("")) |
| 529 | set ocidSetChar to (ocidSetChar's stringByReplacingOccurrencesOfString:(strTab) withString:("")) |
| 530 | #スペース除去は色々考えた結果処理することにした |
| 531 | #After thinking about it, I decided to process the space removal. |
| 532 | set ocidSetChar to (ocidSetChar's stringByReplacingOccurrencesOfString:(strSpace) withString:("")) |
| 533 | #文字数が0ならラベルインデックスの処理だけ行う |
| 534 | #If the number of characters is 0, only the label index will be processed. |
| 535 | set strResponse to ocidSetChar as text |
| 536 | set numCntResponseText to (count of (every character of strResponse)) as integer |
| 537 | if numCntResponseText = 0 then |
| 538 | set boolCharNeed to false as boolean |
| 539 | else |
| 540 | set boolCharNeed to true as boolean |
| 541 | end if |
| 542 | |
| 543 | #入力値がSF Symbolの名称か?判定 |
| 544 | #Is the input value the name of SF Symbol? chack |
| 545 | set boolChkOK to doChkSymbolName(ocidSetChar) |
| 546 | #SF Symbolでない場合は最大文字数を10文字にする |
| 547 | #If it is not a SF Symbol, set the maximum number of characters to 10 characters |
| 548 | if boolChkOK is false then |
| 549 | #いったんテキストに戻して見た目の文字数で取り出すことにした |
| 550 | #I decided to return it to the text and take it out by the number of characters it looks like. |
| 551 | set strSetChar to ocidSetChar as text |
| 552 | set numCntChar to (count of character of strSetChar) as integer |
| 553 | if numCntChar = 0 then |
| 554 | set str10Text to ("") as text |
| 555 | else if numCntChar < 10 then |
| 556 | set str10Text to (characters 1 through numCntChar of strSetChar) as text |
| 557 | else |
| 558 | set str10Text to (characters 1 through 10 of strSetChar) as text |
| 559 | end if |
| 560 | set ocidSetChar to refMe's NSString's stringWithString:(str10Text) |
| 561 | end if |
| 562 | ############################# |
| 563 | #入力された文字をJSONをファイルにする |
| 564 | # Convert the entered text into a JSON file |
| 565 | set ocidTempDirURL to appFileManager's temporaryDirectory() |
| 566 | set ocidUUID to refMe's NSUUID's alloc()'s init() |
| 567 | set ocidUUIDString to ocidUUID's UUIDString |
| 568 | set ocidSaveDirPathURL to ocidTempDirURL's URLByAppendingPathComponent:(ocidUUIDString) isDirectory:(true) |
| 569 | set ocidAttrDict to refMe's NSMutableDictionary's alloc()'s init() |
| 570 | ocidAttrDict's setValue:(511) forKey:(refMe's NSFilePosixPermissions) |
| 571 | set listDone to appFileManager's createDirectoryAtURL:(ocidSaveDirPathURL) withIntermediateDirectories:(true) attributes:(ocidAttrDict) |error|:(reference) |
| 572 | #ファイルパス |
| 573 | #JSON SAVE file Path |
| 574 | set strFileName to "com.apple.icon.folder.json" as text |
| 575 | set ocidSaveJsonFilePathURL to ocidSaveDirPathURL's URLByAppendingPathComponent:(strFileName) isDirectory:(false) |
| 576 | set strSaveJsonFilePathURL to ocidSaveJsonFilePathURL's |path|() as text |
| 577 | #JSON用DICT |
| 578 | set ocidJsonDict to refMe's NSMutableDictionary's alloc()'s init() |
| 579 | ############# |
| 580 | if boolChkOK is true then |
| 581 | ocidJsonDict's setObject:(ocidSetChar) forKey:("sym") |
| 582 | else if boolChkOK is false then |
| 583 | ocidJsonDict's setObject:(ocidSetChar) forKey:("emoji") |
| 584 | end if |
| 585 | #NSJSONSerialization |
| 586 | set ocidOption to (refMe's NSJSONReadingJSON5Allowed) |
| 587 | set listResponse to (refMe's NSJSONSerialization's dataWithJSONObject:(ocidJsonDict) options:(ocidOption) |error|:(reference)) |
| 588 | set ocidSaveData to (first item of listResponse) |
| 589 | ##NSDATA |
| 590 | set ocidOption to (refMe's NSDataWritingAtomic) |
| 591 | set listDone to ocidSaveData's writeToURL:(ocidSaveJsonFilePathURL) options:(ocidOption) |error|:(reference) |
| 592 | ############################# |
| 593 | #次工程に処理を依頼 |
| 594 | repeat with itemFolderURL in ocidFolderURLArray |
| 595 | doAppndIcon(itemFolderURL, strSaveJsonFilePathURL, numIndexNO, strIndexName, boolCharNeed, boolDidChange) |
| 596 | end repeat |
| 597 | try |
| 598 | tell application "System Events" to quit |
| 599 | end try |
| 600 | return 0 |
| 601 | end open |
| 602 |
|
| 603 |
|
| 604 | ############################# |
| 605 | #今日の日付合字 |
| 606 | to doGetTodayString() |
| 607 | #月レコード |
| 608 | set recordMonth to {|01|:"㋀", |02|:"㋁", |03|:"㋂", |04|:"㋃", |05|:"㋄", |06|:"㋅", |07|:"㋆", |08|:"㋇", |09|:"㋈", |10|:"㋉", |11|:"㋊", |12|:"㋋"} as record |
| 609 | set ocidMonthDict to refMe's NSMutableDictionary's alloc()'s initWithDictionary:(recordMonth) |
| 610 | #日レコード |
| 611 | set recordDate to {|01|:"㏠", |02|:"㏡", |03|:"㏢", |04|:"㏣", |05|:"㏤", |06|:"㏥", |07|:"㏦", |08|:"㏧", |09|:"㏨", |10|:"㏩", |11|:"㏪", |12|:"㏫", |13|:"㏬", |14|:"㏭", |15|:"㏮", |16|:"㏯", |17|:"㏰", |18|:"㏱", |19|:"㏲", |20|:"㏳", |21|:"㏴", |22|:"㏵", |23|:"㏶", |24|:"㏷", |25|:"㏸", |26|:"㏹", |27|:"㏺", |28|:"㏻", |29|:"㏼", |30|:"㏽", |31|:"㏾"} as record |
| 612 | set ocidDateDict to refMe's NSMutableDictionary's alloc()'s initWithDictionary:(recordDate) |
| 613 | # |
| 614 | set ocidDate to refMe's NSDate's |date|() |
| 615 | set ocidNSDateFormatter to refMe's NSDateFormatter's alloc()'s init() |
| 616 | ocidNSDateFormatter's setLocale:(refMe's NSLocale's localeWithLocaleIdentifier:"ja_JP_POSIX") |
| 617 | ocidNSDateFormatter's setDateFormat:("yyyyMMdd") |
| 618 | set ocidDateAndTime to ocidNSDateFormatter's stringFromDate:(ocidDate) |
| 619 | set strDateAndTime to ocidDateAndTime as text |
| 620 | ocidNSDateFormatter's setDateFormat:("EEE") |
| 621 | set ocidWeekDay to ocidNSDateFormatter's stringFromDate:(ocidDate) |
| 622 | set strWeekDay to ocidWeekDay as text |
| 623 | ocidNSDateFormatter's setDateFormat:("dd") |
| 624 | set ocidDayNo to ocidNSDateFormatter's stringFromDate:(ocidDate) |
| 625 | set strDayNo to ocidDayNo as text |
| 626 | set ocidDateValue to ocidDateDict's objectForKey:(ocidDayNo) |
| 627 | ocidNSDateFormatter's setDateFormat:("MM") |
| 628 | set ocidMonthNo to ocidNSDateFormatter's stringFromDate:(ocidDate) |
| 629 | set strMonthNo to ocidMonthNo as text |
| 630 | set ocidMonthValue to ocidMonthDict's objectForKey:(ocidMonthNo) |
| 631 | set ocidSetJsonValue to ocidMonthValue's stringByAppendingString:(ocidDateValue) |
| 632 | ocidNSDateFormatter's setDateFormat:("d") |
| 633 | set ocidDayNo to ocidNSDateFormatter's stringFromDate:(ocidDate) |
| 634 | set strSFdate to ("" & ocidDayNo & ".calendar") as text |
| 635 | set strSetJsonValue to ocidSetJsonValue as text |
| 636 | set listReturn to {strSetJsonValue, strSFdate} as list |
| 637 | return listReturn |
| 638 | |
| 639 | end doGetTodayString |
| 640 |
|
| 641 | ############################# |
| 642 | #アイコン付与するメインプロセス |
| 643 | to doAppndIcon(ocidDirPathURL, strSaveJsonFilePathURL, numIndexNO, strIndexName, boolCharNeed, boolDidChange) |
| 644 | ############################# |
| 645 | #フォルダにインデックスを付ける |
| 646 | # Assign an index color to the folder |
| 647 | #ラベルのインデクス番号 |
| 648 | # Label index number |
| 649 | set ocidLabelNo to (refMe's NSNumber's numberWithInteger:(numIndexNO)) |
| 650 | #順番に処理 |
| 651 | # Process in sequence |
| 652 | #ラベルをつける |
| 653 | #Attach a label index no |
| 654 | # set listResult to (ocidDirPathURL's setResourceValue:(ocidLabelNo) forKey:(refMe's NSURLLabelNumberKey) |error|:(reference)) |
| 655 | #PLIST 本処理 |
| 656 | #PLIST Main Process |
| 657 | #1秒まってから次の処理 |
| 658 | # Wait 1 second before proceeding Magic 1 Second |
| 659 | delay numMagicTime |
| 660 | |
| 661 | #現在のタグを取得して |
| 662 | set ocidKey to (refMe's NSURLTagNamesKey) |
| 663 | set listResponse to (ocidDirPathURL's getResourceValue:(reference) forKey:(ocidKey) |error|:(reference)) |
| 664 | set ocidTagNameArray to (2nd item of listResponse) |
| 665 | if ocidTagNameArray = (missing value) then |
| 666 | set ocidTagArray to refMe's NSMutableArray's alloc()'s init() |
| 667 | else |
| 668 | set ocidTagArray to ocidTagNameArray's mutableCopy() |
| 669 | end if |
| 670 | |
| 671 | #まずタグをつけます |
| 672 | # Add tags first |
| 673 | #タグのDICTとARRAY |
| 674 | # Create tag DICT and ARRAY |
| 675 | set ocidTagName to (refMe's NSString's stringWithString:(strIndexName)) |
| 676 | (ocidTagArray's addObject:(ocidTagName)) |
| 677 | set ocidSetDict to refMe's NSMutableDictionary's alloc()'s init() |
| 678 | (ocidSetDict's setObject:(ocidTagArray) forKey:(refMe's NSURLTagNamesKey)) |
| 679 | #フォルダにタグをつける場合は |
| 680 | # When adding tags to a folder: |
| 681 | if numIndexNO ≠ 0 then |
| 682 | #タグを付与して |
| 683 | # - Apply tags |
| 684 | # set listDone to (ocidDirPathURL's setResourceValues:(ocidTagArray) |error|:(reference)) |
| 685 | set ocidKey to (refMe's NSURLTagNamesKey) |
| 686 | set listDone to (ocidDirPathURL's setResourceValue:(ocidTagArray) forKey:(ocidKey) |error|:(reference)) |
| 687 | |
| 688 | #0の場合はタグを除去する |
| 689 | # - If set to 0, remove the tag |
| 690 | else if numIndexNO = 0 then |
| 691 | set ocidNullArray to refMe's NSArray's alloc()'s init() |
| 692 | set ocidKey to (refMe's NSURLTagNamesKey) |
| 693 | set listDone to (ocidDirPathURL's setResourceValue:(ocidNullArray) forKey:(ocidKey) |error|:(reference)) |
| 694 | end if |
| 695 | |
| 696 | |
| 697 | #1秒まってから次の処理 |
| 698 | # Wait 1 second before proceeding Magic 1 Second |
| 699 | delay numMagicTime |
| 700 | #Finderでフォルダの内容を更新する |
| 701 | # Refresh folder contents in Finder |
| 702 | set aliasDirPath to (ocidDirPathURL's absoluteURL()) as alias |
| 703 | tell application "Finder" |
| 704 | tell folder aliasDirPath |
| 705 | update |
| 706 | end tell |
| 707 | end tell |
| 708 | |
| 709 | #1秒まってから次の処理 |
| 710 | # Wait 1 second before proceeding Magic 1 Second |
| 711 | delay numMagicTime |
| 712 | |
| 713 | ############################# |
| 714 | #JSONファイルを拡張属性を設定 |
| 715 | #Set extended attributes for JSON files |
| 716 | #パス |
| 717 | set ocidDirPath to ocidDirPathURL's |path|() |
| 718 | set strFolderPath to ocidDirPath as text |
| 719 | #####com.apple.icon.folder#S |
| 720 | #拡張属性のcom.apple.icon.folderにJSONを入れます |
| 721 | # Insert JSON into the extended attribute com.apple.icon.folder |
| 722 | ###### |
| 723 | #ダイアログで文字入力がなかった場合 |
| 724 | if boolCharNeed is false then |
| 725 | #何もしない |
| 726 | else if boolCharNeed is true then |
| 727 | #文字入力があれば処理する |
| 728 | set strCmdText to ("/usr/bin/xattr -x -w com.apple.icon.folder#S \"$(/usr/bin/xxd -p \"" & strSaveJsonFilePathURL & "\" | tr -d \"\\\n\")\" \"" & strFolderPath & "\"") as text |
| 729 | try |
| 730 | do shell script strCmdText |
| 731 | on error strErrMes number numErrNo |
| 732 | #プロセスクリーニングしてから終了 |
| 733 | #Finish after process cleaning |
| 734 | log doUiCleaning() |
| 735 | log strCmdText & strErrMes |
| 736 | return false |
| 737 | end try |
| 738 | #com.apple.FinderInfo |
| 739 | #com.apple.FinderInfoを更新することでアイコンの表示が反映されます |
| 740 | # Updating com.apple.FinderInfo reflects the icon change |
| 741 | set strCmdText to ("/bin/zsh -c '/usr/bin/SetFile -a C \"" & strFolderPath & "\"'") |
| 742 | try |
| 743 | do shell script strCmdText |
| 744 | on error strErrMes number numErrNo |
| 745 | #プロセスクリーニングしてから終了 |
| 746 | #Finish after process cleaning |
| 747 | log doUiCleaning() |
| 748 | log strCmdText & strErrMes |
| 749 | return false |
| 750 | end try |
| 751 | end if |
| 752 | |
| 753 | #更新通知を送る |
| 754 | # Send update notification |
| 755 | set appWorkspace to refMe's NSWorkspace's sharedWorkspace() |
| 756 | #更新 |
| 757 | (appWorkspace's noteFileSystemChanged:(ocidDirPath)) |
| 758 | |
| 759 | |
| 760 | #UIプロセスを終了させる |
| 761 | #KIll the UI process |
| 762 | log doUiCleaning() |
| 763 | |
| 764 | #NSUserDefaultsの設定変更をしていたらFinderを再起動させる |
| 765 | #If NSUserDefaults have changed the settings, restart the Finder |
| 766 | if boolDidChange is true then |
| 767 | do shell script "/bin/zsh -c '/usr/bin/killall Finder'" |
| 768 | end if |
| 769 | return true |
| 770 | end doAppndIcon |
| 771 |
|
| 772 |
|
| 773 |
|
| 774 | ############################ |
| 775 | #UIを終了させる |
| 776 | # Terminate UI |
| 777 | (* |
| 778 | osascriptで実行する場合(スクリプトメニューからとかzsh実行とか) |
| 779 | 実行後に自然終了する事もあるのですが |
| 780 | Open and Save Panel Service(SystemUIServer) |
| 781 | com.apple.appkit.xpc.openAndSavePanelService |
| 782 | と |
| 783 | QuickLookUIService(SystemUIServer) |
| 784 | com.apple.quicklook.QuickLookUIServiceのプロセスが残ります |
| 785 | HUPを送ることで自然終了するようにしました |
| 786 | 判定は簡易で |
| 787 | osascriptよりPIDが大きい(後から呼び出された) |
| 788 | Open and Save Panel Serviceをkill -HUPします |
| 789 |
|
| 790 | Clean up leftover macOS services after osascript execution. |
| 791 |
|
| 792 | When executed via osascript (e.g., from Script Menu or zsh), |
| 793 | the following processes may remain active: |
| 794 | - com.apple.appkit.xpc.openAndSavePanelService (Open and Save Panel Service) |
| 795 | - com.apple.quicklook.QuickLookUIService (QuickLookUIService) |
| 796 |
|
| 797 | These are "orphaned" processes that can be forced to terminate gracefully |
| 798 | by sending the HUP signal. |
| 799 |
|
| 800 | Action: Send HUP signal (kill -HUP) to the Open and Save Panel Service |
| 801 | with a PID greater than the osascript process (simple check for processes |
| 802 | called after the script started). |
| 803 |
|
| 804 | *) |
| 805 | to doUiCleaning() |
| 806 | set strName to (name of current application) as text |
| 807 | if strName is "osascript" then |
| 808 | log "Start process cleaning" |
| 809 | #まずosascriptのPIDを取得します |
| 810 | #First, get the PID of osascript |
| 811 | try |
| 812 | tell current application |
| 813 | tell application "System Events" |
| 814 | tell application process "osascript" |
| 815 | set numOsascriptPID to unix id as integer |
| 816 | end tell |
| 817 | end tell |
| 818 | end tell |
| 819 | on error strErrMes number numErrNo |
| 820 | log "Interrupt and end" & strErrMes & numErrNo |
| 821 | return false |
| 822 | end try |
| 823 | #続けて子プロセスのopenAndSavePanelServiceのPIDを取得します |
| 824 | #Continue to get the PID of the child process openAndSavePanelService |
| 825 | set ocidAppArray to (refMe's NSRunningApplication's runningApplicationsWithBundleIdentifier:("com.apple.appkit.xpc.openAndSavePanelService")) |
| 826 | repeat with itemApp in ocidAppArray |
| 827 | set numPID to itemApp's processIdentifier() |
| 828 | #osascriptの後に呼び出されたopenAndSavePanelServiceは終了する |
| 829 | #openAndSavePanelService called after osascript ends |
| 830 | if numOsascriptPID < numPID then |
| 831 | set strPID to numPID as text |
| 832 | try |
| 833 | do shell script ("/bin/zsh -c '/bin/kill -1 " & strPID & "'") |
| 834 | # do shell script ("/bin/zsh -c '/bin/kill -15 " & strPID & "'") |
| 835 | # do shell script ("/bin/zsh -c '/bin/kill -9 " & strPID & "'") |
| 836 | # log itemApp's terminate() as boolean |
| 837 | # log itemApp's forceTerminate() as boolean |
| 838 | on error strErrMes number numErrNo |
| 839 | log strErrMes & numErrNo |
| 840 | return false |
| 841 | end try |
| 842 | end if |
| 843 | end repeat |
| 844 | log "Done process cleaning" |
| 845 | else |
| 846 | log "Nothing Done process cleaning" |
| 847 | end if |
| 848 | #System Eventsも終了させないと残ることがあります |
| 849 | #If you don't end System Events, it may remain. |
| 850 | try |
| 851 | tell application "System Events" to quit |
| 852 | end try |
| 853 | refMe's NSRunningApplication's terminateAutomaticallyTerminableApplications() |
| 854 | return true |
| 855 | end doUiCleaning |
| 856 |
|
| 857 |
|
| 858 | ############################ |
| 859 | #SF Symbolsシンボル名チェッカー |
| 860 | #SF Symbol name checker |
| 861 | (* |
| 862 | SFSymbols.frameworkからシンボル名を収集取得して |
| 863 | シンボル名として、収集したシンボル名に含まれていれば |
| 864 | シンボル名として正しい と簡易に判定します |
| 865 |
|
| 866 | Collect and obtain the symbol name from SFSymbols.framework and simply determine that if it is included in the collected symbol name as a symbol name, it is correct as a symbol name. |
| 867 |
|
| 868 | CoreGlyphs.bundleとCoreGlyphsPrivate.bundle両方を対象にしました |
| 869 | CoreGlyphs.bundleとCoreGlyphsPrivate.bundleI targeted both |
| 870 |
|
| 871 | *) |
| 872 | to doChkSymbolName(argNameString) |
| 873 | #チェック用のArray |
| 874 | set ocidSymbolsArray to refMe's NSMutableArray's alloc()'s init() |
| 875 | #PLISTのパス |
| 876 | set listPlistFilePath to {"/System/Library/PrivateFrameworks/SFSymbols.framework/Versions/A/Resources/CoreGlyphs.bundle/Contents/Resources/name_availability.plist", "/System/Library/PrivateFrameworks/SFSymbols.framework/Versions/A/Resources/CoreGlyphsPrivate.bundle/Contents/Resources/name_availability.plist"} as list |
| 877 | repeat with itemPlistFilePath in listPlistFilePath |
| 878 | #パス path |
| 879 | set strPlistFilePath to (itemPlistFilePath) as text |
| 880 | set ocidFilePathStr to (refMe's NSString's stringWithString:(strPlistFilePath)) |
| 881 | set ocidFilePath to ocidFilePathStr's stringByStandardizingPath() |
| 882 | set ocidFilePathURL to (refMe's NSURL's fileURLWithPath:(ocidFilePath) isDirectory:(false)) |
| 883 | #PLISTをDICTで読み込んで |
| 884 | #Load PLIST with DICT |
| 885 | set listResponse to (refMe's NSMutableDictionary's alloc()'s initWithContentsOfURL:(ocidFilePathURL) |error|:(reference)) |
| 886 | set ocidPlistDict to (first item of listResponse) |
| 887 | set ocidItemSymbolsDict to (ocidPlistDict's objectForKey:("symbols")) |
| 888 | set ocidAllKeys to ocidItemSymbolsDict's allKeys() |
| 889 | #キーの値を格納する |
| 890 | #Store the value of the key |
| 891 | (ocidSymbolsArray's addObjectsFromArray:(ocidAllKeys)) |
| 892 | end repeat |
| 893 | #チェック check |
| 894 | #含まれていれば シンボル名が正しいと判定します |
| 895 | #If it is included, it is determined that the symbol name is correct. |
| 896 | set boolContain to ocidSymbolsArray's containsObject:(argNameString) |
| 897 | #戻し値はBOOL |
| 898 | #The return value is BOOL |
| 899 | if boolContain is false then |
| 900 | return false as boolean |
| 901 | else if boolContain is true then |
| 902 | return true as boolean |
| 903 | end if |
| 904 | |
| 905 | end doChkSymbolName |
| 906 |
|
| 907 |
|
| 908 | ###################### |
| 909 | #カントリーコードから絵文字の旗 |
| 910 | to doGetCountryCode2EmojiFlag(argCountryCode) |
| 911 | #念の為テキストにしてから再度NSStringにしておく |
| 912 | set strCountryCode to argCountryCode as text |
| 913 | set ocidCountryCode to refMe's NSString's stringWithString:(strCountryCode) |
| 914 | #オフセット値 |
| 915 | set ocidOffSetA to refMe's NSString's stringWithString:("A") |
| 916 | set uniOffSetA to ocidOffSetA's characterAtIndex:(0) |
| 917 | set intOffSetA to uniOffSetA as integer |
| 918 | #サローゲートNO |
| 919 | set intSurrogateNo to 127462 as integer |
| 920 | #キャラクター上位 |
| 921 | set uniHiChar to ocidCountryCode's characterAtIndex:(0) |
| 922 | set intHiCharDec to uniHiChar as integer |
| 923 | set intHiInd to (intSurrogateNo + intHiCharDec - intOffSetA) as integer |
| 924 | set strHiUniCode to doDec2Hex(intHiInd) as text |
| 925 | #キャラクター下位 |
| 926 | set uniLwChar to ocidCountryCode's characterAtIndex:(1) |
| 927 | set intLwCharDec to uniLwChar as integer |
| 928 | set intLwInd to (intSurrogateNo + intLwCharDec - intOffSetA) as integer |
| 929 | set strLwUniCode to doDec2Hex(intLwInd) as text |
| 930 | #ユニコードサロゲートに整形 |
| 931 | set strUniSurrogate to ("U+" & strHiUniCode & "U+" & strLwUniCode & "") as text |
| 932 | set ocidUniSurrogate to refMe's NSString's stringWithString:(strUniSurrogate) |
| 933 | set ocidFlagEmoji to (ocidUniSurrogate's stringByApplyingTransform:("Any-Hex/Unicode") |reverse|:(true)) |
| 934 | #テキストで戻すか?はお好きな方で |
| 935 | # return ocidFlagEmoji |
| 936 | return ocidFlagEmoji as Unicode text |
| 937 | end doGetCountryCode2EmojiFlag |
| 938 |
|
| 939 | ######################## |
| 940 | #10進数を16進数に変換 |
| 941 | to doDec2Hex(argIntNo) |
| 942 | #大文字指定(プロパティで指定する場合はここは削除) |
| 943 | set boolCaps to true as boolean |
| 944 | #10進数-->16進数の変換レコード |
| 945 | if boolCaps is true then |
| 946 | set recordDec2Hex to {|0|:"0", |1|:"1", |2|:"2", |3|:"3", |4|:"4", |5|:"5", |6|:"6", |7|:"7", |8|:"8", |9|:"9", |10|:"A", |11|:"B", |12|:"C", |13|:"D", |14|:"E", |15|:"F"} as record |
| 947 | else |
| 948 | set recordDec2Hex to {|0|:"0", |1|:"1", |2|:"2", |3|:"3", |4|:"4", |5|:"5", |6|:"6", |7|:"7", |8|:"8", |9|:"9", |10|:"a", |11|:"b", |12|:"c", |13|:"d", |14|:"e", |15|:"f"} as record |
| 949 | end if |
| 950 | set ocidDec2HexDict to refMe's NSMutableDictionary's alloc()'s init() |
| 951 | ocidDec2HexDict's setDictionary:(recordDec2Hex) |
| 952 | #次工程に回す余りを格納するArray |
| 953 | set ocidRemArray to refMe's NSMutableArray's alloc()'s init() |
| 954 | #引数を数値で再定義して |
| 955 | set inteRes to argIntNo as integer |
| 956 | #初回用のあまり値 |
| 957 | set numValue to 9999999 as integer |
| 958 | set numDiv to 9999999 as integer |
| 959 | #余りが0になるから値が0になるまで繰り返し |
| 960 | repeat while (numDiv > 0) |
| 961 | #16で割って |
| 962 | set numDiv to (round (inteRes / 16) rounding down) as integer |
| 963 | #余りを |
| 964 | set numValue to inteRes - (numDiv * 16) as integer |
| 965 | #ループの次の回用に再定義 |
| 966 | set inteRes to numDiv as integer |
| 967 | #Arrayに加えていく |
| 968 | ocidRemArray's addObject:(numValue) |
| 969 | end repeat |
| 970 | #逆順に並び替えて |
| 971 | set ocidRemArray to (ocidRemArray's reverseObjectEnumerator())'s allObjects() |
| 972 | set ocidHexString to refMe's NSMutableString's alloc()'s init() |
| 973 | (ocidHexString's appendString:("000000")) |
| 974 | #順番に |
| 975 | repeat with itemNo in ocidRemArray |
| 976 | #10進数を |
| 977 | set strItemNo to itemNo as text |
| 978 | #16進数に置き換えて |
| 979 | set strValue to (ocidDec2HexDict's objectForKey:(strItemNo)) |
| 980 | (ocidHexString's appendString:(strValue)) |
| 981 | end repeat |
| 982 | #ゼロサプレス6桁 |
| 983 | set ocidLength to ocidHexString's |length|() |
| 984 | set numStart to (ocidLength - 5) as integer |
| 985 | set ocidRange to refMe's NSRange's NSMakeRange(numStart, 5) |
| 986 | set ocidReturnString to ocidHexString's substringWithRange:(ocidRange) |
| 987 | #HEX値の出来上がりを戻す |
| 988 | return ocidReturnString |
| 989 | |
| 990 | end doDec2Hex |
| 991 |
|