月別アーカイブ: 2010年8月

Canzona

連休前で忙しくプログラミングしていないので久々に音楽。

palepoli で検索すると今でもマニアックな漫画が一番上。
つーてもこの作者さんも間違いなく名前のネタ元は同じで Osanna だろう。

まぁこれと The Who の Tommy は何度も紹介していると思うが。
その Osanna のアルバムに Milano Calibro 9 ってのがある。
サントラだと聞いていたので避けていたがつい最近 YouTube で曲を見つけた。

YouTube – OSANNA – Canzona

こんなにグッとくる曲が入っていたとは知らなかった。
CD が全然売れないとかネットでよく見かけるようになった昨今。
やっぱり音楽はどこかで一度は耳にしないと購入するキッカケすら無いよね。

どうでもいいけどイタリアンでカンツォーネとはストレートな名前を付ける
new trolls のコンチェルト・グロッソも合奏協奏曲という意味だし。

テレビをまったく見ないので最近マスゴミが何を流行らせようとしているか知らないけど。
どっちにしろこういう音楽はどうせ流してくれないだろう。

そういえば昔 Il Balletto Di Bronzo の Ys の良さがイマイチ解らなかった。
今なら解るかな?と思ってこれを書きながら聴いてみた。

やっぱり悪くは無いけど自分にはイマイチ良さが解らないや。
評判は恐ろしくイイのだがイタリアン・プログレッシブなら全部オケではないわな。
PFM だけは万人受けすると思うけど。

YouTube – Premiata Forneria Marconi (PFM) – River of life

日本人なんて全然解らない。
ランカとシェリルくらいなものか、いやマジでマクロスの曲は結構いいと思う。

Logicool Mouse M505

ここ最近 Opera でマウス動作の調子が悪い。
クリックが勝手に文字列選択になったりマウスジェスチャ後に右メニューが出たりetc…
Chrome ではなんともない、やっぱりこんなところが Opera だなぁ…

と思っていたけど Chrome でも何か動作が変になってきた!
それどころか GEdit や Nautilus でもマウスで上手く選択ができなくなってきた!

試しにドスパラ BTO 付属の超握りにくいマウスに繋ぎ替えてみる。
Opera のバグだと思っていたマウス動作が全部解決…

Opera ちゃん疑ってごめんよ!

単純に Opera は設計上マウスカーソルに対して強烈に敏感だったということだろう。
Linux Opera の動作がおかしくなったら先にマウスかキーボードを先に疑ったほうがいいかも。
フォント表示がおかしいのは昔からというか毎度のことだけど…

ということで、ようするにマウスが壊れた。

しばらくは今繋いでいるドスパラ BTO 付属のマウスを使ってみよう。
Windows Vista の時に世間の反応と自分の使用感のあまりの違いを見て
「今までと違う考えは積極的に受け入れよう」
と自分で決めたのだから。

と思っていたけど超握りにくいわ軽過ぎるわ反応鈍いわでタマラン!
マウスは自動車のタイヤがクソじゃどうにもならんのと同じでストレスが凄すぎる。
素直に新しいのを買おう…

価格.com – マウス 売れ筋ランキング

Logicool 製ばっかだなぁ…
ちなみに私は今まで Logicool 製しか買ったことが無いのは前に書いたっけ。

しかし今でも Logicool 製か Microsoft 製かの選択肢しか無いんだね。
この二社以外は余程のことがないかぎり、その余程のことなんてありえるのか?

次もやはり Logicool かとも思うけど Windows 7 ノート用にコレを使っている。
Logicool の Bluetooth はコレしか見つからなかっただけなのだが。

反応とか握りやすさはまったく不満が無いてか最高だけどホイールクリックを間違えるのよね。
Bluetooth のせいかスリープ復帰が一瞬遅れる場合がある、2.4GHz タイプなら大丈夫なのかな?
高速ホイールはあんまり使わないしやはりホイールをクリックする方式なマウスががイイ。

有線にするか無線にするかも悩む、なんたって Linux で無線マウスは使えるのか?
検索しまくったら上記の一番人気である M505 ならば何も問題無いみたい。
なにより今更接続コードの存在に制約を受けるのも嫌だしやはり無線式を選びたい。
そうなると M505 を選ぶのが一番いいみたい。

