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

タグ: NSAlertSecondButtonReturn

アラートダイアログでMarkdownをプレビュー v3a

Posted on 8月 15, 2020 by Takaaki Naganoya

edama2さんからの投稿です。Markdown書類をプレビューするAppleScriptです。

–> Download Script bundle

本Scriptには、画期的な技術が用いられています。普通、AppleScriptObjCでは、WkWebViewによるネットワークアクセスを行うと、ネットワークアクセスを行う子プロセスと、WkWebViewで表示を行う子プロセスが生じて、処理が終了しても残ってしまいます。

スクリプトエディタ上で実行した場合には、スクリプトエディタを終了すればこうした子プロセスはメモリ上からパージされますが、終了するまで子プロセスは残されたままです。

「まー、AppleScriptObjCだから仕方ないよねー」

などと去年の年末に秋葉原でカレーを食べながらバカ話をしていた記憶がありますが、edama2さんがついにこれを回避する記法を編み出してしまったわけです。

回避方法については、やり方を説明されると「なるほど」という単純明快なものです(それを思いつくのがすごい)。osascript経由でAppleScriptを再実行することで、ランタイム環境を明示的にosascriptに指定してプログラムを実行。osascriptの終了とともにメモリ上から子プロセスがパージされるということのようです。

ランタイム環境を動的に生成し、実行後にランタイム環境がメモリ上から消去されるようになっていれば、子プロセス(ゴミ)が残っていてもまとめて消える………AppleScriptのランタイム環境はosascriptのほかCocoa系もあるので、そちらでも試してみるとよいでしょう。

ほかにも、WkWebViewによる表示を行う専用の支援アプリケーションを作っておき、AppleScript用語辞書経由で表示を行わせるという解決策も考えられます(ためしていないですが)。

AppleScript名:アラートダイアログでMarkdownをプレビュー v3a
use AppleScript
use framework “AppKit”
use framework “Foundation”
use framework “WebKit”
use scripting additions

on run args
  if (args’s class) is script then
    set myPath to (path to me)’s POSIX path
set resultText to do shell script “osascript “ & myPath’s quoted form
  else
    my main()
  end if
end run


on main()
  set mes to “Markdownファイルを選択してください。”
set chooseItems to choose file of type {“net.daringfireball.markdown”} with prompt mes


  #
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 aHeight to aHeight * 0.845
set aWidth to aWidth * 0.94 / 2


  set paramObj to {myMessage:“Markdown preview”}
set paramObj to paramObj & {mySubMessage:“file : “ & chooseItems’s POSIX path}
set paramObj to paramObj & {mdFile:chooseItems}
set paramObj to paramObj & {viewWidth:aWidth}
set paramObj to paramObj & {viewHeight:aHeight}


  my performSelectorOnMainThread:“displayMarkdownPreview:” withObject:(paramObj) waitUntilDone:true
end main


# Markdownをダイアログで表示
on displayMarkdownPreview:paramObj
  set mesText to myMessage of paramObj as text
set infoText to mySubMessage of paramObj as text
set mdFile to (mdFile of paramObj) as alias
set viewWidth to (viewWidth of paramObj) as integer
set viewHeight to (viewHeight of paramObj) as integer


  ## HTMLを読み込む
set mePath to path to me
set resPath to (mePath & “Contents:Resources:index.html”) as text
set htmlStr to (read (resPath as alias) as «class utf8») as text


  ## MDを読み込む
set mdStr to (read mdFile as «class utf8») as text


  ## MD内に改行があるとうまく読み込まれないので改行を置き換え
set mdStr to current application’s NSString’s stringWithString:mdStr
set mdStr to mdStr’s stringByReplacingOccurrencesOfString:(linefeed) withString:“\\n”
set mdStr to mdStr’s stringByReplacingOccurrencesOfString:“’” withString:“\\’”


  ## html内の文字を置き換え
set aString to current application’s NSString’s stringWithFormat_(htmlStr, mdStr) as text
log result


  ## baseURL
set aPath to mdFile’s POSIX path
set baseURL to current application’s NSURL’s fileURLWithPath:aPath
set baseURL to baseURL’s URLByDeletingLastPathComponent()


  ##
set aConf to current application’s WKWebViewConfiguration’s new()
tell current application’s WKUserContentController’s new()
    aConf’s setUserContentController:it
  end tell


  ## WebViewを作成&読み込み
set frameSize to current application’s NSMakeRect(0, 0, viewWidth, viewHeight)
tell current application’s WKWebView’s alloc()
    tell initWithFrame_configuration_(frameSize, aConf)
      setNavigationDelegate_(me)
setUIDelegate_(me)
loadHTMLString_baseURL_(aString, baseURL)
set theView to it
    end tell
  end tell


  ## アイコンの指定
set aImage to current application’s NSWorkspace’s sharedWorkspace()’s iconForFileType:“net.daringfireball.markdown”


  current application’s NSRunningApplication’s currentApplication()’s activateWithOptions:0


  ## set up alert
tell current application’s NSAlert’s new()
    addButtonWithTitle_(“Close”)
setAccessoryView_(theView)
setIcon_(aImage)
setInformativeText_(infoText)
setMessageText_(mesText)
tell |window|()
      setInitialFirstResponder_(theView)
    end tell
### show alert in modal loop
if runModal() is (current application’s NSAlertSecondButtonReturn) then return
  end tell


  ## 後始末
theView’s stopLoading()
set js to “window.open(’about:blank’,’_self’).close();”
theView’s evaluateJavaScript:js completionHandler:(missing value)
set theView to missing value
end displayMarkdownPreview:

★Click Here to Open This Script 
Posted in dialog Markdown URL | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy NSAlert NSAlertSecondButtonReturn NSRunningApplication NSScreen NSString NSURL NSWorkspace WKUserContentController WKWebView WKWebViewConfiguration | Leave a comment

アラートダイアログでMarkdownをプレビュー v2

Posted on 8月 8, 2020 by Takaaki Naganoya

edama2さんから投稿していただいた、Markdown書類をダイアログ上でプレビューするScriptの第二弾です。

–> Download Script Bundle

WKWebViewではなくNSAttributedStringを使ってMarkdownを表示しています。
NSAttributedStringでhtmlが表示できるとわかってWKWebViewの代わりになるかな?と思ったんですが、javascriptは使えないので自前で実行し、NSAttributedStringに<hr>に相当するものがないのとWKWebViewとは描画結果が違うので、プレビューとして使うのはイマイチです。作っておいてなんですが…😢

本Scriptの見どころは2点。「Scriptバンドル内にJavaScriptのライブラリを突っ込んで呼び出しているところ」と、「Markdownを(HTML経由で)NSAttributedStringに変換してプレビューしている」ところです。

ひかえめな説明文とは裏腹に、ずいぶんと攻めているというか、野心的な実装です。

JavaScriptのライブラリをローカルに置く案についてはいろいろedama2さんと意見交換をしていたんですが、割とさらっと書いているところにショックを受けます。これだけでも、相当に試行錯誤が必要な内容なんですが、このレベルに追いつくためには相当の苦労が、、、

AppleScript名:アラートダイアログでMarkdownをプレビュー v2
use AppleScript
use framework "Foundation"
use scripting additions

on run
  my main()
end run

on main()
  set mes to "Markdownファイルを選択してください。"
  
set chooseItems to choose file of type {"net.daringfireball.markdown"} with prompt mes
  
  
#
  
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 aHeight to aHeight * 0.845
  
set aWidth to aWidth * 0.94 / 2
  
  
set paramObj to {}
  
set paramObj to paramObj & {myMessage:"Markdown preview"}
  
set paramObj to paramObj & {mySubMessage:"file : " & chooseItems’s POSIX path}
  
set paramObj to paramObj & {mdFile:chooseItems}
  
set paramObj to paramObj & {viewWidth:aWidth}
  
set paramObj to paramObj & {viewHeight:aHeight}
  
  
my performSelectorOnMainThread:"displayMarkdownPreview:" withObject:(paramObj) waitUntilDone:true
end main

# Markdownをダイアログで表示
on displayMarkdownPreview:paramObj
  set mesText to myMessage of paramObj as text
  
set infoText to mySubMessage of paramObj as text
  
set mdFile to (mdFile of paramObj) as alias
  
set viewWidth to (viewWidth of paramObj) as integer
  
set viewHeight to (viewHeight of paramObj) as integer
  
  
## MDを読み込む
  
set mdStr to (read mdFile as «class utf8») as text
  
  
## javascriptを読み込む
  
set mePath to path to me
  
set resPath to (mePath & "Contents:Resources:marked.min.js") as text
  
set jsStr to (read (resPath as alias) as «class utf8») as text
  
  
## javascriptでMarkdownをhtmlに変換
  
tell current application’s JSContext’s new()
    evaluateScript_(jsStr)
    
tell objectForKeyedSubscript_("marked")
      tell callWithArguments_({mdStr})
        set resultStr to toString()
      end tell
    end tell
  end tell
  
  
## HTMLを読み込む
  
set mePath to path to me
  
set resPath to (mePath & "Contents:Resources:index.html") as text
  
set htmlStr to (read (resPath as alias) as «class utf8») as text
  
  
## html内の文字を置き換え
  
set aString to current application’s NSString’s stringWithFormat_(htmlStr, resultStr) as text
  
log result
  
  
  
## NSAttributedString
  
set aString to current application’s NSString’s stringWithString:aString
  
set stringData to aString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
  
set aValue to {current application’s NSHTMLTextDocumentType, current application’s NSUTF8StringEncoding}
  
set aKey to {current application’s NSDocumentTypeDocumentAttribute, current application’s NSCharacterEncodingDocumentAttribute}
  
set aOption to current application’s NSDictionary’s dictionaryWithObjects:aValue forKeys:aKey
  
  
tell current application’s NSAttributedString’s alloc()
    tell initWithHTML_options_documentAttributes_(stringData, aOption, missing value)
      set attributedString to it
    end tell
  end tell
  
log result
  
  
# Create a TextView with Scroll View
  
set frameSize to current application’s NSMakeRect(0, 0, viewWidth, viewHeight)
  
tell current application’s NSTextView’s alloc()
    tell initWithFrame_(frameSize)
      setEditable_(false)
      
tell textStorage()
        appendAttributedString_(attributedString)
      end tell
      
set aView to it
    end tell
  end tell
  
tell current application’s NSScrollView’s alloc()
    tell initWithFrame_(frameSize)
      setDocumentView_(aView)
      
set theView to it
    end tell
  end tell
  
  
  
## アイコンの指定
  
set aImage to current application’s NSWorkspace’s sharedWorkspace()’s iconForFileType:"net.daringfireball.markdown"
  
  
## set up alert
  
tell current application’s NSAlert’s new()
    addButtonWithTitle_("Close")
    
setAccessoryView_(theView)
    
setIcon_(aImage)
    
setInformativeText_(infoText)
    
setMessageText_(mesText)
    
tell |window|()
      setInitialFirstResponder_(theView)
    end tell
    
### show alert in modal loop
    
if runModal() is (current application’s NSAlertSecondButtonReturn) then return
  end tell
end displayMarkdownPreview:

★Click Here to Open This Script 

そして、本Scriptをよくよく見回してみると、NSAttributedStringになっているのでPDFに変換するのがとても簡単でした。WkWebView上に表示したWebコンテンツをPDF化しようと試みているものの、うまくできていません。Blocks構文を必要とする機能であるため(なんでこんなものまでBlocks(非同期実行)必要なんだろ?)、AppleScriptからの呼び出しができないためです。Xcode上で他の言語をまじえて組めば不可能ではない気もしますが……

CSSがWeb表示用のものなので、PDF出力時には割とゆったり目で密度の低いレイアウトになってしまうものの、このCSS指定を別のものにできればけっこうMarkdown→PDFの変換を行う部品として使えるレベルになってくるのではないでしょうか。それはそれで、Scriptバンドル内に入れたCSSを指定するとか、Web上のどこかに印刷用のCSSをホスティングしておくなどの方法が必要になることでしょう。

Posted in dialog JavaScript Markdown | Tagged 10.13savvy 10.14savvy 10.15savvy 11.0savvy JSContext NSAlert NSAlertSecondButtonReturn NSAttributedString NSCharacterEncodingDocumentAttribute NSDictionary NSDocumentTypeDocumentAttribute NSScreen NSScrollView NSString NSTextView NSUTF8StringEncoding NSWorkspace | Leave a comment

アラートダイアログ上にTable Viewを表示 v5_複数キー抽出つき

Posted on 12月 23, 2019 by Takaaki Naganoya

アラートダイアログ上にTableViewを表示し、複数キーの組み合わせによって項目抽出。選択項目のデータを返すAppleScriptです。

あくまで試作品なので、あちらこちらに「お可愛らしい」実装が転がっています。NSBoxがまだまともに使いこなせていないあたりとか(Xcode上で部品として配置するのは楽勝ですが、プログラムから動的に生成して使用するのは別なので)。

抽出キー数は可変で外部から指定できるとよいのですが、本Scriptでは固定です。また、各抽出条件も外部から供給するのが本来あるべき姿ですが、ハードコーディングしています。

あと、TableViewの下側に謎の余白があるのは、めんどくさくなってそのまま放置しています。これで外部から各種パラメータを指定できるようにして、sdefつけて1命令で呼び出せるようにしておけば、レコード数の多い選択項目から条件抽出しつつ項目選択できてよいでしょう。

プログラム内容自体は、高度でもなければ高尚でもありません。実にダラダラとGUI部品のパラメータを設定しているだけです。

AppleScript名:アラートダイアログ上にTable Viewを表示 v5_複数キー抽出つき
— Created 2019-12-22 by Takaaki Naganoya
— 2019 Piyomaru Software
set aRes to displayCondTable() of filterTableDialogView
–> {field3:"3.0GHz 6コア Intel Core i5(Turbo Boost使用時最大4.1GHz)", field2:198800, field1:"iMac 5K 27"}

script filterTableDialogView
  use scripting additions
  
use framework "Foundation"
  
use framework "AppKit"
  
property parent : AppleScript
  
  
property NSBox : a reference to current application’s NSBox
  
property NSView : a reference to current application’s NSView
  
property NSAlert : a reference to current application’s NSAlert
  
property NSColor : a reference to current application’s NSColor
  
property NSIndexSet : a reference to current application’s NSIndexSet
  
