MOSA Multi-OS Software Artists

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

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

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

2005-09-06

目次

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

「WebObjects Dev Report」  第20回  田畑 英和

 前回に引き続きシステムで扱うデータについて検討していきます。前回は登録者情報について検討してみましたが、今回はその他のデータについてみていきましょう。

ユーザタイプ

 現在、以下の3種類のユーザタイプを想定しています。

・MOSA会員
・非会員
・事務局(管理者)

 登録したユーザは、それぞれユーザタイプを設定することになりますが、システムを利用するさいにユーザタイプによるアクセス制限をおこないます。例えば「MOSA会員」のみ閲覧可能なページといった制限をおこないます。つまり、アクセスのあったユーザを特定(ログイン認証が必要)して、そのユーザのタイプにより処理を振り分けるということになります。

 こういったユーザタイプの実装方法としては何通りか考えられます。まず、ユーザのEntityにユーザタイプ用のAttributeを用意するのがもっとも単純な実現方法でしょう。たとえばMOSA会員は「1」、非会員は「2」、事務局は「0」といったやり方です。たしかに実現方法は単純なのですが、これでは「1」というユーザタイプがなんであるのかといった情報を別途管理する必要があります。
 そこで2つ目の方法としては、ユーザタイプ用のEntityを別途用意しておき、ユーザEntityとのRelationを設定します。こうすればユーザタイプはユーザとは切り離して管理でき、ユーザタイプに関する属性を一元管理できるようになります。
 また、EOFを用いればオブジェクト指向的アプローチをとることもできます。まず、すべてのタイプのユーザに共通する項目を抽出して、基底ユーザEntityとして定義します。次にその基底ユーザEntityから、各タイプのユーザEntityを派生させ、派生したEntityにはそれぞれのタイプごとに依存する属性情報をAttributeとして追加していきます。このようにモデルを定義すれば、各ユーザタイプをそれぞれ異なったEntityとして表現することができます。

開発者募集情報

 ビジネスマッチングには2種類のやり方があります。1つは登録されているユーザのProfile情報を検索/閲覧し、目的に該当する人材を探すというやり方。もう1つは案件情報を掲載して人材を募集するというやり方です。
 後者の人材を募集するやり方では、まず案件の内容をシステムに入力することになりますが、次のようなデータが考えられます。

・概要
・期間
・開発環境
・言語
・地域/条件等
・開発依頼内容
・備考

 人材を募集する場合は、案件ベースで一時的に募集する場合と、社員を募集する場合がありますが、上記の項目は一時的に募集する場合を想定しています。
 これらのデータですが、基本的には文字列情報として記録することになります。募集情報を検索するとなると、まとまりのあるデータのほうが扱いやすいのですが、募集情報によって様々な要求があるでしょうから、基本的には自由入力とします。言語などは、あらかじめ登録しておいた一覧から選択するような形式でもよいでしょうが、マイナーな言語をどこまで登録するのかといった問題もあります。

評価情報

 マッチング結果として、マッチングの成立件数を記録します。成立の確認をどのようにするかという問題はありますが、マッチング結果はつまり実績になりますので、人材を探すさいに1つの評価基準にもなるでしょう。
 もっともネットオークションなどと違って、短期間で成立件数が増えるようなことはないでしょうが、成立件数の他に会員からの紹介推薦文の掲載もおこないます。こちらは会員同士がお互いに推薦をおこなうというものです。実際にビジネスマッチングをおこなった相手からの推薦があれば、よい評価材料にもなるでしょう。

 さて、ビジネスマッチングシステムとして扱うデータは以上です。他にも細かなデータや、管理用のデータなどが必要になってきますが、主要なデータとしては以上です。今後はこれらのデータをモデルとして定義してから、アプリケーションの開発を進めていきたいと思います。

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

画像ファイルをウィンドウに表示する(その1)

