Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

タグ: NSValueTransformer

アラートダイアログ上のTable Viewで起動中のアプリケーションを選択 v3c

Posted on 8月 9, 2020 by Takaaki Naganoya

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:

★Click Here to Open This Script 

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

★Click Here to Open This Script 

Posted in dialog | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy AppDelegate NSAlert NSBundle NSDictionary NSFileManager NSFont NSFontAttributeName NSImage NSString NSValueTransformer NSWorkspace | Leave a comment

アラートダイアログ上にTable Viewを表示 v9_アイコンを表示、Finderからのドラッグ&ドロップ

Posted on 1月 15, 2020 by Takaaki Naganoya

Edama2さんからの投稿Scriptです。アラートダイアログ中に各種GUI部品を詰め込む「箱庭インタフェース」シリーズ。テーブルビューを表示して、Finderからのアプリケーションのドラッグ&ドロップを受け付けるAppleScriptです。

–> Download Editable & Executable Script Bundle Document

カスタムクラスの作り方がわかったので、懲りずにTable Viewネタです。
Thanks  Shane Stanley!

アプリケーションフォルダ直下のアプリを、NSValueTransformerを使ってコラムにローカライズ名とアイコンを表示するのと、finderからのドラッグ&ドロップでアイテムの追加です。
追加時に重複チェックをしているので試す時はユーティリティフォルダか別の場所にあるアプリで試してください。

本Scriptは自分も作りたいと思いつつも調査が進んでいなかったものですが、TableViewでFinderからのドラッグ&ドロップを受け付けます。

これを鍛えて再利用しやすい部品に育てることで、ドロップレットの代替品にできると思っています。macOS 10.12以降、Finder上のファイルをAppleScriptドロップレットにドラッグ&ドロップで処理させても、OS側がダウンロードファイルにつけた拡張属性(Xattr)「com.apple.quarantine」がついているとドロップレット側で処理できなかったりします(回避方法はありますけれども)。

このドロップレットという仕組みを使わずに、同様にドラッグ&ドロップによる処理を手軽にできる代替インタフェースとしてこのようなものを考えていた次第です。自分で作らなくてもEdama2さんが作ってくださったので助かりました、、、、

AppleScript名:アラートダイアログ上にTable Viewを表示 v9_アイコンを表示、Finderからのドラッグ&ドロップ
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppleScriptObjC"
use scripting additions

on run
  my main()
end run
on main()
  # 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()
  
  
#
  
set aFolder to path to applications folder
  
set aPath to aFolder’s POSIX path
  
set aURL to current application’s NSURL’s fileURLWithPath:aPath
  
  
# 指定フォルダの直下のファイルを取得
  
set filePaths to current application’s NSFileManager’s defaultManager’s ¬
    contentsOfDirectoryAtURL:aURL ¬
      includingPropertiesForKeys:{current application’s NSURLNameKey} ¬
      
options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) ¬
      
|error|:(missing value)
  
  
set filePaths to filePaths as list
  
set thisFileType to "com.apple.application-bundle"
  
  
set fileURLs to {}
  
repeat with anItem in filePaths
    
    
set aPath to anItem’s contents’s POSIX path
    
set aURL to (current application’s NSURL’s fileURLWithPath:aPath)
    
    
set {aResult, aUTI, aError} to (aURL’s getResourceValue:(reference) ¬
      forKey:(current application’s NSURLTypeIdentifierKey) ¬
      
|error|:(reference))
    
    
if (aUTI as text) is thisFileType then
      set fileURLs’s end to aURL
    end if
  end repeat
  
  
set optionRec to {fileURLs:fileURLs, fileType:thisFileType}
  
  
set aMainMes to "アプリケーションの選択"
  
set aSubMes to "適切なものを以下からえらんでください"
  
set dateObj to my chooseItemByTableView(aMainMes, aSubMes, optionRec)
end main

# アラートダイアログでtableviewを表示
on chooseItemByTableView(aMainMes, aSubMes, optionRec)
  ### set up view
  
set {theView, makeObj} to my makeContentView(optionRec)
  
  
set paramObj to {myMessage:aMainMes, mySubMessage:aSubMes, setView:theView, myOption:makeObj}
  