property NSPredicate : a reference to current application’s NSPredicate
  
property NSScrollView : a reference to current application’s NSScrollView
  
property NSTableView : a reference to current application’s NSTableView
  
property NSTableColumn : a reference to current application’s NSTableColumn
  
property NSPopUpButton : a reference to current application’s NSPopUpButton
  
property NSMutableArray : a reference to current application’s NSMutableArray
  
property NSRunningApplication : a reference to current application’s NSRunningApplication
  
property NSCompoundPredicate : a reference to current application’s NSCompoundPredicate
  
property NSModalPanelWindowLevel : a reference to current application’s NSModalPanelWindowLevel
  
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn
  
  
  
property theResult : 0
  
property returnCode : 0
  
property theDataSource : {}
  
property tView : missing value
  
property aDataList : {}
  
property aSel : 0
  
property bSel : 0
  
property cSel : 0
  
property predList : {}
  
property a1Button : missing value
  
property a2Button : missing value
  
property a3Button : missing value
  
  
on displayCondTable()
    set (my theResult) to 0 –initialize
    
    
set aDataList to {{field1:"MacBook Air", field2:119800, field3:"1.6GHzデュアルコアIntel Core i5(Turbo Boost使用時最大3.6GHz)、4MB L3キャッシュ"}, {field1:"MacBook Pro 13", field2:139800, field3:"1.4GHzクアッドコアIntel Core i5(Turbo Boost使用時最大3.9GHz)、128MB eDRAM"}, {field1:"MacBook Pro 15", field2:258800, field3:"2.6GHz 6コアIntel Core i7(Turbo Boost使用時最大4.5GHz)、12MB共有L3キャッシュ"}, {field1:"Mac mini", field2:122800, field3:"3.0GHz 6コアIntel Core i5 Turbo Boost使用時最大4.1GHz 9MB共有L3キャッシュ"}, {field1:"iMac 21.5", field2:120800, field3:"2.3GHzデュアルコアIntel Core i5(Turbo Boost使用時最大3.6GHz)"}, {field1:"iMac 4K 21.5", field2:142800, field3:"3.6GHzクアッドコアIntel Core i3"}, {field1:"iMac 5K 27", field2:198800, field3:"3.0GHz 6コア Intel Core i5(Turbo Boost使用時最大4.1GHz)"}, {field1:"iMac Pro", field2:558800, field3:"3.2GHz Intel Xeon W Turbo Boost使用時最大4.2GHz 19MBキャッシュ"}, {field1:"Mac Pro 2019", field2:599800, field3:"3.5GHz 8コアIntel Xeon Wプロセッサ(Turbo Boost使用時最大4.0GHz)"}}
    
    
set paramObj to {myMessage:"項目の選択", mySubMessage:"適切なものを以下からえらんでください", aTableList:aDataList, aSortOrder:{"field1", "field2", "field3"}}
    
    
–my chooseItemByTableView:paramObj –for debug
    
my performSelectorOnMainThread:"chooseItemByTableView:" withObject:paramObj waitUntilDone:true
    
    
return (my theResult)
  end displayCondTable
  
  
on chooseItemByTableView:paramObj
    set aMainMes to myMessage of paramObj
    
set aSubMes to mySubMessage of paramObj
    
set aTList to (aTableList of paramObj) as list
    
set labelSortList to (aSortOrder of paramObj) as list
    
    
set aWidth to 800
    
set aHeight to 400
    
set my aSel to 0
    
set my bSel to 0
    
    
–Viewをつくる
    
set parentView to NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
    
    
    
–BOX Aをつくる
    
set aBox to (NSBox’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aHeight – 60, aWidth, 60)))
    (
aBox’s setTitle:("Filter Condition"))
    
    
–このあたり、項目数に合わせてUIを可変で生成するように(本Scriptは試作品なので、決め打ちでUI生成)
    
set a1Button to (NSPopUpButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 200, 30)) pullsDown:false)
    
a1Button’s removeAllItems()
    (
a1Button’s addItemsWithTitles:{"▼Select Item", "MacBook", "iMac", "mini", "Air", "Pro"})
    
a1Button’s setTarget:(me)
    
a1Button’s setAction:("mySelector:")
    
a1Button’s setEnabled:(true)
    
    
set a2Button to (NSPopUpButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(220, 0, 200, 30)) pullsDown:false)
    
a2Button’s removeAllItems()
    (
a2Button’s addItemsWithTitles:{"▼Select Item", "150000", "200000", "300000", "400000", "600000"})
    
a2Button’s setTarget:(me)
    
a2Button’s setAction:("mySelector:")
    
a2Button’s setEnabled:(true)
    
    
set a3Button to (NSPopUpButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(440, 0, 200, 30)) pullsDown:false)
    
a3Button’s removeAllItems()
    (
a3Button’s addItemsWithTitles:{"▼Select Item", "デュアルコア", "クアッドコア", "6コア", "8コア"})
    
a3Button’s setTarget:(me)
    
a3Button’s setAction:("mySelector:")
    
a3Button’s setEnabled:(true)
    
    
    (
aBox’s addSubview:a1Button)
    (
aBox’s addSubview:a2Button)
    (
aBox’s addSubview:a3Button)
    
    
    
–BOX Bをつくる
    
set bBox to (NSBox’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight – 80)))
    (
bBox’s setTitle:("Data"))
    
    
set aScroll to makeTableView(aTList, aWidth, aHeight – 150, labelSortList) of me
    
    (
bBox’s addSubview:aScroll)
    
    
parentView’s setSubviews:{aBox, bBox}
    
    
— set up alert  
    
set theAlert to NSAlert’s alloc()’s init()
    
tell theAlert
      its setMessageText:aMainMes
      
its setInformativeText:aSubMes
      
its addButtonWithTitle:"OK"
      
its addButtonWithTitle:"Cancel"
      
its setAccessoryView:(parentView)
      
      
set myWindow to its |window|
    end tell
    
    
myWindow’s setLevel:(NSModalPanelWindowLevel)
    
    
— show alert in modal loop
    
NSRunningApplication’s currentApplication()’s activateWithOptions:0
    
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
    
if (my returnCode) = 1001 then error number -128
    
    
set tmpResult to (aScroll’s documentView’s selectedRow()) + 1
    
set (my theResult) to contents of item tmpResult of ((my theDataSource) as list)
  end chooseItemByTableView:
  
  
  
on doModal:aParam
    set (my returnCode) to (aParam’s runModal()) as number
  end doModal:
  
  
  
  
  
–TableView Event Handlers
  
on numberOfRowsInTableView:aView
    return (my theDataSource)’s |count|()
  end numberOfRowsInTableView:
  
  
on tableView:aView objectValueForTableColumn:aColumn row:aRow
    set aRec to (my theDataSource)’s objectAtIndex:(aRow as number)
    
set aTitle to (aColumn’s headerCell()’s title()) as string
    
set aRes to (aRec’s valueForKey:aTitle)
    
return aRes
  end tableView:objectValueForTableColumn:row:
  
  
  
  
on makeTableView(aDicList, aWidth, aHeight, labelSortList)
    set aOffset to 40
    
set theDataSource to NSMutableArray’s alloc()’s init()
    
theDataSource’s addObjectsFromArray:aDicList
    
    
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
    
set tView to NSTableView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
    
    
set aLen to length of labelSortList
    
    
repeat with i in labelSortList
      set j to contents of i
      
set aColumn to (NSTableColumn’s alloc()’s initWithIdentifier:j)
      (
aColumn’s setWidth:(aWidth div aLen))
      (
aColumn’s headerCell()’s setStringValue:j)
      (
tView’s addTableColumn:aColumn)
    end repeat
    
    
tView’s setDelegate:me
    
tView’s setDataSource:me
    
tView’s reloadData()
    
    
aScroll’s setDocumentView:tView
    
tView’s enclosingScrollView()’s setHasVerticalScroller:true
    
aScroll’s setVerticalLineScroll:(30.0 as real)
    
    
–1行目を選択
    
set aIndexSet to NSIndexSet’s indexSetWithIndex:0
    
tView’s selectRowIndexes:aIndexSet byExtendingSelection:false
    
    
–強制的にトップにスクロール
    
set aDBounds to aScroll’s documentView()’s |bounds|()
    
if class of aDBounds = list then
      –macOS 10.13 or later
      
set maxHeight to item 2 of item 1 of aDBounds
    else
      –macOS 10.10….10.12
      
set maxHeight to height of |size| of aDBounds
    end if
    
    
set aPT to current application’s NSMakePoint(0.0, -1 * (maxHeight as real))
    
aScroll’s documentView()’s scrollPoint:aPT
    
    
return aScroll
  end makeTableView
  
  
  
on alertShowHelp:aNotification
    display dialog "Help Me!" buttons {"OK"} default button 1 with icon 1
    
return false –trueを返すと親ウィンドウ(アラートダイアログ)がクローズする
  end alertShowHelp:
  
  
  
on mySelector:aObject
    set aIndex to (aObject’s indexOfSelectedItem()) as number
    
filterByMultipleCondition() of me
  end mySelector:
  
  
  
  
on filterByMultipleCondition()
    set prediCatesArray to {}
    
    
set aInd to (my a1Button’s indexOfSelectedItem()) as number
    
set bInd to (my a2Button’s indexOfSelectedItem()) as number
    
set cInd to (my a3Button’s indexOfSelectedItem()) as number
    
    
if {aInd, bInd, cInd} = {0, 0, 0} then
      set (my theDataSource) to NSMutableArray’s arrayWithArray:(my aDataList)
      
tView’s reloadData()
      
return
    end if
    
    
–このあたり、複数条件をハードコーディングしているのは超絶頭悪い。項目数の増減に対応できるべき
    
if aInd > 0 then
      set aTitle to (my a1Button’s title()) as string
      
set the end of prediCatesArray to "field1 contains ’" & aTitle & "’"
    end if
    
    
if bInd > 0 then
      set bTitle to (my a2Button’s title()) as string
      
set the end of prediCatesArray to "field2.integerValue < " & bTitle
    end if
    
    
if cInd > 0 then
      set cTitle to (my a3Button’s title()) as string
      
set the end of prediCatesArray to "field3 contains ’" & cTitle & "’"
    end if
    
    
–データ 抽出
    
set tmpList to filterDictArrayByLabel3((my aDataList), prediCatesArray) of me
    
    
–データ 再表示
    
set (my theDataSource) to NSMutableArray’s arrayWithArray:(tmpList)
    
tView’s reloadData()
  end filterByMultipleCondition
  
  
  
  
–リストに入れたレコードを、指定の属性ラベルの値で抽出(複数PredicatesをANDで合成)
  
on filterDictArrayByLabel3(origArray as list, aPredicateList as list)
    set aArray to NSMutableArray’s arrayWithArray:origArray
    
set predArray to NSMutableArray’s new()
    
    
repeat with i in aPredicateList
      (predArray’s addObject:(NSPredicate’s predicateWithFormat:(contents of i)))
    end repeat
    
    
set pred to current application’s NSCompoundPredicate’s andPredicateWithSubpredicates:predArray
    
set filteredArray to aArray’s filteredArrayUsingPredicate:pred
    
    
return filteredArray
  end filterDictArrayByLabel3
end script

★Click Here to Open This Script 

Posted in dialog GUI list Record search | Tagged 10.13savvy 10.14savvy 10.15savvy NSAlert NSAlertSecondButtonReturn NSBox NSColor NSCompoundPredicate NSIndexSet NSModalPanelWindowLevel NSMutableArray NSPopUpButton NSPredicate NSRunningApplication NSScrollView NSTableColumn NSTableView NSView | 1 Comment

アラートダイアログ上にRadio Buttonを表示 v3

Posted on 8月 7, 2019 by Takaaki Naganoya

アラートダイアログ上にラジオボタン的なUIを表示して選択するAppleScriptです。

–> Downdload calImageDialog (with Library within its bundle)

本当はRadio Button的なものを作りたかったのですが、NSMatrixがmacOS 10.8で非推奨というか事実上の廃止になったことを受けて、Radio Button的なものを作ってみたのですが、割と中途半端です(見た目はスゲーいいのに)。


▲macOS 10.14+Script Editor上の動き


▲macOS 10.14+Script Debugger上の動き

一応、ボタンの画像に1月分のカレンダー画像を割り当てており、機能と見た目のバランスを取ろうとしたのですが、Radio Buttonっぽい動きにはなっていません(残念!)。

あと、1年分のカレンダー画像を作成するのに不思議なぐらい時間がかかっています。

あんな素朴なcalコマンドにmacOS 10.13から当日のハイライト表示を消すための「-h」オプションが追加されていたとは、気づきませんでした。10.14で作って10.12上で動かなかったのでcalコマンドのオプションを条件分岐で変更するように初版から修正しました。

AppleScript名:アラートダイアログ上にRadio Buttonを表示 v3
— Created 2019-08-07 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use calImage : script "calImageKit"

property NSView : a reference to current application’s NSView
property NSAlert : a reference to current application’s NSAlert
property NSMatrix : a reference to current application’s NSMatrix
property NSButton : a reference to current application’s NSButton
property NSButtonCell : a reference to current application’s NSButtonCell
property NSRadioButton : a reference to current application’s NSRadioButton
property NSRadioModeMatrix : a reference to current application’s NSRadioModeMatrix
property NSRoundedBezelStyle : a reference to current application’s NSRoundedBezelStyle
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn

property theResult : 0
property returnCode : 0

