Under-Construction

家庭コンピュータ環境の模索 >gemcal の Gtk2 への移植
最終更新 (2005/03/05)


gemcal の Gtk2 への移植

目次

カレンダーと時計が無い

遅ればせながら、OS環境を Vine 2.6 → Vine3.1 にバージョンアップした。何が困ったかというと、良いカレンダー、時計が無い!!!

時計は、GNOME1.4 の AfterStep 時計をGNOMEパネルの左下に入れて使っていた。アナログ表示で、日付曜日も表示される。

afterstep 時計

カレンダーは MHC 付属のgemcal というカレンダーを使っていた。表示の大きさが適切で、繰り返し予定の機能が強力で気に入っている。うちのゴミ出しは、gemcal だよりだ。けっこうルールが複雑なので、ショボイ繰り返し予定では対応できないのだ。メールから予定を直接取り込めるのも便利。

gemcal

Vine 3.1 にしたら、GNOME 2 になって、サイドバーに入る時計が全然付属してこなかった。あと XFce4 がわりとシンプルでカッコ良かったので、そっちを使うことにした。時計は、日付が表示されない(マウスを合わせるとポップアップするけど常時表示されない)のが不満だが、XFce4 のものをサイドバーに入れている。

XFce4 の時計

Vine 3.1 では、GNOME2 になったのにともなって、Gtk2 になっている。また、ruby のバージョンも 1.8 になっている。gemcal は、ruby 1.4 と Gtk1 に対応した ruby-gtk に依存しており、Vine 3.1 の環境では、Gtk1 に対応した、ruby-gtk は入手できない。MHCのサイトMLを覗いてみても、最近、開発がすすんでいて、gtk2 対応されている様子がない。Web で検索してもても、Gtk2 バージョンの gemcal は見つからなかった。

じゃ、自分で対応させてみることにした。どうせ、ユーザは自分なので、完全な対応でなくても、自分が使う範囲で対応してればいいのだから、それぐらいならできるだろう、ってことで。

gemcal2

ruby-gtk2 で動いている gemcal。widget のパッキングがよくわかってないので、すこし表示が太くなっている。

技術的背景

ちなみに、私は、ruby は、日常ほとんど触らない。ruby 1.2 のころ(1999年)に少し触っていたが、5年以上読み書きしていない。ruby の文法とクラス体系はオンラインマニュアルで参照できる。Gtk、Gtk2、(Qt、MS-Windows) のGUIプログラムも未経験だ。1999年ごろ、ruby/Tk を触っていたが、それはGtkのような本格的オブジェクト指向ではなく、Tk の ruby wrapper みたいなものだった。Gtk2 については、ruby-gnome2 のサイトで、クラスライブラリやチュートリアルがオンラインで参照できる。

そんな人間でも、自分が使う範囲での移植作業なら、なんとかできる、ということだ。せっかくソースが付いているので、みなさんも、インストールして使うだけでなく、改造などにもチャレンジしてみて欲しい。

移植のポイント

Gtkから Gtk2になるときに、大きくライブラリの構成が変わっている。gemcal の移植で引っ掛かった点を述べる。

フォントまわりが Pango に移動

### ruby-gtk の場合
FONT  = Gdk::Font .fontset_load(FONTSET)
STYLE_SATURDAY = Gtk::Style .new .set_font(FONT)
label = Gtk::Label .new(str)   # str は EUC
### ruby-gtk2 の場合
FONT  = Pango::FontDescription.new('sans 10')
STYLE_SATURDAY = Gtk::Style .new .set_font_desc(FONT)
label = Gtk::Label .new(GLib.convert(str,"utf-8", "euc-jp"))
# str が EUC の時

Pango が使えるフォントは、次のようなスクリプトで取得できる。(書体関係 Wiki - X でのフォント設定で紹介されていた)

#!/usr/bin/env ruby
require 'gtk2'
Gtk.init
fontsel = Gtk::FontSelectionDialog.new("gtkfontsel").show
fontsel.signal_connect("delete-event"){ Gtk.main_quit }
fontsel.cancel_button.signal_connect("clicked"){ Gtk.main_quit }
fontsel.ok_button.signal_connect("clicked") do
  puts fontsel.font_selection.font_name
  Gtk.main_quit
end
Gtk.main

CList から TreeView へ変更

表形式データを扱う、CList から、表形式とツリー形式を扱うことのできる TreeView へ移行した。TreeView は View だけで、Model には TreeModel(の下位クラスであるListStoreなど)、Iterator には TreeIter、列の表示には TreeViewColumn などのクラス群を使う。

# ruby-gtk で CList を使って、2列の表を作る。
@lst = Gtk::CList .new(['Time', 'Desc']) .column_titles_hide \
                  .set_selection_mode(Gtk::SELECTION_SINGLE) \
                  .set_column_auto_resize(0, true) .unset_flags(CAN_FOCUS) \
                  .set_usize(1, 1)

# CList に行を付け加える。
@lst .append([time, item])
# ruby-gtk で CList を使って、2列の表を作る。

# ListStore を作る
model = Gtk::ListStore .new(String,String)

# TreeView を作る
@lst = Gtk::TreeView .new(model)

# 1列目の表示方法をきめる。
renderer1 = Gtk::CellRendererText.new
renderer1.expander=true
column1   = Gtk::TreeViewColumn.new('item',renderer1,'text' => 0) \
                .set_fixed_width(10) \
                .set_min_width(1) \
                .set_sizing(Gtk::TreeViewColumn::AUTOSIZE)
@lst.append_column(column1)

# 2列目も同様に
renderer2 = Gtk::CellRendererText.new
renderer1.expander=true
column2   = Gtk::TreeViewColumn.new('time',renderer2,'text' => 1) \
                .set_fixed_width(200) \
                .set_min_width(1) \
                .set_sizing(Gtk::TreeViewColumn::AUTOSIZE)
@lst.append_column(column2)

# 行を付け加える。
model = @lst.model
iter = model.append
iter.set_value(0,time)
iter.set_value(1,GLib.convert(item, "utf-8", "euc-jp"))

Text から TextView に変更

マルチカラムテキストのクラスも、Text から TextView(と周辺クラス)に移行して、多機能、本格的になった。同様に Model として TextBuffer などの周辺クラスといっしょに使う。

# ruby-gtk でテキスト

# text を作る
@txt = Gtk::Text .new(nil, nil)

# テキストを書き込む
@txt .insert_text(text, 0)
# ruby-gtk2 でテキスト

# buffer を作る
@buffer = Gtk::TextBuffer .new

# text を作る
@txt = Gtk::TextView .new(@buffer)

# iterator を得る
iter = @buffer.start_iter

# 色を変える場合は、タグを作っておく
@buffer.create_tag("blue_foreground",   "foreground" => "blue")

# テキストを書き込む
@buffer.insert(iter, GLib.convert(text, "utf-8", "euc-jp"), "blue_forground")

その他

改めて書くまでもない雑多なこと。抜けがあるかも。

当初は、この、「その他」に書いてあるぐらいの修正で移植できるのでは、と甘く考えていた。

移植版の配布

移植版を配布します。

配布に問題があるようでしたら、近藤までご連絡下さい。

配布しているファイルにバグがある場合は、私まで連絡していただければ、なんとかしてみるかも知れませんが、基本的には自分が困らない限り放置の方向です。自分でなんとかしてください。

配布内容は、次の3ファイルです。gemcal2 は gemcal の置き換え、mhc-gtk2.rb はmhc-gtk.rb の置き換えです。

gemcal2/
   00copyright
   gemcal2
gemcal2/ruby-ext/lib
   mhc-gtk2.rb

gemcal2-20050310.tar.gz

リンク

MHC Official Homepage
MHC は メール保存の MH 形式をカレンダーに採用したカレンダである。emacs 上で動くメールソフト(Wanderlust など)と協調して、メールから予定を取り込むことができる。そのスケジュールデータに対する ruby-gtk インターフェイスが gemcalになる。gemcal単体でも(emacs を使わなくても)動作可能。
(たぶん、自動で CVS から作成されている)最新版スナップをダウンロードしてきて、改造のベースとする。
MHC ML Log and search
MHC-ML のアーカイブ、検索。2002年12月〜2005年3月現在に至るまで、アーカイブ上で見る限り投稿がない。
Ruby-GNOME2 Project Website
Ruby-GNOME2 の日本語サイト。ruby-gtk2 は ruby-gnome2 に含まれる。Ruby/GTK2 チュートリアルや、API リファレンスがある。夜など、動作が重い。
Pango
Pango についてのドキュメント。
書体関係 Wiki - X でのフォント設定
歴史的事情で複雑になった X のフォントを説明している。Pango の仕組みについても説明している。
オブジェクト指向言語 Ruby
ruby 本家。

ruby, ruby-gtk2 は、私はディストリビューション付属のものを使った。Vine 3.1 なので、apt-get install ほげほげ、でOK。

$ rpm -q ruby
ruby-1.8.1-0vl20

$ rpm -q ruby-gtk2
ruby-gtk2-0.9.1-0vl1


近藤靖浩