my performSelectorOnMainThread:"raizeAlert:" withObject:paramObj waitUntilDone:true
  
  
if (my _retrieve_data) is missing value then error number -128
  
return (my _retrieve_data)
end chooseItemByTableView

## retrieve date
on raizeAlert:paramObj
  set mesText to paramObj’s myMessage
  
set infoText to paramObj’s mySubMessage
  
set theView to paramObj’s setView
  
set aTableObj to paramObj’s myOption
  
  
global _retrieve_data
  
set _retrieve_data to missing value
  
  
### set up alert
  
tell current application’s NSAlert’s new()
    setMessageText_(mesText)
    
setInformativeText_(infoText)
    
addButtonWithTitle_("OK")
    
addButtonWithTitle_("Cancel")
    
setAccessoryView_(theView)
    
tell |window|()
      setInitialFirstResponder_(theView)
    end tell
    
#### show alert in modal loop
    
if runModal() is (current application’s NSAlertSecondButtonReturn) then return
  end tell
  
  
### retrieve date
  
set aIndexSet to aTableObj’s selectedRowIndexes()
  
  
set chooseItems to ((aTableObj’s dataSource())’s arrangedObjects()’s objectsAtIndexes:aIndexSet) as list
  
set _retrieve_data to {}
  
repeat with anItem in chooseItems
    set _retrieve_data’s end to anItem’s fileURL
  end repeat
end raizeAlert:

## ContentView を作成
on makeContentView(paramObj)
  ## 準備
  
set fileURLs to (paramObj’s fileURLs) as list
  
set thisFileType to (paramObj’s fileType) as text
  
  
set keyrec to {column1:"Name"}
  
set keyDict to (current application’s NSDictionary’s dictionaryWithDictionary:keyrec)
  
  
set theDataSource to current application’s YKZArrayController’s new()
  
  
## NSTableView
  
tell current application’s NSTableView’s alloc()
    tell initWithFrame_(current application’s CGRectZero)
      setAllowsEmptySelection_(false)
      
setAllowsMultipleSelection_(true)
      
setDataSource_(theDataSource)
      
setDelegate_(theDataSource)
      
setDoubleAction_("doubleAction:")
      
setGridStyleMask_(current application’s NSTableViewSolidVerticalGridLineMask)
      
setSelectionHighlightStyle_(current application’s NSTableViewSelectionHighlightStyleRegular)
      
setTarget_(theDataSource)
      
setUsesAlternatingRowBackgroundColors_(true)
      
      
set thisRowHeight to rowHeight() as integer
      
set theDataSource’s _table_view to it
    end tell
  end tell
  
  
# data sourceに追加
  
tell (theDataSource)
    awakeFromNib()
    
set its _file_type to thisFileType
    
    
repeat with aURL in fileURLs
      addObject_({fileURL:aURL})
    end repeat
    
    
setSelectionIndex_(0)
  end tell
  
  
## NSTableColumn
  
### Columnの並び順を指定する
  
set viewWidth to 320
  
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
      
      
### Columnの横幅を指定
      
setWidth_(viewWidth)
      
      
### バインディングのオプション
      
— ソートを無効にする
      
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, theDataSource, "arrangedObjects", bOptions)
      
      (
theDataSource’s _table_view’s addTableColumn:it)
    end tell
    
  end repeat
  
  
## NSScrollView
  
### Viewの高さを計算
  
set rowCount to 12 –> 行数を固定
  
set viewHeight to (thisRowHeight + 2) * rowCount + thisHeaderHeight –> 2を足さないと高さが合わない
  
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_(theDataSource’s _table_view)
      
–setHasHorizontalScroller_(true)
      
setHasVerticalScroller_(true)
      
set aScroll to it
    end tell
  end tell
  
  
return {aScroll, theDataSource’s _table_view}
end makeContentView

★Click Here to Open This Script 

AppleScript名:subClasses
#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

#MARK: – Array Controller
script YKZArrayController
  property parent : class "NSArrayController"
  
  
#MARK: IBOutlets
  
property _table_view : missing value
  
#MARK:
  
property _data_type : do shell script "uuidgen"
  
property _file_type : ""
  
  
on awakeFromNib()
    –log "YKZArrayController – awakeFromNib"
    