set paramObj to {myMessage:"Select target month", mySubMessage:"適切なものを以下からえらんでください", matrixTitleList:{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"}}

–my chooseItemByRadioButton:paramObj–for Debugging

my performSelectorOnMainThread:"chooseItemByRadioButton:" withObject:paramObj waitUntilDone:true
return theResult

on chooseItemByRadioButton:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aMatList to (matrixTitleList of paramObj) as list
  
set aLen to length of aMatList
  
  
  
set aButtonCellWidth to 104
  
set aButtonCellHeight to 104
  
  
set colNum to 4
  
set rowNum to 3
  
  
set targYear to 2019
  
  
set viewWidth to aButtonCellWidth * colNum
  
set viewHeight to aButtonCellHeight * rowNum
  
  
–create the radio button prototype
  
set aProto to NSButtonCell’s alloc()’s init()
  
aProto’s setTitle:"Options"
  
aProto’s setButtonType:(NSRadioButton)
  
  
–define the matrix size where you’ll put the radio buttons
  
set matrixRect to current application’s NSMakeRect(0.0, 0.0, viewWidth, viewHeight)
  
set aView to NSView’s alloc()’s initWithFrame:(matrixRect)
  
  
set aCount to 1
  
set tmpArray to current application’s NSMutableArray’s new()
  
repeat with y from 1 to rowNum
    repeat with x from 1 to colNum
      set j to contents of item aCount of aMatList
      
set tmpB to (NSButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(((x – 1) * aButtonCellWidth), ((aLen – aCount) div colNum) * aButtonCellHeight, aButtonCellWidth, aButtonCellHeight)))
      
–(tmpB’s setTitle:j)
      
      
set tmpImage to makeSmallCalendarImage(targYear, aCount) of calImage
      (
tmpB’s setImage:(tmpImage))
      (
tmpB’s setShowsBorderOnlyWhileMouseInside:true)
      (
tmpB’s setTag:(aCount))
      (
tmpB’s setTarget:me)
      (
tmpB’s setAction:("clicked:"))
      (
tmpB’s setButtonType:(current application’s NSButtonTypeMomentaryPushIn))
      
      (
tmpArray’s addObject:tmpB)
      
set aCount to aCount + 1
    end repeat
  end repeat
  
  (
aView’s setSubviews:tmpArray)
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aView
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
  
end chooseItemByRadioButton:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on clicked:aParam
  set aTag to tag of aParam
  
set theResult to aTag
end clicked:

★Click Here to Open This Script 

Posted in Calendar dialog GUI Image | Tagged 10.12savvy 10.13savvy 10.14savvy 10.15savvy NSAlert NSAlertSecondButtonReturn NSButton NSRoundedBezelStyle NSRunningApplication NSView | Leave a comment

アラートダイアログ上にTable Viewを表示 v4

Posted on 7月 11, 2019 by Takaaki Naganoya

アラートダイアログ上にTable Viewを表示するAppleScriptです。

データを表UIで表示する部品としては、Shane Stanleyの「Myriad Tables Lib」が定番ですが、高機能なぶんライブラリ中にFrameworkが含まれていたりして、場合によっては困ることもあります。また、見た目をカスタマイズしたい場合にも、あまりいじくれなくて困ることもあります(とくにデータの文字サイズを変更できなくて困ること多し)。

そのため、AppleScriptだけで書いた表UI表示用の部品も、たまに必要になることがあります。


▲スクリプトエディタで実行@macOS 10.14.5(左:Light Mode、右:Dark Mode)


▲Script Debuggerで実行@macOS 10.14.5(左:Light Mode、右:Dark Mode)


▲AppleScriptアプレットで実行@macOS 10.14.5(左:Light Mode、右:Dark Mode)

AppleScript名:アラートダイアログ上にTable Viewを表示 v4
— Created 2019-02-21 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSAlert : a reference to current application’s NSAlert
property NSColor : a reference to current application’s NSColor
property NSIndexSet : a reference to current application’s NSIndexSet
property NSScrollView : a reference to current application’s NSScrollView
property NSTableView : a reference to current application’s NSTableView
property NSTableColumn : a reference to current application’s NSTableColumn
property NSMutableArray : a reference to current application’s NSMutableArray
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSModalPanelWindowLevel : a reference to current application’s NSModalPanelWindowLevel
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn

property theResult : 0
property returnCode : 0
property theDataSource : {}

on run
  set (my theResult) to 0 –initialize
  
  
set paramObj to {myMessage:"項目の選択", mySubMessage:"適切なものを以下からえらんでください", aTableList:{{field1:"MacBook Air", field2:"119,800円", field3:"1.6GHzデュアルコアIntel Core i5(Turbo Boost使用時最大3.6GHz)、4MB L3キャッシュ"}, {field1:"MacBook Pro 13", field2:"139,800円", field3:"1.4GHzクアッドコアIntel Core i5(Turbo Boost使用時最大3.9GHz)、128MB eDRAM"}, {field1:"MacBook Pro 15", field2:"258,800円", field3:"2.6GHz 6コアIntel Core i7(Turbo Boost使用時最大4.5GHz)、12MB共有L3キャッシュ"}, {field1:"Mac mini", field2:"122,800円", field3:"3.0GHz 6コアIntel Core i5 Turbo Boost使用時最大4.1GHz 9MB共有L3キャッシュ"}, {field1:"iMac 21.5", field2:"120,800円", field3:"2.3GHzデュアルコアIntel Core i5(Turbo Boost使用時最大3.6GHz)"}, {field1:"iMac 4K 21.5", field2:"142,800円", field3:"3.6GHzクアッドコアIntel Core i3"}, {field1:"iMac 5K 27", field2:"198,800円", field3:"3.0GHz 6コア Intel Core i5(Turbo Boost使用時最大4.1GHz)"}, {field1:"iMac Pro", field2:"558,800円", field3:"3.2GHz Intel Xeon W Turbo Boost使用時最大4.2GHz 19MBキャッシュ"}}, aSortOrder:{"field1", "field2", "field3"}}
  
  
–my chooseItemByTableView:paramObj–for debug
  
my performSelectorOnMainThread:"chooseItemByTableView:" withObject:paramObj waitUntilDone:true
  
return (my theResult)
end run

on chooseItemByTableView:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aTList to (aTableList of paramObj) as list
  
set labelSortList to (aSortOrder of paramObj) as list
  
  
set aWidth to 600
  
set aHeight to 200
  
  
set aScroll to makeTableView(aTList, aWidth, aHeight, labelSortList) of me
  
  
–Detect Dark Mode
  
set dMode to retLIghtOrDark() of me
  
if dMode = true then
    set tvCol to 1
    
set tvAlpha to 0.8
    
set bCol to 0.1
    
set bAlpha to 0.8
    
set contentCol to (NSColor’s cyanColor())
  else
    set tvCol to 0
    
set tvAlpha to 0.1
    
set bCol to 1
    
set bAlpha to 0.8
    
set contentCol to (NSColor’s blackColor())
  end if
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aScroll
    
    
set myWindow to its |window|
  end tell
  
  
myWindow’s setOpaque:(false)
  
myWindow’s setBackgroundColor:(NSColor’s colorWithCalibratedWhite:(bCol) alpha:(bAlpha))
  
myWindow’s setLevel:(NSModalPanelWindowLevel)
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode) = 1001 then error number -128
  
  
set (my theResult) to (aScroll’s documentView’s selectedRow()) + 1
end chooseItemByTableView:

on doModal:aParam
  set (my returnCode) to (aParam’s runModal()) as number
end doModal:

–TableView Event Handlers
on numberOfRowsInTableView:aView
  return my theDataSource’s |count|()
end numberOfRowsInTableView:

on tableView:aView objectValueForTableColumn:aColumn row:aRow
  set aRec to (my theDataSource)’s objectAtIndex:(aRow as number)
  
set aTitle to (aColumn’s headerCell()’s title()) as string
  
set aRes to (aRec’s valueForKey:aTitle)
  
return aRes
end tableView:objectValueForTableColumn:row:

on makeTableView(aDicList, aWidth, aHeight, labelSortList)
  set aOffset to 40
  
set theDataSource to current application’s NSMutableArray’s alloc()’s init()
  
theDataSource’s addObjectsFromArray:aDicList
  
  
set aScroll to current application’s NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
set aView to current application’s NSTableView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
  
set aLen to length of labelSortList
  
  
repeat with i in labelSortList
    set j to contents of i
    
set aColumn to (current application’s NSTableColumn’s alloc()’s initWithIdentifier:j)
    (
aColumn’s setWidth:(aWidth div aLen))
    (
aColumn’s headerCell()’s setStringValue:j)
    (
aView’s addTableColumn:aColumn)
  end repeat
  
  
aView’s setDelegate:me
  
aView’s setDataSource:me
  
aView’s reloadData()
  
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasVerticalScroller:true
  
aScroll’s setVerticalLineScroll:(30.0 as real)
  
  
–1行目を選択
  
set aIndexSet to current application’s NSIndexSet’s indexSetWithIndex:0
  
aView’s selectRowIndexes:aIndexSet byExtendingSelection:false
  
  
–強制的にトップにスクロール
  
set aDBounds to aScroll’s documentView()’s |bounds|()
  
if class of aDBounds = list then
    –macOS 10.13 or later
    
set maxHeight to item 2 of item 1 of aDBounds
  else
    –macOS 10.10….10.12
    
set maxHeight to height of |size| of aDBounds
  end if
  
  
set aPT to current application’s NSMakePoint(0.0, -1 * (maxHeight as real))
  
aScroll’s documentView()’s scrollPoint:aPT
  
  
return aScroll
end makeTableView

on alertShowHelp:aNotification
  display dialog "Help Me!" buttons {"OK"} default button 1 with icon 1
  
return false –trueを返すと親ウィンドウ(アラートダイアログ)がクローズする
end alertShowHelp:

–ダークモードの判定。ダークモード時:true、ライトモード時:falseが返る。System Eventsを使っていないのは、macOS 10.14以降対策(承認を取得しなくてもいいように)
on retLIghtOrDark()
  set curMode to (current application’s NSUserDefaults’s standardUserDefaults()’s stringForKey:"AppleInterfaceStyle") as string
  
return (curMode = "Dark") as boolean
end retLIghtOrDark

★Click Here to Open This Script 

Posted in Color GUI list Record | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSAlert NSAlertSecondButtonReturn NSColor NSIndexSet NSModalPanelWindowLevel NSMutableArray NSRunningApplication NSScrollView NSTableColumn NSTableView | 1 Comment

アラートダイアログ上にBrowser+Map Viewを表示 v2

Posted on 3月 17, 2019 by Takaaki Naganoya

ダイアログ上に表示したNSBrowserで都道府県→都道府県別データを選択し、選択したデータの位置情報をMap Viewに表示するAppleScriptの改良版です。

初版掲載時のおかしな挙動を減らし、地図種別の切り替えができるようになっています。本掲載リストだけだと動作が完結しないため、ライブラリを含んだスクリプトバンドルをダウンロードして実行してください。下記リストは「参考までに」掲載しているものです。

–> Download whole Script bundle with Library

前バージョンでは、NSBrowser上でデータが存在していない箇所に空白のセルが表示され、クリックするとクラッシュするという状態でした。本バージョンでもたまに出てくるので完全ではないのですが、

 ・予想どおりデータの行数をカウントするハンドラで絞り込みを行うPredicates文の文字列に問題があった
 ・データに半角のシングルクォートが入っていて、これによってデータの絞り込みに問題が出た

という問題を解消しました。前者はこまめにstringにcastし、後者は全角文字に置き換えました。

それでもまだ問題が出るケースがあるので、まだしばらく実際に使いつつ様子見といったところでしょうか。

AppleScript名:アラートダイアログ上にBrowser+Map Viewを表示 v2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/03/10
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use framework "MapKit"
use scripting additions
use skLib : script "senjoNoKizunaLib"

property NSView : a reference to current application’s NSView
property NSAlert : a reference to current application’s NSAlert
property NSColor : a reference to current application’s NSColor
property NSBrowser : a reference to current application’s NSBrowser
property MKMapView : a reference to current application’s MKMapView
property NSScrollView : a reference to current application’s NSScrollView
property NSMutableArray : a reference to current application’s NSMutableArray
property MKMapTypeHybrid : a reference to current application’s MKMapTypeHybrid
property MKMapTypeSatellite : a reference to current application’s MKMapTypeSatellite
property MKMapTypeStandard : a reference to current application’s MKMapTypeStandard
property NSSegmentedControl : a reference to current application’s NSSegmentedControl
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn
property NSSegmentStyleTexturedRounded : a reference to current application’s NSSegmentStyleTexturedRounded

property zLevel : 17
property aMaxViewWidth : 1000
property aMaxViewHeight : 500
property theResult : 0
property returnCode : 0
property theDataSource : {}
property aSelection : {}
property aMapView : missing value
property aBrowser : missing value
property skDataList : {}

property prefList : {"北海道", "青森県", "岩手県", "宮城県", "秋田県", "山形県", "福島県", "茨城県", "栃木県", "群馬県", "埼玉県", "千葉県", "東京都", "神奈川県", "新潟県", "富山県", "石川県", "福井県", "山梨県", "長野県", "岐阜県", "静岡県", "愛知県", "三重県", "滋賀県", "京都府", "大阪府", "兵庫県", "奈良県", "和歌山県", "鳥取県", "島根県", "岡山県", "広島県", "山口県", "徳島県", "香川県", "愛媛県", "高知県", "福岡県", "佐賀県", "長崎県", "熊本県", "大分県", "宮崎県", "鹿児島県", "沖縄県"}

if my skDataList = {} then
  set my skDataList to current application’s NSMutableArray’s arrayWithArray:(getSenjoNokizunaGameCenterDataList() of skLib)
end if

set tmpLen to length of (my skDataList as list)

set aSelection to {}

set paramObj to {myMessage:"Choose a Game Center", mySubMessage:("Choose an appropriate Game Center from list (" & tmpLen as string) & ") to play Senjo-no-Kizuna"}

my performSelectorOnMainThread:"chooseItemByBrowser:" withObject:(paramObj) waitUntilDone:true
if (my returnCode as number) = 1001 then error number -128

return my aSelection
–> {loc_id:"QIEXj9er5QSA_Y42-OjPNg", gcName:"THE 3RD PLANET ジャングルパーク鹿児島", latitude:31.5703088, longitude:130.5653137, address:"鹿児島県 鹿児島市 与次郎 1-11-1 フレスポジャングルパーク2F"}

on chooseItemByBrowser:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
  
— create a view
  
set theView to NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aMaxViewWidth, aMaxViewHeight))
  
set aMapView to MKMapView’s alloc()’s initWithFrame:(current application’s NSMakeRect(410, 30, aMaxViewWidth – 410, aMaxViewHeight – 30))
  
tell aMapView
    its setMapType:(MKMapTypeStandard)
    
its setZoomEnabled:true
    
its setScrollEnabled:true
    
its setPitchEnabled:true
    
its setRotateEnabled:true
    
its setShowsCompass:true
    
its setShowsZoomControls:true
    
its setShowsScale:true
    
its setShowsUserLocation:true
    
its setDelegate:me
  end tell
  
  
— make browser view with scroll view
  
set aScrollWithTable to makeBrowserView(prefList, 400, aMaxViewHeight) of me
  
  
–Segmented Controlをつくる
  
