2011年7月31日日曜日

Office:mac評価版

うわ、出来心でOffice:mac評価版をダウンロード中。VBAがどの程度使えるか、試してみよう。でもファイル関連の操作はだめだろうなあ。

使ったら欲しくなりそうだ。でもなー、結局仕事に使うアプリを自腹で買うの、癪だなあ。Excel単体で13,000強、Office1ライセンスで15,000強、3ライセンスで17,000強か・・・。OSXを仕事用にするのもイマイチ気が進まないし。

でも考えてみたらソフトの値段安くなりましたな。一番最初に買ったOfficeは95、WordとExcelだけのバージョン(・・・だったかな、Word単体だったかな)で2万円以上はした気がする。

VisualC++2.0はバージョンアップ版が59,800でした。買ったけど。プアマンズ「松」と呼ばれた初期「一太郎」でさえ49,800。そしてFD1枚のLotus1-2-3は98,000だった・・・。

この前iPad用に購入したゲームは115円だったもんな。今なら85円になっちゃうのか。

ついでに書くと、Office:macのファイルサイズはおよそ1G、MSのサイトからのダウンロード速度はおよそ250KB/sec。1時間ちょいで落ちてきます。

2400ボー(スペル忘れた)だと、1M落とすのに10分かかってたのを思い出す・・・。

Cocoa 触らず

そんなんでXcodeに全然触れていない。ちょっとモチベーション下がっているのも確か。自分程度の技術でどれだけ作っても、結局使えるアプリは作れそうにもないなあ、とちょっとネガティブ思考気味。

OSX Lion AppleScript : How to get current space # from mission control? - Stack Overflow

この質問に対する答えの追加がなかなか上がってこないのも残念。やはりLionの、Spaces.appに該当する機能に外から触るのは無理か・・・残念。

そうすると、デスクトップでマウスのホイールくるくるしたら何かできる、というアプリでも作ってみようかしら。

自分としては、一番使いそうなのはタスクスイッチャかなあ。なんせiMacは画面がでかいから、Dockにマウスカーソルを動かすのもけっこう手首を使う。

Excel VBA classのメソッドを書いてみた

結局昨日はずーっとWindowsの中にいて、OSXを起動しなかったため日記までつけなかったという。なんせ仕事で、職場の人みんなが使うことになるファイル作りなんでけっこう追いまくられている。ちゃんと完成するかな。

一覧表から必要なデータを読み込んで、児童の氏名をファイル名にして指導要録を1人1ファイルで作る、というところまでできた。

次は
1,評定や所見を別の一覧表からコピーする処理
2,年度ごとに学級編制があれば要録のファイルを移動させる処理

を考えている。

さらに、学年全員分の6年間分の評定その他を入力するシートも作成中。横にどどーっと長い表になった。しかし使うセルの数も1000までいかないので、最近のパソコンやOSやExcelの処理能力からすれば大したことのない表みたい。

2011年7月29日金曜日

読了・小暮写眞館

小暮写眞館 (100周年書き下ろし)
宮部 みゆき
講談社
売り上げランキング: 13969

いやー、まいった。
宮部には毎度圧倒される。

特に第4章になってからは泣きっぱなしになった。年をとって涙腺がゆるくなってきているところに、こんな話を読まされたらたまらない。

風子のお葬式の関わるエピソードとか、うまいよなあ。物語冒頭からずーっとひっぱってきて、一気に放出する謎解き(?)のえぐさ。

考えてみれば、700ページのこの物語、大きな事件とか全然ないお話だった。高校生とその家族・友人の日常を静かに語る、というだけの話でここまで読ませる宮部、恐るべし。

これだけおもしろい作品を読んだら、次に読むものに困る。

Excel VBA classオブジェクトの配列を作る

なーんだ、「ユーザ定義変数」という名前の「構造体」がちゃんとあるのらしい。ま、いいか。classにしておくとメソッドが書けるから、オブジェクト指向っぽくできていいかもしれないし。

classの書き方も、プライベートなメンバとそのセッタ・ゲッタ、という構成にしなくても、publicなメンバにしてしまえば楽だったみたい。

特にセッタ書くなら、プライベートにする意味があまりないような気がする。

VBAは書く必要がある時はたいてい書き方を忘れているという言語で、そのたびにあちこち調べるのが惑わしい。今回も図書館からけっこうな数の入門書を借りているが、一番基本的なことをていねいに解説している本を(見栄をはって)借りていないため、Selectionの中のセルの指定の仕方とか、よくわからなくて悶絶している。

あしたまた図書館にいかなきゃ。

本日は選択範囲から1行ずつセルを読み込んで、「児童」classのメンバに名前とか住所とかセットする、オブジェクトは配列に納めておく、というところまで。

児童の名前で新しいWorkBookを作り、そこに様式1〜3のシートをコピーして、必要なデータを様式1にセットして、という流れを考えている。一人に1ファイル、という作り方。

それとは別に、年度ごとに1学年1ファイルで処理するWorkBookも作る予定。小学校の先生には、児童1人に1ファイル、のほうが自然だろうなあ。今日あった中学校の先生は、1学年1ファイルで、そのファイルを学年で共有する、と言っていた。この辺が小と中のちがいでありますな。

2011年7月28日木曜日

Excel classを作る

暑くてiMacの前にいられない。真夏にiMacを使用するのは初めての経験。(買ったのは昨年の9月)けっこう発熱しますな。

本日も自由時間はExcelの研究。VBAでもclassが書けることを知る。さっそく1つ作ってみた。プロパティのセッタとゲッタだけという、classというより構造体。

それでも
1,とあるセルの内容を読み込み
2,他のセルにコピーする
という動作の見通しがかなり良くなることが判明した。

・・・それにしても、VBエディタの出来の悪さに悶絶する。コード補完ってこんなにありがたいものだったのか。

2011年7月27日水曜日

Excel VBAを勉強する

またまたExcelである。今度は「指導要録」という、学校版住民台帳みたいな書類のExcelファイル化を仰せつかった。