黒が人気だけどシルバーが汚れが目立たないしよさそう。
アマゾンで見つけたけど早速パソコンショップに行って(ぉい!
だってこういうのは実際に手で握って感触を確かめたいんだもの。

と思ったけどショップで握ってみてもイマイチ感覚が解らないや!
とっとと購入し家で試す、二千九百八十円だったからそんなに差は無いし。
どうでもいいけど先日電気屋で買った炊飯器の値段をアマゾンで調べてガックリした…

単三電池二本は付属していたのでそのまま入れる。
重さや重心は M555 とほぼ同じ、形状が全然違うはずなのに握った感触も似ている。
ホイールの位置や高さ、ボタンの傾斜角、親指と薬指が収まる位置関係、床面のすべり具合
といったところを並べて見比べると見事に一致、さすが同じメーカー。

気になっていた無線は Linux マシンなのにスイッチを入れただけで当然のように動いた。
あっけなさすぎ、あぁケーブルの無いマウスってすばらしい。

ということで使いごこちが悪いはずもなくとても快適。
スリープしているのか?というくらい反応も敏感、精度も有線時代と変わらない。
どうしても Bluetooth がいいというのでなければコレ最高です。

ただホイールクリックが少々固いのとホイール左右倒しがボタンとして機能している。
そのせいで Opera でホイールクリックしようとすると「戻る」になってしまったり…
そういうときは

の2つを上記に変更すれば横倒しは左右スクロールになるみたい。
Chrome や GEdit とかはデフォルトで横スクロールしてくれるのに…

SeeMe 5.0.1 and 1.0.5

GtkSharp TreeView Tutorial – Mono

まだ SeeMe for Linux を GTK# で作っていた頃の参考にしたトコ。
よく見ると自作クラスを型として GtkListStore を作成しているコードがあった。
Controlling how the model is used 以下のところね。

こういう型指定って PyGtk でもできるのかな?
可能であればもっと本体のコード量を減らすことができるんだが。
とりあえず Python で同じように SeeMe コードを書きかえてみた。

class Engine():
    def __init__(self, deleted=True, name="New Item", key="", url="", query="",
                post=False, endsp=False, encode="utf8", stype=0, pos=0,
                nameid=0, verb=0, icon="", unique="", usetld=0):
        self.delete = deleted
        self.name = name
        self.key = key
        self.url = url
        self.query = query
        self.post = post
        self.endsep = endsp
        self.encode = encode
        self.stype = stype
        self.pos = pos
        self.nameid = nameid
        self.verb = verb
        self.icon = icon
        self.unique = unique
        self.usetld = usetld

class SeeMe4(gtk.Window):
    def __init__(self, sset):
        gtk.Window.__init__(self)
        #...
        #self.default_liststore = gtk.ListStore(bool, str, str, str, str, bool, bool, str, int, int, int, int, str, str, int)
        self.custome_liststore = gtk.ListStore(Engine)

型指定の時点で駄目ジャン…
property にしてみたり小細工してみたりしたけど無駄な努力だった。
Python では変数宣言しただけでは型が決まっていないので当然なのかも。

gtk.ListStore

ま、公式の Constructor 解説には C 言語と同じ型を全部書く方法しか書かれていない。
できないことは素直に諦めて、せめて GtkListStore への append をもう少し簡単にやれないか?

てか、そうしておかないと後々のメンテで沢山書き換えを行わなければいけなくなる。
後で書き換えが必要だろう箇所が少なければ少ないほどミスが減るのよね。
というかソレがオブジェクト指向最大のメリットなのだし。

よく考えたら SeeMe で GtkListStore の型は一つしか無い。
だったら GtkListStore サブクラスを作ってコンストラクタでとっとと型を指定。
ついでに Engine クラスを受け取る add メソッドを作れば簡単になるかな?

class Engine():
    def __init__(self, deleted=True, name="New Item", key="", url="", query="",
                post=False, endsp=False, encode="utf8", stype=0, pos=0,
                nameid=0, verb=0, icon="", unique="", usetld=0):
        self.delete = deleted
        self.name = name
        self.key = key
        self.url = url
        self.query = query
        self.post = post
        self.endsep = endsp
        self.encode = encode
        self.stype = stype
        self.pos = pos
        self.nameid = nameid
        self.verb = verb
        self.icon = icon
        self.unique = unique
        self.usetld = usetld

class CreateListStore(gtk.ListStore):
    def __init__(self):
        gtk.ListStore.__init__(self, bool, str, str, str, str, bool, bool, str, int, int, int, int, str, str, int)

    def add(self, en):
        return self.append( [en.delete, en.name, en.key, en.url, en.query,
                en.post, en.endsep, en.encode, en.stype, en.pos,
                en.nameid, en.verb, en.icon, en.unique, en.usetld] )

class SeeMe4(gtk.Window):
    def __init__(self, sset):
        gtk.Window.__init__(self)
        #...
        self.custome_liststore = CreateListStore()
        #...

    def read_default_searchini(self):
        self.default_liststore.clear()
        inipath = self.sset.default_path
        lngpath = self.sset.lang_path
        if os.path.exists(inipath):
            ini = inifile8.Inifile(inipath)
            lng = inifile8.InifileReader(lngpath)
            try:
                self.iniver = ini.read_int("Version", "File Version", 0)
                i = 0
                while 1:
                    i += 1
                    s = "Search Engine %i" % i
                    if not ini.section_exists(s):
                        break
                    t = ini.read_str(s, "Key", "")
                    if t == "":
                        continue
                    en = Engine();
                    en.nameid = ini.read_int(s, "Nameid", 0);
                    if en.nameid != 0:
                        # Get View Name from *.lng
                        if en.nameid == 17171:
                            en.name = lng.read_str("Translation", "1632215285", "")
                        elif en.nameid == 17183:
                            en.name = lng.read_str("Translation", "-1971470391", "")
                        elif en.nameid == 71103:
                            en.name = lng.read_str("Translation", "-1453429782", "")
                        else:
                            en.name = lng.read_str("Translation", str(en.nameid), "")
                        if en.name == "":
                            n = -1752227277 - en.nameid;
                            en.name = lng.read_str("Translation", str(n), "")
                    else:
                        en.name = ini.read_str(s, "Name", "")
                    en.key = t
                    en.url = ini.read_str(s, "URL", "")
                    en.query = ini.read_str(s, "Query", "")
                    en.post = ini.read_bool(s, "Is post", False)
                    en.endsep = ini.read_bool(s, "Has endseparator", False)
                    en.encode = ini.read_str(s, "Encoding", "utf-8")
                    en.stype = ini.read_int(s, "Search Type", 0)
                    en.pos = ini.read_int(s, "Position", -1)
                    en.verb = ini.read_int(s, "Verbtext", 0)
                    en.delete = True #!
                    en.unique = ini.read_str(s, "UNIQUEID", "")
                    en.icon = ini.read_str(s, "ICON", "")
                    en.usetld = ini.read_int(s, "UseTLD", 0)
                    """self.default_liststore.append( [
                            en.delete, en.name, en.key, en.url, en.query,
                            en.post, en.endsep, en.encode, en.type, en.pos,
                            en.nameid, en.verb, en.icon, en.unique, en.usetld] )"""
                    self.default_liststore.add(en)

    def on_item_new(self, widget, event=None):
        uid = self.create_uuid()
        num = self.deditor.get_radio_num()
        if num == 2:
            num = -1988219522
        else:
            num = 0
        en = Engine(verb=num, unique= uid)
        #it = self.custome_liststore.append( [True, "", "", "", "", False, False, "utf-8", 0, -1, 0, num, "", uid, 0] )
        it = self.custome_liststore.add(en)

コードは全然短くならないけど Engine を直で渡して展開できるようになった。
デフォルト引数によってアトリビュートの型も大半が気にしないでいいという。
読み込みや新規アイテムで順番を気にする必要が無くなったのはデカい。
これなら後々で順番の入れ替えや追加の必要があっても型側で調節できる。

ただこのコードでは展開するために for ループにすると

for row in self.default_liststore:
    if row[0] == False:
        i += 1
        s = "Search Engine %i" % i
        ini.write_str(s, "UNIQUEID", row[13])

添字アクセスにするしか無いんだなぁこれが、意味ネェ。
イテレーターは整数による順番という概念を使わないことに意義があるのだが。
この部分については WPF は徹底的にやっている感じ、よく考えて作られているよ。
ここをアトリビュートで取り出すサブクラスをどうすれば作れるか考え中。

ということで重複キーチェック追加や不具合修正で Linux 版更新。
キーボードショートカットを増やしたり不具合修正で Windows 版も更新。

「こんなことができると楽」
な方法を考えている時がアプリケーション作りで一番楽しいです。