本サンプルアプリケーションでは、データブラウザに登録されたファイル一覧のダブルクリック(もしくは表示ボタンクリック)で、その画像をスクロールバー付きのウィンドウへ表示(オープン)することが可能です。今回からは、自作アプリケーションへの画像表示用ウィンドウの実装について解説していきたいと思います。

Mac OS X 10.2から、Carbon Frameworkには「HIView」という仕組みが導入されました。その仕組みの一部として、「Image View」や「Scroll View」といった新しいユーザインターフェースユニット(旧コントロールの一種)が用意されています。これらと、Carbon Event Handlerををうまく利用することで、画像をスクロールバー付きのウィンドウに表示する機能を簡単に実現することが可能となりました。本サンプルは、このImage ViewとScroll Viewを使うことで、画像ファイルをウィンドウに表示させます。

画像を独立したウィンドウに表示(オープン)させるには、データブラウザの画像ファイル一覧をダブルクリックするか、表示させたい画像ファイルを選択しておいてから、カタログウィンドウの「表示」ボタンをクリックします。後者の場合には、同時に複数の画像ファイルをオープンすることが可能です。前者は、「データブラウザ・コールバックルーチン」を解説した時に紹介した、myNotification()ルーチンが実行していますので、そちらを参照してみてください。後者の場合は、以下のopenSelectedImageFile()ルーチンが実行しています。

#define    MAX_FILE  1000      // カタログに登録できる最大ファイル数

void openSelectedImageFile( WindowRef window,short launch )
{
    unsigned long    i,nb,ct,item[MAX_FILE]; // ファイル最大数は1000
    ControlRef       browser;
    WindowRef        wptr;
    ObjectPtr        optr;

    getMyControlRef( window,BROW_ID,&browser );  // ブラウザのControlRefを得る
    getSelectedDataBrowser( browser,item,&ct );  // 選択されているアイテムを得る
    for( i=0;io_fsc ); // 画像を作成したアプリを起動し
        else                                   // そちらにオープンしてもらう
            openViwerWindow( window,&optr->o_fsc,&wptr );
                                               // 画像表示用ウィンドウをオープン
    }
}


まず最初に、以下のgetSelectedDataBrowser()を使い、データブラウザで選択されている画像ファイルのアイテム番号と、その個数を得ます。

void getSelectedDataBrowser( ControlRef browser,unsigned long item[],
                                                       unsigned long *ct )
{
    long    size;
    Handle  hd;

    *ct=0;
    if( hd=NewHandle( 0 ) ) //アイテム番号を保存するためのHandleを確保
    {
        GetDataBrowserItems( browser,kDataBrowserNoItem,0,
                                              kDataBrowserItemIsSelected,hd );
                                        // 選択されているアイテム番号を得る
        if( size=GetHandleSize( hd ) )  // Handleのサイズを得る
        {
            HLock( hd );                      // Handleをロックする
            BlockMoveData( *hd,item,size );   // 引数のitem[]へコピーする
            *ct=size/sizeof( unsigned long ); // アイテム番号の個数を計算する
        }
        DisposeHandle( hd ); // 確保したHandleを削除
    }
}


アイテム番号から1を引いた値は、カタログウィンドウのプロパティとして保存されているWInfo構造体(以下参照)のw_optr配列の引数と一致します。そこで、getWObject()ルーチンを使い、その番号に対応するObject構造体のポインタを得ておきます。

typedef struct {
                    WindowRef       w_pref;           // 親ウィンドウのWindowRef
                    unsigned long   w_count;          // ObjectPtrの個数
                    ObjectPtr       w_optr[MAX_FILE]; // ObjectPtrのリスト

                }   WInfo,*WInfoPtr,**WInfoHandle;

short getWObject( WindowRef window,unsigned long nb,ObjectPtr *optr )
{
    WInfo    winf;

    if( ! getWInfo( window,&winf ) ) // ウィンドウのプロパティとして
    {                                // 保存されているWInfo構造体を得る
        *optr=winf.w_optr[nb];       // 指定番号のObjectPtrを返す
        return( noErr );
    }
    return( 1 );
}