set segTitleList to {"Map", "Satellite", "Satellite + Map"}
  
set aSeg to makeSegmentedControl(segTitleList, 410, 0, 150, 20) of me
  
  
–Compose Views in NSView
  
theView’s setSubviews:{aScrollWithTable, aMapView, aSeg}
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:theView
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
end chooseItemByBrowser:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on makeBrowserView(aList as list, aWidth as number, aHeight as number)
  set (my theDataSource) to NSMutableArray’s arrayWithArray:aList
  
  
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
set aBrowser to NSBrowser’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
  
aBrowser’s setDelegate:(me)
  
aBrowser’s setTarget:(me)
  
aBrowser’s setAction:"browserCellSelected:"
  
aBrowser’s setMinColumnWidth:120
  
aBrowser’s setSeparatesColumns:true
  
aBrowser’s setMaxVisibleColumns:2
  
aBrowser’s setAutohidesScroller:true
  
aBrowser’s setTakesTitleFromPreviousColumn:true
  
–aBrowser’s setBackgroundColor:(NSColor’s grayColor())
  
  
aScroll’s setDocumentView:aBrowser
  
aBrowser’s enclosingScrollView()’s setHasHorizontalScroller:true
  
aBrowser’s enclosingScrollView()’s setHasVerticalScroller:true
  
  
return aScroll
end makeBrowserView

–NSBrowser Event Handlers
on browser:aView numberOfRowsInColumn:aColumn
  if aColumn = 0 then
    return my theDataSource’s |count|()
  else if aColumn = 1 then
    set aPath to (text 2 thru -1 of ((aView’s |path|()) as string)) as string –ここが問題だったもよう
    
set tmpArray to (my filterRecListByLabel1(skDataList, "address BEGINSWITH ’" & aPath & "’")) as list
    
return (length of tmpArray)
  else
    return 0
  end if
end browser:numberOfRowsInColumn:

on browser:aView willDisplayCell:(aCell) atRow:(rowIndex as integer) column:(colIndex as integer)
  if colIndex = 0 then
    –Prefectures
    
aCell’s setTitle:((item (rowIndex + 1) of prefList) as string)
    
aCell’s setLeaf:false
    
  else if colIndex = 1 then
    –Each Game Centers in the Prefecture
    
set aPath to text 2 thru -1 of ((aView’s |path|()) as string)
    
set tmpArray to my filterRecListByLabel1(skDataList, "address BEGINSWITH ’" & aPath & "’")
    
set tmpItem to (tmpArray’s objectAtIndex:rowIndex)
    
    
set aGameCenterName to (tmpItem’s gcName) as string
    
aCell’s setTitle:(aGameCenterName)
    
aCell’s setLeaf:true
    
  else if colIndex ≥ 2 then
    error "Wrong NSBrowser status"
  end if
end browser:willDisplayCell:atRow:column:

on browserCellSelected:aSender
  set aPath to my aBrowser’s |path|()
  
set aList to (aPath’s pathComponents()) as list
  
set aLen to length of aList
  
  
if aLen = 3 then
    –set aPref to contents of item 2 of aList
    
set aGc to contents of last item of aList
    
    
set tmpArray to my filterRecListByLabel1(skDataList, "gcName == ’" & aGc & "’")
    
–set tmpArray to my filterRecListByLabel1(skDataList, "gcName == " & aGc)
    
set tmpItem to contents of first item of (tmpArray as list)
    
    
copy tmpItem to my aSelection
    
    
set aLatitude to (latitude of tmpItem) as real
    
set aLongitude to (longitude of tmpItem) as real
    
    
tell aMapView
      set aLocation to current application’s CLLocationCoordinate2DMake(aLatitude, aLongitude)
      
its setCenterCoordinate:aLocation zoomLevel:(zLevel) animated:false
    end tell
    
  end if
end browserCellSelected:

–NSArrayに入れたNSDictionaryを、指定の属性ラベルの値で抽出
on filterRecListByLabel1(aRecList, aPredicate as string)
  set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate
  
set filteredArray to aRecList’s filteredArrayUsingPredicate:aPredicate
  
return filteredArray
end filterRecListByLabel1

–Segmented Controlをつくる
on makeSegmentedControl(titleList, startX, startY, aWidth, aHeight)
  set aLen to length of titleList
  
  
set aSeg to NSSegmentedControl’s alloc()’s init()
  
aSeg’s setSegmentCount:aLen
  
  
set aCount to 0
  
repeat with i in titleList
    set j to contents of i
    (
aSeg’s setLabel:j forSegment:aCount)
    
set aCount to aCount + 1
  end repeat
  
  
aSeg’s setTranslatesAutoresizingMaskIntoConstraints:false
  
aSeg’s setSegmentStyle:(NSSegmentStyleTexturedRounded)
  
aSeg’s setFrame:(current application’s NSMakeRect(startX, startY, aWidth, aHeight))
  
aSeg’s setTrackingMode:0
  
aSeg’s setTarget:me
  
aSeg’s setAction:"clickedSeg:"
  
aSeg’s setSelectedSegment:0
  
  
return aSeg
end makeSegmentedControl

–Segmented Controlのクリック時のイベントハンドラ
on clickedSeg:aSender
  set aSel to aSender’s selectedSegment()
  
set tList to {MKMapTypeStandard, MKMapTypeSatellite, MKMapTypeHybrid}
  
set tmpType to contents of item (aSel + 1) of tList
  
  
aMapView’s setMapType:(tmpType)
  
  
set selSeg to aSel
end clickedSeg:

★Click Here to Open This Script 

Posted in geolocation GUI list Map regexp | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy MKMapTypeHybrid MKMapTypeSatellite MKMapTypeStandard MKMapView NSAlert NSAlertSecondButtonReturn NSBrowser NSColor NSMutableArray NSRunningApplication NSScrollView NSSegmentedControl NSSegmentStyleTexturedRounded NSView | Leave a comment

アラートダイアログ上にBrowser+Map Viewを表示

Posted on 3月 12, 2019 by Takaaki Naganoya

ダイアログ上に表示したNSBrowserで都道府県→都道府県別データを選択し、選択したデータの位置情報をMap Viewに表示するAppleScriptです。

# 2021年11月末にアーケードゲーム「戦場の絆」のサービスが終了したため、Webサイト側からデータ取得する部分の処理は動作しません(Webサイトごとアクセスできなくなったため)


▲macOS 10.12.6上で動作

「OK」ボタンをクリックすると選択したゲームセンターの諸元情報を返してきます。リスト一覧から名称を選択し、途中でその位置情報を地図で見られるという程度のインタフェースです。

NSBrowserを利用したUIの習作で、Web上の「戦場の絆」公式ページから導入店舗の情報を取得し(このあたりライブラリにまとめて部品化)、データを都道府県別にしぼりこんでNSBrowser上で選択できるようにしてみました。


▲macOS 10.13.6上で動作


▲macOS 10.14.4上で動作(Light Mode)


▲macOS 10.14.4上で動作(Dark Mode)

ぱっと見は「何かすごいもの」に見えるのですが、キーワード検索が実装されていないため、データしぼりこみに柔軟性がないと感じるものです。

NSBrowserをAppleScriptから利用した場合に、Xcodeを利用しないとこのレベルの単純なデータ階層固定でデータしぼりこみを行う程度のものしか作りにくいところでしょうか。不可能とは言わないものの、「普通にXcode上で作れば?」という話になると思います。

さらに、該当するカラムの行数を返すハンドラでデータをしぼりこんでレコード数を返しているものの、いまひとつここがうまく動いていない印象を受けます。NSBrowser上で「存在しないデータのような何か」をクリックできるケースがあり、それをクリックすると実行環境(スクリプトエディタとか、Script Debuggerとか)ごとクラッシュします。

→ 原因がわかりました。問題箇所も想像どおり。目下、修正版で謎のゴースト行も出てこなくなったので、あとで修正版を掲載しておきます。問題が2つあって、1つがPredicates文をas stringですべてcastしていなかった件、もうひとつは、、、副次的に発生した問題で、愛知県のデータに「M’s」という半角クォート文字を含むものがあって、これでPredicates文が中断されてしまった問題。半角シングルクォートを全角に置き換えるとかいろいろ手を加える必要がありました。

本Script全体をダウンロードして、スクリプトエディタ上で実行すると、最初に「戦場の絆」公式ホームページの日本国内の店舗情報をスキャンして店舗情報を抽出するため、サーバーの混雑具合やネットワーク回線速度にも左右されますが、自分の環境では5〜15秒程度でデータの取得が終了し、ダイアログが表示されます。

–> Download whole Script bundle with Library

AppleScript名:アラートダイアログ上にBrowser+Map Viewを表示.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/03/10
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use framework "MapKit"
use scripting additions
use skLib : script "senjoNoKizunaLib"

property NSView : a reference to current application’s NSView
property NSAlert : a reference to current application’s NSAlert
property NSColor : a reference to current application’s NSColor
property NSBrowser : a reference to current application’s NSBrowser
property MKMapView : a reference to current application’s MKMapView
property NSScrollView : a reference to current application’s NSScrollView
property NSMutableArray : a reference to current application’s NSMutableArray
property MKMapTypeStandard : a reference to current application’s MKMapTypeStandard
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn

property zLevel : 17
property aMaxViewWidth : 1000
property aMaxViewHeight : 500
property theResult : 0
property returnCode : 0
property theDataSource : {}
property aSelection : {}
property aMapView : missing value
property aBrowser : missing value
property skDataList : {}

property prefList : {"北海道", "青森県", "岩手県", "宮城県", "秋田県", "山形県", "福島県", "茨城県", "栃木県", "群馬県", "埼玉県", "千葉県", "東京都", "神奈川県", "新潟県", "富山県", "石川県", "福井県", "山梨県", "長野県", "岐阜県", "静岡県", "愛知県", "三重県", "滋賀県", "京都府", "大阪府", "兵庫県", "奈良県", "和歌山県", "鳥取県", "島根県", "岡山県", "広島県", "山口県", "徳島県", "香川県", "愛媛県", "高知県", "福岡県", "佐賀県", "長崎県", "熊本県", "大分県", "宮崎県", "鹿児島県", "沖縄県"}

if my skDataList = {} then
  set my skDataList to current application’s NSMutableArray’s arrayWithArray:(getSenjoNokizunaGameCenterDataList() of skLib)
end if

set aSelection to {}

set paramObj to {myMessage:"Choose a Game Center", mySubMessage:"Choose an appropriate Game Center from list to play Senjo-no-Kizuna"}

my performSelectorOnMainThread:"chooseItemByBrowser:" withObject:(paramObj) waitUntilDone:true
return my aSelection
–> {loc_id:"QIEXj9er5QSA_Y42-OjPNg", gcName:"THE 3RD PLANET ジャングルパーク鹿児島", latitude:31.5703088, longitude:130.5653137, address:"鹿児島県 鹿児島市 与次郎 1-11-1 フレスポジャングルパーク2F"}

on chooseItemByBrowser:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
  
— create a view
  
set theView to NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aMaxViewWidth, aMaxViewHeight))
  
set aMapView to MKMapView’s alloc()’s initWithFrame:(current application’s NSMakeRect(410, 0, aMaxViewWidth – 410, aMaxViewHeight))
  
tell aMapView
    its setMapType:(MKMapTypeStandard)
    
its setZoomEnabled:true
    
its setScrollEnabled:true
    
its setPitchEnabled:true
    
its setRotateEnabled:true
    
its setShowsCompass:true
    
its setShowsZoomControls:true
    
its setShowsScale:true
    
its setShowsUserLocation:true
    
its setDelegate:me
  end tell
  
  
— make browser view with scroll view
  
set aScrollWithTable to makeBrowserView(prefList, 400, aMaxViewHeight) of me
  
  
–Compose Views in NSView
  
theView’s setSubviews:{aScrollWithTable, aMapView}
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:theView
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
end chooseItemByBrowser:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on makeBrowserView(aList as list, aWidth as number, aHeight as number)
  set (my theDataSource) to NSMutableArray’s arrayWithArray:aList
  
  
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
set aBrowser to NSBrowser’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
  
aBrowser’s setDelegate:(me)
  
aBrowser’s setTarget:(me)
  
aBrowser’s setAction:"browserCellSelected:"
  
aBrowser’s setMinColumnWidth:120
  
aBrowser’s setSeparatesColumns:true
  
aBrowser’s setMaxVisibleColumns:2
  
aBrowser’s setAutohidesScroller:true
  
aBrowser’s setTakesTitleFromPreviousColumn:true
  
–aBrowser’s setBackgroundColor:(NSColor’s grayColor())
  
  
aScroll’s setDocumentView:aBrowser
  
aBrowser’s enclosingScrollView()’s setHasHorizontalScroller:true
  
aBrowser’s enclosingScrollView()’s setHasVerticalScroller:true
  
  
return aScroll
end makeBrowserView

–NSBrowser Event Handlers
–ここ、いまひとつきちんと動いていないかも???
on browser:aView numberOfRowsInColumn:aColumn
  if aColumn = 0 then
    return my theDataSource’s |count|()
  else if aColumn = 1 then
    set aPath to text 2 thru -1 of ((aView’s |path|()) as string)
    
set tmpArray to (my filterRecListByLabel1(skDataList, "address BEGINSWITH ’" & aPath & "’")) as list
    
return (length of tmpArray)
  end if
end browser:numberOfRowsInColumn:

on browser:aView willDisplayCell:(aCell) atRow:(rowIndex as integer) column:(colIndex as integer)
  if colIndex = 0 then
    –Prefectures
    
aCell’s setTitle:((item (rowIndex + 1) of prefList) as string)
    
aCell’s setLeaf:false
    
  else if colIndex = 1 then
    –Each Game Centers in the Prefecture
    
set aPath to text 2 thru -1 of ((aView’s |path|()) as string)
    
set tmpArray to my filterRecListByLabel1(skDataList, "address BEGINSWITH ’" & aPath & "’")
    
set tmpItem to (tmpArray’s objectAtIndex:rowIndex)
    
    
set aGameCenterName to (tmpItem’s gcName) as string
    
aCell’s setTitle:(aGameCenterName)
    
aCell’s setLeaf:true
    
  end if
end browser:willDisplayCell:atRow:column:

on browserCellSelected:aSender
  set aPath to my aBrowser’s |path|()
  
