MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

プログラマーに興味がある方なら誰でも入会いただけます。
MOSA Multi-OS Software Artists
===SINCE 1995===

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSADenバックナンバー 2007年2月発行分

  • MOSA Developer News[MOSADeN=モサ伝]第241号

    2007-02-27 

    目次

    • 「Wonderful Server Life」       第39回  田畑 英和
    • 藤本裕之のプログラミング夜話   #109
    • 高橋真人の「プログラミング指南」  第107回
    • ニュース・解説                小池 邦人

    「Wonderful Server Life」  第39回  田畑 英和

    ■  〜アクセス権編〜

     アクセス権の解説は今回でひとまず区切りをつけますが、最後にアクセス権の管理と密接な関係にあるユーザ認証についてお話しておきましょう。ちなみにユーザ認証は英語で”Authentication”、アクセス権の判定は”Authorization”と呼ばれています。
     よく似た単語ではありますが、これらの処理はそれぞれ独立した異なる処理になっています。ユーザ認証(Authentication)は、ユーザ名やパスワードなどの情報に基づいてシステムを使用するユーザを認証する処理、アクセス権の判定(Authorization)は、ユーザ認証によって特定されたアカウントがシステム上でアクセス可能なリソースを判定する処理になります。
     つまりアクセス権の判定を行うにはあらかじめユーザ認証がおこなわれ、アカウントが特定されている必要があります。

    ◇ユーザ認証
     では、ユーザ認証がどのようにして行われるかをみてみましょう。ユーザ認証の代表な例としては、ログインウインドウでの認証があります。ログインウインドウでは、ログインするユーザの「名前」と「パスワード」を入力することにより認証を行います。つまり「名前」を使ってシステム上に存在するアカウントを特定するわけです。
     アカウントを登録するときには、「名前」のほかに「ユーザ名」の登録も行いますがログインウインドウでは「名前」だけではなく「ユーザ名」を使って認証を行うこともできます。つまり「名前」もしくは「ユーザ名」が分ればアカウントを特定することができるわけです。ではここでアカウントの「名前」と「ユーザ名」の仕様を再確認しておきましょう。それぞれ以下のような仕様になっています。

    ・名前
      最大長は255byte、ロングネームとも呼ばれる
      1byte文字の場合は255文字、3byte文字の場合は85文字まで
      フォーマット:UTF-8
    ・ユーザ名
      最大長は255byte、ショートネームとも呼ばれる
      最大16個登録可能(最低1つは必要)
      1つ目のフォーマット:A〜Z、a〜z、0〜9、_、-
      2つ目以降のフォーマット:UTF-8

     「名前」は1ユーザにつき1つのみ設定可能です。一方「ユーザ名」は、1ユーザにつき複数登録することが可能です。Mac OS Xのログインウインドウには「名前」と表示されていますので、ログイン時にいつも「名前」を入力している方をときどきみかけますが、「ユーザ名」を使ってもユーザの認証を行うことができます。一般的に「名前」にはフルネームで日本語を入力することが多いかと思いますので、ログインには英数字(および一部の記号)で構成される「ユーザ名」を使ったほうが便利でしょう。

    ◇アクセス権の判定
     「名前」または「ユーザ名」と、「パスワード」を使ってユーザ認証に成功したとしましょう。そうするとシステムを使用中のユーザが特定できたことになります。
     ユーザが特定できれば、あらかじめ設定しておいたアクセス権の情報に基づいて、ファイルやフォルダへのアクセスが制御されます。ファイルやフォルダにはオーナーやグループが設定されていますが、「ターミナル」、「ワークグループマネージャ」、「Finder」でオーナーを確認すると、オーナーは「ユーザ名」や「名前」で表示されます。
     ですが、POSIXのアクセス権を使用する場合、オーナーは内部的にはユーザID(UID)を使って管理されています。UIDはユーザ登録時に自動的に割り当てられ、idコマンドを使って簡単に調べることができます。UIDは次のような仕様になっています。

    ・UID
      500〜2,147,483,648の数値、100未満はシステム用に予約
      フォーマット:32ビットの数値
    


     UIDは単純な数値ですので、マシンが異なれば別ユーザに対して重複したUIDが割り当てられる場合があります。つまり「ユーザ名」や「名前」が違っていたとしても、マシン間でUIDが重複する場合があり、UIDが重複していればアクセス権が正しく守られないケースが出てきます。
     もちろんディレクトリサービスを利用してユーザをサーバ上で一元管理すれば、ユーザIDも一元管理することができます。しかしそれでもサーバ上のユーザとローカルマシン上のユーザとでユーザIDが重複することまでは防げません。

     一方、ACLのアクセス権を使用した場合にはUIDではなく、GloballyUniqueIdentifier(GUID)が使用されます。GUIDはMACアドレスとユーザを作成した日時に基づいて作成される128bitの文字列であり、マシンが異なってもユニークなIDが発行されるようになっています。ですのでUIDよりもGUIDを使ったほうが、ユーザを厳密に特定することができます。

    ・GUIDの一例
    EB95D2CE-EBE3-12D8-9CD4-010391C630B0

    つづく                               

    藤本裕之のプログラミング夜話 #109

     ご存知の方もいると思うが、「Yの悲劇」などで有名なアメリカの推理作家、エラリー・クイーンのいくつかの小説には「読者への挑戦状」というのが出てくる。「ここまでで事件の犯人を特定するために探偵が使う手がかりはすべて読者に提示されている。だから我と思わん読者は論理的に犯人を推定してみたまえ」というのだ。かっこいいねぇ。
     で、オレも「読者への挑戦状」というのをやってみようと思った。いやべつにこの連載で突然推理小説を書き始めようってんぢゃなくて、「いままで何ヶ月間かかけてCocoaにおけるドラッグ&ドロップの実現方法をみてきたわけだが、ほんぢゃこういう場合はどうやるのだろう、わかるかねアケチ君、ふはははは」というのを書こうと目論んだわけだ。

     Mac OS X 10.3以降の Cocoa には ObjectController のクラスが各種用意され、バインディングという技術を使うことで従来よりモデルとコントローラに関わるコーディングを大幅に減らせるようになった。オレも全部使ってみたわけぢゃないが、シェアウエアとして公開した xRadio (http://xemem.com からダウンロードできます、どうぞよろしく)では NSArrayController を使ってる。
     手順は簡単だ。Interface Builderのパレットから NSArrayControllerをドラッグしてきてインスタンシエイトし、こいつにモデルである Array をバインドする。具体的にはインスペクタのポップアップメニューから「Bindings」を選び、上から2番目「Controller Content」のところの「contentArray」に、そのArrayを参照するアクセスパス(どのオブジェクトにどんなメッセージを送ればその Array を獲得できるか)を記載する。これでArrayに対するアクションメソッド、insert: とかremove: 、fetch: などが使える。
     次にこれをビューにつなげる。まず、NSArrayControllerの「Attribute」インスペクタで、このArrayのメンバのクラス名を入力し(やってみるだけならNSDictionaryをお勧めする。簡単だから)、適当なキーを設定する。例えば「testData」にしますか。これがどういう意味かというと、Array の各メンバに対して objectForKey:@”testData” というメッセージを送ればなんか nil以外の値が返ってくるということね。そしたら新たに NSTableView を作り、NSTableColumn のインスペクタから「Bindings」を選ぶ。一番上の「Value」のところで上の NSArrayController へのバインドを設定、Model Key Path には当然 「testData」を指定する。ここまでやったら、contentArray として例
    えば下のような Array を用意しよう。

    NSMutableArray*     contentArray = [[NSMutableArray alloc] initWithObjects:
         [NSDictionary dictionaryWithObject:@"AppleScript"forKey:@"testData"],
         [NSDictionary dictionaryWithObject:@"Audio" forKey:@"testData"],
         [NSDictionary dictionaryWithObject:@"Carbon" forKey:@"testData"],
         [NSDictionary dictionaryWithObject:@"Cocoa" forKey:@"testData"],
         [NSDictionary dictionaryWithObject:@"Darwin" forKey:@"testData"],
         [NSDictionary dictionaryWithObject:@"Games" forKey:@"testData"],
         [NSDictionary dictionaryWithObject:@"Tools" forKey:@"testData"], nil];

     NSArrayController からの要求に応じてこれを返すようにしておくだけであら不思議、従来 NSTableDataSource Protocol に従って一所懸命書いてたコードのほとんどが不要になっちゃう。あんまり楽過ぎてだまされたみたいである。バインディング万歳。
     ところが問題はこっからなのだ。このやり方をするとこの NSTableView のdataSource アウトレットはnil のまま(嘘だと思ったら確かめてくれ)。なので、NSTableDataSource Protocol の一部であった TableView に関するドラッグ&ドロップのメッセージはどこにも来ない。つまり、前回までオレが解説したTableView 上のドラッグ&ドロップ・コードは使えない。ではどうするか。……これが「読者への挑戦状」である。

     と、言えたら良かったんだけどねぇ(笑)。
     白状すると、これを「挑戦状」とするべく一所懸命解決案を探したのだが見つからなかったのだ。どうも今のところ「オブジェクト・バインディングを使ってArrayの中身をテーブルに表示している場合、そのテープルのメンバに対するドラッグ&ドロップをサポートするのはとってもめんどくさい(NSTableView をサブクラスして、NSView上でのドラッグ&ドロップのように書けばできるんぢゃないかと思う。とっても面倒そうなのでやってみてないけど)ということらしい。「挑戦状」は撤回して「お知恵拝借」にするので、こうすればできるぢゃん、という人がいたらメールください。さて、次回からの
    ネタを考えなくちゃ。
                                (2007_02_22)

    高橋真人の「プログラミング指南」第107回

    プログラマのためのオブジェクト指向再入門(15)

    〜GUIアプリの基本構造(1)・イベントループ〜

     こんにちは、高橋真人です。
     前回からの続きですが、これからPowerPlant Xというアプリケーションフレームワークを借りて、オブジェクト指向と非オブジェクト指向の実装の違いについて見ていきます。ただ、PowerPlant Xを持ち出すからと言って、ここでPowerPlant Xの使い方についての解説を展開しようなどという大それたことを考えているわけではありません。それから、PowerPlant Xという「Carbon用のフレームワーク」を例に使うからと言ってCocoaを無視しようと考えているわけでもありません。
     むしろ私としてはCocoaに取り組み始めた、またはこれから取り組もうとしている人にも是非ともこれからの解説記事を読んでほしいと思っているのです。Cocoaはオブジェクト指向の技術を利用した優れた開発環境です。開発効率も柔軟性も、既存のオブジェクト指向開発環境の中でもトップクラスに位置するのではないかとすら思っています。その昔「使って天国、作って地獄」などと言われていたGUIアプリケーションを「気軽に構築できる」ようにしたその貢献度はかなりのものでしょう。
     しかし同時に、その気軽さゆえにCocoa自体に対しても気軽に取り組もうとする人が多い気がします。気軽に取り組むこと自体は必ずしも悪いことではないとは思いますが、せっかくCocoaという優れた開発環境を使えるのだから、見よう見まねで表面的に真似るのではなく、Cocoaの持つ真のパワーを可能な限り引き出してほしいと思うのです。そのためにはやはりどうしてもオブジェクト指向に対する理解が不可欠です。
     Cocoaの源流は、オブジェクト指向技術の中でも老舗級のものですので、Cocoaの各所にオブジェクト指向技術が使われています。よって、オブジェクト指向技術を学ぶことによってこそ、Cocoaの仕組みを効果的にかつ効率的に使うことができるのだと思います。

     それではなぜ解説にCocoaを使わないのかと言いますと、それはCocoa自体がMac OS Xと非常に高い親和性を持っているため、言語と開発環境を切り離して解説することが難しいのです(単に私の能力の問題かもしれませんが)。
     それに対してCarbonはもともとC言語で使われることを想定して構築されたフレームワークですから、ただのCから使う場合と、PowerPlant XというC++で書かれたオブジェクト指向開発環境から使う場合の違いを並べて比較することが容易です。これが今回の説明にCarbonを使う理由です。

     それでは早速GUIアプリケーションの構造についてのお話をしていきましょう。まずはイベントループというものについてです。
     私が最初にMacのプログラミングに取り組んだ時、イベントループというものはMac独自のものかと思っていました。結果的に言えば、この私の理解は間違っていたのですが、その当時の私の身の回りにあったシステムにイベントループを持ったものがなかったことも事実です。たとえば、少しだけ仕事で書いたNECのPC9800シリーズのプログラムはMS-DOS上で動作していましたから、これもイベントループという概念とは無縁でした。
     では、そんなイベントループとはどういうものでしょうか?

     コンピュータがプログラムを動かす場合、そのプログラム自体は「指示書」であると言えます。コンピュータはこの指示書を読んでプログラムを起動させ、走らせるわけですが、特に何かの理由でもない限りコンピュータは黙々と指示書に書かれている手順を順に休みなく処理していきます。そして指示書の最後まで到達すると、コンピュータはプログラムをそこで終了させます。
     今、「黙々と」という表現を使いましたが、コンピュータの処理は人間の感覚から見るととても速いので、印象としてはまさに「一目散に駆け抜ける」という感じです。例えば文字列を5つ、順に表示するようなプログラムを書いた場合、コードを書く人間の側にとっては「文字列を、一つずつ」という感覚であったとしても、それがプログラムになって走る場合は、5つの文字列全部がいっぺんに書き出される感覚です。
     皆さんには以下のような経験はないでしょうか?
     私が最初にGUIアプリケーションにチャレンジした時に、「とりあえず、まずはウインドウを一つ表示してみよう」というわけで、見よう見まねでシステムの初期化のコードを書き、メニューの構築をし、ウインドウを作成し、表示するところまでをやっとの思いで書き上げ、「さあ!」と走らせてみたところ、画面には何の変化も起こらずに「あれ?」となったのです。「どこかコードを書き間違えたかな?」と何度も確認して試してみても結果は変わりませ
    ん。
     これはまあ、初心者の多くが最初に経験する勘違いの一つですが、実はウインドウはちゃんと表示されています(プログラム的には)。しかし、表示された直後にプログラム自体が終了してしまっているため、ウインドウは表示されるやいなや閉じられ、始末されてしまったのです。
     こんな時、特にANSI CのHello world!を経てからここに到達している人の場合、この状況がすぐに飲み込めません。「Hello world!は、ちゃんと消えずに残っているのに、何でウインドウは消えちゃうの?」と。しかし、普通でないのは実はHello worldの方なのです。
     よぉーく考えてみてください。その文字列を表示しているプログラムはどのプログラムですか? それはあなたの書いたプログラムなんでしょうか?
     printf(“Hello world!\n”);のすぐ次にreturn 0;と書いて、そこでプログラムが終了していることは分かっているのに、Hello worldという文字列を表示しているのが自分のプログラムだと漠然と誤解している人が案外多いような気がします(私もそうでした)。
     プログラムをどのような環境から起動したかにもよりますが、例えばXcodeからHello worldプログラムを起動したとしますと、その文字列を表示したままにしてくれているのは、Xcodeなわけです。考えてみれば当然ですよね。
     あなたのプログラムは、printf()という関数を使って、Xcodeに対して(間接的にですが)「この文字列、表示しといてねっ」と言ったと思うや、とっとと走り去っていってしまうのです。
     そういうわけで、先のウインドウを表示するプログラムの場合、ウインドウを開いたままにしていてくれる人(?)は誰もいませんから、プログラムの終了と同時にウインドウ自体も消滅してしまったわけなのです。
     このように、プログラムというのはとてもせっかちな動き方をします。特別なことをしなければ、そこに止まって、人間の指示を待ってくれるようなことはしないのです。
     そこでプログラムを「終了させてしまわないための仕組み」が必要になるのですが、この時に使うのが、ループです。whileとかforとかいう例のアレです。
     「とりあえずその辺を回ってて」と、同じところをグルグル空回りさせておいて、用事ができたらそこで指示を出して処理をさせます。これがイベントループです。
     かなり擬人化した説明になってしまいましたが、何となくイメージは湧きましたでしょうか? 次回はもう少しシステム的な説明をしたいと思います。

    ニュース・解説

     今週の解説担当:小池邦人

    ● Carbon ドキュメント & サンプル & SDK ナビゲーション(2007/02/23)

    【開発環境】

    Apple社のウェブサイトで、WWDC2007における大まかなセッショントラックが発表になりました。ただし細かなセッション内容はまだ不明です。それぞれのトラックについて「Learn more…」をクリックし詳細を見ても、今まで発表があった範囲以内の技術内容であり、あまり目新しい点はありません。

    http://developer.apple.com/wwdc/tracks/

    6つのトラックが用意されるようですが、やはり一番の注目は「LeopardInnovations」でしょう。WWDC2006以降、Leopardに関する大きな発表は無いのですが(SF Expoでも完全に無視された)、WWDC2007では、Leopard(Mac OS X10.5)はとっくの昔にデベロッパの手元にあり、皆がそれを操作しながらセッションを聞くことが可能であると信じたいところです(笑)。

    また、良くある質問(Q&A)を掲載した「Frequently Asked Questions」サイトと、学生向けの奨学金制度を説明した「WWDC Student ScholarshipProgram」サイトもオープンしています。学生の方で奨学金制度に興味のある方は覗いてみてください。

    http://developer.apple.com/wwdc/faq/

    http://developer.apple.com/wwdc/students/

    【テクニカルドキュメント】

    前回から2月23日の期間中、Apple社のGuidesとReferenceサイトにはドキュメントがひとつも登録されませんでした。ただし、リリースノートがひとつだけ登録されています。つい最近アップデートされた「Java for Mac OS X 10.4Release 5」に関するものです。また、デベロッパ向け読み物も3つ登録されています。

    リリースノート

    「Java for Mac OS X 10.4 Release 5 Release Notes」

    http://developer.apple.com/releasenotes/

    「ADC Developer Pavilion at Macworld 2007」(読み物)
    http://developer.apple.com/business/pavilion/2007/index.html

    「Lineform: From Student Project to Retail Distribution」(読み物)
    http://developer.apple.com/business/macmarket/lineform.html

    「Enhance Your Dashboard Widgets with Quartz Composer Compositions」(読み物)
    http://developer.apple.com/graphicsimaging/quartz/quartzcomposerfordashboard
    .html

    前回から2月23日の期間中、新規テクニカルノートはひとつも登録されません
    でしたが、新規テクニカルQ&Aの方は4つ登録されました。QuickTime関連が多
    いようです。

    QA1508「Adding metadata to an iTunes file using the QuickTime Metadata APIs」
    (初版)
    QA1512「Video Digitizers – Adding Clean Aperture and Pixel Aspect Ratio
    Information」(初版)
    QA1513「Advertising a Bonjour service on a specific set of networking
    interfaces」(初版)
    QA1515「Adding metadata to a QuickTime movie using the QuickTime MetaData
    APIs」(初版)

    http://developer.apple.com/technicalqas/index-rev-date.html

    【サンプルソースコード】

    前回から2月23日の期間中、Apple社のSample Codeサイトには、サンプルソースコードが2つ登録されました。両方とも新版ではなく改良版としての再登録です。

    「UIElementInspector」(Accessibility関連)
    「SoftVDigX」(QuickTime関連)

    http://developer.apple.com/samplecode/index-rev-date.html

    【デベロップメント SDK】

    前回から2月23日の期間中、Apple社のSDKサイトには新しいSDKがひとつも登録されませんでした。

    http://developer.apple.com/sdk/

    ◇MOSAからのお知らせと編集後記は割愛します◇

       

     MOSA Developer News   略称[MOSADeN=モサ伝]
            配信停止 mailto:mosaden-ml@mosa.gr.jp
     記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
          記事投稿受付 http://www.mosa.gr.jp/?page_id=850
    Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等
    はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    特定非営利活動法人MOSA  http://www.mosa.gr.jp/
    Copyright (C)2007 MOSA. All rights reserved.

  • MOSA Developer News[MOSADeN=モサ伝]第240号

    2007-02-20

    目次

    • 「「Wonderful Server Life」    第38回   田畑 英和
    • 小池邦人の「Carbon API 徒然草」
    • SqueakではじめるSmalltalk入門  第79回   鷲見 正人
    • ニュース・解説               木下 誠

    「Wonderful Server Life」  第38回  田畑 英和

      〜アクセス権編〜

     これまでACLのアクセス権について解説してきましたが、そのしめくくりとして、コマンドラインからのACLのアクセス権の管理方法について解説したいと思います。もちろん「ワークグループマネージャ」を使えばACLのアクセス権は管理できるのですが、コマンドライン上での管理ができればより応用の幅が広がります。

    ◇アクセス権の確認
     それではまず「ワークグループマネージャ」で設定した既存のアクセス権をコマンドラインを使って確認してみます。次のように設定されたアクセス権をコマンドライン上で確認してみます。

    ・フォルダ名
      Sample
    ・POSIXのアクセス権
      オーナー:admin > 読み出し/書き込み
      グループ:admin > 読み出し専用
      全員:     > 読み出し専用
    ・ACLのアクセス権
      ユーザ:test > 読み出し関連のアクセス権をすべて許可

     まずPOSIXのアクセス権を確認してみましょう。lsコマンドの-lオプションを使うことによりPOSIXのアクセス権を確認することができます。

    $ ls -l
    total 0
    drwxr-xr-x + 2 admin  admin  68 Feb 16 15:00 Sample

     アクセス権が”rwxr-xr-x”と表示され、最初の3文字でオーナーは「読み出し/書き込み」、真ん中と最後の3文字で、それぞれグループと全員が「読み出し専用」に設定されていることが確認できます。
     では次にACLのアクセス権を確認します。ACLのアクセス権を確認するには-lオプションにeオプションを追加します。

    $ ls -le
    total 0
    drwxr-xr-x + 2 admin  admin  68 Feb 16 15:00 Sample
     0: user:test allow list,search,readattr,readextattr,readsecurity,
    file_inherit,directory_inherit
    


     さきほどのコマンドの実行結果にACLのアクセス権の表示が加わったことが確認できます。この出力結果から”test”ユーザに対していくつかのACLのアクセス件が設定されていることが確認できます。
     コマンドライン上で表示されているアクセス権の名前と「ワークグループマネージャ」上で表示されるアクセス権の対応関係は次のようになります。これら以外にも、継承に関する設定が出力結果に表示されていることが確認できます。

    ・アクセス権の名前の対応関係
      readattr:属性を読み込む
      readextattr:拡張属性を読み込む
      list:フォルダの内容を一覧表示/データを読み込む
      search:フォルダをスキャン/ファイルを実行
      readsecurity:アクセス権を読み込み
    

    ◇アクセス権の設定
     では次にアクセス権を設定してみましょう。さきほどアクセス権を確認し「Sample」フォルダに新たにACLのアクセス権を追加してみます。ACLのアクセス権の設定には、POSIXのアクセス権の設定にも使用するchmodコマンドを使います。それでは、”test2″ユーザに対して”list”のアクセス権を許可してみます。

    $ chmod +a "test2 allow list" Sample
    $ ls -le
    total 0
    drwxr-xr-x + 2 admin  admin  68 Feb 16 15:00 Sample
     0: user:test2 allow list
     1: user:test allow list,search,readattr,readextattr,readsecurity,
    file_inherit,directory_inherit
    


     アクセス権の設定後に、再度アクセス権を確認するとACLのエントリーが1つ追加されていることが分ります。ACLのエントリーには番号が割り振られていますが、この番号の若い順にアクセス権が処理されます。
     既存のACLのアクセス権を削除することもできます。アクセス権の設定にはchmodコマンドの+aオプションを使用しましたが、削除を行うには-aオプションを使い、削除したいエントリーの番号を指定します。

    $ chmod -a# 1 Sample
    $ ls -le
    total 0
    drwxr-xr-x + 2 admin  admin  68 Feb 16 15:00 Sample
     0: user:test2 allow list
    


     これで任意のアクセス権のエントリーを削除することができます。
    ◇ACLのアクセス権の有効化
     lsやchmodコマンドを使ったACLのアクセス権の管理は、Mac OS X Serverだけでなく、Mac OS X上でも行うことができます。ただし、ACLを使用するにはボリュームに対してACLが有効に設定されている必要があります。
     ルートボリュームに対してACLを有効にしたり無効にするにはfsaclctlコマンドを使用します。

    ・ACLを有効に設定
    $ sudo fsaclctl -p / -e
    ・ACLを無効に設定
    $ sudo fsaclctl -p / -d


     ACLが有効化されていなボリュームでchmodコマンドを使ってACLのアクセス権を設定しようとすると次のようなエラーメッセージが表示されます。

    $ chmod +a "tabata allow list" hoge
    chmod: Failed to set ACL on file hoge: Operation not supported
    


                                   つづく

    小池邦人のCarbon API 徒然草(2007/02/16)

    〜 Carbonモダンアプリケーションへの道(その10) 〜
    今回は、CoreGraphics APIに頼らないテキスト描画を試してみます。処理が複雑になりがちなMLTE(Multilingual Text Engine)やATS(Apple TypeServices)のAPIを使うのではなく、割と簡単な操作でテキスト描画を実現できるAPIを探してみます。

    まずは話の流れとして、MLTE(Multilingual Text Engine)の方を調べてみることにします。Carbon Frameworkの一部であるMLTEは、ある程度複雑なテキスト処理を実現したい時に用いられ、アプリケーション内に小規模のテキストエディタを実装することも可能です。関連するAPIや定数が定義されているヘッダファイルは、MacTextEditor.hでして、旧TextEdit APIのTETextBox()に相当するAPIなども準備されています。例えば、矩形領域にUnicode文字列やCFString文字列(CFStringRefで参照)を表示するAPIは以下の2つです。

    OSStatus TXNDrawUnicodeTextBox(
    
      const UniChar                  iText[],    // 描画するUnicode文字列
      UniCharCount                   iLen,       // 文字列の長さ
      Rect *                         ioBox,      // 描画矩形領域
      ATSUStyle                      iStyle,     // フォント種類、サイズ、スタイ
    ル
      const TXNTextBoxOptionsData *  iOptions ); // 描画時のオプション
    
    OSStatus TXNDrawCFStringTextBox(
    
      CFStringRef                    iText,      // 描画するCFString文字列
      Rect *                         ioBox,      // 描画矩形領域
      ATSUStyle                      iStyle,     // フォント種類、サイズ、スタイ
    ル
      const TXNTextBoxOptionsData *  iOptions ); // 描画時のオプション
    
    TXNDrawUnicodeTextBox()はUnicode文字列の描画を行い、TXNDrawCFStringTextBox()ではCFString文字列の描画を行います。引数のiOptionsで参照するTXNTextBoxOptionsData構造体は、以下のように定義されています。
    
    struct TXNTextBoxOptionsData
    {
      TXNTextBoxOptions   optionTags;     // オプションビット
      Fract               flushness;      // テキスト描画方向
      Fract               justification;  // ジャスティフィケーション
      Fixed               rotation;       // 矩形領域の回転
      void *              options;        // リザーブ(NULL指定)
    };
    


    このTXNTextBoxOptionsData構造体を設定すれば、かなり複雑なテキスト描画にも対応していることが分かります。しかし両者の引数を見ると、描画用矩形領域の指示にはRect構造体が利用されており、描画座標系もQuickDraw環境のままです。これらの点から推測しても、完全にモダンなAPIとは言い難いようです(笑)。また、フォント情報等を指定するための引数であるiStyleにはATSUStyleオブジェクトを渡す必要があり、こちらについてはATS(Apple TypeServices)の方のヘッダファイル(ATSUnicodeTypes.h)の定義を色々と参照する必要があります。

    また、ATSUStyleオブジェクトを作成するのには、ATS APIであるATSUCreateStyle()(ヘッダファイルはATSUnicodeObjects.h)などを利用する必要があり、面倒な手続きをふまないと最終的なテキスト描画まで到達しません。APIとしては高機能なのですが、ウィンドウにちょっとしたテキストを描画したい目的には、少々複雑すぎる気がします。

    まあ、フォントの種類やサイズにあまり頓着しないような簡単なテキスト描画であれば、ウィンドウの描画位置にあらかじめStatic Textコントロールを貼り付けておき、そこに以前に紹介したsetUnicodeControl()などのルーチンで、Unicode文字列を描画してやることも可能です。

    void setUnicodeControl( ControlRef chd,HFSUniStr255 *ustr )
    {
        CFStringRef    cfstr;
    
        if( ! unicodeToCFString( ustr,&cfstr ) ) // UnicodeをCFString文字列に変
    換
        {
            setCFStringControl( chd,cfstr );     // Static Textコントロールに表
    示
            CFRelease( cfstr );                  // ControlRefをリリース
        }
    }
    
    OSErr unicodeToCFString( HFSUniStr255 *ustr,CFStringRef *cfstr )
    {
        short    err=1;
    
        if( *cfstr=CFStringCreateWithCharacters( NULL,ustr->unicode,ustr->length
    ) )
            err=noErr;      // Unicode文字列ををCFString文字列に変換
        return( err );
    }
    
    void setCFStringControl( ControlRef chd,CFStringRef cfstr )
    {
        if( cfstr )
        {
            SetControlData( chd,kControlNoPart,kControlEditTextCFStringTag,
                                                  sizeof(CFStringRef),&cfstr );
            DrawOneControl( chd ); // コントロール(エキスと)描画
        }
    }
    


    多くのケースはこれで事足りるかもしれませんが、さすがにこれだけでは機能が貧弱で汎用的には使えません。そこで、文字の回転などは必要ありませんから、もう少し簡単で便利なテキスト描画用APIはないものかと探してみると、ヘッダファイルのAppearance.hの中に目的のAPIを発見しました。それが、以下のDrawThemeTextBox()です。つまり「コントロール描画でテキスト描画を担当している汎用APIを直接使う」というアイデアです。

    OSStatus DrawThemeTextBox(
    
      CFStringRef      inString,        // 描画CFString文字列
      ThemeFontID      inFontID,        // フォントID
      ThemeDrawState   inState,         // 描画モード
      Boolean          inWrapToWidth,   // 領域端で折返しをするか
      const Rect *     inBoundingBox,   // 描画矩形領域
      SInt16           inJust,          // ジャスティフィケーション
      void *           inContext );     //  CoreGraphicsのCGContextRef
    


    DrawThemeTextBox()は、ウィンドウなどのカレントポート(Current Port)にテキストを描画します。このAPIも矩形領域指定にRect構造体を使いますので、やはりQuickDraw環境を引きずっている事は間違いありません。ただし、前記のTXNDrawCFStringTextBox()とは異なり、最後の引数でCoreGraphics環境のCGContextRefを指定することが可能ですので、CoreGraphicsの描画設定もそのまま引き継ぐことが可能です。つまり、描画する文字のカラーや形状等をCoreGraphics APIで指定できるわけです。

    また、フォントIDにkThemeCurrentPortFontを指定すると、カレントポートのフォント設定でテキスト描画をします。つまり、描画する直前に行ったSetPortTextFont()などによるフォント設定が生きるわけです。QuickDrawのTextFont()、TextSize()、TextFace()などがすべてDEPRECATED指定で全滅したのにも関わらず、似たようなSetPortTextFont()、SetPortTextSize()、SetPortTextFace()が生き残っているのは、このAPIの存在が大きいのかもしれません(笑)。面白い機能としては、引数のinStateで、コントロール標準の描画モード(アクティブ、インアクティブ等)を複数の種類から選択可能です。

    enum {
    
      kThemeStateInactive            = 0,
      kThemeStateActive              = 1,
      kThemeStatePressed             = 2,
      kThemeStateRollover            = 6,
      kThemeStateUnavailable         = 7,
      kThemeStateUnavailableInactive = 8
    };
    


    例えば、描画文字列(CFStringRef)をcref、カレントポート(CGrafPort)をport、描画対象を(CGContextRef)ctxとして、(0,0,100,20)の矩形領域に12ポイント、角ゴ W3、ノーマル、中心合わせ、赤色でテキストを描画する場合は、以下の記述となります。

      CGrafPort    port;
       CFStringRef  cref;
       CGContextRef ctx;
    
       SetPortTextFont( port,-31551 );  // 角ゴ W3
       SetPortTextSize( port,12 );      // 12ポイント
       SetPortTextFace( normal );       // ノーマル
       CGContextSetRGBFillColor( ctx,1.0,0.0,0.0,1.0);  // 文字は赤色
       SetRect( &drt,0,0,100,20 );                      // 描画矩形領域
    
       DrawThemeTextBox( cref,kThemeCurrentPortFont,kThemeStateActive,false,
                                                        &drt,teJustCenter,ctx );
    


    筆者も、最近までテキスト描画用としてこのAPIを便利に使っていたのですが、自作アプリケーションをMac OS X 10.5(Leoperd)へ対応させる作業(さらなるモダン化)で幾つかの問題点に遭遇しました。次回はそのお話をしたいと思います。
                                    つづく

    SqueakではじめるSmalltalk入門   第79回  鷲見 正人

    本連載では、Macと切っても切れない関係にあるSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。

    ここのところ、少々遠回りをしながら回数を割いて、簡易GUIビルダの作成をしてみました。一般の言語処理系(あるいは、Macを含めた一般のコンピュータシステム)における「編集-ビルド-デバッグ」サイクルとは異質の、ソフトを走らせながらでも開発を進めてゆくことができる…という、Smalltalkシステム(=暫定ダイナブックシステム)独自の「インクリメンタル」な開発スタイルを、ほんのさわりだけですが垣間見ていただけたことと思います。

    いったんは完成にこぎつけたこの簡易GUIビルダですが、じつは、Smalltalkアプリとしては“うまくない仕組み”で動いています。具体的には、モデルとユーザーインターフェイス(ビュー及びコントローラ)の分離がきちんとできていないのですね。今後はこの点を、Smalltalk発祥でCocoaでもお馴染みのMVCライクなアーキテクチャを学びつつ、手直ししてゆくつもりです。

    しかしその前に、近頃リリースされた新しいSqueakシステムのバージョンである「3.9」をご紹介がてら、Smalltalk環境の基本をおさらいすることにいたしましょう。この連載で使用するシステムも、この最新の3.9ベースに切り替えるので、連載を途中から読み始めて実際に環境を用意していなかった方も、この機会に以下の手順に従い、Squeakシステムのインストールとセットアップを試みてはいかがでしょうか。これからしばらく、すでにSqueakを使いこなしておられる方には冗長な内容になるかと思いますが、どうか我慢しておつきあいください。

    ▼Squeak3.9の入手と、その内容の簡単な解説
    最新版を含むSqueakシステム(英語版)は、公式サイトであるsqueak.orgより入手可能です。ダウンロードページもありますが、トップページの右手にある「Downloads」枠にある「Mac」のリンクを利用する方が手っ取り早いでしょう。本稿執筆時点では、くだんのリンクは具体的には次のURLを指しています。

    http://ftp.squeak.org/3.9/mac/Squeak3.9-7067mac%20vm%203.8.15beta1U.zip

    ダウンロードが終わると、そのとき用いたソフト(たいていはSafariやFirefox)であらかじめ指定済みの場所に「Squeak3.9-7067mac vm3.8.15beta1U.zip」アイコンが現われるはずなので、それをダブルクリックで展開します。展開後に現われる「Squeak3.9-7067mac」フォルダには次の五つのファイルが収められています。「Squeak3.9-7067mac」フォルダは適宜「アプリケーション」フォルダやデスクトップなど、分かりやすい場所に移動しておいてください。

    Squeak 3.8.15beta1U.app
    Squeak3.9-final-7067.image
    Squeak3.9-final-7067.changes
    SqueakV39.sources
    WelcomeSqueak39

    Squeakシステムを動かすのに必須なのは「Squeak 3.8.15beta1U.app」と
    「Squeak3.9-final-7067.image」の二つのファイルです。それぞれ「仮想マシン」「仮想イメージ」と呼ばれます。仮想マシンは「オブジェクトメモリ」と呼ばれるメモリとハードディスクの両方の特徴を併せ持つ特殊な仮想的記憶デバイスを、ホストOSであるOS Xが管理するメモリ空間内に作り出します。仮想マシンはさらに、指定された仮想イメージの内容をオブジェクトメモリ内に読み込ませ、Squeakシステムを動作させます。通常は、仮想イメージファイル(.image)を仮想マシンアプリ(.app)にドロップインすることで、以上の作業をいっぺんに済ませることが可能です。

    SmalltalkシステムというのはALTOのOSだった時代からずっと、Macを含む通常のコンピュータシステムとは違った、かなり変わった方式で動いています。必要なときに補助記憶装置にあるファイルをメインメモリに読み込んでアプリを起動したり文書を開いたり…というお馴染みものではなく、扱うデータやプログラムはすべて「オブジェクト」としてオブジェクトメモリという仮想デバイス内に保持し、システムやアプリ(あるいはその文書)で必要なとき、必要なオブジェクト同士を構成要素として協働させ、機能させます。

    ちなみにアラン・ケイは、Smalltalkシステムを「生命体」に、その唯一の構成要素で、互いに協働して機能するオブジェクトを「細胞」に、それぞれを例えることがあります。とかくALTOというとMacにとっての「GUIの始祖」とだけ連想しておしまいにされがちですが、暫定的な「ダイナブック」として見るならば、GUIよりはむしろこの特殊な“仕組み”とそれが実現する“メリット”(たとえば、冒頭に述べたソフトを走らせながらのインクリメンタルな開発手法が使える…とか)のほうがはるかに重要だったりします。

    閑話休題。

    残りの「Squeak3.9-final-7067.changes」と「SqueakV39.sources」は、仮想イメージ内のオブジェクトの定義を、それを記述したSmalltalkのソースコード片群として保持するテキストファイルで、それぞれ「チェンジ」「ソース」と呼ばれます。後者の「ソース」はごく初期のリリース時の仮想イメージの内容を反映していて“読み出し専用”なのに対し、前者の「チェンジ」はその後、システムに加えられた改変を逐次、追記し、記録するための“ログファイル”のように使われます。念のため、後者は「ソース」という名前がついていても、仮想マシンなどのソースコードファイルというわけではないので注意してください。また、チェンジやソースの内容は、仮想イメージ内のオブジェクトから参照されているので、テキストエディタで開いて読むことができるからといって、Squeak環境外で勝手に内容を書き換えてはいけません。

    オブジェクトメモリ内の状況、すなわち、Squeak環境の“様子”は、好きなタイミングで仮想イメージとして保存することが可能で、この作業を「スナップショット」と呼ぶことがあります。情報は、起動時に用いた仮想イメージファイルに重ね書きすることも、別仮想イメージファイルを新たに作ってそこに保存することも可能です(当然ですが、重ね書きをすれば、以前の状態は永久に失われます)。新たに仮想イメージを作ったときは、同名のチェンジファイルも同時に作られます。なお、こうして作られた仮想イメージとチェンジは同名のものを常にペアで扱う必要があります(仮想イメージファイルの名前を変える必要があるときは、対応するチェンジファイルのリネームも同時に行なうことを忘れないようにしてください)。ソースファイルはひとつあれば、それを各ペアで共有できます。

    ▼Squeak環境の起動と終了
    それでは、仮想イメージ「Squeak3.9-final-7067.image」を仮想マシン「Squeak 3.8.15beta1U.app」にドロップインしてSqueakシステムを起動しましょう。起動に成功するとホストOSであるOS Xの描くウインドウ内にSqueak環境のデスクトップが現われます。ちょうど、VMWareやVirtualPCなどのエミュレーションソフトが動作するときと似たような感じです。もし、仮想マシンに仮想イメージをドロップインしているにもかかわらず、仮想イメージを指定するようなダイアログが表示される場合は「Squeak3.9-7067mac」フォルダを日本語を含むフォルダに入れてしまっていないか確認してください。

    動作しているSqueak環境を終了させるにはいくつかの方法があります。

    ●デスクトップメニューを使う
    1. デスクトップをクリックして「デスクトップメニュー」をポップアップ。
    2. 「quit」を選択して、「Save changes before quitting?」には「No」。
    (ちなみにこのとき「Yes」を選べば、前述のスナップショットになります)

    ●ナビゲータフラップを使う
    1. 右下の「Navigator」タブをクリックして“フラップ”を呼び出す。
    2. 右端の「QUIT」ボタンをクリック。
    3. 「Are you sure you want to Quit Squeak?」に「Yes」。

    ●ホストOSであるOS Xから終了の指示を出す
    #(OS Xの)メニューバーの「File」から「Quit do not save」を選択。

    最後のは環境内でデスクトップメニューやナビゲータフラップが使えないときの緊急時の終了のしかたで、通常のハードウエアでいうなら「リセット」、アプリケーションソフトなら「強制終了」に相当します。よって、通常は前二者のいずれかの方法で終了することをお薦めします。もっとも最後の方法でも、いきなり終了してしまうことで、作業中の内容を保存するタイミングを逸する可能性があることを除けば、さしたる支障はありませんが…。

    次回は、日本語を扱うためのリソースの追加と、いつくかの設定を行ないます。

    バックナンバー:
    http://squab.no-ip.com:8080/mosaren/

    ニュース・解説

     今週の解説担当:木下 誠

    ———————————————————————-
    DashboardでQuartz Composerを使う
    ———————————————————————-

    Dashbaordの表現力を飛躍的に高めるためにQuartz Composerを使おう、という記事、「Enhance Your Dashboard Widgets with Quartz ComposerCompositions」が公開されています。

    Quartz Composerは、Tiger登場当初はDashboardで使うことはできませんでしたが、10.4.7から可能になっています。また、JavaScriptを使って、QuartzComposerを細かく操作することもできます。

    Enhance Your Dashboard Widgets with Quartz Composer Compositions
    http://developer.apple.com/graphicsimaging/quartz/quartzcomposerfordashboard
    .html

    ———————————————————————-
    Java 10.4 Release 5が登場
    ———————————————————————-

    Javaのアップデート、Java for Mac OS X v10.4 Release 5が登場しています。同時に、リリースノートも公開されています。

    これには、夏時間(Day light saving)の変更に対する対応が含まれます。その他にも、多数の改良、バグ修正、が含まれます。詳しくは、リリースノートをご覧ください。

    Java for Mac OS X 10.4 Release 5 Release Notes
    http://developer.apple.com/releasenotes/Java/Java104R5RN/index.html

    ———————————————————————-
    QuickTime Metadata APIのQA
    ———————————————————————-

    QuickTimeのMetadata APIに関するQAが、2つ公開されています。このAPIを使う事で、メディアファイルに、アルバムのアートファイルや、アーティスト名といった情報を埋め込むことができます。

    QA1508: Adding metadata to an iTunes file using the QuickTime Metadata APIs
    http://developer.apple.com/qa/qa2007/qa1508.html

    QA1515: Adding metadata to a QuickTime movie using the QuickTime MetaData
    APIs
    http://developer.apple.com/qa/qa2007/qa1515.html

    ———————————————————————-
    BonjourのQA
    ———————————————————————-

    Bonjourに関するQA、「Advertising a Bonjour service on a specific set of networking interfaces」が公開されています。

    Bonjourを使うと、自分のマシンが提供しているサービスを、ローカルネットワーク上のすべてのデバイスにアピールできますが、それを特定のデバイスだけに限定する方法です。このようなことは可能ですが、NSNetServicesやCFNetServicesといったハイレベルAPIを使うのではなく、DNSServiceDsicoveryを使うことになります。

    QA1513: Advertising a Bonjour service on a specific set of networking
    interfaces
    http://developer.apple.com/qa/qa2007/qa1513.html

     

    ◇MOSAからのお知らせと編集後記は割愛します◇

     

    MOSA Developer News   略称[MOSADeN=モサ伝]
            配信停止 mailto:mosaden-ml@mosa.gr.jp
     記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
          記事投稿受付 http://www.mosa.gr.jp/?page_id=850
    Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。このメールの再配信、および掲載された記事の無断転載を禁じます。
    特定非営利活動法人MOSA  http://www.mosa.gr.jp/
    Copyright (C)2007 MOSA. All rights reserved.

  • MOSA Developer News[MOSADeN=モサ伝]第239号

    2007-02-13  

    目次

    • 「Wonderful Server Life」       第37回  田畑 英和
    • 藤本裕之のプログラミング夜話  #108
    • 高橋真人の「プログラミング指南」 第106回
    • ニュース・解説                小池 邦人

    「Wonderful Server Life」  第37回  田畑 英和

      〜アクセス権編〜

     今回はACLのアクセス権の設定方法について解説します。ACLのアクセス権を使用するにはまずボリュームごとにACLのアクセス権の有効/無効を設定します。
     ボリュームごとの設定には、「ワークグループマネージャ」を使用します。ツールバーの「共有」をクリックし、左側のリストから「すべて」を選択し、ACLを有効にしたいボリュームを選択します。次に、画面右側で「一般」をクリックし、「このボリュームでアクセス制御リストを有効にする」を選択し、画面右下の「保存」ボタンをクリックします。
     これで、設定したボリューム上でACLのアクセス権が有効になります。

    ・「ワークグループマネージャ」でACLを有効に設定
    http://homepage.mac.com/htabata/MXS10.3/img/WGM_Sharing/WGM_10.png

     ACLのアクセス権を有効にしたボリューム上では、「ワークブループマネージャ」を使って任意のフォルダにACLのアクセス権が設定できるようになります。「ワークグループマネージャ」ではフォルダに対してしか直接ACLのアクセス権を設定することができません。ACLを使ってファイルのアクセス権を管理するには、前回説明した継承の機能を使って管理します。

     ACLのアクセス権を設定するには、画面左側のリストでアクセス権を設定するフォルダを選択し、「ユーザとグループ」ボタンをクリックして「ユーザとグループ」パネルを表示します。「ユーザとグループ」パネルは、ローカルドメインのリストと共有ドメインのリストを切り替えて表示できるため、現在どのドメインのアカウントを表示しているのかを意識しながら作業を行うようにしましょう。表示するドメインは、パネル上部のポップアップメニューから切り替えることができます。

    ・「ユーザとグループ」パネル
    http://homepage.mac.com/htabata/MXS10.3/img/WGM_Sharing/WGM_06.png

     次に、「ユーザとグループ」パネルからACLのアクセス権を設定したいユーザもしくはグループを選択して、「アクセス制御リスト」にドラッグ&ドロップします。ACLのアクセス権では複数のユーザおよびブループに対してアクセス権を設定することができます。
     ACLには13種類のアクセス権があると前回解説しましたが、フォルダに対して設定した複数のユーザおよびグループに対して、個別に13種類のアクセス権を設定できます。また、アクセス権には「許可」と「拒否」の2種類のタイプがあります。アクセス許可を与えたい場合には「タイプ」を「許可」に設定し、許可したいアクセス権を指定します。逆に「タイプ」を「拒否」に設定すれば、アクセスを許可しないアクセス権を指定することができます。
     ACLのアクセス権は順番に意味があり、「許可」のアクセス権を設定していた場合には、上から順番にリスト上のアクセス権が判定され、関連するアクセス権がすべて足し合わされた結果がユーザに適用されます。一方「拒否」のアクセス権を設定した場合、リスト上でそれ以降に設定した「許可」のアクセス権よりも優先されます。

    ・アクセス制御リストの設定
    http://homepage.mac.com/htabata/MXS10.3/img/WGM_Sharing/WGM_11.png

     リスト上で選択可能なアクセス権は「フルコントロール」、「読み出し/書き込み」「読み出し」「書き込み」となっており、大まかな設定しかできませんが、「カスタム」を選択すると13種類あるすべての種類のアクセス権を設定することができます。「カスタム」の設定ではアクセス権のタイプの設定に加えて、継承の設定なども可能です。

    ・カスタム設定画面
    http://homepage.mac.com/htabata/MXS10.3/img/WGM_Sharing/WGM_12.png

     リストでは他にも継承の有無や、継承の適用先を確認することができます。上位のフォルダからアクセス権を継承していれば、継承したアクセス権が表示されます。継承したアクセス権を直接変更することはできませんが、もし継承しているアクセス権を取り除きたい場合には、取り除きたいアクセス権をリスト上で選択し、画面右下のアクションメニューから「継承したエントリを取り除く」を選択すると取り除くことができます。
     既存のアクセス権が特定のユーザに対してどのように適用されるかを確認するにはアクションメニューから「有効なアクセス権インスペクタを表示」を選択し、表示されたインスペクタに「ユーザとグループ」パネルからアクセス権を確認したいアカウントをドラッグ&ドロップします。

    ・アクションメニュー
    http://homepage.mac.com/htabata/MXS10.3/img/WGM_Sharing/WGM_13.png
    ・有効なアクセス権インスペクタ
    http://homepage.mac.com/htabata/MXS10.3/img/WGM_Sharing/WGM_14.png

    つづく                               

    藤本裕之のプログラミング夜話 #108

     指折り数えてなんと連載108回目である。私の子供のころ、星一徹は息子の飛雄馬に「野球のボールにある108つの縫い目は人間の煩悩だ」と言ったが(言ったっけ? そんな気がするだけかな?)、メジャーリーグで使ってるボールも縫い目の数は同じなんだろうか? もしそうなら、アメリカ人に「野球のボールの縫い目の数は108で、これは東洋思想で人間が生涯に直面する葛藤(煩悩っても通じないだろからね)の数と言われているんだ」とか言うと受けそうな気がするんだが(しませんか)。

     さて、そんなことより前回の続き。NSTableView のアイテムをドラッグ&ドロップし、その表示順を変更しようという処理の最後は、そのドロップを受け取るこのメソッドである。

    - (BOOL)tableView:(NSTableView *)aTableView
           acceptDrop:(id )info
                  row:(int)row
        dropOperation:(NSTableViewDropOperation)operation;
    


    これの中身をだらだら書くと分かりにくいので、何をするか、しなければならないかを順を追って見ていくことにしよう。

    1)引数 info から draggingPasteboard を獲得し、中に格納されている(つうかドラッグ開始のときに自分で格納した)NSIndexSet を復元する。復元するには以下のように NSUnarchiver を使えばいい。

    NSIndexSet*    indexSet = [NSUnarchiver unarchiveObjectWithData:
                                       [pb dataForType:PXLibOrderPboardType]];

    2)この indexSet を走査して、選択されているインデックスのアイテムをデータソースから抜き出し、別の配列にセットする。この際、もし抜き出すインデックスが最終的にこれらをインサートする場所(引数 row )より小さければ、row を減算する。これ、分かりにくいかな。例えば NSTableView に現在10個のアイテムがあり、そこから0番目、3番目、7番目を選んで(commandキーを押しながらマウスクリックするとこういう選択が行える)ドラッグを始め、2番目のアイテムの上にドロップしたとすると row には「2」が入ってくるんだけど、実際に挿入を行うときにはその前にある0番目のアイテムが無く
    なっているので、挿入するべき位置はその時点で1番目のアイテムの上になるわけ。いいですか? ここだけコードを書くとこんな感じかな。

     unsigned int        loc;
         NSMutableArray*     moveArray = [NSMutableArray arrayWithCapacity:0];
         unsigned int        indexToMove = [indexSet firstIndex];
         while(indexToMove != NSNotFound){
              [moveArray addObject:[sourceArray objectAtIndex:indexToMove]];
              if(indexToMove < row){
                   --row;
              }
              indexToMove = [indexSet indexGreaterThanIndex:indexToMove];
         }
         [sourceArray removeObjectsInArray:moveArray];

    3)最後に抜き出したアイテムを挿入位置にインサートする。まぁこれは以下のごとく簡単な処理なんだけど(なんで reverseObjectEnumerator を使ってるかはわかるよね)、

     NSEnumerator*  bEm = [moveArray reverseObjectEnumerator];
         id                  item;
         while( item = [bEm nextObject]){
              [sourceArray insertObject:item atIndex:row];
         }
    


     なんでこの時に、2で使った removeObjectsInArray: みたいに Array の中身全部を一度にインサートしちゃうメソッドがないのであろうか。Mac OS X10.4では、NSMutableArray に

    - (void)insertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes

    というのが追加されたのだが、これも objects の中身の数だけ indexes の方も用意しなくちゃならず、あんまり面倒さが軽減しないん気がするんだよね。

      NSRange        indexRange = NSMakeRange( row, [moveArray count] );
         NSIndexSet*    indexSet =
                             [NSIndexSet indexSetWithIndexesInRange:indexRange];
         [sourceArray insertObjects:moveArray atIndexes:indexSet];

    ね、そう思いませんか?
                                (2006_02_09)

    高橋真人の「プログラミング指南」第106回

    プログラマのためのオブジェクト指向再入門(14)

    〜再利用化について(2)〜

     こんにちは、高橋真人です。
     さて前回の最後に「次回はオブジェクト指向が再利用化をどのように実現しているのかを見ていきたい」と書きました。この段階で私の頭には「何らかのサンプルコードを使い、CとC++での違いを解説しよう」という考えがあったのですが、その後いろいろ考えてみた結果、実際にそれを行うことがどうもそんなに簡単ではないという結論に至りました。
     既存のサンプルを引き合いに出すにも、なかなか適したものが見つからないし、かといって自分でイチから仕立て上げても具合の良いものができそうにも思えません。そんなわけで、説明のためのサンプルを使うことは諦め、最初から実用のために設計されたものを使って解説することにしました。
     具体的にはPowerPlant XというC++で書かれているCarbon用のフレームワークを取り上げます。PowerPlant Xと言えば、実用のために作られたオブジェクト指向のフレームワークですから、実例としてはこれほど適したものはないと思う部分もないではありませんが、PowerPlant X特有のクセというか設計方針のために、かえって説明が厄介になる部分も出てきそうな気がしないでもありません。
     もっとも、これはPowerPlant Xに限った話ではなく、実用のために作られたシステムというのは多かれ少なかれ何らかの「辻褄合わせ」があるものです。この世は決して理想だけで成り立っているわけではありませんから、個々の仕組みごとにそれぞれの「事情」は当然あるわけです。
     余談ですが、メーカーがこれらのシステムを語る場合、ほとんどその「裏側の事情」を隠すのが常です。まさに宣伝文句に乗せられて、買ったり導入したりしてみたものの、肝心なところになって「げ、これってこんなこともできなかったの?!」なんて叫び声を上げることは、実は世間では珍しくないことなのです。

     さてそんなわけで、これからPowerPlant Xを材料にして、非オブジェクト指向とオブジェクト指向でのアプローチの違いについて解説していくことになるわけですが、この連載は主要読者層は「GUIアプリケーション未経験者」(もちろんプログラミング対象としての)です(知らなかった人は憶えておいてくださいね)。なので、いきなり「PowerPlant XがCarbonアプリケーションをどのように実現しているのか」という方向に切り込むと読者が付いてこれなくなる危険性が大きいので、GUIアプリケーションの基本的な構造を解説するところから始めてゆっくりと話を進めて行きたいと思います。
     とはいえ、ここから具体的な話に踏み込んで行くにはちょっと中途半端なので、今回の残りの部分では、PowerPlant Xの基礎知識とでもいうべきところについてをお話しします。
     PowerPlant Xは、今までも何度か話題にしてきたPowerPlantの後継のフレームワークです。設計者は、Think Class Libraryというオブジェクト指向フレームワーク(Symantec社から出されていたThink Cという開発ツールに付属していた)を作った後に、MetrowerksでPowerPlantを手がけた人ですので、その意味でPowerPlant Xは「過去の経験を存分に生かした」設計になっていると言うことができます。
     PowerPlantも、アプリケーションフレームワークとしてはかなり柔軟性が高いと評価されていましたから、その経験を踏まえたPowerPlant Xがさらによいものになっていると考えるのは自然なことです(もちろん、「必然」ではありませんが)。
     PowerPlant Xでは、ターゲットをMac OS Xのみに絞り、Mac OS 9との互換性、つまりCarbonLibを切り捨てました。よって、イベントモデルも最初からCarbonイベントモデルになっています。
     ところで、オリジナルのPowerPlantが登場したのは1993年ごろのようですが、C++の世界では97年に大きな規格の拡張がありました。このときに正式にC++の機能の一部なったテンプレートという仕組みは、言語の設計者が予想していたよりはるかに多角的な活用をされるに至り、今やC++にとってなくてはならない機能となっています(ある意味テンプレートの導入により別の言語になってしまったとすら言えるくらいです)。
     そんな背景もあって、PowerPlant XはPowerPlantとは全く設計が異なり、このテンプレート機能を積極的に取り入れています。
     このように、「新しい時代のフレームワーク」として、絶大な期待(をしたのは、私だけ?)と共に登場したPowerPlant Xですが、ご存知のように「時代の流れ」に勝つことはできずに不運な運命をたどることになってしまいました。今でもオープンソース*として生き続けてはいるものの、お世辞にも活発に利用されているとは言い難いのが現状です。私の知る限り日本で使っている人は私以外に聞いたことがない、という悲しい状況なのもさらに涙を誘います。
    *注:http://sourceforge.net/projects/open-powerplant

     まあ、そんなこんなでPowerPlant Xを使ってこれからお話をしていくわけですが、できればXcode上で動かせるように私もちょっとチャレンジしてみようと思っています。(たぶん、既にやっている人はいるはずなんですが)

    ニュース・解説

     今週の解説担当:小池邦人

    ● Carbon ドキュメント & サンプル & SDK ナビゲーション(2006/02/09)

    【開発環境】

    WWDC2007の日程が発表されました。6/11-6/15(サンフランシスコ)だそうです。

    http://developer.apple.com/wwdc/

    開催期間が例年通りの季節に戻りました。昨年のように渡航費と宿泊費がピークの8月ではなくてなによりです。6月がカルフォルニアでは春なのかどうかは人によって意見が分かれるところですが、Leopard(Mac OS X 10.5)の発売開始日は、この開催日程に合わされるかもしれませんね。そして注目度ナンバーワンのiPhoneも同じく...。

    昨年の参加者は4700人だったそうですが、もしそうだとすると、今年はもっと参加者が増えるかもしれません(会場のキャパは大丈夫か?)。参加者締め切りなどと言う前代未聞の事態が起こらないともかぎりませんから、今年は早めに参加手続きをしておいた方が良いかもしれません。そして、さらにランチが不味くなるような嫌な予感がするのは私だけでしょうか(笑)。

    【テクニカルドキュメント】

    前回から2月9日の期間中、Apple社のGuidesとReferenceサイトには月例の更新により数多くのドキュメントが登録されました。しかし、その中で内容が大きく更新されたのはたったひとつだけでした。「Resource Programming Guide」では、CocoaやCarbonアプリケーションにおけるリソース(Nibファイル、アイコンファイル、ローカライズテキストなど)の取り扱いが詳しく解説されています。また、デベロッパ向け読み物もひとつだけ登録されています。

    「Resource Programming Guide」(PDFあり)

    http://developer.apple.com/documentation/index-rev-date.html

    http://developer.apple.com/reference/index-rev-date.html

    「Kerberos: Highly Secure Single Sign On Authentication in Mac OS X」(読み
    物)
    http://developer.apple.com/opensource/kerberosintro.html

    前回から2月9日の期間中、新規テクニカルノートはひとつも登録されませんでしたが、新規テクニカルQ&Aの方は3つ登録されました。alut.hはOpenAL frameworkから外されてしまったようですね(10.4.7から)。

    QA1504「The header file 'alut.h' is missing from the OpenAL framework」(初
    版)
    QA1360「Describing the kSecTrustResult- Unspecified」(初版)
    QA1468「NSOpenPanel - Choosing any file and ignoring packages」(初版)

    http://developer.apple.com/technicalqas/index-rev-date.html

    【サンプルソースコード】

    前回から2月9日の期間中、Apple社のSample Codeサイトには、サンプルソースコードがひとつだけ登録されました。これは以前からあったサンプルの再登録なのですが、CocoaをCarbonやC++ルーチンと併用する簡単な例題を示しています。

    「Cocoa_With_Carbon_or_CPP 」(Carbon&Cocoa関連)

    http://developer.apple.com/samplecode/index-rev-date.html

    【デベロップメント SDK】

    前回から2月9日の期間中、Apple社のSDKサイトには新しいSDKがひとつも登録されませんでした。

    http://developer.apple.com/sdk/

    ◇MOSAからのお知らせと編集後記は割愛します◇

                   

     MOSA Developer News   略称[MOSADeN=モサ伝]
            配信停止 mailto:mosaden-ml@mosa.gr.jp
     記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
          記事投稿受付 http://www.mosa.gr.jp/?page_id=850
    Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。このメールの再配信、および掲載された記事の無断転載を禁じます。
    特定非営利活動法人MOSA  http://www.mosa.gr.jp/
    Copyright (C)2007 MOSA. All rights reserved.

  • MOSA Developer News[MOSADeN=モサ伝]第238号

    2007-02-06

    目次

    • 「「Wonderful Server Life」    第36回   田畑 英和
    • 小池邦人の「Carbon API 徒然草」
    • SqueakではじめるSmalltalk入門  第78回   鷲見 正人
    • ニュース・解説               木下 誠

    「Wonderful Server Life」  第36回  田畑 英和

      〜アクセス権編〜

     ハードウェアRAIDのストレージ「Xserve RAID」がアップデートしました。
    今回はまずこのニュースから始めたいと思います。アップデートしたといいましても基本的な仕様は変更ないのですが、利用可能なドライブが250GB、500GBに加え、新たに750GBのドライブも利用できるようになりました。
     Apple Store(Online)で750GBのドライブを14基(Xserve RAIDはドライブを最大14基搭載可能)選択すると計10.5TBのストレージが購入でき、価格は税込みで1,721,607円となります。10.5TBといいましても使用するRAIDのレベルにより、実際に利用可能な容量は少なくなります。ちなみに1GBあたりの価格を計算すると約164円になります。

     Xserve RAIDの管理ツール「RAID Admin」およびファームウェアもアップデートしました。このバージョンでは新たにリリースされた750GBのドライブをサポートするようになっています。またこれまでのバージョンでは「RAID Admin」で設定を変更しても設定項目が一部正しく保存されない問題がありましたが、1.5.1のアップデートでこの問題は解消されました。
     ファームウェアのアップデートですが、「RAID Admin」から実施することができます。「RAID Admin」の「システム」>「ファームウェアをアップデート」メニューから最新のファームウェアのアップデートファイルを選択してアップデートを実施します。ファームウェアのアップデート時にはXserve RAIDの再起動が必要になります。

    ・Xserve RAID Admin Tools v1.5.1
    http://www.apple.com/jp/ftp-info/reference/xserveraidadmintools151.html
    ・「RAID Admin」とファームウェアのアップデートファイルのインストール先「/アプリケーション/ユーティリティ/Xserve RAID Update」
    ・ファームウェアのファイル名
    「firmware-1.5.1-1.51.xfb」

    ◇ACLのアクセス権
     さて、本題のアクセス権に話を戻すとしましょう。前回まではPOSIXのアクセス権の確認方法と「ワークグループマネージャ」を使ったPOSIXのアクセス権の設定方法を解説しました。今回からv10.4で新たに導入されたACLのアクセス権について解説いたします。
     まずACLのアクセス権の概要をPOSIXのアクセス権と比較しながらみていきたいと思います。POSIXのアクセス権ではオーナーとグループは1つずつしか設できませんでしたが、ACLのアクセス権ではユーザおよびグループを複数設定することができます。
     POSIXのアクセス権しか使用できない場合に、例えばグループごとにアクセス権を管理したいとします。あるグループは特定のフォルダに対して「読み出し/書き込み」ができて、別のグループは「読み出し専用」しかできないように設定したいとします。しかしPOSIXのアクセス権ではフォルダに対してグループは1つしか設定できないためこのような設定はできないことになります。ですがACLのアクセス権の場合は複数のグループを1つのフォルダに対して設定できますので、より複雑なアクセス権の管理ができるようになります。

     ユーザ、グループが複数設定できるという特徴に加え、ACLのアクセス権ではPOSIXよりも多くの種類のアクセス権を設定することができます。POSIXのアクセス権は基本的に3種類(読み出し/書き込み/実行)しかありませんが、ACLのアクセス権では3つのカテゴリーに分類された次のような13種類のアクセス権を設定することができます。

    ・ACLのアクセス権の種類
    <情報を管理>
     アクセス権を変更/オーナーを変更
    <読み出し>
     属性を読み込む/拡張属性を読み込む/フォルダの内容を一覧表示
     フォルダをスキャン/アクセス権を読み込む
    <書き込み>
     属性を書き込む/拡張属性を書き込む/ファイルを作成
     フォルダを作成/削除/サブフォルダとファイルを削除

     これらのアクセス権を複数のグループとユーザに対してそれぞれ設定することができます。さらに、ACLのアクセス権には継承の機能があり、フォルダに設定したアクセス権を、フォルダ内のファイルやフォルダに継承させることができます。
     どのレベルまで継承を行うかも設定することができ、継承のレベルとしては次の4種類が用意されています。

    ・ACLの継承のレベル
      このフォルダに適用
      子フォルダに適用
      子ファイルに適用
      すべての子孫に適用

     ACLのアクセス権には継承の機能があるため、個別のファイルにそれぞれアクセス権を設定しなくても、フォルダにアクセス権を設定するだけで、内部のファイル/フォルダのアクセス権を制御することができます。
     ACLのアクセス権のより詳しい仕様についてはMac OS X Serverのマニュアル「ファイルサービスの管理」(P.19)に解説があります。

    ・「ファイルサービスの管理」
    http://images.apple.com/jp/server/pdfs/File_Services_v10.4_j.pdf
                                 
     つづく

    小池邦人のCarbon API 徒然草(2007/02/02)

    〜 Carbonモダンアプリケーションへの道(その9) 〜

    今回からは、Localizable.stringsなどから入手したテキストをウィンドウに表示したりプリントアウト(印刷)したりする状況を考えてみます。Carbonモダンアプリケーションでは、いったいどんなAPIを使えば最良の結果を得られるのでしょうか?

    昔々、ToolBox APIを使ったテキスト描画には、QuickDrawのDrawString()や
    DrawText()、もしくはTextEdit APIのTETextBox()などを選択していました(いや〜懐かしい)。しかし残念ながら、これらのAPIはMac OS X 10.4以降ではすべて「DEPRECATED指定ですので、そのうち消えてしまう運命です。それではテキスト描画を実行するにはどんなCarbon APIを使えば良いのでしょうか?

    最初に思いつくのは、CoreGraphics(Quartz 2D)のテキスト描画用APIを使うことです。CoreGraphicsには、以下の2つのテキスト描画用APIが用意されています。

    void CGContextShowText( CGContextRef c,const char *string,size_t length );
    
    void CGContextShowTextAtPoint( CGContextRef c,float x,float y,const char
                                                     *string, size_t length );

    CGContextShowText()とCGContextShowTextAtPoint()の違いは、先んじてテキスト描画位置をCGContextSetTextPosition()で指示しておくかどうかです。また、描画用フォントのサイズや種類はCGContextSelectFont()で、描画モードはCGContextSetTextDrawingMode()で設定します。QuickDraw環境とは異なりCoreGraphics環境ではテキスト描画位置は左下が原点となり、位置指定用の座標値(X,Y)には浮動小数点(1.0が1/72インチ)を利用しますので注意してください。

    void drawQuartzText( CGContextRef cont )
    {
        CGContextSaveGState( cont );     // 現在のCGContext環境を保存する
        CGContextSetTextDrawingMode( cont,kCGTextFill );     // 塗り文字
        CGContextSetRGBFillColor( cont,1.0,0.0,0.0,1.0 );    // 赤色指定
        CGContextSelectFont( cont,"Geneva",64.0,kCGEncodingMacRoman ); // フォン
    ト
        CGContextShowTextAtPoint( cont,10,10,"Think Different",15 );   // 描画文
    字
        CGContextFlush( cont );          // 描画実行
        CGContextRestoreGState( cont );  // 保存しておいたCGContext環境の復帰
    }
    


    上記ルーチンを実行すると、ウィンドウの左下付近に64ポイントのGenevaフォントで赤色の「Think Different」が描画されます。ちなみCGContextSetTextDrawingMode()で指定できるテキスト描画モードは以下の8種類です。

    enum CGTextDrawingMode {
    
        kCGTextFill,
        kCGTextStroke,
        kCGTextFillStroke,
        kCGTextInvisible,
        kCGTextFillClip,
        kCGTextStrokeClip,
        kCGTextFillStrokeClip,
        kCGTextClip
    };
    


    kCGTextFill指定は文字のペイント描画です、kCGTextStrokeは縁取りのみの描画となります。kCGTextFillStrokeは各パートに別々の色が指定できます。kCGTextInvisibleは描画はしませんが、カレント描画位置のみを移動させます。最後にClipが付いたモードで描画した場合には、現在のクリッピング領域(Current Clipping Path)により描画領域が制限されます。一番最後の、kCGTextClipはテキスト描画はせず、描画対象がクリッピング領域に影響を受けるかどうかの判定に用います。

    テキスト描画での色の指定方法は、CoreGraphicsで描画する他の図形とまったく同じであり、CGContextSetRGBFillColor()やCGContextSetRGBStrokeColor()で指定します。RGBの値は0.0から1.0の範囲で(0.0,0.0,0.0)で黒を(1.0,1.0,1.0)で白を表します。最後の引数は描画時のαチャンネル値(透明度)の指定で、1.0は完全な不透明を表します。また、描画文字のアンチエイリアスを制御したい時にはCGContextSetAllowsAntialiasing()を使います。2つ目の引数にfalseを渡せばアンチエイリアスはOFFになり、trueを渡せば再度ONとなります。

    テキスト描画の位置やその方向は、他の図形描画と同様に、CGContextのCTM(Current Transformation Matrix)の影響を受けます。CTMとは描画用変換マトリックスのことです。例えば、CGContextRotateCTM()で角度を指定すれば、ある位置を中心にテキストを回転させて描画することも可能です(QuickDrawでは難しかった)。先ほどのルーチンのCGContextSaveGState()の次の行に以下の処理を追加すれば、描画テキストを原点(左下)を中心に左回りに45度回転させることができます。

    CGContextRotateCTM( cont,3.1415/4.0 );

    また、同様に以下のルーチンを追加すると、テキストはウィンドウの左上(QuickDrawと同じ座標系)に上下ミラー反転されて描画されることになります。

    void flipQuartzContxt( WindowRef window,CGContextRef cont )
    {
        Rect    prt;
    
        GetWindowPortBounds( window,&prt );
        CGContextTranslateCTM( cont,0.0,(float)(prt.bottom-prt.top) );
        CGContextScaleCTM( cont,1.0,-1.0 );
    }
    


    これらのAPI、使い勝手はQuickDrawのDrawText()と似たようなレベルなのですが、テキスト描画に日本語フォントを指定しようとすると大きな壁にぶつかります。フォント指定方法が良く分からないのです。先ほどの例では、CGContextSelectFont(に”Geneva”という文字列を代入し指定しています。この名称にはPostScriptフォント名を使う必要があるようですが、日本語フォント(例えばヒラギノ)のPostScriptフォント名がすぐに分かりません。そこで、もっと簡単な指定方法がないものかと探してみると、CGContext.hには以下のようなAPIも用意されていました。

    void CGContextSetFont( CGContextRef c,CGFontRef font);

    CGFontRefについては、CGFont.hの方に色々と操作するAPIが定義されていますので、そちらを探してみると、CGFontRefを得るために以下のルーチンが定義されていました。

    CGFontRef CGFontCreateWithPlatformFont( void *platformFontReference );

    で、引数として渡す「platformFontReference」とは何ぞや? ということでヘッダファイルのコメントを読んでみると、「Mac OS XではATSFontRefのことである」と記載されています。そこで今度はATSFont.hを探索して以下の2つのAPIを探し出しました。

    OSStatus ATSFontFamilyGetName(
      ATSFontFamilyRef   iFamily,
      ATSOptionFlags     iOptions,
      CFStringRef *      oName );
    
    ATSFontRef ATSFontFindFromName(
      CFStringRef      iName,
      ATSOptionFlags   iOptions );

    フォントパネルで入手した情報を使いATSFontFindFromName()でフォントのファミリー名を得て、それをATSFontFindFromName()に渡してATSFontRefを得ました。やっとのことでCGContextSetFont()にATSFontRefを渡してCGFontRefを得ることができたわけです。しかし、この方法で手続きとしては正しいような気がしますが…日本語を描画させても文字化けしてしまいます(涙)。

    CGContextSelectFont()に渡すエンコード指定のkCGEncodingMacRomanが間違っているのかと思い、こちらをkCGEncodingFontSpecificに変更してみても正しい描画は行われません。こうなると、さすがにギブアップです(笑)。どのたか、CoreGraphics APIで日本語フォントを指定し正しく日本語を描画する方法をご存じの方はいらしゃいませか?

    まあどちらにしろ、矩形領域指定によるテキストのジャスティフィケーションなど、最低でもTETextBox()レベルのテキスト処理が可能でないと実際の作業では使いものになりません。また、CFStringRefで指定されたテキストやユニコードテキストを描画する時にもこのままでは扱いが大変そうです。そこで、CoreGraphics APIを利用することは止めにして、もう少し高級な(レベルが高い)テキスト描画用APIを探すことにしました。

    次回は、CoreGraphics APIに頼らないテキスト描画を試します。何かと処理が大げさで複雑になりがちな、MLTE(Multilingual Text Engine)APIやATS(Apple Type Services)APIは避けたいところですので、それらには頼らないテキスト描画ルーチンを紹介したいと思います。
                                    
    つづく

    SqueakではじめるSmalltalk入門   第78回  鷲見 正人

    本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、作成した簡易GUIビルダに出力させたスクリプトを、実際にGUIとして動作させてみます。

    ▼出力されたスクリプトをそのまま評価してみる
    前回は、配置したウィジェット情報を出力する側、つまり、メソッド「GuiBuilder >> #generateScriptOf:」の手続きの内容を見て、おおまかには次の流れであることを確認しました。

    1. ‘widget types’に分類してあるメソッドのソースをカタログ化。
    2. 各ウィジェットからレイアウト情報を引き出す。
    3. ソースとレイアウト情報を組み合わせて加工し、スクリプトを構成。
    4. スクリプトをmywindow.stファイルに出力後、あらためてそれを表示。

    たとえば、次図に示すような上半分に二つのリスト枠、下半分に一つのテキスト枠を設置したレイアウトの場合、

    [fig.A]ウィジェットのレイアウト例

    GUIビルダのウインドウメニューから「show script」を選ぶと、前述の手順に従ってスクリプトが生成され、画面に現われます。

    | model window |
    model := Model new.
    window := (SystemWindow labelled: 'My Window') model: model.
    window addMorph: (PluggableListMorph
          on: self
          list: nil
          selected: nil
          changeSelected: nil
          menu: nil) frame: (0.024@0.014 corner: 0.478@0.429).
    window addMorph: (PluggableListMorph
          on: self
          list: nil
          selected: nil
          changeSelected: nil
          menu: nil) frame: (0.483@0.014 corner: 0.979@0.426).
    window addMorph: (PluggableTextMorph
          on: self
          text: nil
          accept: nil
          readSelection: nil
          menu: nil) frame: (0.024@0.444 corner: 0.982@0.97).
    ^ window openInWorld
    


    たしかに、二つのリスト枠(a PluggableListMorph)、ひとつのテキスト枠(a PluggableTextMorph)をウインドウ(a SystemWindow)に配置(#addMorph:frame:)した内容になっていますね。このスクリプトにより、アプリケーションソフトとしての機能こそ持ちませんが、GUIとしては立派に機能するウインドウを生じさせることが可能です。全選択してdo it(cmd +D)してみてください。

    [fig.B]スクリプトの実行結果として現われるウインドウ

    GUIというのは、アプリケーションソフトの実体(モデル)にかぶせる“皮”のようなものです。モデルを適切なものに差し替え、各ウィジェットをそのモデルにしかるべく“接続”することができれば、このスクリプトが記述するウィジェットたちを、特定のモデルの“手足”のように機能させることができるはずです。実際に試してみましょう。

    ▼プロセスブラウザと接続して動作させてみる
    Smalltalkは、言語処理系というよりはOSに近い性質を持つソフトウエアで、事実、かつてはALTOのOSのひとつ(ちなみに、SmalltalkをOSとするときALTOは「暫定ダイナブック」と呼ばれて、これがMacを含めた現在主流のGUIの始祖…)として開発された経緯を持ちます。内部ではプロセスのようなものの管理も行なわれており、そのためのユーティリティソフト「プロセスブラウザ」も存在します。プロセスブラウザは、次の式をdo it(cmd + D)することで起動できます。

    ProcessBrowser open

    OS Xでいうところの「アクティビティモニタ」のようなソフトですね。

    [fig.C]プロセスブラウザ

    プロセスブラウザのGUIの生成は、メソッド「ProcessBrowser >>#openAsMorph」でその内容を読むことができます(上の式の「ProcessBrowser」をドラッグして選択し、browse it(cmd + B)でブラウザを開いた後、メソッドリスト枠から「openAsMorph」を探してクリックします)。実は先ほどの「リスト枠二つ、テキスト枠一つ」というウィジェットの構成は、このプロセスブラウザのGUIを意識したものです。したがって、この#openAsMorphの内容は、GUIビルダが出力した上のスクリプトと、その内容が非常に似通っていることがお分かりいただけると思います。

    では、この#openAsMorphに倣って、先ほどのGUIビルダの出力スクリプトを書き換えてみましょう。

    まず、モデル(model)はa Modelの代わりにa ProcessBrowserに差し替えます。一つめのリスト枠の第一引数(on:キーワード欄)はもちろんmodel、第二引数(list:欄)はプロセス一覧を得るための#processNameList、第三引数(selected:欄)には選択項目インデックスを得るための#processListIndex、第四引数(changeSelected:欄)には選択項目の変更をモデルに伝えるための#processListIndex:、第五引数(menu:欄)には黄ボタンメニューを得るための#processListMenu:を、それぞれすでに記入済みのnilと置き換えます。

    二つめのリスト枠についても同様に#openAsMorphに従い、第一から第五引数について、それぞれ順に、model、#stackNameList、#stackListIndex、#stackListIndex:、#stackListMenu:に置き換えます(セレクタのコロンの有無に注意してください)。

    テキスト枠については、第一、第二引数のみを、それぞれmodelと
    #selectedMethodに置き換え、それ以外はnilのままで結構です。

    | model window |
    model := ProcessBrowser new.
    window := (SystemWindow labelled: 'My ProcessBrower') model: model.
    window addMorph: (PluggableListMorph
          on: model
          list: #processNameList
          selected: #processListIndex
          changeSelected: #processListIndex:
          menu: #processListMenu:) frame: (0.024@0.014 corner: 0.478@0.429).
    window addMorph: (PluggableListMorph
          on: model
          list: #stackNameList
          selected: #stackListIndex
          changeSelected: #stackListIndex:
          menu: #stackListMenu:) frame: (0.483@0.014 corner: 0.979@0.426).
    window addMorph: (PluggableTextMorph
          on: model
          text: #selectedMethod
          accept: nil
          readSelection: nil
          menu: nil) frame: (0.024@0.444 corner: 0.982@0.97).
    ^ window openInWorld

    改めてこのスクリプトを全選択しdo it(cmd + D)すると、今度は“中味”のあるウインドウが現われ、そのままプロセスブラウザとして機能します。出力の順序の関係で、元のプロセスブラウザとは、上段の二つのリスト枠の左右が入れ替わったりしますが、ここではあまり気にする必要はないでしょう(#addMorph:frame:の第二引数の矩形情報を見ることで両者を見分けることは可能です)。

    [fig.D]GUIビルダが生成したGUIで動作するプロセスブラウザ

    ここでは、ウィジェット構成がシンプルなプロセスブラウザを選びましたが、比較的複雑にみえるシステムブラウザでも、GUIビルダ出力スクリプトを介して、元のGUIとほぼ同様に機能するGUIを作り出すことができます。ぜひ、チャレンジしてみてください。

    バックナンバー:
    http://squab.no-ip.com:8080/mosaren/

    ニュース・解説

     今週の解説担当:木下 誠

    ———————————————————————-
    オープンダイアログで、パッケージの内部を表示
    ———————————————————————-

    オープンダイアログを表示するためのNSOpenPanelで、パッケージの中身も表
    示させる方法を解説したQA、「NSOpenPanel – Choosing any file and
    ignoring packages」が公開されています。

    標準のオープンパネルでは、.appや.pluginなどのパッケージは、ファイルと
    して見えます。それを、本来のフォルダとして表示し、内部のファイルにアク
    セスしたいときに使います。

    QA1468: NSOpenPanel – Choosing any file and ignoring packages
    http://developer.apple.com/qa/qa2007/qa1468.html

     

    ◇MOSAからのお知らせと編集後記は割愛します◇

     

    MOSA Developer News   略称[MOSADeN=モサ伝]
            配信停止 mailto:mosaden-ml@mosa.gr.jp
     記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
          記事投稿受付 http://www.mosa.gr.jp/?page_id=850
    Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。このメールの再配信、および掲載された記事の無断転載を禁じます。
    特定非営利活動法人MOSA  http://www.mosa.gr.jp/
    Copyright (C)2007 MOSA. All rights reserved.