tell _table_view
      registerForDraggedTypes_({current application’s NSFilenamesPboardType, _data_type})
      
setDraggingSourceOperationMask_forLocal_(current application’s NSDragOperationCopy, false)
    end tell
    
    
#Transformerの登録
    
set tNames to {}
    
set tNames’s end to "YKZURLToIcon"
    
set tNames’s end to "YKZURLToDisplayedName"
    
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
  end awakeFromNib
  
  
#MARK: Data Source Overrides
  
on numberOfRowsInTableView:aTableView
    return my content()’s |count|()
  end numberOfRowsInTableView:
  
  
on tableView:aTableView viewForTableColumn:aColumn row:aRow
    –log "viewForTableColumn"
    
    
set aCellView to aTableView’s makeViewWithIdentifier:"YKZTableCellView" owner:me
    
–set isNull to aCellView’s isEqual:(current application’s NSNull’s |null|())
    
–log isNull as text
    
    
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
      
    end if
    
    
return aCellView
  end tableView:viewForTableColumn:row:
  
  
# テーブル内のセルが編集できるか
  
on tableView:aTableView shouldEditTableColumn:aColumn row:aRow
    return false
  end tableView:shouldEditTableColumn:row:
  
  
# テーブル内をダブルクリックしたら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:
  
  
#MARK: Drag Operation Method
  
#ドラッグを開始(ペーストボードに書き込む)
  
on tableView:aTableView writeRowsWithIndexes:rowIndexes toPasteboard:pboard
    –log "writeRowsWithIndexes"
    
set aData to current application’s NSKeyedArchiver’s archivedDataWithRootObject:rowIndexes
    
pboard’s declareTypes:{_data_type} owner:(missing value)
    
pboard’s setData:aData forType:_data_type
    
return true
  end tableView:writeRowsWithIndexes:toPasteboard:
  
#ドラッグ途中
  
on tableView:aTableView validateDrop:info proposedRow:row proposedDropOperation:operation
    –log "validateDrop"
    
#列の間にドラッグ
    
if (operation is current application’s NSTableViewDropAbove) then
      return current application’s NSDragOperationMove
    end if
    
#項目の上にドラッグ
    
set aTypes to info’s draggingPasteboard’s types()
    
if (aTypes’s containsObject:_data_type) as boolean then
      return current application’s NSDragOperationNone
    end if
    
return current application’s NSDragOperationNone
  end tableView:validateDrop:proposedRow:proposedDropOperation:
  
#ドラッグ終了
  
on tableView:aTableView acceptDrop:info row:row dropOperation:operation
    –log "acceptDrop"
    
#
    
set pboard to info’s draggingPasteboard()
    
set aTypes to pboard’s types()
    
    
if (aTypes’s containsObject:_data_type) as boolean then
      
      
set rowData to pboard’s dataForType:_data_type
      
set rowIndexes to current application’s NSKeyedUnarchiver’s unarchiveObjectWithData:rowData
      
      
if (rowIndexes’s firstIndex()) < row then
        set row to row – (rowIndexes’s |count|())
      end if
      
      
set aRange to current application’s NSMakeRange(row, rowIndexes’s |count|())
      
set aIndexSet to current application’s NSIndexSet’s indexSetWithIndexesInRange:aRange
      
      
set anObj to ((my content())’s objectsAtIndexes:rowIndexes)
      
my removeObjects:anObj
      
my insertObjects:anObj atArrangedObjectIndexes:aIndexSet
      
my rearrangeObjects()
      
    else
      set pathList to pboard’s propertyListForType:(current application’s NSFilenamesPboardType)
      
–log result as list
      
repeat with aPath in pathList
        set isAdd to addItem_({filePath:aPath, atIndex:row})
        
if isAdd then beep
      end repeat
      
    end if
    
return true
  end tableView:acceptDrop:row:dropOperation:
  
  
#追加する
  
on addItem:sender –> {filePath:aPath, atIndex:aIndex}
    –log "addItem:"
    
set isAdd to false
    
    
#missing valueの時は最後に追加
    
set {filePath:aPath, atIndex:aIndex} to sender
    
if aIndex is missing value then
      set aIndex to my content()’s |count|() as number
    end if
    
    