何年もの長きにわたって残す重要書類、ではあるのだけれど、ま、義務教育なので職員が考えているほどの重要性はないのだろう。増して小学校だし。(進学とか就職に関係するわけでもない、というわけで)

もう何年も前からデータはExcelで作って、「指導要録」に直接プリントアウト、という形でのExcelファイル化はされていたが、今回は文部科学省直々の「正式許可」が下りたようだ。すなわち、なんらかの形のコンピュータファイルの状態で保存していい、ということになったみたい。(それでも必ず印刷しておけ、という腰の引けた指示も下りてきている。きっとこっちは文科省からのお達しにはないのだろうけど)

毎年年度末に必ず自分の学級分作成している。それと同じように、Excelファイル化してもかまわないけれど1部印刷、さらにPDF化しておけ、ということで、できるだけ各担任が手間をかけず面倒な作業をしないで済むよう考え中。

PDFはJustのPDFアプリが学校のパソコンにインストールされているので、きっとそれで手間なくできるはず。

問題は、どうやって「児童の進級に合わせて6年間使い続けられるファイル」にするか、だな。

通知表の場合は、成績や所見を大きなテーブルにして、そこからlookupで印刷用のシートにデータを埋めている。学級ごとに1ファイルで済む、と。

指導要録も同じ形でいいか、と思ったのだけれど、途中で必ず学級編制があるんだな。

というわけで「学級1ファイル」よりも「6年間使う個人ファイル」の方が現実的かもしれない。しかしそうなると、40人児童がいたら40個のファイルを編集して、印刷してPDF化しないといけなくなる。これはけっこうな手間だ。当然ミスも多くなるし、ミスを前提に最終チェックする手間も増える。(喜んでパソコンを使う人ばかりではないし・・・というか手書きの方がいい、という人のほうがまだ多いかもしれない)

学級編制でファイルを仕分けするのもできるだけ簡単に済むようにしたい。

埋め込むデータは大きな一覧表、ファイルは個人別で6年間使い続ける、という形にできないか研究している。

当然VBAでマクロを組むわけだが、ファイル操作するとなるとこれはもうプログラミングって感じになるな。40個のセルの中の文字列を読み込んで、それをファイル名にして新しいBookを作り、必要なシートをコピーして、さらにシートの中にできるだけ成績などのデータも埋め込んでいく、という作業になりそうだ。

VBAエディタがもうちょっと高性能だと、作業も楽になるのだろうけど・・・。

2011年7月26日火曜日

Cocoa NSViewのアニメーション(4)

NSViewにアニメーション効果をつける、という勉強。

やりたいことは、デスクトップ上にボタンをひとつ表示して、そのボタンを押すとビヨーンともうひとつのViewが飛び出てくる、という非常に簡単なもの。


大きさ64×64ピクセルのボタン・・・というかNSViewのサブクラス。これをクリックすると


横からびよーんと伸びてくるもうひとつ。

CATransitionのMoveInが一番思い描いているものに近い動きをするようなので、FakeViewとTransitionViewというふたつのViewを用意してやってみたりしていた。結果から言うと、FakeViewを全く透明にしてしまうと望んだ通りの効果が生まれないらしい、ということがわかった。透明度を下げて、少しでも見える状態に描画するとMoveInができるのだが・・・。

NSAnimationContextを使って
    NSAnimationContext* current=[NSAnimationContext currentContext];
    rect.origin.x-=250;
    rect.size.width=300;
    [current setDuration:0.5];
    [[trasitionView animator] setFrame:rect];
こんなふうにも書いてみたが、ビヨーンと飛び出すふうにはならない。もう少し違う書き方をすればいいのか・・・。

とかやっているうちに結局いつものxcatsan師匠のこのページ、

(旧) Cocoaの日々: Windowアニメーション(その3)NSViewAnimation

の解説のとおりにNSViewAnimationでやってみたところ、ほぼ、考えていた「びよーん」が実現できた。一番簡単な方法一番よかった、というよくあるオチ。

次はもう1回クリックしたらピロピロピロ、と引っ込むようにしてみたり、下から出てきたり上に飛び出したりしてみよう。

おもしろくて何度もボタンを押してビヨーンをやってしまった。

2011年7月25日月曜日

Cocoa NSViewのアニメーション(3)

Lion祭りもそろそろ終了で、ゆっくりとCocoaプログラミングのお勉強。

NSView と UIView (フェンリル | デベロッパーズブログ)

を読んだり。
CATransitionでNSViewを入れ替える操作をしてみたり。

しかしどーもうまくいかないなあ。あせらず勉強しよう。

2011年7月24日日曜日

Lion fullscreen

Lionで追加された機能のひとつ、fullscreen mode、正直言ってiMac27inchだと使う気にならない。

たとえばSafari。Yahooがこうなってしまう。


iGoogleだとこうなる。

もともと、ひとつのアプリでスクリーンをほとんど占有されるのが嫌ででかい液晶のモデルを選んでいるわけで、そういうユーザは使うな、ということか。

fullscreenのもうひとつ好きになれないところは、新しいSpace(デスクトップ)を作ってしまうところ。LionのSpacesは右方向か左方向か、リニアにしか動かないのでSpacesの移動に手間がかかる。そのため、Dockでアプリを切り替える操作を多用するようになった。

fullscreenモードになると肝心のDockも隠れてしまうので、タスクの切り替えは⌘+TAB、というマウス派としてはけっこう不満な操作となる。

とまあ、文句をたれていても仕方がない。ただ、Windowsもそうだけど、もっとユーザに選択させてほしいな、とは思う。appleのやり方をユーザに押し付けるのはいかがか。(それがいやならOSXさわらないでね、ということか)

Lion礼賛の記事とか読むといささか鼻白む思いがする。そんなに素敵な進化ではない、と今のところ思うが。

ただ、例えばWifi関連のネットワーク探索のスピードがかなり上がった、とか、Dockの右クリックで出るメニューが改善されている、とか、細かいところで作り込んでいるのは好印象。

2011年7月23日土曜日

Cocoa Spacesはどこへ行った?

答え:Dockに統合された

なんのことかという、自作の豆アプリ「Spin」がLionでまともに動かないのでいろいろ調べてみた、という話。

SpinではいわゆるSpacesを変更するのに@"com.apple.switchSpaces"という名前のNotificationをpostしている。これはまだ有効で、まあまともに機能している。

しかし「現在アクティブなSpacesのNo」を得るのに

CGSGetWorkspace

というプライベート関数を使っており、こっちはまともに機能しなくなっている。
Spacesでのデスクトップの数などはcom.apple.dock.plistに記録されていて、これは現在も有効、かと思ったらデスクトップを増やしても変更が反映されていないからもう使われていないのか。


さらにSpaces関連と思われる2つの.plistが新しくできている。

com.apple.spaces.plist



これはデスクトップ毎のuuid(・・・って何?ですな。ユニークな文字列の識別子らしい)を記録している。増やした分のSpacesもちゃんとあるので、デスクトップの数はこいつで取得すればいいようだ。


com.apple.desktop.plist

こっちはデスクトップ毎の壁紙を記録している。

というわけで現在困っているのがアクティブなデスクトップのNoをどうやって取得するのか。
StackOverflowでも早速同じ趣旨の質問が上がっていて、その回答がDockのclass-dumpで現在遊んでいるので、明日詳しく報告するよ、だった。

OSX Lion AppleScript : How to get current space # from mission control? - Stack Overflow

私もこの回答に習ってDockのclass-dumpをとってみた。WVSpaceとかWVSpaceSwitcherとか、それっぽいクラスがあるなあ。

不幸なことに、こうやって取得したヘッダファイルをどうやって使うのか、素人は全然わからないという。(^^;)

2011年7月22日金曜日

Lion Windowsパーティションが消える

昨日、寝酒を飲み始めてから、rEFItでWin7が起動できなくなっていることに気づいた。bootできるdiskを入れろ、といわれる。

Winのパーティションが消えたのか、それともbootできなくなっただけなのか、今となっては知る由もないが(あわててLionのディスクユーティリティであれこれやってしまったので)「リカバリHDD」パーティションがなにやらやらかしたのだけは確かだ。

我が家のiMacのHDDパーティションは、OSXの他はubuntuのインストール中に作ったパーティションをWin7インストール時にNTFSにフォーマットしなおした変則的な構成で、消したと思っていたswapもちゃんと残っている体たらく。何事かあっても自己責任、というものか。

Linuxとデュアルブートにしていた人たちは大丈夫だったのだろうか。

そんなんで本日はWin7のインストールのし直し。Chorme、Officeと再インストールしてとりあえずは使える状態にしておいた。rEFItそのものは全く問題がなく、逆にWinのDVDを入れたらすぐにWinのICONを表示してくれるようになっていた。以前はちがったような。

2011年7月21日木曜日

Lionインストール後

昨夜はダウンロードに時間がかかりすぎて諦めてiMacの電源を落として寝た。

本日、帰宅後に改めてダウンロードを再開。さすがにすぐに終わってインストールへと進む。
Lionインストーラが表示されているうちでないと、dmgのバックアップができないことを後で知ってがっくりした。もしLionの具合が悪くなったら、Snow Leopardから再インストールが必要になるのかしらん。ま、その辺を心配しても仕方がない。

インストール後にやったことは大きく3つ。

1,dolipo.appがどうやら使えなくなっているようなので、プロクシ使うのを中止
2,ご多分にもれずスクロールバーの進行操作がなじめないので「普通」にもどした(後述)
3,MissionControlの「最新の仕様状況に基づいて操作スペースを入れ替える」オプションを外した。

スクロールバーを世間標準(Windowsなどと同じ向きに操作する)に戻すのに少しとまどった。なんせ私はMicroSoftのインテリマウスを使っている変わり種なので、環境設定でいくら探してもスクロールバーについてのオプションが見つからなかった。

マジックマウスをつなげたら(10ヶ月ぶりに電源を入れた)ちゃんとみつかった。マジックマウスはどうも平べったすぎて使いづらいので、Magic Trackpad買うべきかなあ。

Spacesに関してはおそらくかなり使い勝手が悪くなったと思われる。Spaces一覧画面でDrag&Dropでアプリを入れ替えられたのができなくなっている。ステータスバーに現在のSpacesの番号も表示されなくなったし。

それほど劇的にUIが変わったわけではないので、全て、そのうち慣れるかなあ、という感じがする。

2011年7月20日水曜日

Lion!

9時30分ちょいすぎに「Lion出た!」というつぶやきが流れたの早速リンクをたどってAppStoreのLionのページへ。

勇んで購入しようとしたら、エラーが出て買えなかった。

時間をおいてまたやってみろ、ということなので20分後にまた試す。
3、4回同じ操作を繰り返したら無事買えた。


ダウンロード、どのくらいかかるのやら。

Lion準備

やはりアメリカ時間の7月20日発売、ということなのでインストールのための準備をする。

まずBootCampがどんなことになるのか想像できないため、とりあえず年賀状の住所録だけをWin7上からbackup。(他の大事なデータはDropbox内に全部あった)

で、OSX側は書き散らかしたコードだけ外付けHDDへ。

念のためソフトウェアアップデートを確かめたら、「移行ヘルパ」(?だったかな)のアップデートが来ていたのでそれを落としている。

ふっふっふ、これで万全だろう。あとはきっと明日、だろうなあ。

2011年7月19日火曜日

Lion?

LionとXcode4.1をけっこう楽しみにしている。

うわさによると明日7月20日発売、らしい。
購入する前に年賀状の住所録のバックアップをしなければ。あ、そうかこういうデータこそDropBoxに入れておけばいいのか。

どうするにせよ、Windows7を起動しないといけないのが面倒だ・・・。年賀状作成もOSXで済ませるようにしようかな。(今だに筆王の古いバージョンをそのまま使っている・・・)

Cocoa NSViewのアニメーション(2)

CATransitionについて引き続き調べる。

おそらく非常に有名なアーティクルなのであろう、

CATransitionでトランジションエフェクトを実行する方法 - プログラミングノート

とか、xcatsan師匠

(旧) Cocoaの日々: スライドトランジション

とかを読んで自分でもコードを書いてみた。
xcatsan師匠によるとViewを2つ用意しておいて、それを「入れ替える」形にすることでTransitionが表示する、らしい。

とりあえず自分で試したのは

1,TransitionをつけたいViewのDrawRectでCATransitionを入れてみる
2,superViewになるViewを用意して、addSubViewしたsubViewが描画されるタイミングでTransitionを入れる

結論からいって両方とも「まず自分自身を描画して、それからTransitionをつける」という形になった。
やはり「入れ替わる」ためのViewがいるのね。

ADCのサンプル「ImageTransition」でも2枚の写真を入れ替えてTransitionを表示しているし。ふむふむ。

その実験は明日以降。

2011年7月18日月曜日

Cocoa NSViewのアニメーション

ファイルマネージャは一旦休止。大まかなアウトラインはできたものの、そこから作り込むにはちょっと大変。Finderで十分、なのだからモチベーション維持も難しい。

そんなわけで、本日はNSViewのアニメーションについて調べていた。CAAnimationやら CATransactionやらのドキュメントを読んでもさっぱりわからないけど。(^^;)

BasicCocoaAnimationsというADCのサンプルコードをコピペしてViewを回してみたりもしたが、今イチうまくいかない。ど派手なエフェクトを作るのは難しそうだなあ。

HalfLife2

Boxer.appでDoom2をやってみたら、今度はもっと現代的なシューターがやりたくなってHalfLife2をインストールした。

もともとsteam経由で購入しているので、OSX版も追徴金なしで利用できたわけだが、あまりゲームをする気が起きなかったので未インストールだった。ダウンロードするのに時間もかかるし。

お休みだったのをいいことにのんびりとダウンロード、インストール。購入したころのPCと比べてiMacはさすがに高スペックなので、非常にサクサク動く。人物の表情とかすげーリアル、と大喜びでプレイしたため、昨日は日記を更新する時間がなくなったという。(^_^;)ま、XcodeもいじらなかったからCocoaネタもなかったし。

AppStoreではBorderLandとかCODとか売っているんだから、steamでもOSX版出せよな、という感じ。この前のサマーセールならすごく安く買えたのだが、PC版買ってもしょうがない、とパスしただけにくやしい。

しかしCOD4、もう何年も前のゲームなのに4300円とは・・・ちなみにsteamなら19.99ドルね。半額以下じゃ。PC版だけど。

Steam:Call of Duty® 4: Modern Warfare®

2011年7月16日土曜日

Cocoa Dockの.plistを読み込む

なぜか本日は「Dock」のplistを読み込んで、表示されているappのリストを取得できるか試した。デベロッパドキュメントのあちこちをさまよっているうちに「Property Lists Programming Guide」を読むハメになり、そのサンプルコードがおもしろかったので。

結論からいうと意外と簡単にできる。

    NSError* error;
    NSPropertyListFormat format;
    NSString *plistPath;
    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
                                                              NSUserDomainMask, YES) objectAtIndex:0];
    plistPath = [rootPath stringByAppendingPathComponent:@"Preferences/com.apple.dock.plist"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath]) {
        NSLog(@"What?");
    }
    NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
    NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization 
                                          propertyListWithData:plistXML options:NSPropertyListMutableContainersAndLeaves format:&format error:&error];
    if (!temp) {
        NSLog(@"Error reading plist: %@, format: %lu", error, format);
    }
    NSArray* appArray=[temp objectForKey:@"persistent-apps"];
    NSDictionary *appData=[appArray objectAtIndex:0];
    //NSLog(@"paaData=%@",appData);
    NSDictionary* tileData=[appData objectForKey:@"tile-data"];
    //NSLog(@"tileData=%@",tileData);
    NSDictionary* fileData=[tileData objectForKey:@"file-data"];
    //NSLog(@"fileData=%@",fileData);
    //NSLog(@"URL=%@",[fileData objectForKey:@"_CFURLString"]);
    NSString *urlString=[fileData objectForKey:@"_CFURLString"];
    NSURL* fileURL=[NSURL fileURLWithPath:urlString];

//    NSURL* fileURL=[NSURL URLWithString:[fileData objectForKey:@"_CFURLString"]];
    NSLog(@"URL=%@",[fileURL path]);

うるさく入っているNSLogは無視。

NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];

でplistを読み込むことができたら、あとは
NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization
propertyListWithData:plistXML options:NSPropertyListMutableContainersAndLeaves format:&format error:&error];

とやればNSDictionaryに変換できる。ただサンプルではpropertyListFromDataを使っていたが、ドキュメントによるとpropertyListWithDataに移行せよ、ということなので差し替えてある。

plistそのものはXcodeであらかじめ開いて、keyを確認してある状態。
入れ子になったDictionaryって地道に読み込んでいくしかないのかなあ。

上のコードではDockに配された最初のappのURLを取得している。うちの場合は環境設定。


この手のデータが入手できるということは、Dockに登録されたappをあらかじめ表示できるラウンチャ、なんかを作ることができる、ということだな。うーん、どうしよう。

Boxer.app

たまたま、今日もXcode4用のthemesを探していたら、こんなサイトに行き当たった。

ByteProject

有名なByteProject — BWToolKit 1.2.5 w/o private APIの開発元なのね。

無事「Yozora」と題されたthemeをいただいて、ふと見るとこんな画像が。


ゲームに特化したDOSエミュレータらしい、ということでさっそくインストールしてみた。
起動するとなかなかいい感じ。


インストールするとユーザディレクトリに「DOS Games」というディレクトリを作ってそこにゲームその他を保存するらしい。このディレクトリをFinderで開くとこうなる。


どうやったらこんなふうにカスタマイズした表示になるのか興味津津だけれども、とりあえず添付された体験版ゲームをやってみたりする。X-COMは最近オープンソースでリメイクされてたな、とか思いつつ、手持ちのゲームもインストールしてみた。

後生大事に、今だに「Doom2」のCDROMを持っているところがいかにもおやぢでありますが、15年以上も前に購入してあまりのおもしろさに寝食を忘れかけた思い出のゲームなので捨てられなくて引き出しにいれてあった。というわけで「Doom2」をインストール。


このウィンドウにマウントしたCDを放りこむと、中身を読み込んでインストーラを探し出し、仮想DOSドライブ(?)にインストールしてくれるらしい。

無事インストールできて、うれしくなってついついDoom2で遊んでしまい、CDのデータを完全にコピーする、というインストールの最終段階に行き着かなかったため、一度目のインストールは結局失敗となった。(^^;)


この画面に行き着かないと、次回起動時に「何もないよ」と言われて泣くことになる。

このアイコンをダブルクリックするとDoom2が起動しますな。

サウンドが、すごーくきれいに聞こえる。このゲームをがんばってやっていたころのPCは初めて買ったDOS/V機で(IBMのDOS/VとWin3.1が走っていた、本当の意味のDOS/V機)、サウンドカードがどうも怪しくて音が出たり出なかったりで苦しんだ記憶がある。Doomって物陰に隠れてたり、ちょっと遠くにいるモンスターの息遣いが重要なヒントになるゲームだったので、必死にドライバを組み込んだ記憶が。

こりゃおもしれー、もっと遊べるゲームはないかな、と「DOS game」とググってみたら、

DOS Games Archive: download free classic games (MS-DOS)

Abandonware DOS games: abandonware games download

といったサイトに行き当たる。違法ROMサイトか、と思ったらそういうこともなく、ちゃんとシェアウェア版とか体験版とかをダウンロードするようになっていて、中にはFullバージョンが使えるゲームもある、と。特にAbandonware DOS games: abandonware games downloadのほうはAbandonwareと名付けられたふるーーーいゲームがたくさんあって楽しい。


これとか


これとか。とくダンマスは遊べますなー。PC98版をプレイした経験があるわけだが、全然遜色ない。


というわけで、休日なので遊んでしまった。こういうのも楽しくていい。

2011年7月15日金曜日

Cocoa NSFontManager

NSFontManagerを使ってFontPanelを出してみた。

相変わらずxcatsan師匠のこんなアーティクルがあって、参考になる。

(旧) Cocoaの日々: フォントを変更する(3) NSFontPanelの変更を受け取る

-(void)changeFont:(id)sender{
    NSFont* changedFont=[sender selectedFont];
    [messageFontTextfield setStringValue:[NSString stringWithFormat:@"%@ %.1f",[changedFont displayName],[changedFont pointSize]]];  
}
てな感じで、変更されたFontをNSTextFieldに表示してみた。

stringWithFormatで、floatの小数点以下の表示をどうするのか、けっこう調べるのに時間がかかった。

%.1f

とすれば小数点以下1桁にできることがわかった。「.1」だとわからなくて難儀した。細かい字が読みづらくなっているからなあ。
fontを変更できるようにしよう、なんていう試みも、自分のこの老化現象が原動力。これからのアプリは老人力が高まっている人むけにしないとだめですよ、はっはっは(^^;)。

2011年7月14日木曜日

Cocoa NSFont


こんな感じでPreference、fontの部を作ってみている。NSTabVeiwがTabのままでToolbarをつけていないのはご愛嬌。そのうち気が向いたらつけるかな。

で、fontのeditボタンを押したらFontDialogを出るようにしよう、として、NSFontやらNSFontManagerやらの勉強中。

いろいろなappでFont選択関係のダイアログがどうなっているのか調べたりなんだり。

XcodeのFont選択関係を調べているうちに、Xcode4のThemeってどうなってんの?と興味をもったのが運の尽き。


「Xcode4 Theme」とかでググったら出てくること。で、調子に乗ってインストールして遊んでみた。
うーん、やっぱり初めからついてくる「MidNight」が私は好きかなあ。TextMateからの移植品らしい「BlackBoard」もけっこう見やすいかも。SyntaxColoringがうまく動いていないことがあるような気がするのは気のせいかそれともXcode4のせいか。

2011年7月13日水曜日

Cocoa 環境設定パネルでFontを指定する

Toolbar上にメッセージを表示する窓をつけたので、そこで表示するfontを環境設定パネルから指定できるようにしてみる。

この手の作業は実はやったことがない。ちょうどいい勉強になりそうだ。
とりあえずファイルを表示するTableViewと、ディレクトリを表示するOutlineViewのfontも設定できるようにしておく、と。
まずはメッセージ窓。

PreferenceControllerと表示するウィンドウであるPanelを作って、MainMenuの「Preferences..」とつなげようとしていろいろ悩む。MainMenu関係ってやったことないから迷ってばかり。

IBActionを書いておけば、どのxibからでもFirstResponderでそのアクションを指定できるようだが、クラスメソッドでないとだめだったりして悩んだ。

結局MainControllerにpreferenceControllerというメンバ変数を持たせることにした。

自分ではけっこうCocoaとかXcodeに慣れてきたかなあ、と思っていたけど、同じ作業をやるのにもあれこれ試行錯誤が必要で時間がいくらあっても足りない感じ。もう少し若くて記憶力のよかったころなら・・なんて思うけれど、考えても仕方のないことなのでどんどん前に進むしかない。

こんな感じでバタバタしている間に、OSX LionがリリースされてXcode4.2だったかがリリースされて、ということになりそうだな。

2011年7月12日火曜日

Cocoa TabFile ローカライズを少し(2)

Xcode4のビルド設定を眺めてみたが、ビルド時にLocalizeStringをどーにかするような便利な設定はないようだ。(いや素人目なので落ちはあるかもしれない)

とすると、ローカライズが必要になりそうな文字列を全部NSLocalizedStringで囲んでおいて、あとで一気に genstrings でLocalizable.stringsを生成する、という一般的な方法がやはり一番いいようだ。

ということで当面、UI関係の文字列をNSLocalizedStringで囲む作業だけしておくことにしよう。
今回はそれがわかっただけで大収穫。

それともうひとつは


このappを試すという方法もあるな。ま、もう少し翻訳対象の文字列が増えてからでも全然いいみたいだけど。

2011年7月11日月曜日

Cocoa TabFile ローカライズを少し(Xcode4)

今回はできるだけ初めから

・ローカライズ
・ユーザデフォルト

を考えて作っていこうと思う。で、最初にローカライズ。自分のプロジェクトでまともにローカライズやったことないのでドキドキですな。

とりあえず、Toolbar上のカスタムViewのメッセージを日本語で表示できるようにしてみる。なにはともあれ、プロジェクトを日本語ローカライズ可能にしてみる。プロジェクトのinfoからローカライズを追加すればいい。


この時点でinfoPlist.stringとMainMenu.xibの日本語版が自動でできあがるが、肝心の(と思われる)Localizable.stringsは姿も形もない。

ちょこちょこググって出てくる情報では、

$genstrings -o

とかを使えということなので早速やってみる。ローカライズ関連のファイルはja.lprojというディレクトリに入れるようだ。TabFileのプロジェクトだと、~HOME/Develop/cocoa/TabFile/TabFile/ja.lprojということになる。で、

$genstrings -o ja.lproj TFToolbarMessageView.m
とやってみるとちゃんとLocalizable.stringsが生成されたが・・・残念ながらこれだけでは日本語化してくれなかった。

当然ここで頭を抱えたわけだが、Xcode4からいろいろ変更があったみたいなので、ちょっと足掻いてみた。

genstringsで生成したLocalizable.stringsはこのままだとプロジェクトに自動的に追加されるわけではない。だから手動でやってみた。


わ、今思いついだんたけど、AddFileしたほうがよかったかも(^^;)。ま、いいや。それでこのダイアログが開くので、

先ほど生成されたLocalizable.stringsを上書きで追加。

これで再ビルドしてみたらちゃんと日本語がでた。


しかしこのままだと、いちいち手動でローカライズする文字列を追加しないといけないのか?それとも

$genstrings -o

で上書きすればいいのだろうか。この辺の実験は明日以降。xibもibtoolでやってみないといけないなあ。ユーザデフォルトとprefarenceをいじる予定なのでちょうどいいか。

2011年7月10日日曜日

Cocoa TabFileプロジェクト開始してみた

新しくTabFileという名前でファイルマネージャのプロジェクトを始めてみた。
実験的にガーベジコレクションを有効にしてみたので、これも途中で頓挫する可能性があるな。ま、いいや。当面、retainとかreleaseとかとお別れである。

細かいところはいつもどおり

詳解 Objective-C 2.0 改訂版
荻原 剛志
ソフトバンククリエイティブ
売り上げランキング: 17767

を参照しながら作る、と。

さて、本日はメインウィンドウにNSToolbarはりつけて、ユーザ向けメッセージを表示するカスタムViewを入れてみた。こんな感じ。


もう、まんまXcodeの下手なマネじゃねえか、という(^^;)。カスタムViewの見た目についてはもう少し研究することにする。今はまだ黒で[path fill]しているだけなので。

NSToolbarの設定の仕方もいちいち忘れていて、以前作りかけたPDFKitを使ったプロジェクトを参照した。その手の書き方をちゃんとこのblogにまとめて書いておくと自分としてはかなり便利なんだけど、なかなかそこまでの時間が取れない。残念。

2011年7月9日土曜日

考える

Tabでディレクトリの中身を表示するファイルマネージャを、もう一度頭から書き直すことにして、どこから作業に入るか考えて過ごす。

自分の書いた(書き散らかした)コードを眺めて、下手だよなあとため息をつくことしばし。

Eseのソースを眺めたり、Skimのプロジェクトをあれこれ眺める。
眺めながら、どーせ自分しか使わないよなあ、などという考えが頭をよぎったりもしますな。(^^;)

本日は休養日、全く何もしないで1日を過ごした感じ。それもまたよし。

追記:
とかなんとか書いたあとにやっぱりプロジェクトをいじっていた(^^;)
Tab関係のbugの原因がやっとはっきりしたのが収穫。

2011年7月8日金曜日

Cocoa ファイルの非同期コピー(9)

ひとつのファイルを非同期コピーするクラスを書く。ざっとこんな感じ。コメントはもともとのソースにあったもの。おおもとのソースは

Cocoa Tutorial: File Copy With Progress Indicator

のはず。

#import "FileAsyncCopyer.h"


@implementation FileAsyncCopyer
@synthesize complateCopyBytes,isCopyDone;
-(id)initWithSorceURL:(NSURL*)sURL destURL:(NSURL*) dURL{
    self=[super init];
    if(self){
        sourceURL=[sURL retain];
        distURL=[dURL retain];
        isCopyDone=NO;
       
    }
    return self;
}

- (void) controlCopyingState:(FSFileOperationRef) fileOp
          FileOperationStage: (FSFileOperationStage) stage
                      Status:(OSStatus) error
               DictionaryRef:(CFDictionaryRef)statusDictionary
{
    
    if (error != noErr){
       
    }
    
 if (statusDictionary)
    {
      
  CFNumberRef bytesCompleted;
  bytesCompleted = (CFNumberRef) CFDictionaryGetValue(statusDictionary, kFSOperationBytesCompleteKey);
 
 
  CFNumberGetValue (bytesCompleted, kCFNumberMaxType, &complateCopyBytes);
       
        NSLog(@"コピー済み:%@ %f Bytes",[sourceURL path] ,complateCopyBytes);
    }
 
 if (stage == kFSOperationStageComplete) {
        NSLog(@"コピー完了 %@",[sourceURL path]);
        isCopyDone=YES;
    }
}

static void statusCallback (FSFileOperationRef fileOp,
                            const FSRef *currentItem,
                            FSFileOperationStage stage,
                            OSStatus error,
                            CFDictionaryRef statusDictionary,
                            void *info )
{
    FileAsyncCopyer* entry=(FileAsyncCopyer *)info;
    [entry controlCopyingState: fileOp FileOperationStage: stage Status: error DictionaryRef: statusDictionary];
    
}

-(void)startCopyAsync{
    CFRunLoopRef runLoop = CFRunLoopGetCurrent();
    FSFileOperationRef fileOp = FSFileOperationCreate(kCFAllocatorDefault);
    
    OSStatus status = FSFileOperationScheduleWithRunLoop(fileOp, runLoop, kCFRunLoopDefaultMode);
    if( status )
    {
        NSLog(@"Failed to schedule operation with run loop: %@", status);
        return;
    }
  
    // Create a filesystem ref structure for the source and destination and
    // populate them with their respective paths from our NSTextFields.
    FSRef source;
    FSRef destination;
    
    FSPathMakeRef( (const UInt8 *)[[sourceURL path] fileSystemRepresentation], &source, NULL );
    
    Boolean isDir = true;
    FSPathMakeRef( (const UInt8 *)[[distURL path] fileSystemRepresentation], &destination, &isDir );    
    
    // Start the async copy.
    FSFileOperationClientContext clientContext = {0};
    clientContext.info = self;
    status = FSCopyObjectAsync (fileOp,
                                &source,
                                &destination, // Full path to destination dir
                                NULL, // Use the same filename as source
                                kFSFileOperationDefaultOptions,
                                statusCallback,
                                1.0,
                                &clientContext);
    
    CFRelease(fileOp);
    
    if( status )
    {
        NSLog(@"Failed to begin asynchronous object copy: %@", status);
    }

}
- (void)dealloc
{
    [sourceURL release];
    [distURL release];
    [super dealloc];
}

@end

このクラスにコピー元、コピー先のURLを渡して非同期コピーをする。 FSCopyObjectAsync を起動する以外は、コピー済みbytesを記録するだけ。

現在、動作を確認中。 FSCopyObjectAsync はコピー元としてディレクトリを渡したら、ディレクトリを1つのファイルのように扱ってもらえるようだ。

コピー元がディレクトリの場合、ディレクトリの中を再帰的に探索していってコピーするべきかどうか、とか、コピー済みbytesは正確に得られるかとかの検証は明日以降。

2011年7月7日木曜日

Cocoa ファイルの非同期コピー(8)

ArukanSoftの中の人から「ファイルを一つずつコピーすればいいのでは?」と教えていただいて驚天動地。本当にそうだわなあ。全然思いつかなかった。コピー用に複数のファイルが渡されたら、それを素直にforループ回してコピー、としか考えなかった。

いかん、老化現象かそれとも単に素人だからか、頭が固い。もっと柔らかくいろいろ考えられるようになりたい。

というわけで、昨日わからなくて首をかしげていたNSTreeControllerの件は、モデルクラスでreloadChildrenという強制的にディレクトリ以下を読み直すメソッドを書き足してちゃっちゃと既決箱に放り込む。

で、FSCopyObjectAsyncのラッパクラスと、それを呼び出すCopyManagerを書くことにする。しかし、これはノートに手書きであれこれアイディアを書いたところで終了。
むかーしむかし、会議中のひまな時間は提案文書の片隅に、プログラミングのアイディアを書き留めていたなあ。思考を整理するには手書きメモが一番有効でございますな、私の場合。

コピーしたい複数ファイルとコピー先URLを受け取って、ダイアログを表示したりするのがManagerクラス、実際のコピーを担当するのがラッパクラス、として、それぞれどんなふうに働かせたらいいだろう。明日以降考えてみる、と。

2011年7月6日水曜日

Cocoa NSTreeController ChildNodeの更新・わからず

現在作っているファイルマネージャのようなもの、外見はこうなっている。


左側NSOutlineView、右側NSTableView、というWindowsでいうところのエクスプローラスタイル2ペインウィンドウでありますな。

TableViewからファイルなりディレクトリなりをDragして、他のTabの上にもっていくとそのTabで表示しているディレクトリがアクティブになってDropできる、という仕様。

Dropされた後はSCEventが「ファイルシステムに変更があったぞよ」と通知してくれるので、通知されたNSTableViewは自分自身を更新する。

・・・しかし、NSOutlineViewの方が困った。ファイルシステムはNSTreeControllerでモデルを操作するようにして、NSOutlineViewは表示を受け持っているだけ。だから「reloadItem」は当然使えない。

へ?どうするんだろう、というところで時間切れ。現在ADCサンプルのDragNDropOutlineViewを読んだりしている。

2011年7月5日火曜日

Cocoa bug噴出

ドバーッと一気にいろいろ不具合があるのがわかった。

なんせ今まで、ファイルシステムの変更をリアルタイムにアプリで更新できるようにしていなかった。ところがDrag&Dropでファイルのコピーができるようになって、しかも非同期コピーの実験を繰り返したものだから、ファイルシステム更新関係のbugが次々に現れる。

そろそろ、ちゃんと書きなおす時期に来ているかな、という感じ。とりあえず動けばいい、というコードがたくさんあるので、自分なりに「せめてここまで」と考えるラインまでちゃんと動作を確認しながら書き直すかな。

Tabがらみのbugもあることはわかっていて原因がわからないものがあるので、その辺りからか。
ついでにGC有効にして書いてみるもの一興か。

それとあとはTestだよなー、と考える素人。ObjCでTest書く、なんて参考資料あるのかしらん。

追記:
OCUnitの解説があちこちにあった。(^^;)
ちょこっと勉強してみよう。

2011年7月4日月曜日

Cocoa ファイルの非同期コピー(7)Copyの進捗状況を表示する

たくさんあちこちにbugを含みつつ、とりあえずこんな感じのダイアログを表示しようとしている。


インジケータにコピーしたbytesを表示していくわけだが、これがどうもうまくいかないので調べてみる。

FSCopyObjectAsyncのcallbackには自クラスのselfを引数で渡して、自クラスのメソッドをさらにcallbackする。このほうがIBOutletとかをいじるのが簡単だし、なにかとCocoaスタイルのほうが初心者には都合がいい。で、そのcallbackのcallbackメソッドの中で

bytesCompleted = (CFNumberRef) CFDictionaryGetValue(statusDictionary, kFSOperationBytesCompleteKey);
という風にコピー済みbyteを得ているが、複数ファイルをいっぺんに非同期コピーしていると「どのファイルが、どれだけコピー済みか」がわからない。
そこでcallbackの中でコピー中のファイルのURLを得るようにして、それをcallbackのcallback(・・ええい、面倒くさい)に渡すようにしてみた。

だからcallbackのcallbackはこうなっている。
          FileOperationStage: (FSFileOperationStage) stage
                      Status:(OSStatus) error
               DictionaryRef:(CFDictionaryRef)statusDictionary
                  currentURL:(NSURL*)aURL{
最後のaURLが現在コピー中のファイルのURL。で、callbackが呼ばれるたびにこのURLの中身をNSLogしてみると、なんと、「コピー元」と「コピー先」の両方のファイルについて、それぞれcallbackが呼ばれていることがわかった。

つまり、

/hoge/hoge.txt

から

/hage/hoge.txt

にコピーするとして、コピー元/hoge/hoge.txtが100Kbytes分転送されたらcallbackが呼ばれ、コピー先/hage/hoge.txtが100K転写されたらもう1回callbackが呼ばれ、単純に「コピー済みbytes」を合計すると2倍の数値を得ることになってしまう。だからインジケータがすぐに動かなくなるのか。

そこで

[copyComplatedbytesOfFiles setObject:compBytes forKey:[[aURL path] lastPathComponent]];

みたいなNSMutableDictionaryを作っておいて、hoge.txtが何byte転送済みかを記録しておくことにしてみた。

で、
for(NSNumber* num in bytesArray){
allFileComplatedByte+=[num doubleValue];
}

辞書内のコピー済みbytesを集計してインジケータに設定する、と。

たったこれだけのことだけど、思った通りの動作をしてうれしい。問題はコードがめちゃくちゃ汚いことだな。(^^;)書きなおそう。

あとはこの動作全体をNSOperationに入れてやればいいのだろうが、非同期コピーなので大きなファイルをコピー中に他のファイルをコピーしても十分動作する。これでいいかなあ。
問題はダイアログがぴったり重なって表示されることだなあ。

2011年7月3日日曜日

Cocoa ファイルの非同期コピー(6)

夕方からCocoaプログラミング再開。やっほー。

しかし軽くNSTableViewのカスタムCellに、NSProgressIndicatorを乗せる方法を調べてみて、やっぱり地道にdrawInteriorWithFrame:内で配置するしかなさそうなことを知る。ふーむ、茨の道じゃのお。

気をとり直してファイルの非同期コピーについてもう少し調べてみた。

FSCopyObjectAsyncで複数のファイルをコピーした場合、callback関数はどんな具合に呼ばれるのかNSLogしまくってみる。

FSFileOperationClientContext clientContext = {0};
        clientContext.info = self;
        status = FSCopyObjectAsync (fileOp,
                                    &source,
                                    &destination, // Full path to destination dir
                                    NULL, // Use the same filename as source
                                    kFSFileOperationDefaultOptions,
                                    statusCallback,
                                    1.0,
                                    &clientContext);

こんな感じでclientContextにselfを渡し、callbackは
static void statusCallback (FSFileOperationRef fileOp,
                            const FSRef *currentItem,
                            FSFileOperationStage stage,
                            OSStatus error,
                            CFDictionaryRef statusDictionary,
                            void *info )
{
    NSLog(@"Callback got called.");
    NSLog(@"stage=%u",stage);
    CFURLRef theURL = CFURLCreateFromFSRef( kCFAllocatorDefault, currentItem );
    NSString* thePath = [(NSURL *)theURL path];
    CFRelease ( theURL );
    NSURL* aURL=[NSURL fileURLWithPath:thePath];

    FileCopyManager* entry=(FileCopyManager*)info;
    [entry controlCopyingState: fileOp FileOperationStage: stage Status: error DictionaryRef: statusDictionary currentURL:aURL];
    
}

とりあえずcontrolCopyingState:というメソッドを呼び出すだけにして、controlCopyingState:側で
- (void) controlCopyingState:(FSFileOperationRef) fileOp
          FileOperationStage: (FSFileOperationStage) stage
                      Status:(OSStatus) error
               DictionaryRef:(CFDictionaryRef)statusDictionary
                  currentURL:(NSURL*)aURL{
    if (error != noErr){
        //エラー処理
    }
    
 if (statusDictionary)
    {
  CFNumberRef bytesCompleted;
  bytesCompleted = (CFNumberRef) CFDictionaryGetValue(statusDictionary, kFSOperationBytesCompleteKey);
  
  double doubleBytesCompleted;
  CFNumberGetValue (bytesCompleted, kCFNumberMaxType, &doubleBytesCompleted);
        [allFileIndicator setDoubleValue:doubleBytesCompleted];
  NSLog(@"コピー済み:%@ %f Bytes",[aURL path], doubleBytesCompleted);
    }
 
 if (stage == kFSOperationStageComplete) {
        NSLog(@"コピー完了 %@",[aURL path]);
 }
}

あれこれ表示してみる、と。もともとのコードは以前紹介した
Objective-Cで非同期ファイルコピー | ArukanSoft
こちらのサイトのサンプルプロジェクトからいただいております。感謝。
しかし・・・やっぱりわからないことだらけだ。

2011年7月2日土曜日

iPad2 安売りアプリを買う

EAのゲームがやたらと安くなっていたので(全部115円)、勢いで2つ購入。


MONOPOLY Here & Now: The World Edition (Version 2.4.29) App
カテゴリ:ゲーム
価格:¥115
デベロッパ名:Electronic Arts
リリース日:2008/12/09
対応デバイス:全機種
現Ver.の平均評価: (3.5 / 25件の評価)
通算の平均評価: (3.0 / 509件の評価)
Game Center:非対応
 


Tiger Woods PGA TOUR® 12 (Version 1.0.1) App
カテゴリ:ゲーム
価格:¥115
デベロッパ名:Electronic Arts
リリース日:2011/03/29
対応デバイス:全機種
現Ver.の平均評価: (3.0 / 8件の評価)
通算の平均評価: (3.0 / 10件の評価)
Game Center:非対応
 

リンクの作成には

【30倍速い】iPhone/Macブロガー専用htmlジェネレータAppStoreHelperテスト版 | ひとりぶろぐ

を使わせていただいた。rubycocoaは完全に削除したはずなのに、このappが動く不思議(^^;)。