set aList to (aPath’s pathComponents()) as list
  
set aLen to length of aList
  
  
if aLen = 3 then
    –set aPref to contents of item 2 of aList
    
set aGc to contents of last item of aList
    
    
set tmpArray to my filterRecListByLabel1(skDataList, "gcName == ’" & aGc & "’")
    
set tmpItem to contents of first item of (tmpArray as list)
    
    
copy tmpItem to my aSelection
    
    
set aLatitude to (latitude of tmpItem) as real
    
set aLongitude to (longitude of tmpItem) as real
    
    
tell aMapView
      set aLocation to current application’s CLLocationCoordinate2DMake(aLatitude, aLongitude)
      
its setCenterCoordinate:aLocation zoomLevel:(zLevel) animated:false
    end tell
    
  end if
end browserCellSelected:

–NSArrayに入れたNSDictionaryを、指定の属性ラベルの値で抽出
on filterRecListByLabel1(aRecList, aPredicate as string)
  set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate
  
set filteredArray to aRecList’s filteredArrayUsingPredicate:aPredicate
  
return filteredArray
end filterRecListByLabel1

★Click Here to Open This Script 

Posted in geolocation list Record | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy MKMapTypeStandard MKMapView NSAlert NSAlertSecondButtonReturn NSBrowser NSColor NSMutableArray NSRunningApplication NSScrollView NSView | Leave a comment

アラートダイアログ上にWebViewを表示

Posted on 3月 5, 2019 by Takaaki Naganoya

アラートダイアログ上にWKWebViewを表示するAppleScriptです。

テストのためにYouTubeのムービーの自動再生URL(戦場の絆のリプレイムービー)をオープンしています。


▲Table ViewとWeb Viewを組み合わせて、所定の場所にYouTubeムービーの頭出しを行う試作品を作ってみたものの、JavaScript経由でWKWebViewをコントロールするのが難しくて頓挫

本来であれば、WkWebViewに対してJavaScript経由でさまざまな操作を行いたいところですが、オープン中のWebコンテンツに対して新たなJavaScriptのインスタンスを生成してセキュリティチェックを行なって、実際に実行を行うのが(自分には)少々難しく感じました。WkWebViewだとあまり凝った制御はできない印象です。Safariをコントロールするほうが自由度が高いところ。

WkWebViewを「自由にこづきまわして操作できる部品」として使うためには、素のままのWkWebViewではない何かを使ったほうがいいのかも?

AppleScript名:アラートダイアログ上にWebViewを表示.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/03/02
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use framework "WebKit"
use scripting additions

property |NSURL| : a reference to current application’s |NSURL|
property NSAlert : a reference to current application’s NSAlert
property NSColor : a reference to current application’s NSColor
property NSString : a reference to current application’s NSString
property NSScreen : a reference to current application’s NSScreen
property NSButton : a reference to current application’s NSButton
property WKWebView : a reference to current application’s WKWebView
property NSScrollView : a reference to current application’s NSScrollView
property WKUserScript : a reference to current application’s WKUserScript
property NSURLRequest : a reference to current application’s NSURLRequest
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property NSBackingStoreBuffered : a reference to current application’s NSBackingStoreBuffered
property WKUserContentController : a reference to current application’s WKUserContentController
property NSMomentaryLightButton : a reference to current application’s NSMomentaryLightButton
property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn
property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd

property theResult : 0
property returnCode : 0
property theDataSource : {}

set aURL to "https://www.youtube.com/embed/GP_tVXTYdmY?autoplay=1&hd=1"
set paramObj to {myMessage:"Browse a Replay", mySubMessage:"Browse Senjo-No-Kizuna Replay Movie", targURL:aURL}
my performSelectorOnMainThread:"browseWebContents:" withObject:(paramObj) waitUntilDone:true

on browseWebContents:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set tmpURL to (targURL of paramObj)
  
  
set aWidth to 600
  
set aHeight to 450
  
  
–WebViewをつくる
  
set aConf to WKWebViewConfiguration’s alloc()’s init()
  
  
–指定URLのJavaScriptをFetch
  
set jsSource to my fetchJSSourceString(tmpURL)
  
set userScript to WKUserScript’s alloc()’s initWithSource:jsSource injectionTime:(WKUserScriptInjectionTimeAtDocumentEnd) forMainFrameOnly:true
  
set userContentController to WKUserContentController’s alloc()’s init()
  
userContentController’s addUserScript:(userScript)
  
aConf’s setUserContentController:userContentController
  
  
set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight – 100)) configuration:aConf
  
aWebView’s setNavigationDelegate:me
  
aWebView’s setUIDelegate:me
  
aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true
  
  
set bURL to |NSURL|’s URLWithString:tmpURL
  
set aReq to NSURLRequest’s requestWithURL:bURL
  
aWebView’s loadRequest:aReq –Webコンテンツのローディング
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aWebView
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
  
–Stop Web View Action
  
set bURL to |NSURL|’s URLWithString:"about:blank"
  
set bReq to NSURLRequest’s requestWithURL:bURL
  
aWebView’s loadRequest:bReq
  
  
if (my returnCode as number) = 1001 then error number -128
end browseWebContents:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on viewDidLoad:aNotification
  return true
end viewDidLoad:

on fetchJSSourceString(aURL)
  set jsURL to |NSURL|’s URLWithString:aURL
  
set jsSourceString to NSString’s stringWithContentsOfURL:jsURL encoding:(NSUTF8StringEncoding) |error|:(missing value)
  
return jsSourceString
end fetchJSSourceString

★Click Here to Open This Script 

Posted in Internet URL | Tagged 10.11savvy 10.12savvy 10.13savvy NSAlert NSAlertSecondButtonReturn NSBackingStoreBuffered NSButton NSColor NSMomentaryLightButton NSRunningApplication NSScreen NSString NSURL NSURLRequest NSUTF8StringEncoding WKUserContentController WKUserScript WKUserScriptInjectionTimeAtDocumentEnd WKWebView WKWebViewConfiguration | Leave a comment

アラートダイアログ上に縦棒グラフを表示

Posted on 3月 4, 2019 by Takaaki Naganoya

アラートダイアログ上に縦棒グラフを表示するAppleScriptです。

グラフを作成するのであれば、NumbersやKeynoteなどを使ったほうがいいですが、簡単にデータの傾向だけダイアログ上で見せたいような場合のために作成した部品です。

NSImageViewの表示実験がしたかっただけなので、別に他の言語処理系で作成したグラフ画像を読み込んでNSImageに読み込んでからNSIMageViewで表示するぐらいの使い方でもぜんぜんOKでしょう。

WebViewを表示してインタラクティブなグラフ(マウスカーソルに反応してアニメーション表示を行うとか)を表示するといった使い方もよさそうです(アプリケーション化しないとダメかも)。

macOS 10.14上のDark Modeについては、実行環境によって対応度が異なります。


▲macOS 10.14上のDark Modeで実行したところ。左側からスクリプトエディタ、AppleScriptアプレット、スクリプトメニュー


▲macOS 10.14上のDark Modeで実行したところ。左側からScript Debugger、Script DebuggerからSD拡張アプレットで書き出したもの

グラフの描画については、色指定をblackColor()とかgrayColor()などと指定せずに、Dark Mode時に制御されるUI色で指定しておく必要があることでしょう。

AppleScript名:アラートダイアログ上に縦棒グラフを表示.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/03/04
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

property NSFont : a reference to current application’s NSFont
property NSAlert : a reference to current application’s NSAlert
property NSColor : a reference to current application’s NSColor
property NSArray : a reference to current application’s NSArray
property NSString : a reference to current application’s NSString
property NSImage : a reference to current application’s NSImage
property NSScreen : a reference to current application’s NSScreen
property NSDictionary : a reference to current application’s NSDictionary
property NSBezierPath : a reference to current application’s NSBezierPath
property NSImageView : a reference to current application’s NSImageView
property NSMutableArray : a reference to current application’s NSMutableArray
property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSFontAttributeName : a reference to current application’s NSFontAttributeName
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn
property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName
property NSImageScaleProportionallyUpOrDown : a reference to current application’s NSImageScaleProportionallyUpOrDown

property returnCode : 0

set plotData to {20, 30, 100, 80, 150, 90}
set paramObj to {myMessage:"This is a graph", mySubMessage:"Browse bar graph", aPlotData:plotData}
my performSelectorOnMainThread:"displayBarGraph:" withObject:(paramObj) waitUntilDone:true

on displayBarGraph:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aTList to (aPlotData of paramObj) as list
  
  
— make NSIMageView with graph image
  
set anImage to makeGraphImage(aTList, 300, 200) of me
  
set anImageView to NSImageView’s alloc()’s initWithFrame:{origin:{x:0.0, y:0.0}, |size|:{width:300.0, height:200.0}}
  
anImageView’s setImageScaling:(NSImageScaleProportionallyUpOrDown)
  
anImageView’s setEditable:false
  
anImageView’s setImage:anImage
  
anImageView’s display()
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:anImageView
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
end displayBarGraph:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on makeGraphImage(plotData, aWidth, aHeight)
  set innerGapL to 30
  
set innerGapU to 10
  
set innerGapR to 20
  
set innerGapD to 20
  
set barGap to 10
  
  
–パラメータから下地になる画像を作成する
  
set aSize to current application’s NSMakeSize(aWidth, aHeight)
  
set anImage to NSImage’s alloc()’s initWithSize:aSize
  
  
–各種パラメータの計算
  
–copy plotArea to {plotWidth, plotHeight}
  
set itemNum to count every item of plotData
  
set barThickness to (aWidth – (itemNum * barGap * 2)) div itemNum
  
  
–プロットデータの最大値
  
set anArray to NSArray’s arrayWithArray:plotData
  
set aYmax to (anArray’s valueForKeyPath:"@max.self")’s intValue()
  
set aMaxYVal to aHeight – innerGapU – innerGapD
  
set aYPlotArea to aHeight – innerGapU – innerGapD – 20
  
set aYUnit to aYPlotArea / aYmax
  
  
–数値データをもとに描画データを組み立てる
  
set drawList to {}
  
  
set startX to innerGapL
  
copy startX to origX
  
  
repeat with i in plotData
    set the end of drawList to current application’s NSMakeRect(startX, innerGapD, barThickness, innerGapD + (i * aYUnit))
    
set startX to startX + barThickness + barGap
  end repeat
  
  
–グラフ塗りつぶし処理呼び出し
  
set fillColor to (NSColor’s colorWithCalibratedRed:0.1 green:0.1 blue:0.1 alpha:0.3)
  
set resImage to drawImageWithColorFill(anImage, drawList, fillColor) of me
  
  
–数値データ(文字)をグラフィックに記入
  
set fillColor2 to NSColor’s blackColor()
  
set resImage to drawImageWithString(resImage, drawList, fillColor2, plotData, "Eurostile Bold", 20.0) of me
  
  
–補助線を引く
  
set fillColor3 to (NSColor’s colorWithCalibratedRed:0.0 green:0.0 blue:0.0 alpha:0.8)
  
set aVertical to current application’s NSMakeRect(origX, innerGapD, aWidth – innerGapL – innerGapR, 1)
  
set aHorizontal to current application’s NSMakeRect(origX, innerGapD, 1, aHeight – innerGapU – innerGapD)
  
set draw2List to {aVertical, aHorizontal}
  
set resImage to drawImageWithColorFill(resImage, draw2List, fillColor3) of me
  
  
return resImage
end makeGraphImage

–NSImageに対して文字を描画する
on drawImageWithString(anImage, drawList, fillColor, dataList, aPSFontName, aFontSize)
  set retinaF to (NSScreen’s mainScreen()’s backingScaleFactor()) as real
  
–>  2.0 (Retina) / 1.0 (Non Retina)
  
  
set aDict to (NSDictionary’s dictionaryWithObjects:{NSFont’s fontWithName:aPSFontName |size|:aFontSize, fillColor} forKeys:{NSFontAttributeName, NSForegroundColorAttributeName})
  
  
anImage’s lockFocus() –描画開始
  
  
set aLen to length of drawList
  
repeat with i from 1 to aLen
    set i1 to contents of item i of drawList
    
    
set v2 to system attribute "sys2"
    
if v2 ≤ 12 then
      –To macOS 10.12.x
      
set origX to (x of origin of i1) / retinaF
      
set origY to (y of origin of i1) / retinaF
      
set sizeX to (width of |size| of i1) / retinaF
      
set sizeY to (height of |size| of i1) / retinaF
      
set theRect to {{x:origX, y:origY}, {width:sizeX, height:sizeY}}
    else
      –macOS 10.13 or later
      
set origX to (item 1 of item 1 of i1) / retinaF
      
set origY to (item 2 of item 1 of i1) / retinaF
      
set sizeX to (item 1 of item 2 of i1) / retinaF
      
set sizeY to (item 2 of item 2 of i1) / retinaF
      
set theRect to {{origX, origY}, {sizeX, sizeY}}
    end if
    
    
set aString to (current application’s NSString’s stringWithString:((contents of item i of dataList) as string))
    (
aString’s drawAtPoint:(current application’s NSMakePoint(origX + (sizeX / 2), sizeY)) withAttributes:aDict)
  end repeat
  
  
anImage’s unlockFocus() –描画ここまで
  
  
return anImage –returns NSImage
end drawImageWithString

–NSImageに対して矩形を塗りつぶす
on drawImageWithColorFill(anImage, drawList, fillColor)
  set retinaF to (NSScreen’s mainScreen()’s backingScaleFactor()) as real
  
–>  2.0 (Retina) / 1.0 (Non Retina)
  
  
anImage’s lockFocus() –描画開始
  
  
repeat with i in drawList
    set v2 to system attribute "sys2"
    
if v2 ≤ 12 then
      –To macOS 10.12.x
      
set origX to (x of origin of i) / retinaF
      
set origY to (y of origin of i) / retinaF
      
set sizeX to (width of |size| of i) / retinaF
      
set sizeY to (height of |size| of i) / retinaF
      
set theRect to {{x:origX, y:origY}, {width:sizeX, height:sizeY}}
    else
      –macOS 10.13 or later
      
set origX to (item 1 of item 1 of i) / retinaF
      
set origY to (item 2 of item 1 of i) / retinaF
      
set sizeX to (item 1 of item 2 of i) / retinaF
      
set sizeY to (item 2 of item 2 of i) / retinaF
      
set theRect to {{origX, origY}, {sizeX, sizeY}}
    end if
    
    
set theNSBezierPath to NSBezierPath’s bezierPath
    (
theNSBezierPath’s appendBezierPathWithRect:theRect)
    
    
fillColor’s |set|() –色設定
    
theNSBezierPath’s fill() –ぬりつぶし
  end repeat
  
  
anImage’s unlockFocus() –描画ここまで
  
  
return anImage –returns NSImage
end drawImageWithColorFill

★Click Here to Open This Script 

Posted in GUI Image list | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSAlert NSAlertSecondButtonReturn NSArray NSBezierPath NSBitmapImageRep NSColor NSDictionary NSFont NSFontAttributeName NSForegroundColorAttributeName NSImage NSImageScaleProportionallyUpOrDown NSImageView NSMutableArray NSRunningApplication NSScreen NSString | Leave a comment

アラートダイアログ上にBrowserを表示

Posted on 3月 2, 2019 by Takaaki Naganoya

アラートダイアログ上にNSBrowserを表示するAppleScriptの試作品です。

# 本Scriptは実験用であって実用性はありません(^ー^;;

Finderに使われていることで認知度は高いものの、使いどころが難しいうえにサンプル・コードも多くないので登場頻度が少ないNSBrowserです。(Mac OS Xの前身である)NEXTSTEPのFile Managerがこんな感じのUIでした。

(個人的に)敷居の高かったNSBrowserも、いろいろ試してみたらいい感じになってきました。現状では単に2次元配列っぽいものにアクセスしているだけですが、ツリー型の構造データを与えるようにするとか、配列から徐々にデータ抽出する(大分類→中分類→小分類)ようにすれば、だいたい期待どおりの動作になるはずです。

NSBrowserも、使いたいときに調べると情報が見つからずに困りますが、用のないときなら調べておくといろいろ大丈夫そうです。

macOS 10.14上のスクリプトエディタ/Script Debugger上で動くようにハンドラをメインスレッド上で明示的に動作させるように変更しましたが、10.14上でだけ独特な挙動があるため要注意です。ただ、テストプログラムなのでそんなものだろうかと。

AppleScript名:アラートダイアログ上にBrowserを表示 v1.1.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2019/03/02
—
–  Copyright © 2019 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

property NSAlert : a reference to current application’s NSAlert
property NSColor : a reference to current application’s NSColor
property NSBrowser : a reference to current application’s NSBrowser
property NSScrollView : a reference to current application’s NSScrollView
property NSMutableArray : a reference to current application’s NSMutableArray
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn

property theResult : 0
property returnCode : 0
property theDataSource : {}

set paramObj to {myMessage:"Choose a data", mySubMessage:"Choose an appropriate data from tree structured data list", aTableList:{{"1", "1.1", "1.1.1"}, {"2", "2.1", "2.1.1"}, {"3", "3.1", "3.1.1"}, {"4", "4.1", "4.1.1"}}}
–set aRes to my chooseItemByBrowser:paramObj
my performSelectorOnMainThread:"chooseItemByBrowser:" withObject:(paramObj) waitUntilDone:true

on chooseItemByBrowser:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aTList to (aTableList of paramObj) as list
  
  
— make browser view with scroll view
  
set aScrollWithTable to makeBrowserView(aTList, 500, 200) of me
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aScrollWithTable
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
end chooseItemByBrowser:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on makeBrowserView(aList as list, aWidth as number, aHeight as number)
  set (my theDataSource) to NSMutableArray’s arrayWithArray:aList
  
  
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
set aView to NSBrowser’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
  
aView’s setDelegate:(me)
  
aView’s setMinColumnWidth:120
  
aView’s setSeparatesColumns:true
  
–aView’s setMaxVisibleColumns:2
  
aView’s setAutohidesScroller:true
  
–aView’s setBackgroundColor:(NSColor’s grayColor())
  
aView’s setReusesColumns:true
  
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasHorizontalScroller:true
  
aView’s enclosingScrollView()’s setHasVerticalScroller:true
  
  
return aScroll
end makeBrowserView

–NSBrowser Event Handlers
on browser:aView numberOfRowsInColumn:aColumn
  set aCount to my theDataSource’s |count|()
  
return aCount
end browser:numberOfRowsInColumn:

on browser:aView willDisplayCell:(aCell) atRow:rowIndex column:colIndex
  set selRow to (my theDataSource)’s objectAtIndex:(rowIndex)
  
set selCol to selRow’s objectAtIndex:(colIndex)
  
aCell’s setTitle:(selCol as string)
  
  
set colMax to ((my theDataSource)’s objectAtIndex:0)’s |count|()
  
log {"colMax, colIndex", colMax, colIndex}
  
set exMax to (colIndex < colMax – 1) as boolean
  
aCell’s setLeaf:(not exMax)
end browser:willDisplayCell:atRow:column:

★Click Here to Open This Script 

Posted in GUI list | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSAlert NSAlertSecondButtonReturn NSBrowser NSColor NSMutableArray NSRunningApplication NSScrollView | Leave a comment

アラートダイアログの背景色を指定してTable Viewを表示

Posted on 2月 25, 2019 by Takaaki Naganoya

指定色のアラートダイアログを作成し、その上にScroll View+Table Viewを表示して選択肢の選択を行うAppleScriptです。

アラートダイアログの背景色変更のテストを行なったものです。また、メソッド名をテキストで(Table Viewから)取得し、そのメソッド名で色を作成するテスト(NSSelectorFromString)も行いました。

Table Viewで選択した色は、次回実行時に反映されます(スクリプトエディタ/Script Debugger上で)。

本当はTable View上で行を選択したときに、アラートダイアログの背景色を変更させたかったのですが、試してみたもののうまく動かなかったので、その機能は削りました。最初から指定色のダイアログウィンドウを表示するだけなら問題はないので、現状のようなコードに落ち着きました。

AppleScript名:アラートダイアログの背景色を指定してTable Viewを表示
— Created 2019-02-25 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSAlert : a reference to current application’s NSAlert
property NSColor : a reference to current application’s NSColor
property NSIndexSet : a reference to current application’s NSIndexSet
property NSScrollView : a reference to current application’s NSScrollView
property NSTableView : a reference to current application’s NSTableView
property NSTableColumn : a reference to current application’s NSTableColumn
property NSMutableArray : a reference to current application’s NSMutableArray
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn
property NSFullSizeContentViewWindowMask : a reference to current application’s NSFullSizeContentViewWindowMask

property theResult : 0
property returnCode : 0
property theDataSource : {}
property theColList : {}
property theWindow : missing value
property selectedColor : missing value

set paramObj to {myMessage:"Choose a color", mySubMessage:"Choose an appropriate color from color name list", aTableList:{"redColor", "blueColor", "yellowColor", "greenColor", "grayColor", "blackColor"}}
set aRes to my chooseItemByTableView:paramObj

on chooseItemByTableView:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aTList to (aTableList of paramObj) as list
  
  
— make table view with scroll view
  
set aScrollWithTable to makeTableView(aTList, 300, 120) of me
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aScrollWithTable
  end tell
  
  
— customize alert’s window style and color
  
if selectedColor = missing value then
    set tmpColor to NSColor’s grayColor()
  else
    set tmpSel to current application’s NSSelectorFromString(selectedColor)
    
set tmpColor to NSColor’s performSelector:tmpSel
  end if
  
  
set theWindow to theAlert’s |window|()
  
theWindow’s setTitleVisibility:false
  
–theWindow’s setStyleMask:( NSFullSizeContentViewWindowMask)
  
theWindow’s setTitlebarAppearsTransparent:true
  
theWindow’s setBackgroundColor:tmpColor
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
  
  
return (aScrollWithTable’s documentView’s selectedRow()) + 1
end chooseItemByTableView:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on makeTableView(aList as list, aWidth as number, aHeight as number)
  set aOffset to 40
  
  
set sourceList to {}
  
repeat with i in aList
    set the end of sourceList to {dataItem:(contents of i)}
  end repeat
  
  
set theDataSource to NSMutableArray’s alloc()’s init()
  
theDataSource’s addObjectsFromArray:sourceList
  
  
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
set aView to NSTableView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
  
  
set aColumn to (NSTableColumn’s alloc()’s initWithIdentifier:"dataItem")
  (
aColumn’s setWidth:aWidth)
  (
aColumn’s headerCell()’s setStringValue:"dataItem")
  (
aView’s addTableColumn:aColumn)
  
  
aView’s setDelegate:me
  
aView’s setDataSource:me
  
aView’s reloadData()
  
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasVerticalScroller:true
  
  
–1行目を選択
  
set aIndexSet to NSIndexSet’s indexSetWithIndex:0
  
aView’s selectRowIndexes:aIndexSet byExtendingSelection:false
  
  
–強制的にトップにスクロール
  
set aDBounds to aScroll’s documentView()’s |bounds|()
  
if class of aDBounds = list then
    –macOS 10.13 or later
    
set maxHeight to item 2 of item 1 of aDBounds
  else
    –macOS 10.10….10.12
    
set maxHeight to height of |size| of aDBounds
  end if
  
  
set aPT to current application’s NSMakePoint(0.0, -40.0) —— (aScroll’s documentView()’s |bounds|()’s |size|()’s height))
  
aScroll’s documentView()’s scrollPoint:aPT
  
  
return aScroll
end makeTableView

–TableView Event Handlers
on numberOfRowsInTableView:aView
  return my theDataSource’s |count|()
end numberOfRowsInTableView:

on tableView:aView objectValueForTableColumn:aColumn row:aRow
  set selRow to (aRow as number)
  
set aRec to (my theDataSource)’s objectAtIndex:selRow
  
set aTitle to (aColumn’s headerCell()’s title()) as string
  
set aRes to (aRec’s valueForKey:aTitle) as string
  
set my selectedColor to aRes
  
  
return aRes
end tableView:objectValueForTableColumn:row:

on tableView:aView shouldEditTableColumn:aTableColumn row:rowIndex
  return false –Not Editable
end tableView:shouldEditTableColumn:row:

★Click Here to Open This Script 

Posted in Color GUI list | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSAlert NSAlertSecondButtonReturn NSColor NSFullSizeContentViewWindowMask NSIndexSet NSMutableArray NSRunningApplication NSScrollView NSTableColumn NSTableView | Leave a comment

アラートダイアログ上にTable View+Map View+Segmented Controlを表示

Posted on 2月 23, 2019 by Takaaki Naganoya

アラートダイアログを作成し、その上にScroll View+Table ViewおよびMap Viewを表示して選択肢の選択を行うAppleScriptです。Segmented Controlで地図の種別切り替えを行い、項目選択用のTable Viewを編集不可にしました。

Map Viewを使用するために、インターネット接続が必要です。地図表示パフォーマンスはインターネット接続速度次第です。


▲Map Type = Standard (Map)


▲Map Type = Satellite


▲Map Type = Hybrid (Satellite + Map)

本Scriptに与える緯度・経度情報についてはあらかじめ住所ジオコーダーによって「住所情報→緯度・経度情報」の変換を行なったものを書いておく必要がありますが、Yahoo!の住所ジオコーダーサービスなどを呼び出せば、住所情報をパラメーターとすることも可能です。

サンプルデータの緯度・経度情報は、例によって「戦場の絆」の入っている近所のゲーセンの情報を適当にみつくろって入れてみたものです。

本ダイアログは、それほど件数の多くない(20件ぐらい?)選択肢からの選択を意図して作ったものですが、数百件とか数千件のデータから選ぶような場合には、Outline Viewを利用して小エリアごとに分割するとか、Search Fieldを連動させてキーワードによる絞り込みを有効にするなど、それなりの対処が必要です。

AppleScript名:アラートダイアログ上にTable View+Map View+Segmented Controlを表示
— Created 2019-02-23 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "MapKit"

property NSAlert : a reference to current application’s NSAlert
property NSIndexSet : a reference to current application’s NSIndexSet
property MKMapView : a reference to current application’s MKMapView
property NSScrollView : a reference to current application’s NSScrollView
property NSTableView : a reference to current application’s NSTableView
property NSTableColumn : a reference to current application’s NSTableColumn
property NSMutableArray : a reference to current application’s NSMutableArray
property MKPointAnnotation : a reference to current application’s MKPointAnnotation
property NSSegmentedControl : a reference to current application’s NSSegmentedControl
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn
property NSSegmentStyleTexturedRounded : a reference to current application’s NSSegmentStyleTexturedRounded

property MKMapTypeHybrid : a reference to current application’s MKMapTypeHybrid
property MKMapTypeSatellite : a reference to current application’s MKMapTypeSatellite
property MKMapTypeStandard : a reference to current application’s MKMapTypeStandard

property zLevel : 21 –Map Zoom Level (0:World View, 21:House/Building Zoom View)
property aMaxViewWidth : 800
property theResult : 0
property returnCode : 0
property theDataSource : {}
property curRow : 0
property aMapView : missing value
property nameL : {}
property placeL : {}

set aPlaceList to {{placeName:"Hey", aLat:"35.69906613", aLong:"139.77084064"}, {placeName:"namco中野", aLat:"35.70859274", aLong:"139.66584339"}, {placeName:"ゲームシティ板橋", aLat:"35.74572771", aLong:"139.67553260"}, {placeName:"ラウンドワンスタジアム板橋", aLat:"35.77661583", aLong:"139.67864491"}, {placeName:"キャロム練馬", aLat:"35.76386421", aLong:"139.66591600"}, {placeName:"アミュージアムOSC", aLat:"35.75308308", aLong:"139.59476696"}}

set paramObj to {myMessage:"場所の選択", mySubMessage:"適切な場所を以下のリストからえらんでください", placeList:aPlaceList}
my performSelectorOnMainThread:"chooseItemByTableViewWithMapAndSegment:" withObject:(paramObj) waitUntilDone:true
if (my theResult) = 0 then error number -128
return (my theResult)

on chooseItemByTableViewWithMapAndSegment:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aTList to (placeList of paramObj) as list
  
  
set nameL to {}
  
set placeL to {}
  
repeat with i in aTList
    set the end of nameL to (placeName of i)
    
set the end of placeL to {contents of (aLat of i), contents of (aLong of i)}
  end repeat
  
  
— create a view
  
set theView to current application’s NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aMaxViewWidth, 400))
  
  
— make table view with scroll view
  
set aScrollWithTable to makeTableView(nameL, 200, 400) of me
  
  
set aMapView to MKMapView’s alloc()’s initWithFrame:(current application’s NSMakeRect(210, 30, aMaxViewWidth – 210, 370))
  
tell aMapView
    its setMapType:MKMapTypeStandard
    
its setZoomEnabled:true
    
its setScrollEnabled:true
    
its setPitchEnabled:true
    
its setRotateEnabled:true
    
its setShowsCompass:true
    
its setShowsZoomControls:true
    
its setShowsScale:true
    
its setShowsUserLocation:true
    
    
set aLocation to current application’s CLLocationCoordinate2DMake((first item of first item of placeL) as real, (second item of first item of placeL) as real)
    
its setCenterCoordinate:aLocation zoomLevel:(zLevel) animated:false
    
its setDelegate:me
  end tell
  
  
–MapにPinを追加
  
repeat with i from 1 to (length of nameL)
    set tmpAdr to contents of item i of nameL
    
copy item i of placeL to {tmpLat, tmpLong}
    
    
set aLocation to current application’s CLLocationCoordinate2DMake(tmpLat as real, tmpLong as real)
    
set anAnnotation to MKPointAnnotation’s alloc()’s init()
    (
anAnnotation’s setCoordinate:aLocation)
    (
anAnnotation’s setTitle:tmpAdr)
    (
aMapView’s addAnnotation:anAnnotation)
  end repeat
  
  
–Segmented Controlをつくる
  
set segTitleList to {"Map", "Satellite", "Satellite + Map"}
  
set aSeg to makeSegmentedControl(segTitleList, 210, 0, 150, 20) of me
  
  
theView’s setSubviews:{aScrollWithTable, aMapView, aSeg}
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:theView
  end tell
  
  
–To enable the first annotation visible
  
copy item 1 of placeL to {tmpLat, tmpLong}
  
set aLocation to current application’s CLLocationCoordinate2DMake(tmpLat as real, tmpLong as real)
  
aMapView’s setCenterCoordinate:aLocation zoomLevel:(zLevel) animated:false
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
  
set (my theResult) to (aScrollWithTable’s documentView’s selectedRow()) + 1
end chooseItemByTableViewWithMapAndSegment:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on makeTableView(aList as list, aWidth as number, aHeight as number)
  set aOffset to 0
  
  
set sourceList to {}
  
repeat with i in aList
    set the end of sourceList to {dataItem:(contents of i)}
  end repeat
  
  
set theDataSource to NSMutableArray’s alloc()’s init()
  
theDataSource’s addObjectsFromArray:sourceList
  
  
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 30, aWidth, aHeight – 30))
  
set aView to NSTableView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 30, aWidth, aHeight – 30))
  
  
  
set aColumn to (NSTableColumn’s alloc()’s initWithIdentifier:"dataItem")
  (
aColumn’s setWidth:aWidth)
  (
aColumn’s headerCell()’s setStringValue:"dataItem")
  (
aView’s addTableColumn:aColumn)
  
  
aView’s setDelegate:me
  
aView’s setDataSource:me
  
aView’s reloadData()
  
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasVerticalScroller:true
  
  
–1行目を選択
  
set aIndexSet to NSIndexSet’s indexSetWithIndex:0
  
aView’s selectRowIndexes:aIndexSet byExtendingSelection:false
  
  
–強制的にトップにスクロール
  
set aDBounds to aScroll’s documentView()’s |bounds|()
  
if class of aDBounds = list then
    –macOS 10.13 or later
    
set maxHeight to item 2 of item 1 of aDBounds
  else
    –macOS 10.10, 10.11, 10.12
    
set maxHeight to height of |size| of aDBounds
  end if
  
  
set aPT to current application’s NSMakePoint(0.0, -40.0) —— (aScroll’s documentView()’s |bounds|()’s |size|()’s height))
  
aScroll’s documentView()’s scrollPoint:aPT
  
  
return aScroll
end makeTableView

–TableView Event Handlers
on numberOfRowsInTableView:aView
  return my theDataSource’s |count|()
end numberOfRowsInTableView:

on tableView:aView objectValueForTableColumn:aColumn row:aRow
  set (tmpRow) to aView’s selectedRow() as number
  
  
–Table View上で現在選択行「以外の」行が選択されたら、Mapを選択項目で更新
  
if (my curRow) is not equal to tmpRow then
    set tmpLat to (first item of item (tmpRow + 1) of placeL) as real
    
set tmpLong to (second item of item (tmpRow + 1) of placeL) as real
    
    
tell aMapView
      set aLocation to current application’s CLLocationCoordinate2DMake(tmpLat, tmpLong)
      
its setCenterCoordinate:aLocation zoomLevel:(zLevel) animated:false
    end tell
    
    
set (my curRow) to tmpRow
  end if
  
  
set aRec to (my theDataSource)’s objectAtIndex:(aRow as number)
  
set aTitle to (aColumn’s headerCell()’s title()) as string
  
set aRes to (aRec’s valueForKey:aTitle)
  
return aRes
end tableView:objectValueForTableColumn:row:

on tableView:aView shouldEditTableColumn:aTableColumn row:rowIndex
  return false –Not Editable
end tableView:shouldEditTableColumn:row:

–Segmented Controlをつくる
on makeSegmentedControl(titleList, startX, startY, aWidth, aHeight)
  set aLen to length of titleList
  
  
set aSeg to NSSegmentedControl’s alloc()’s init()
  
aSeg’s setSegmentCount:aLen
  
  
set aCount to 0
  
repeat with i in titleList
    set j to contents of i
    (
aSeg’s setLabel:j forSegment:aCount)
    
set aCount to aCount + 1
  end repeat
  
  
aSeg’s setTranslatesAutoresizingMaskIntoConstraints:false
  
aSeg’s setSegmentStyle:(NSSegmentStyleTexturedRounded)
  
aSeg’s setFrame:(current application’s NSMakeRect(startX, startY, aWidth, aHeight))
  
aSeg’s setTrackingMode:0
  
aSeg’s setTarget:me
  
aSeg’s setAction:"clickedSeg:"
  
aSeg’s setSelectedSegment:0
  
  
return aSeg
end makeSegmentedControl

–Segmented Controlのクリック時のイベントハンドラ
on clickedSeg:aSender
  set aSel to aSender’s selectedSegment()
  
set tList to {MKMapTypeStandard, MKMapTypeSatellite, MKMapTypeHybrid}
  
set tmpType to contents of item (aSel + 1) of tList
  
  
aMapView’s setMapType:(tmpType)
  
  
set selSeg to aSel
end clickedSeg:

★Click Here to Open This Script 

Posted in geolocation GUI | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy MKMapView MKPointAnnotation NSAlert NSAlertSecondButtonReturn NSIndexSet NSMutableArray NSRunningApplication NSScrollView NSSegmentedControl NSSegmentStyleTexturedRounded NSTableColumn NSTableView | Leave a comment

アラートダイアログ上にTable View+Map Viewを表示

Posted on 2月 22, 2019 by Takaaki Naganoya

アラートダイアログを作成し、その上にScroll View+Table ViewおよびMap Viewを表示して選択肢の選択を行うAppleScriptです。

Map Viewを使用するために、インターネット接続が必要です。地図表示パフォーマンスはインターネット接続速度次第です。

{{placeName:"Hey", aLat:"35.69906613", aLong:"139.77084064"}....}

のように位置データを、

名称, 緯度, 経度

とまとめたリストで選択肢を指定します。実行すると選択肢のアイテム番号(1からはじまる)を返してきます。


▲左から、macOS 10.12.6、10.13.6、10.14.4betaで同じAppleScriptを動かしたところ。同じ場所、同じZoom LevelでもOSバージョンごとに微妙に表示内容が違う

現状の実装では、表UI(Table View)内のデータがダブルクリックで編集できてしまうので、編集できないようにするあたりが改良対象でしょうか。あと、地図・衛星写真の切り替えもつけておくとよいでしょう。

本Scriptに与える緯度・経度情報についてはあらかじめ住所ジオコーダーによって「住所情報→緯度・経度情報」の変換を行なったものを書いておく必要がありますが、Yahoo!の住所ジオコーダーサービスなどを呼び出せば、住所情報をパラメーターとすることも可能です。

サンプルデータの緯度・経度情報は、例によって「戦場の絆」の入っている近所のゲーセンの情報を適当にみつくろって入れてみたものです。

AppleScript名:アラートダイアログ上にTable View+Map Viewを表示 v2
— Created 2019-02-22 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "MapKit"

property NSAlert : a reference to current application’s NSAlert
property NSIndexSet : a reference to current application’s NSIndexSet
property MKMapView : a reference to current application’s MKMapView
property NSScrollView : a reference to current application’s NSScrollView
property NSTableView : a reference to current application’s NSTableView
property NSTableColumn : a reference to current application’s NSTableColumn
property NSMutableArray : a reference to current application’s NSMutableArray
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn

property zLevel : 18
property aMaxViewWidth : 800
property theResult : 0
property returnCode : 0
property theDataSource : {}
property curRow : 0
property aMapView : missing value
property nameL : {}
property placeL : {}

set aPlaceList to {{placeName:"Hey", aLat:"35.69906613", aLong:"139.77084064"}, {placeName:"namco中野", aLat:"35.70859274", aLong:"139.66584339"}, {placeName:"ゲームシティ板橋", aLat:"35.74572771", aLong:"139.67553260"}, {placeName:"ラウンドワンスタジアム板橋", aLat:"35.77661583", aLong:"139.67864491"}, {placeName:"キャロム練馬", aLat:"35.76386421", aLong:"139.66591600"}, {placeName:"アミュージアムOSC", aLat:"35.75308308", aLong:"139.59476696"}}

set paramObj to {myMessage:"場所の選択", mySubMessage:"適切な場所を以下のリストからえらんでください", placeList:aPlaceList}
my performSelectorOnMainThread:"chooseItemByTableViewWithMap:" withObject:(paramObj) waitUntilDone:true
return (my theResult)

on chooseItemByTableViewWithMap:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aTList to (placeList of paramObj) as list
  
  
set nameL to {}
  
set placeL to {}
  
repeat with i in aTList
    set the end of nameL to (placeName of i)
    
set the end of placeL to {contents of (aLat of i), contents of (aLong of i)}
  end repeat
  
  
— create a view
  
set theView to current application’s NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aMaxViewWidth, 400))
  
  
— make table view with scroll view
  
set aScrollWithTable to makeTableView(nameL, 200, 400) of me
  
  
set aMapView to MKMapView’s alloc()’s initWithFrame:(current application’s NSMakeRect(210, 0, aMaxViewWidth – 210, 400))
  
tell aMapView
    its setMapType:(current application’s MKMapTypeStandard)
    
its setZoomEnabled:true
    
its setScrollEnabled:true
    
its setPitchEnabled:true
    
its setRotateEnabled:true
    
its setShowsCompass:true
    
its setShowsZoomControls:true
    
its setShowsScale:true
    
its setShowsUserLocation:true
    
    
set aLocation to current application’s CLLocationCoordinate2DMake((first item of first item of placeL) as real, (second item of first item of placeL) as real)
    
    
its setCenterCoordinate:aLocation zoomLevel:(zLevel) animated:false
    
its setDelegate:me
  end tell
  
  
theView’s setSubviews:{aScrollWithTable, aMapView}
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:theView
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
  
  
set (my theResult) to (aScrollWithTable’s documentView’s selectedRow()) + 1
end chooseItemByTableViewWithMap:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on makeTableView(aList as list, aWidth as number, aHeight as number)
  set aOffset to 0
  
  
set sourceList to {}
  
repeat with i in aList
    set the end of sourceList to {dataItem:(contents of i)}
  end repeat
  
  
set theDataSource to NSMutableArray’s alloc()’s init()
  
theDataSource’s addObjectsFromArray:sourceList
  
  
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
set aView to NSTableView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
  
  
set aColumn to (NSTableColumn’s alloc()’s initWithIdentifier:"dataItem")
  (
aColumn’s setWidth:aWidth)
  (
aColumn’s headerCell()’s setStringValue:"dataItem")
  (
aView’s addTableColumn:aColumn)
  
  
aView’s setDelegate:me
  
aView’s setDataSource:me
  
aView’s reloadData()
  
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasVerticalScroller:true
  
  
–1行目を選択
  
set aIndexSet to NSIndexSet’s indexSetWithIndex:0
  
aView’s selectRowIndexes:aIndexSet byExtendingSelection:false
  
  
–強制的にトップにスクロール
  
–強制的にトップにスクロール
  
–set maxHeight to aScroll’s documentView()’s |bounds|()’s |size|()’s height
  
set aDBounds to aScroll’s documentView()’s |bounds|()
  
if class of aDBounds = list then
    –macOS 10.13 or later
    
set maxHeight to item 2 of item 1 of aDBounds
  else
    –macOS 10.10….10.12
    
set maxHeight to height of |size| of aDBounds
  end if
  
  
set aPT to current application’s NSMakePoint(0.0, -40.0) —— (aScroll’s documentView()’s |bounds|()’s |size|()’s height))
  
aScroll’s documentView()’s scrollPoint:aPT
  
  
return aScroll
end makeTableView

–TableView Event Handlers
on numberOfRowsInTableView:aView
  return my theDataSource’s |count|()
end numberOfRowsInTableView:

on tableView:aView objectValueForTableColumn:aColumn row:aRow
  set (tmpRow) to aView’s selectedRow() as number
  
  
–Table View上で現在選択行「以外の」行が選択されたら、Mapを選択項目で更新
  
if (my curRow) is not equal to tmpRow then
    set tmpLat to (first item of item (tmpRow + 1) of placeL) as real
    
set tmpLong to (second item of item (tmpRow + 1) of placeL) as real
    
    
tell aMapView
      set aLocation to current application’s CLLocationCoordinate2DMake(tmpLat, tmpLong)
      
its setCenterCoordinate:aLocation zoomLevel:(zLevel) animated:false
    end tell
    
    
set (my curRow) to tmpRow
  end if
  
  
set aRec to (my theDataSource)’s objectAtIndex:(aRow as number)
  
set aTitle to (aColumn’s headerCell()’s title()) as string
  
set aRes to (aRec’s valueForKey:aTitle)
  
return aRes
end tableView:objectValueForTableColumn:row:

★Click Here to Open This Script 

Posted in geolocation GUI list | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy MKMapView NSAlert NSAlertSecondButtonReturn NSIndexSet NSMutableArray NSRunningApplication NSScrollView NSTableColumn NSTableView | Leave a comment

アラートダイアログ上にTable Viewを表示

Posted on 2月 22, 2019 by Takaaki Naganoya

アラートダイアログを作成し、その上にScroll View+Table Viewを表示して選択肢の選択を行うAppleScriptです。

1D List(1次元配列)を与え、選択を行うUIです。実行すると選択肢のアイテム番号(1からはじまる)を返してきます。

とくにこれが作りたかったのではなく、位置情報(Geo Location)の選択をTable Viewで行い、該当する場所をMap Viewに表示させると擬似的に複数の固定位置情報から任意のものを選択させるダイアログが作れるだろうかと思って作成した試作品です。

東京への引っ越しの荷物が到着して、ようやく検証用のサブマシンが届いたものの、ネットワークを新規敷設しなくてはならないのでぼちぼちです。

AppleScript名:アラートダイアログ上にTable Viewを表示 v3
— Created 2019-02-21 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSAlert : a reference to current application’s NSAlert
property NSIndexSet : a reference to current application’s NSIndexSet
property NSScrollView : a reference to current application’s NSScrollView
property NSTableView : a reference to current application’s NSTableView
property NSTableColumn : a reference to current application’s NSTableColumn
property NSMutableArray : a reference to current application’s NSMutableArray
property NSRunningApplication : a reference to current application’s NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn

property theResult : 0
property returnCode : 0
property theDataSource : {}

set paramObj to {myMessage:"項目の選択", mySubMessage:"適切なものを以下からえらんでください", aTableList:{"なし", "りんご", "ひよこ", "ぎょうざ", "すなぎも", "ぼんじり", "もも"}}
set aRes to my chooseItemByTableView:paramObj

on chooseItemByTableView:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aTList to (aTableList of paramObj) as list
  
  
–define the matrix size where you’ll put the radio buttons
  
set aScrollWithTable to makeTableView(aTList, 300, 150) of me
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aScrollWithTable
  end tell
  
  
— show alert in modal loop
  
NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
  
  
return (aScrollWithTable’s documentView’s selectedRow()) + 1
end chooseItemByTableView:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

on makeTableView(aList as list, aWidth as number, aHeight as number)
  set aOffset to 40
  
  
set sourceList to {}
  
repeat with i in aList
    set the end of sourceList to {dataItem:(contents of i)}
  end repeat
  
  
set theDataSource to NSMutableArray’s alloc()’s init()
  
theDataSource’s addObjectsFromArray:sourceList
  
  
set aScroll to NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
set aView to NSTableView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, aOffset, aWidth, aHeight))
  
  
  
set aColumn to (NSTableColumn’s alloc()’s initWithIdentifier:"dataItem")
  (
aColumn’s setWidth:aWidth)
  (
aColumn’s headerCell()’s setStringValue:"dataItem")
  (
aView’s addTableColumn:aColumn)
  
  
aView’s setDelegate:me
  
aView’s setDataSource:me
  
aView’s reloadData()
  
  
aScroll’s setDocumentView:aView
  
aView’s enclosingScrollView()’s setHasVerticalScroller:true
  
  
–1行目を選択
  
set aIndexSet to NSIndexSet’s indexSetWithIndex:0
  
aView’s selectRowIndexes:aIndexSet byExtendingSelection:false
  
  
–強制的にトップにスクロール
  
–set maxHeight to aScroll’s documentView()’s |bounds|()’s |size|()’s height
  
set aDBounds to aScroll’s documentView()’s |bounds|()
  
if class of aDBounds = list then
    –macOS 10.13 or later
    
set maxHeight to item 2 of item 1 of aDBounds
  else
    –macOS 10.10….10.12
    
set maxHeight to height of |size| of aDBounds
  end if
  
  
set aPT to current application’s NSMakePoint(0.0, -40.0) —— (aScroll’s documentView()’s |bounds|()’s |size|()’s height))
  
aScroll’s documentView()’s scrollPoint:aPT
  
  
return aScroll
end makeTableView

–TableView Event Handlers
on numberOfRowsInTableView:aView
  return my theDataSource’s |count|()
end numberOfRowsInTableView:

on tableView:aView objectValueForTableColumn:aColumn row:aRow
  set aRec to (my theDataSource)’s objectAtIndex:(aRow as number)
  
set aTitle to (aColumn’s headerCell()’s title()) as string
  
set aRes to (aRec’s valueForKey:aTitle)
  
return aRes
end tableView:objectValueForTableColumn:row:

★Click Here to Open This Script 

Posted in GUI list | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy NSAlert NSAlertSecondButtonReturn NSIndexSet NSMutableArray NSRunningApplication NSScrollView NSTableColumn NSTableView | 1 Comment

アラートダイアログ上にRadio Buttonを表示

Posted on 2月 19, 2019 by Takaaki Naganoya

アラートダイアログを作成し、その上にRadio Buttonを表示して位置座標の選択を行うAppleScriptです。

任意の選択肢をlist(配列)で指定すると、その通りのRadio Buttonを表示します。ユーザーが選択した項目のtitle文字列を返します。項目番号ではありません。

AppleScript名:アラートダイアログ上にRadio Buttonを表示 v2
— Created 2019-02-14 by Takaaki Naganoya
— 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSAlert : a reference to current application’s NSAlert
property NSMatrix : a reference to current application’s NSMatrix
property NSButtonCell : a reference to current application’s NSButtonCell
property NSRadioButton : a reference to current application’s NSRadioButton
property NSRadioModeMatrix : a reference to current application’s NSRadioModeMatrix
property NSAlertSecondButtonReturn : a reference to current application’s NSAlertSecondButtonReturn

property theResult : 0
property returnCode : 0

set paramObj to {myMessage:"項目の選択", mySubMessage:"適切なものを以下からえらんでください", matrixTitleList:{"なし", "りんご", "ひよこ", "ぎょうざ", "すなぎも", "ぼんじり", "もも"}}
set aRes to my chooseItemByRadioButton:paramObj

on chooseItemByRadioButton:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
set aMatList to (matrixTitleList of paramObj) as list
  
set aLen to length of aMatList
  
  
–create the radio button prototype
  
set aProto to NSButtonCell’s alloc()’s init()
  
aProto’s setTitle:"Options"
  
aProto’s setButtonType:(NSRadioButton)
  
  
–define the matrix size where you’ll put the radio buttons
  
set matrixRect to current application’s NSMakeRect(20.0, 20.0, 200.0, (20.0 * aLen))
  
set aMatrix to NSMatrix’s alloc()’s initWithFrame:matrixRect mode:(NSRadioModeMatrix) prototype:aProto numberOfRows:(aLen) numberOfColumns:1
  
  
set cellList to aMatrix’s cells()
  
set aCount to 0
  
repeat with i in aMatList
    set j to contents of i
    ((
cellList’s objectAtIndex:aCount)’s setTitle:j)
    
set aCount to aCount + 1
  end repeat
  
  
— set up alert  
  
set theAlert to NSAlert’s alloc()’s init()
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:aMatrix
  end tell
  
  
— show alert in modal loop
  
current application’s NSRunningApplication’s currentApplication()’s activateWithOptions:0
  
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
  
if (my returnCode as number) = 1001 then error number -128
  
  
return (aMatrix’s selectedCell()’s title()) as string
end chooseItemByRadioButton:

on doModal:aParam
  set (my returnCode) to aParam’s runModal()
end doModal:

★Click Here to Open This Script 

Posted in dialog GUI list | Tagged 10.11savvy 10.12savvy 10.13savvy NSAlert NSAlertSecondButtonReturn NSButtonCell NSMatrix NSRadioButton NSRadioModeMatrix | Leave a comment

Keynoteの最前面のドキュメントの現在のスライドに指定月の日曜日はじまりカレンダーを表で作成

Posted on 2月 14, 2019 by Takaaki Naganoya

Keynoteの最前面の書類の現在選択中のスライド(ページ)に、指定月の日曜日はじまりカレンダーを、表オブジェクトで作成するAppleScriptです。

Keynoteで資料を作成していると、資料にカレンダーを入れたいケースが多々あります。Terminal.appを起動してcalコマンドでカレンダーを作ってみたり、Dashboardのカレンダーをコピーして入れることも多いですが、Dashboardはもうあるんだかないんだ分からない状態。かわりのものを用意してみました。

あとは、サイズやスタイル、土日のデータを削除するなど用途に応じて編集して表カレンダーを利用するとよいでしょう。

macOS標準装備のスクリプトメニューに入れて呼び出す場合には、アプリケーション形式で書き出したものを使う必要があります。

世の中のカレンダーは日曜日はじまりだけではないので、月曜日はじまりなど、その国、その現場ごとのルールに合わせて変更することが重要です。曜日名についても、実行中のユーザーの言語環境から取得して入れることも可能なので、そのようにしてもよいでしょう。

同じぐらいのスペックのマシンで本Scriptを動かすと、macOS 10.14, Mojave上では10.12.6上の(Keynote v8.1の)倍ぐらい速くて驚かされます。10.13.6上でも同様なのでOS側の対応というよりは、Keynote側のバージョンアップ(v8.1 –> v8.3)によるものかもしれません。

AppleScript名:指定月の日曜日はじまりカレンダーを表で作成 v2.scptd
— Created 2019-02-14 by Takaaki Naganoya
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property theDate : missing value

property daysList : {"日", "月", "火", "水", "木", "金", "土"} –Japanese
–property daysList : {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}–English

set paramObj to {myMessage:"月選択", mySubMessage:"作成対象の月を選択してください。日付はどれでもけっこうです。"}
set {targYear, targMonth} to chooseMonth(paramObj) of me

–指定月のカレンダーを1D List(7 days x 6 weeks) で作成
set aCalList to retListCalendar(targYear, targMonth) of me

set fullCalList to daysList & aCalList

set aTitle to (targYear as string) & (targMonth as string)
set dCount to 1

tell application "Keynote"
  tell front document
    tell current slide
      set aTable to make new table with properties {header column count:0, header row count:1, row count:7, column count:7, name:aTitle}
      
tell aTable
        repeat with i from 1 to 49
          tell cell i
            ignoring application responses
              set value to contents of item dCount of fullCalList
            end ignoring
          end tell
          
set dCount to dCount + 1
        end repeat
      end tell
    end tell
  end tell
end tell

–カレンダー作成対象の年、月を選択(ただし、日付をクリックして選択しないと値を取得できないので注意)
on chooseMonth(paramObj)
  my performSelectorOnMainThread:"chooseDate:" withObject:(paramObj) waitUntilDone:true
  
set aYear to year of theDate
  
set aMonth to month of theDate as number
  
return {aYear, aMonth}
end chooseMonth

on chooseDate:paramObj
  set aMainMes to myMessage of paramObj
  
set aSubMes to mySubMessage of paramObj
  
  
— create a view
  
set theView to current application’s NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 100, 200))
  
set datePicker to current application’s NSDatePicker’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, 100, 100))
  
datePicker’s setDatePickerStyle:(current application’s NSClockAndCalendarDatePickerStyle)
  
datePicker’s setDatePickerElements:((current application’s NSYearMonthDayDatePickerElementFlag) + (current application’s NSHourMinuteSecondDatePickerElementFlag as integer))
  
  
datePicker’s setDateValue:(current application’s NSDate’s |date|())
  
  
set theSize to datePicker’s fittingSize()
  
  
theView’s setFrameSize:theSize
  
datePicker’s setFrameSize:theSize
  
  
theView’s setSubviews:{datePicker}
  
  
set theAlert to current application’s NSAlert’s alloc()’s init()
  
  
— set up alert
  
tell theAlert
    its setMessageText:aMainMes
    
its setInformativeText:aSubMes
    
its addButtonWithTitle:"OK"
    
its addButtonWithTitle:"Cancel"
    
its setAccessoryView:theView
  end tell
  
  
— show alert in modal loop
  
set returnCode to theAlert’s runModal()
  
if returnCode = (current application’s NSAlertSecondButtonReturn) then error number -128
  
  
— retrieve date
  
set (my theDate) to (datePicker’s dateValue()) as date
  
end chooseDate:

–指定月のカレンダーを1D List(7 days x 6 weeks) で返す
on retListCalendar(tYear, tMonth)
  set mLen to getMlen(tYear, tMonth) of me
  
set aList to {}
  
  
set fDat to getDateInternational(tYear, tMonth, 1) of me
  
tell current application
    set aOffset to (weekday of fDat) as number
  end tell
  
  
–header gap
  
repeat (aOffset – 1) times
    set the end of aList to ""
  end repeat
  
  
–calendar body
  
repeat with i from 1 to mLen
    set the end of aList to (i as string)
  end repeat
  
  
–footer gap
  
repeat (42 – aOffset – mLen + 1) times
    set the end of aList to ""
  end repeat
  
  
return aList
end retListCalendar

–現在のカレンダーで指定年月の日数を返す(国際化対応版)
on getMlen(aYear as integer, aMonth as integer)
  set theNSCalendar to current application’s NSCalendar’s currentCalendar()
  
set theDate to theNSCalendar’s dateWithEra:1 |year|:aYear |month|:aMonth |day|:1 hour:0 minute:0 |second|:0 nanosecond:0
  
set theResult to theNSCalendar’s rangeOfUnit:(current application’s NSDayCalendarUnit) inUnit:(current application’s NSMonthCalendarUnit) forDate:theDate
  
return |length| of theResult
end getMlen

–現在のカレンダーで指定年月のdate objectを返す
on getDateInternational(aYear, aMonth, aDay)
  set theNSCalendar to current application’s NSCalendar’s currentCalendar()
  
set theDate to theNSCalendar’s dateWithEra:1 |year|:aYear |month|:aMonth |day|:aDay hour:0 minute:0 |second|:0 nanosecond:0
  
return theDate as date
end getDateInternational

★Click Here to Open This Script 

Posted in Calendar GUI list | Tagged 10.11savvy 10.12savvy 10.13savvy 10.14savvy Keynote NSAlert NSAlertSecondButtonReturn NSCalendar NSClockAndCalendarDatePickerStyle NSDate NSDatePicker NSDayCalendarUnit NSHourMinuteSecondDatePickerElementFlag NSMonthCalendarUnit NSView NSYearMonthDayDatePickerElementFlag | 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