edama2さんからの投稿です。起動中のアプリケーション一覧をダイアログ表示するAppleScriptシリーズで、アプリケーションのアイコン画像やパス情報を表示し、単数/複数のアプリケーション選択ができます。
–> Download Script Bundle archive
タイトルは「アラートダイアログ上のTable Viewで起動中のアプリケーションを選択」 起動中のアプリケーションをiOSライクなレイアウトで表示します Table Viewにカスタムセルビューを作って表現し、アプリの起動と終了を検知してリアルタイムで更新します 行数は12行に固定し、項目の複数選択がオプションで選べます
AppleScriptObjCフレームワークを呼び出すことにより、Xcod上で記述するAppleScriptアプリケーションのように、各種クラスのサブクラスを定義して利用しているScriptです。さまざまなScripterの技術が積み上がっている感じがして壮観ですが、ほとんどはedama2さんが長い時間をかけて積み上げてきたものの集大成といったものです。
本Scriptは途中で試行錯誤がいろいろあって、返り値がファイルパスだったりアプリケーションオブジェクトになったりと紆余曲折あって、現在の「アプリケーションオブジェクト」になりました。
ただ、実行中のアプリケーション自身を選択すると「current application」になってしまう点に注意が必要です。
AppleScript名:アラートダイアログ上のTable Viewで起動中のアプリケーションを選択 v3c |
use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use framework "AppleScriptObjC" use scripting additions on run my testRun() end run on testRun() set mes to "選択モードを指定してください" set bOK to "複数選択" set bOther to "単一選択" set bCancel to "キャンセル" set bList to {bCancel, bOther, bOK} set userAction to display dialog mes buttons bList default button bOK cancel button bCancel with icon note if userAction’s button returned is bOther then set isMultiple to false else if userAction’s button returned is bOK then set isMultiple to true end if set aMainMes to "Select Runnning Application" set aSubMes to "Sub Message" set execButtonTitle to "OK😁" set dateObj to my chooseRunningApplication:aMainMes subMes:aSubMes withMultipleSelections:(isMultiple) okTitle:execButtonTitle end testRun on chooseRunningApplication:(aMainMes as text) subMes:(aSubMes as text) withMultipleSelections:(isMultiple as boolean) okTitle:(execButtonTitle as text) # Script Bundle内のResourcesフォルダを求める set resourcePath to POSIX path of (path to me) & "Contents/Resources/" set theBundle to current application’s NSBundle’s bundleWithPath:resourcePath theBundle’s loadAppleScriptObjectiveCScripts() # subClasses.scptを呼び出す set DialogCore to current application’s AppDelegate’s new() set fRes to DialogCore’s chooseRunningApplication:aMainMes subMes:aSubMes withMultipleSelections:isMultiple okTitle:execButtonTitle if fRes is missing value then error number -128 return fRes as list end chooseRunningApplication:subMes:withMultipleSelections:okTitle: |
AppleScript名:subClasses.scpt |
#MARK: AppDelegate script AppDelegate property parent : class "NSObject" — IBOutlets property theWindow : missing value on applicationShouldTerminate:sender return current application’s NSTerminateNow end applicationShouldTerminate: on applicationShouldTerminateAfterLastWindowClosed:sender return true end applicationShouldTerminateAfterLastWindowClosed: on applicationWillFinishLaunching:aNotification log my testRun() end applicationWillFinishLaunching: —————— #MARK: テスト on testRun() –log "testRun" set mes to "選択モードを指定してください" set bOK to "複数選択" set bOther to "単一選択" set bCancel to "キャンセル" set bList to {bCancel, bOther, bOK} set userAction to display dialog mes buttons bList default button bOK cancel button bCancel with icon note if userAction’s button returned is bOther then set isMultiple to false else if userAction’s button returned is bOK then set isMultiple to true end if set aMainMes to "Select Runnning Application" set aSubMes to "Sub Message" set execButtonTitle to "OK😁" set dateObj to my chooseRunningApplication:aMainMes subMes:aSubMes withMultipleSelections:(isMultiple) okTitle:execButtonTitle return dateObj end testRun #MARK: アラートダイアログでtableviewを表示 property _retrieve_data : missing value on chooseRunningApplication:(aMainMes as text) subMes:(aSubMes as text) withMultipleSelections:(isMultiple as boolean) okTitle:(execButtonTitle as text) # reset set my _retrieve_data to missing value # if aMainMes = "" then error "Dialog main message is missing" # set dataSourceList to {} # OKボタンの文字 if execButtonTitle = "" then set execButtonTitle to "Execute" set thisFileType to "com.apple.application-bundle" # set paramObj to {myMessage:aMainMes} set paramObj to paramObj & {mySubMessage:aSubMes} set paramObj to paramObj & {myDataSource:dataSourceList} set paramObj to paramObj & {myType:thisFileType} set paramObj to paramObj & {mySelectType:isMultiple} set paramObj to paramObj & {myOKTitile:execButtonTitle} my performSelectorOnMainThread:"raizeAlert:" withObject:paramObj waitUntilDone:true if (my _retrieve_data) is missing value then error number -128 set retrieveData to my _retrieve_data set my _retrieve_data to missing value return retrieveData end chooseRunningApplication:subMes:withMultipleSelections:okTitle: #MARK: Raize Alert on raizeAlert:paramObj set mesText to paramObj’s myMessage as text set infoText to paramObj’s mySubMessage as text set dataSourceList to paramObj’s myDataSource as list set myUTI to paramObj’s myType as text set isMultiple to paramObj’s mySelectType as boolean set okButton to paramObj’s myOKTitile as text ### set up view #### data sourceにデータを追加 set theController to current application’s YKZArrayController’s alloc()’s initWithContent:dataSourceList theController’s setMultipleSelections:isMultiple theController’s setupView() ### アイコンの指定 –set aImage to current application’s NSWorkspace’s sharedWorkspace()’s iconForFileType:myUTI set setSize to 128 set fontObj to current application’s NSFont’s systemFontOfSize:setSize set aValue to {fontObj} set aKey to {current application’s NSFontAttributeName} set attributes to current application’s NSDictionary’s dictionaryWithObjects:aValue forKeys:aKey set strEmoji to current application’s NSString’s stringWithString:"😎" set newSizeObj to current application’s NSMakeSize(setSize, setSize) tell current application’s NSImage’s alloc tell initWithSize_(newSizeObj) lockFocus() strEmoji’s drawInRect:(current application’s NSMakeRect(0, 0, setSize, setSize)) withAttributes:attributes unlockFocus() set aImage to it end tell end tell ### set up alert tell current application’s NSAlert’s new() addButtonWithTitle_(okButton) addButtonWithTitle_("Cancel") setAccessoryView_(theController’s _the_view) setIcon_(aImage) setInformativeText_(infoText) setMessageText_(mesText) tell |window|() setInitialFirstResponder_(theController’s _the_view) end tell #### show alert in modal loop if runModal() is (current application’s NSAlertSecondButtonReturn) then return end tell ### retrieve data set (my _retrieve_data) to theController’s retrieveSelectItems() return my _retrieve_data end raizeAlert: end script #MARK: – NSValueTransformer script YKZURLToIcon property parent : class "NSValueTransformer" property allowsReverseTransformation : false –>逆変換 property transformedValueClass : a reference to current application’s NSImage –>クラス #変換処理 on transformedValue:fileURL if fileURL is missing value then return set appPath to fileURL’s |path|() set iconImage to current application’s NSWorkspace’s sharedWorkspace’s iconForFile:appPath return iconImage end transformedValue: end script script YKZURLToDisplayedName property parent : class "NSValueTransformer" property allowsReverseTransformation : false –>逆変換 property transformedValueClass : a reference to current application’s NSString –>クラス #変換処理 on transformedValue:fileURL if fileURL is missing value then return set appPath to fileURL’s |path|() set displayedName to current application’s NSFileManager’s defaultManager’s displayNameAtPath:appPath return displayedName end transformedValue: end script script YKZURLToPath property parent : class "NSValueTransformer" property allowsReverseTransformation : false –>逆変換 property transformedValueClass : a reference to current application’s NSString –>クラス #変換処理 on transformedValue:fileURL if fileURL is missing value then return set appPath to fileURL’s |path|() return appPath end transformedValue: end script script YKZURLToVersion property parent : class "NSValueTransformer" property allowsReverseTransformation : false –>逆変換 property transformedValueClass : a reference to current application’s NSString –>クラス #変換処理 on transformedValue:fileURL if fileURL is missing value then return set appPath to fileURL’s |path|() tell (current application’s NSBundle’s bundleWithURL:fileURL) tell its infoDictionary() set aVar to objectForKey_("CFBundleShortVersionString") end tell end tell return aVar end transformedValue: end script #MARK: – Array Controller script YKZArrayController property parent : class "NSArrayController" #MARK: IBOutlets property _the_view : missing value property _table_view : missing value #MARK: Property property multipleSelections : false property rowCount : 12 #MARK: 初期化 on initWithContent:aContent continue initWithContent:aContent #通知の登録 tell current application’s NSWorkspace’s sharedWorkspace()’s notificationCenter() addObserver_selector_name_object_(me, "changed:", "NSWorkspaceDidLaunchApplicationNotification", missing value) addObserver_selector_name_object_(me, "changed:", "NSWorkspaceDidTerminateApplicationNotification", missing value) end tell return me end initWithContent: #MARK: 戻り値 on retrieveSelectItems() set retrieveData to {} set aIndexSet to my _table_view’s selectedRowIndexes() set chooseItems to ((my _table_view’s dataSource())’s arrangedObjects()’s objectsAtIndexes:aIndexSet) as list repeat with anItem in chooseItems set aPath to anItem’s fileURL set retrieveData’s end to application (aPath as text) end repeat return retrieveData as list end retrieveSelectItems #MARK: viewの作成 on setupView() #Transformerの登録 set tNames to {} set tNames’s end to "YKZURLToIcon" set tNames’s end to "YKZURLToDisplayedName" set tNames’s end to "YKZURLToPath" set tNames’s end to "YKZURLToVersion" repeat with aTransformer in tNames set theTransformer to current application’s class aTransformer’s new() (current application’s NSValueTransformer’s setValueTransformer:theTransformer forName:aTransformer) end repeat log multipleSelections ## NSTableView tell current application’s NSTableView’s alloc() tell initWithFrame_(current application’s CGRectZero) –registerForDraggedTypes_({current application’s NSFilenamesPboardType, (my _data_type)}) setAllowsEmptySelection_(false) setAllowsMultipleSelection_(multipleSelections) setDataSource_(me) setDelegate_(me) setDoubleAction_("doubleAction:") –setDraggingSourceOperationMask_forLocal_(current application’s NSDragOperationCopy, false) setGridStyleMask_(current application’s NSTableViewSolidVerticalGridLineMask) setSelectionHighlightStyle_(current application’s NSTableViewSelectionHighlightStyleRegular) setTarget_(me) setUsesAlternatingRowBackgroundColors_(true) setHeaderView_(missing value) setRowHeight_(50) set thisRowHeight to rowHeight() as integer set my _table_view to it end tell end tell ## NSTableColumn ### Columnの並び順を指定する set keyrec to {column1:"Name"} set keyDict to (current application’s NSDictionary’s dictionaryWithDictionary:keyrec) set viewWidth to 400 –表示幅を変更 set columnsCount to keyDict’s |count|() repeat with colNum from 1 to columnsCount set keyName to "column" & colNum as text set aTitle to (keyDict’s objectForKey:keyName) tell (current application’s NSTableColumn’s alloc()’s initWithIdentifier:(colNum as text)) tell headerCell() setStringValue_(aTitle) set thisHeaderHeight to cellSize()’s height end tell ### バインディングのオプション — ソートを無効にする set anObj to (current application’s NSNumber’s numberWithBool:false) set aKey to current application’s NSCreatesSortDescriptorBindingOption set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey) ### 表示内容をNSArrayControllerにバインディング bind_toObject_withKeyPath_options_(current application’s NSValueBinding, (my _table_view’s dataSource()), "arrangedObjects", bOptions) set aTableColumn to it end tell ### Columnの横幅を調整 tell (my _table_view) addTableColumn_(aTableColumn) end tell tell aTableColumn setWidth_(viewWidth) end tell end repeat ## NSScrollView ### Viewの高さを計算 set viewHeight to thisRowHeight * rowCount + thisHeaderHeight #ダイアログ内のビューサイズを指定 set aScreen to current application’s NSScreen’s mainScreen() set screenFrame to aScreen’s frame() set aHeight to current application’s NSHeight(screenFrame) set aWidth to current application’s NSWidth(screenFrame) set maxHeight to aHeight * 0.845 set maxWidth to aWidth * 0.94 –log viewHeight –log maxHeight –set viewHeight to viewHeight + aSpace + sfHeight if viewHeight > maxHeight then set viewHeight to maxHeight if viewWidth > maxWidth then set viewWidth to maxWidth if viewWidth < 360 then set viewWidth to 360 set vSize to current application’s NSMakeRect(0, 0, viewWidth, viewHeight) ### Viewを作成 tell current application’s NSScrollView’s alloc() tell initWithFrame_(vSize) setBorderType_(current application’s NSBezelBorder) setDocumentView_(my _table_view) setHasHorizontalScroller_(true) setHasVerticalScroller_(true) set my _the_view to it end tell end tell my changed:me # 1行目を選択 my setSelectionIndex:0 return my _the_view end setupView #MARK: アプリケーションが切り替わった時 — tableViewを作成してから実行する on changed:sender log "changed" tell (my _table_view)’s dataSource() removeObjects_(arrangedObjects()) end tell #起動中のアプリケーション set aList to current application’s NSWorkspace’s sharedWorkspace()’s runningApplications() set sort to (current application’s NSSortDescriptor’s alloc()’s initWithKey:"localizedName" ascending:true selector:"caseInsensitiveCompare:") set sortedList to aList’s sortedArrayUsingDescriptors:(sort as list) repeat with anItem in (sortedList as list) #普通のアプリだけ set aFlag to anItem’s activationPolicy() is current application’s NSApplicationActivationPolicyRegular if aFlag then set theURL to anItem’s bundleURL() ((my _table_view)’s dataSource()’s addObject:{fileURL:theURL}) end if end repeat end changed: #MARK: Data Source Overrides on numberOfRowsInTableView:aTableView return (aTableView’s dataSource())’s content()’s |count|() end numberOfRowsInTableView: on tableView:aTableView viewForTableColumn:aColumn row:aRow set aCellView to aTableView’s makeViewWithIdentifier:"YKZTableCellView" owner:me if aCellView is missing value then set frameRect to current application’s NSMakeRect(0, 0, aColumn’s width, aTableView’s rowHeight()) set aCellView to current application’s YKZTableCellView’s alloc’s initWithFrame:frameRect set anObj to "YKZURLToIcon" set aKey to current application’s NSValueTransformerNameBindingOption set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey) (aCellView’s imageView())’s bind:(current application’s NSValueBinding) toObject:aCellView withKeyPath:"objectValue.fileURL" options:bOptions set anObj to "YKZURLToDisplayedName" set aKey to current application’s NSValueTransformerNameBindingOption set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey) (aCellView’s textField())’s bind:(current application’s NSValueBinding) toObject:aCellView withKeyPath:"objectValue.fileURL" options:bOptions set anObj to "YKZURLToPath" set aKey to current application’s NSValueTransformerNameBindingOption set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey) (aCellView’s pathTextField)’s bind:(current application’s NSValueBinding) toObject:aCellView withKeyPath:"objectValue.fileURL" options:bOptions set anObj to "YKZURLToVersion" set aKey to current application’s NSValueTransformerNameBindingOption set bOptions to (current application’s NSDictionary’s dictionaryWithObject:anObj forKey:aKey) (aCellView’s varTextField)’s bind:(current application’s NSValueBinding) toObject:aCellView withKeyPath:"objectValue.fileURL" options:bOptions return aCellView end if return missing value end tableView:viewForTableColumn:row: # テーブル内のセルが編集できるか on tableView:aTableView shouldEditTableColumn:aColumn row:aRow return false end tableView:shouldEditTableColumn:row: # on validateProposedFirstResponder:aResponder forEvent:aEvent log "validateProposedFirstResponder" return true set aBoolean to aResponder’s isKindOfClass:(current application’s NSTableCellView’s |class|()) if aBoolean as boolean then return true end if return true end validateProposedFirstResponder:forEvent: # テーブル内をダブルクリックしたらOKボタンを押す on doubleAction:sender log "doubleAction" ## ヘッダをクリックした時は何もしない if (sender’s clickedRow()) is -1 then return set theEvent to current application’s NSEvent’s ¬ keyEventWithType:(current application’s NSEventTypeKeyDown) ¬ location:(current application’s NSZeroPoint) ¬ modifierFlags:0 ¬ timestamp:0.0 ¬ windowNumber:(sender’s |window|()’s windowNumber()) ¬ context:(current application’s NSGraphicsContext’s currentContext()) ¬ |characters|:return ¬ charactersIgnoringModifiers:(missing value) ¬ isARepeat:false ¬ keyCode:0 current application’s NSApp’s postEvent:theEvent atStart:(not false) end doubleAction: end script #MARK: – NSTableCellView script YKZTableCellView property parent : class "NSTableCellView" property acceptsFirstResponder : true property pathTextField : missing value property varTextField : missing value on initWithFrame:rect continue initWithFrame:rect setAutoresizingMask_(current application’s NSViewWidthSizable) –set myWidth to current application’s NSWidth(rect) –set myHeight to current application’s NSHeight(rect) # アイコン tell current application’s NSImageView’s alloc tell initWithFrame_(current application’s NSMakeRect(12, 1, 48, 48)) setImageScaling_(current application’s NSImageScaleProportionallyUpOrDown) setImageAlignment_(current application’s NSImageAlignCenter) my setImageView:it my addSubview:it end tell end tell # 表示名 tell current application’s NSTextField’s alloc tell initWithFrame_(current application’s NSMakeRect(66, 26, 280, 17)) setBordered_(false) setDrawsBackground_(false) setEditable_(false) setLineBreakMode_(current application’s NSLineBreakByTruncatingMiddle) setFont_(current application’s NSFont’s boldSystemFontOfSize:13) my setTextField:it my addSubview:it end tell end tell # パス tell current application’s NSTextField’s alloc tell initWithFrame_(current application’s NSMakeRect(66, 6, 316, 17)) setBordered_(false) setDrawsBackground_(false) setEditable_(false) setLineBreakMode_(current application’s NSLineBreakByTruncatingMiddle) setFont_(current application’s NSFont’s systemFontOfSize:11) set my pathTextField to it my addSubview:it end tell end tell # バージョン tell current application’s NSTextField’s alloc tell initWithFrame_(current application’s NSMakeRect(300, 24, 80, 17)) setBordered_(false) setDrawsBackground_(false) setEditable_(false) setFont_(current application’s NSFont’s systemFontOfSize:11) setLineBreakMode_(current application’s NSLineBreakByTruncatingMiddle) setAlignment_(current application’s NSRightTextAlignment) set my varTextField to it my addSubview:it end tell end tell return me end initWithFrame: end script |
More from my site
(Visited 68 times, 2 visits today)