続いて紹介するのは、openSelectedImageFile()で呼ばれているopenViwerWindow()ルーチンです。最初にimageFileToImage()ルーチンで、画像ファイルからCore Graphics Imageを作り、それを、createMyWindow()ルーチンで作成したウィンドウに表示させます。ウィンドウにImage ViewやScroll Viewを配置するのは、setupViwerWindow()ルーチンの役割です。そして最後に、setupViwerWindowEvent()で必要とされるCarbon Event Handlerが登録されています。

short openViwerWindow( WindowRef window,FSSpec *fsc,WindowRef *wptr )
{
    short               ret=1;
    CGImageRef          image;
    WindowClass         wcls;
    WindowAttributes    watt;
    GWorldPtr           off;
    Rect                drt;

    if( ! imageFileToImage( fsc,&image,&off,&drt ) )
    {                              // 画像ファイルからCore Graphics Imageを作る
        wcls=kDocumentWindowClass; // ウィンドウクラスはドキュメントにセット
        watt=kWindowStandardDocumentAttributes|kWindowLiveResizeAttribute|
             kWindowStandardHandlerAttribute|kWindowCompositingAttribute;
                                   // ウィンドウアトリビュートをセット
        if( ! createMyWindow( fsc->name,'VIEW',wcls,watt,&drt,fsc,wptr ) )
        {                          // 画像表示用ウィンドウの作成
            if( ! setupViwerWindow( *wptr,image ) ) // ウィンドウの各種初期化
            {
                setupViwerWindowEvent( *wptr ); // Carbon Event Handlerの登録
                setWParent( *wptr ,window );    // 親ウィンドウのセット
                ShowWindow( *wptr  );           // ウィンドウを表示する
                ret=0;
            }
            else
                DisposeWindow( *wptr );         // エラーであれば削除する
        }
        CGImageRelease( image );    // 得られたCore Graphics Imageをリリース
        DisposeGWorld( off );       // オフスクリーン用GWorldを削除
    }
    return( ret );
}


画像ファイルを選択し、「表示」の代わりに「起動」ボタンが押された場合には、アプリ起動オプションがONで(引数のlaunchが1)openSelectedImageFile()が実行されます。その時、画像を作成したアプリケーションを起動しているのが、launchApplication()ルーチンです。この処理にはシステムのLaunch Servicesが提供するAPIが利用されています。各APIの詳しい内容については、LSInfo.hやLSOpen.hを参照してみてください。

short launchApplication( FSSpec *fsc )
{
short ret=1;
FSRef ref;

if( ! FSpMakeFSRef( fsc,&ref ) ) // FSSpecからFSRefを作成する
ret=LSOpenFSRef( &ref,NULL ); // 作成したアプリをオープンしそれに渡す
return( ret );
}

次回は、openViwerWindow()から呼ばれているimageFileToImage()ルーチンについて解説します。基本的には、画像ファイルからCore Graphics Imageを作る処理なのですが、Mac OS Xのバージョンにより、その方法が大きく異なることを紹介したいと思います。

つづく

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

 本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。引き続き、ファイルリストの文字化けをフィックスする作業を通じて、Smalltalkならではの便利機能に触れてゆきます。

▼メソッドのバージョンをもとに戻す(バージョン管理システム)
 前回、「FileList >> #readContentsBrief:」というメソッドを改変することで、ファイルリストをテキストエディタモードで呼び出したとき、このメソッドが呼び出されていることを確認しました。もはやこの細工は必要ないので、忘れないうちに元に戻しておくことにします。

 もちろん追加した行を削除して再コンパイルすれば済むことですが、ここではあえて、Smalltalkシステムのバージョン管理機構を使用して、元のバージョンを復活させてみましょう。

 Smalltalkでは、メソッド単位でコンパイルが完結することは、前回すでに体験していただいているとおりです。したがって、バージョン、つまり、改変の履歴も、各メソッドごとに個別に管理されています。注目するメソッドの過去のバージョンを見るには、ブラウザでそのメソッドを閲覧中にウインドウ中段のボタン群の中にある「versions」ボタンをクリックします。

[fig.A]「versions」ボタン
http://squab.no-ip.com:8080/mosaren/uploads/46a.png

 バージョンブラウザの上のペインには、そのメソッドの改変履歴がリストで表示されます。リストには、改変者のイニシャル(最初のメソッド改変のときに尋ねられたり、Utilities setAuthorInitialsでセットされたものです)、改変の日時、クラス名、メソッド名の順に表示されています。リストの上に行くほど最近の改変で、一番上のものが現行バージョンです。ためしに現行バージョンをクリックしてみてください。

[fig.B]バージョンブラウザ
http://squab.no-ip.com:8080/mosaren/uploads/46b.png

 ウインドウ中段、右端の「diff」(差分表示)オプションがオンになっているので、加えられた行は赤く、また、この差分にはありませんが、削除された行は青い色で、さらに取消線が付いた状態で表示されます。

 では、改変を加える前のバージョンに戻してみましょう。上のペインの2行目をクリックして選択します(この時点で、差分の青い取消線表示も確認できるはずです)。選択したバージョンに戻すには、ウインドウ中段のボタン「revert」をクリックします。これだけです。

 ウインドウを切り換え、元のブラウザに戻って確認してみると分かりますが、ちゃんとメソッドは手を加える前のバージョンに戻っています。

▼原因メソッドの呼び出し
 前回の解析の結果、FileList >> #readContentsBrief:の定義中、

f converter: (self defaultEncoderFor: self fullName).

とあるところで正しくコンバータが設定されていないのが、どうやら文字化けの原因であることが分かりました(簡単のため、そういうことにしてください)。ここでコンバータを生成している、#defaultEncoderFor:というメソッドがなにをしているのかを覗いてみることにしましょう。

 Smalltalkのメソッドは、やはりそれ自体がオブジェクトで、自分の定義の中で、どんなメソッドを呼び出しているのか(正確には、呼び出すためのメッセージを送信しているか)を把握しています。たとえば、今、注目している「FileList >> #readContentsBrief:」というメソッドなら、これにmessagesというメッセージを送ることで、自分の定義の中で呼び出しているメソッドの名前の一覧を返してきます。

(FileList >> #readContentsBrief:) messages

=>  a Set(#oldFileOrNoneNamed: #defaultEncoderFor: #not #braceWith:with:with: 
#translated #contentsOfEntireFile #'<=' #next: #readServerBrief #fullName #close 
#converter: #size #format: #isRemoteDirectory #'==')


 この性質を利用して、定義の中で送信されているメッセージに関係した情報をたやすく引き出せるように用意されたUIが、ブラウザ中段やや右寄りに並んでいるボタン「senders」と「implementors」です。これらのボタンをクリックすると、現在ブラウズ中のメソッド名に続いて、メソッドにmessgesメッセージを送信したときに得られるメソッド名の一覧がポップアップします。

[fig.C]「implementors」をクリックしたときポップアップするメニュー
http://squab.no-ip.com:8080/mosaren/uploads/46c.png

 このポップアップから適当なメソッド名を選ぶと、クリックしたのがたとえば「senders」ならsenders of it、つまり、選択した項目と同名のメソッドを呼び出しているメソッドの一覧がブラウズできます。これは、メソッド名をタイプして入力後、選択してcmd-Nとしたのと同じです。同様に「implementors」ならimplementors of it、つまり、選択した項目と同名のメソッドの定義をブラウズできます(cmd-B、もしくはcmd-Mと同じ)。

 今回は、指定したメソッドの定義を見たいので、implementorsボタンをクリックしてdefaultEncoderFor:を選びます。さいわい、この名前を持つメソッドはFileListに定義されたひとつだけです。

[fig.D]FileList >> defaultEncoderFor:の定義
http://squab.no-ip.com:8080/mosaren/uploads/46d.png

 最後の行で、a Latin1TextConverterを返していますが、どうやらこれが文字化けの元凶のようです。試しに、文字化けの起こらないa ShiftJISTextConverterを返すように差し替えて動きを見てみましょう。

 まず、Latin1TextConverterを選択して、Shiftjまでタイプしたあと、cmd-Qとします(クラス名やメソッド名の補完サービス)。すると、ShiftJISTextConverterと完全なクラス名が挿入されるので、そのままaccept(cmd-S)してコンパイルします。

[fig.E]暫定的なFileList >> defaultEncoderFor:の定義
http://squab.no-ip.com:8080/mosaren/uploads/46e.png

 あらためて、どこか適当な場所で、次の式をdo it (cmd-D)してみてください。

(FileStream fileNamed: 'ShiftJisExample.txt') edit

 どうでしょう。文字化けは解消されましたね。次回は、この改変の影響を最小限にするため、ファイルの拡張子が.txtか.textの場合だけa ShiftJISTextConverterを返すような仕組みを設けて、このハックを終わりにしようと思います。

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

ニュース・解説

今週の解説担当:木下 誠

----------------------------------------------------------------------
Developer Transition Resource Centerがオープン
----------------------------------------------------------------------

ADCに、Intelチップへのアプリケーションの移行を促進するためのWebページ、「Developer Transition Resource Center」がオープンしました。基本的に、あちこちに分散していたIntel移行に関するドキュメントの、リンク集となっています。

特に目新しい情報はありませんが、今後追加される情報は、要チェックでしょう。WWDCでの関連するセッションのビデオへのリンクがあるのが、うれしいところです。(視聴にはADCへの登録が必要)

また、Universal Binaryへの移行をまとめた記事、「Adopting Universal Binaries」も公開されていました。Universal Binaryの必要性と、そのために必要なリソースを、まとめて紹介する内容になっています。

Developer Transition Resource Center
http://developer.apple.com/transition/index.html

Adopting Universal Binaries
http://developer.apple.com/macosx/adoptinguniversalbinaries.html

----------------------------------------------------------------------
Xcode 2.1の紹介
----------------------------------------------------------------------

Xcode 2.1の機能を紹介する記事、「Working with Xcode: Building Applications for the Future」が公開されていました。Xcodeが持つ機能を、初めて使う人に紹介するような内容になっています。

事実上、Mac OS Xでの開発環境は、Xcodeただ一つになってしまいました。今後は、Intel対応などのような機能の拡張に加え、他の環境からの移行者を受け入れるための、ユーザインタフェースの拡充が求められるでしょう。

Working with Xcode: Building Applications for the Future
http://developer.apple.com/tools/xcode/xcodefuture.html

----------------------------------------------------------------------
Technical Q&A
----------------------------------------------------------------------

新規Technical Q&Aが、4つ公開されていました。

Core Videoに関するもの(QA1440、QA1401)、QuickTimeのテキストトラックに関するもの(QA1400)、IntelマシンでのJavaアプリケーションに関するもの(QA1295)です。

QA1440: Implementing a CVFillExtendedPixelsCallback
http://developer.apple.com/qa/qa2005/qa1440.html

QA1401: Registering custom pixel formats with QuickTime and Core Video
http://developer.apple.com/qa/qa2005/qa1401.html

QA1400: Adding Unicode characters to Text Media in a Text Track
http://developer.apple.com/qa/qa2005/qa1400.html

QA1295: Java on Intel-based Macintosh Computers
http://developer.apple.com/qa/qa2005/qa1295.html

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

MOSA Developer News   略称[MOSADeN=モサ伝]
記事投稿受付 http://www.mosa.gr.jp/topics/mdn-toukou.html
Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA
Copyright (C)2005 MOSA. All rights reserved.