#URLに変換
    
set appURL to (current application’s NSURL’s fileURLWithPath:aPath)
    
#アプリケーション以外は追加しない
    
set {aResult, aUTI, aError} to (appURL’s getResourceValue:(reference) ¬
      forKey:(current application’s NSURLTypeIdentifierKey) ¬
      
|error|:(reference))
    log aUTI
    
if (aUTI as text) is not (my _file_type as text) then return isAdd
    
    
#すでにあるか確認
    
set bList to my content() as list
    
repeat with aRecord in bList
      if ((appURL’s isEqual:(aRecord’s fileURL)) as boolean) then
        set isAdd to true
        
exit repeat
      end if
    end repeat
    
    
#なければ追加
    
if not isAdd then
      set anObj to {fileURL:appURL}
      (
my insertObject:anObj atArrangedObjectIndex:aIndex)
    end if
    
return isAdd
  end addItem:
end script

#MARK: – NSTableCellView
script YKZTableCellView
  property parent : class "NSTableCellView"
  
  
on initWithFrame:rect
    –log "initWithFrame"
    
continue initWithFrame:rect
    
    
setAutoresizingMask_(current application’s NSViewWidthSizable)
    
    
tell current application’s NSImageView’s alloc
      tell initWithFrame_(current application’s NSMakeRect(0, 0, 16, 16))
        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(20, 2, 200, 14))
        setBordered_(false)
        
setDrawsBackground_(false)
        
setEditable_(false)
        
        
my setTextField:it
        
my addSubview:it
      end tell
    end tell
    
    
return me
  end initWithFrame:
end script

★Click Here to Open This Script 

Posted in dialog GUI | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSArrayController NSBundle NSCreatesSortDescriptorBindingOption NSDictionary NSNumber NSScrollView NSTableCellView NSTableView NSURL NSValueBinding NSValueTransformer | Leave a comment

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • macOS 13, Ventura(継続更新)
  • アラートダイアログ上にWebViewで3Dコンテンツを表示(WebGL+three.js)v3
  • UI Browserがgithub上でソース公開され、オープンソースに
  • macOS 13 TTS Voice環境に変更
  • Xcode 14.2でAppleScript App Templateを復活させる
  • 2022年に書いた価値あるAppleScript
  • ChatGPTで文章のベクトル化(Embedding)
  • 新発売:AppleScriptからSiriを呼び出そう!
  • iWork 12.2がリリースされた
  • 従来と異なるmacOS 13の性格?
  • 新発売:CotEditor Scripting Book with AppleScript
  • macOS 13対応アップデート:AppleScript実践的テクニック集(1)GUI Scripting
  • AS関連データの取り扱いを容易にする(はずの)privateDataTypeLib
  • macOS 13でNSNotFoundバグふたたび
  • macOS 12.5.1、11.6.8でFinderのselectionでスクリーンショット画像をopenできない問題
  • ChatGPTでchatに対する応答文を取得
  • 新発売:iWork Scripting Book with AppleScript
  • Finderの隠し命令openVirtualLocationが発見される
  • macOS 13.1アップデートでスクリプトエディタの挙動がようやくまともに
  • あのコン過去ログビューワー(暫定版)

Tags

10.11savvy (1101) 10.12savvy (1242) 10.13savvy (1390) 10.14savvy (586) 10.15savvy (434) 11.0savvy (277) 12.0savvy (185) 13.0savvy (55) CotEditor (60) Finder (47) iTunes (19) Keynote (98) NSAlert (60) NSArray (51) NSBezierPath (18) NSBitmapImageRep (20) NSBundle (20) NSButton (34) NSColor (51) NSDictionary (27) NSFileManager (23) NSFont (18) NSImage (41) NSJSONSerialization (21) NSMutableArray (62) NSMutableDictionary (21) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (117) NSURL (97) NSURLRequest (23) NSUTF8StringEncoding (30) NSView (33) NSWorkspace (20) Numbers (56) Pages (37) Safari (41) Script Editor (20) WKUserContentController (21) WKUserScript (20) WKUserScriptInjectionTimeAtDocumentEnd (18) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • Clipboard
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • drive
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • rectangle
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC