2009年11月8日日曜日

表示専用のカレンダーJSが欲しい

日付を選択するためのカレンダーJSはよく見るのですが、表示に特化したものは余り見ないので。たとえばこんな感じでjQueryのプラグインみたいに使えるカレンダーが欲しいのです。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Calendar object test</title>
<script type="text/javascript" src="js/jquery-1.2.6.min.js" type="text/javascript"></script>
<script type="text/javascript" >
$(function(){
// add a new text and set its style
$("calendar")
.from(2009, 10, 30)
.to(2009, 10, 31)
.text("Halloween")
.color("#ffcccc")
.style("bold")
.backgroundcolor("#ffddcc");
});

// calendar event handling
// use customized Event object which has "day" and "from, to" attr
$("calendar").click(function(e){
day = e.day
this.day(day).text("clicked")
});
$("calendar").select(function(e){
from = e.from
to = e.to
this.from(from).to(to).text("selected")
});
</script>
</head>
<body>
<div id="calendar">Calendar will be shown here</div>
</body>
</html>
どうでしょ?探せばあると思うのですが・・・

2009年11月1日日曜日

PDFをiPhoneから生成するサンプルプロジェクトを公開いたしました

本編はこちら
エラーハンドリング編はこちら

ここまでの成果をgithubにアップいたしました。ダウンロードしてXcodeを開き、ターゲットのビルド設定から開発用コードサインをご自身のものと入れ替えてビルドすれば、すぐにPDF作成がお試しいただけます。
http://github.com/akisute/iPhonePDF

ライセンスはlibHaruと合わせてZLIB/LIBPNG Licenseにしてみました。


当方でも動作確認は行っておりますが、何か不具合ございましたらご一報いただけると幸いです。

2009年10月31日土曜日

libHaru on iPhone: Objective-Cでエラーハンドリング



前回記載できなかったエラーハンドリングについて軽くさわってみました。


■libHaruのエラーハンドリング
http://libharu.org/wiki/Documentation/Error_handlingに詳しく書いてあります。要するに、一番最初のPDFドキュメントを生成するところでエラーハンドラ関数を渡したらあとはエラーが発生するたびにその関数が呼び出されるみたいです。
// まずはヘッダファイルの中で
// ユーザーデータ用の構造体の宣言と、エラーハンドラ関数のプロトタイプ宣言をしておく

typedef struct _PDFService_userData {
HPDF_Doc pdf;
PDFService *service;
NSString *filePath;
} PDFService_userData;

// エラーハンドラ関数のシグネチャは常にこうでなければならない
// 関数名は自由に決めて良いが、引数と返り値は決められている
void PDFService_errorHandler(HPDF_STATUS error_no,
HPDF_STATUS detail_no,
void *user_data);
// 注意点として、エラーハンドラ関数はHPDF_Newより前の行で実装しておかなければならない
// (プロトタイプ宣言しておいてもだめみたいです)
void PDFService_errorHandler(HPDF_STATUS error_no,
HPDF_STATUS detail_no,
void *user_data) {
// ユーザーデータを取得する
// C言語の構造体からでもObjective-Cのクラスが取り出せますよ
PDFService_userData *userData = (PDFService_userData *)user_data;
HPDF_Doc pdf = userData->pdf;
PDFService *service = userData->service;
NSString *filePath = userData->filePath;

// エラーハンドリング後、PDF関連の処理を続行したい場合は
// このHPDF_ResetError関数を呼び出す必要がある。
// これを呼び出さないと後続の処理がうまくいかない。
HPDF_ResetError(pdf);

// 逆にエラーハンドリング後、PDF関連の処理をすべて中断したい場合には
// HPDF_Free関数を使ってpdfオブジェクトを解放するとよい。こうすると、以後の
// HPDF関連の関数はすべて何もしないで終了してくれる。ただし、同じpdfオブジェクトを
// 2回HPDF_Freeしてしまうとエラーになるため、HPDF_HasDocを使って制御すること
HPDF_Free(pdf);
}

// あとはPDFドキュメント生成時に関数とユーザーデータを引数として渡す
int main(int argc, char** args) {
PDFService_userData userData;
HPDF_Doc pdf = HPDF_New(PDFService_defaultErrorHandler, &userData);
userData.pdf = pdf;
userData.filePath = @"/var/tmp/hogehoge.pdf";
// 以下省略
}


■CとObjective-Cをつなげる
C言語的にはこれでよいのですが、Objective-C、ひいてはCocoa Touchフレームワーク的にはこういうエラー処理はdelegateにしてしまったほうが便利です。たとえば、PDFファイルを生成するためのObjective-CクラスPDFServiceに、PDFServiceDelegateを持たせて運用してみましょう。libHaruのエラーハンドラ関数を以下のように作ってみます。
void PDFService_defaultErrorHandler(HPDF_STATUS   error_no,
HPDF_STATUS detail_no,
void *user_data)
{
// ユーザーデータを展開
PDFService_userData *userData = (PDFService_userData *)user_data;
HPDF_Doc pdf = userData->pdf;
PDFService *service = userData->service;
NSString *filePath = userData->filePath;

// 以後のPDF作成処理をすべてストップする
HPDF_Free(pdf);

// Delegate呼び出し
if (service.delegate) {
[service.delegate service:service
didFailedCreatingPDFFile:filePath
errorNo:error_no
detailNo:detail_no];
}
}
あとはこのDelegateを適当なViewControllerなどに準拠させて、
#pragma mark -
#pragma mark delegate method
- (void)service:(PDFService *)service
didFailedCreatingPDFFile:(NSString *)filePath
errorNo:(HPDF_STATUS)errorNo
detailNo:(HPDF_STATUS)detailNo
{
NSString *message = [NSString stringWithFormat:@"Couldn't create a PDF file at %@\n errorNo:0x%04x detalNo:0x%04x",
filePath,
errorNo,
detailNo];
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"PDF creation error"
message:message
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil] autorelease];
[alert show];
}
とすると、冒頭のイメージのようになります。