eog plugin 3.16

随分前に Fedora を 22 にアップデートしたような。
そうだ、自作 eog プラグインの更新を忘れていた!

私的に傑作プラグインだけど、そんなにリネームなんてしないジャン。
ということでとっとと更新しなければ。

Apps/EyeOfGnome/Plugins – GNOME Wiki!

公式は相変わらずヤル気ネェ…
とにかく Gedit 同様に GtkUIManager を排除する必要があるだろう。

GEdit 用に作った奴をコピペして Eog に書き換えてみた。
Eog.App なんて無いよと Python に怒られる、なんでじゃ!

dir(Eog) で調べると Eog.Application らしい、まぎらわしいわ!
AppActivatable も ApplicationActivatable だ、統一してよ。
同じ GNOME 標準アプリといっても企業ではなく GPL だからしかたがないが。

メニューを作ろうとしたけど extend_menu メソッドが使えない。
よく解らないのでソースを落とし reload プラグインを見てみる。
GtkApplicationWindow の activate で突っ込んでいた。
だから統一、、、まあいいか。

この方法だとメニュー排除が凄く面倒臭いようだ。
というか g_menu_item_set_attribute が何故か上手くいかない。
ええい面倒だ、メニューは廃止にしてしまえwww

昨今の GNOME に合わせシンプルにしたといえば皆納得するだろう。
実際筆者はメニューからリネームなんてしたことないもん。

Mac でも F2 をつい何度と押したことか、Mac は Enter なんだよね。
はどうでもよくて。
ということでこんなソースになりました。

renamedlg.py

#-*- coding:utf-8 -*-

#    Eye of GNOME renamedlg plugin version 3.16.0
#    Copyright © 2012 sasakima-nao <sasakimanao@gmail.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    Eye of GNOME Plugins
#    https://wiki.gnome.org/Apps/EyeOfGnome/Plugins
#    Eye of GNOME Reference Manual
#    http://developer.gnome.org/eog/stable/index.html
#
#   2015.06.16 3.16.0
#   Support eog 3.16 (Remove GtkUIManager)
#
#   2012.08.28 3.12.0
#   Support eog 3.12 (Python3)
#
#   2012.08.28 3.0.0

from gi.repository import GObject, Gtk, Eog, Gio, GLib
import os

class RenameDlgAppActivatable(GObject.Object, Eog.ApplicationActivatable):
    """
        Set GMenu and Accelerator
    """
    app = GObject.property(type=Eog.Application)
 
    def __init__(self):
        GObject.Object.__init__(self)
 
    def do_activate(self):
        self.app.add_accelerator("F2", "win.rename", None)
 
    def do_deactivate(self):
        self.app.remove_accelerator("win.rename", None)

class RenameDlgPlugin(GObject.Object, Eog.WindowActivatable):
    """
        Rename Dialog Plugin for eog 3.6
        Actibate from F2 key
    """
    __gtype_name__ = "Rename"
    window = GObject.property(type=Eog.Window)
    def __init__(self):
        GObject.Object.__init__(self)

    def do_activate(self):
        # Add Action
        self.action = Gio.SimpleAction.new("rename", None)
        self.action.connect('activate', self.on_rename)
        self.window.add_action(self.action)

    def do_deactivate(self):
        # Remove Action
        self.window.remove_action("rename")

    def do_update_state(self):
        #self.action.set_enabled(not self.window.is_empty())
        self.action.set_enabled(True)
        pass

    def on_rename(self, action, data=None):
        img = self.window.get_image()
        if img == None:
            return
        fullname = img.get_uri_for_display()[7:]
        path, name = os.path.split(fullname)
        label = Gtk.Label(name)
        entry = Gtk.Entry()
        entry.set_text(name)
        d = Gtk.Dialog( "Rename",
                        self.window,
                        Gtk.DialogFlags.MODAL,
                        (Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT,
                        Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT) )
        vbox = d.get_content_area()
        try:
            vbox.pack_start(label, False, False, 0)
            vbox.pack_start(entry, False, False, 0)
            d.show_all()
            def dlg_ok(self):
                d.response(Gtk.ResponseType.ACCEPT)
            def on_focus_in(self, widget):
                try:
                    # Calculate the number of characters
                    # Converted to a Display Name
                    s = entry.get_text()
                    displayname = GLib.filename_display_name(s)
                    i = displayname.rindex(".")
                    entry.select_region(0, i)
                except ValueError:
                    # Full select
                    pass
            def on_focus_out(self, widget):
                entry.select_region(0, 0)
            entry.connect("activate", dlg_ok)
            entry.connect("focus-in-event", on_focus_in)
            entry.connect("focus-out-event", on_focus_out)
            # Loop until success or Cancel
            while 1:
                if d.run() == Gtk.ResponseType.ACCEPT:
                    text = entry.get_text()
                    if text == "":
                        self.messagebox("File name is empty")
                        entry.set_text(name)
                    elif text == name:
                        self.messagebox("Have not changed")
                    elif  text in os.listdir(path):
                        self.messagebox("Found the same file name")
                    else:
                        # Get the EogListStore
                        store = self.window.get_store()
                        # Rename
                        newname = os.path.join(path, text)
                        os.rename(fullname, newname)
                        # Turn the queue
                        while Gtk.events_pending():
                            Gtk.main_iteration()
                        # Create EogImage
                        f = Gio.file_new_for_path(newname)
                        newimg = Eog.Image.new_file(f)
                        # Insert EogListStore
                        store.append_image(newimg)
                        # EogThumbView
                        tv = self.window.get_thumb_view()
                        tv.set_current_image(newimg, True)
                        # Turn the queue
                        while Gtk.events_pending():
                            Gtk.main_iteration()
                        # Remove Image from EogListStore
                        store.remove_image(img)
                        break
                else:
                    # Cancel Button
                    break
        finally:
            d.destroy()

    def messagebox(self, text):
        dlg = Gtk.MessageDialog(
                self.window,
                Gtk.DialogFlags.MODAL,
                Gtk.MessageType.WARNING,
                Gtk.ButtonsType.OK,
                text)
        dlg.set_title("Eye of GNOME")  
        r = dlg.run()  
        dlg.destroy()
        return r

koruri

Gedit 及び Eye of Gnome プラグイン – L’Isola di Niente

よしよし、キチンとリネーム可能だぞと。
よく見ると update_state ハンドラが実験用のままじゃないか。
特に問題は無いから次の更新で修正しよう、オープンソースはそれでイイ。

*.plugin ファイルの仕様は 3.14 までと変わっていない。
IAge が今でも 2 のまま動く、多分ガン無視しているだけだろうけど。

ところで。
Gedit で今頃気が付いたが 3.16 は単語 W クリックの仕様が変わっていた。
do_update_state 等の W クリック単語選択はアンダーバーを含めるようになた。
以前は区切りになっていたはずなんだが、あの動作に慣れているのでとまどうYO!

Terminal.app

Fedora 使いが MacBook Air を使って約二週間。

実は一番困ったのが端末エミュレーター(Terminal.app)だったりする。
いや普通の人は端末はあまり使わないだろうけど。

Fedora のように Ctrl+D で終了すると bash のみが終了しウインドウが残る。
終了するには command+Q を使うのだが癖でつい何度もやってしまう。
exit を打たなければいけない某 OS よりはいいけど。

それと US キーボードなのにバックスラッシュが¥記号に。
コレは設定で変更できるようだ。

backslash

プロンプト表示でユーザー名が最後というのも気に入らない。
bash なので ~/.bash_profile で PS1 変数を指定すればいいはず。
gnome-terminal の使い方 – L’Isola di Niente
せっかくだから Fedora 等と同じように ~/.bashrc も用意して。

~/.bash_profile

if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH

~/.bashrc

PS1='[\u@\h \W]$ '

を $HOME に用意して再ログイン。
見事に Fedora と同じプロンプトになりました。

ps1

ついでに Fedora デフォルト同様に ~/bin へのパスを通した。
ホームに bin ディレクトリを作りこんな感じのスクリプトを。

edit

#!/bin/bash

for param in $@; do
	open -a /Applications/TextEdit.app $param
done

edit

実行パーミッションン (chmod +x) を忘れずに。
これで Mac でも端末から GUI アプリが使えます。
Linux はこんなことしなくても使えるのに面倒臭い…

てゆーか、もっと Mac らしい使い方をしろよ俺。

Mac x86_64

さて、筆者もついに Mac を手に入れた。
これで Mac 向けアプリの開発、をするかどうか今は解らない。

ところで Mac 向けアプリの C コンパイラは UNIX 系なので gcc である。
困ったことに Xcode 付属品らしい、つまり Xcode を入れる必要がある。

App Store から落とす、って Xcode って 2.57GB もあるんかい!
単なるアプリケーションなのに Fedora iso の二倍って何だよ。
Linux アプリはデカくてもキロバイト単位なので本当にウンザリする。

インストールが終わって即使おうと思ったが gcc が見つからない。
C言語入門 – MacでC言語 – コンパイラ(gcc)のインストール – Xcode – Command Line Tools – Webkaru
こんなページを見つけたけど Yosemite では一度起動すれば自動で入った。

gcc で C/C++ – L’Isola di Niente
OS X はたしか 64bit だったはず。
コンパイラが gcc だから Linux x86_64 と同じ結果になると思う。
上記ページの x86_64 サイズ確認コードを動かしてみる。

以前は sizeof の値を %d にしていたのだが %lu にしろと Warning が出た。
Mac の gcc は Linux より警告レベルを高く設定しているようだ。
ということで %lu 指定に書き換えて普通にビルド、そして実行。

x86_64

やはり Linux x86_64 とまったく同じだね。
日本語を扱う場合は UCS-4 だということに注意しよう。
てか UTF-16 なのは Windows だけなんだが。

しかし /usr/include ディレクトリが存在しないぞ。
スタジオエッチはドコにあるのだ?

stdioh

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include
にあった、なるほど Xcode 必須なわけだ。

まあ Xcode のエディタは思っていたよりシンプルで使えそう。
エディタを探そうと思ったけどコレを使いこなしたほうがよさげ。
というか、なるべくアプリは少なくしたい、デカいのはもう嫌。
私的に必須な逆インデントのショートカットキーもあるので問題ない。

no_modeline

さすがに modeline は使えなかった、惜しい。
ちなみに Gedit は Yosemite では起動すらできなかった。

Connect of Linux and Mac

実は最近 MacBook Air 13inch を買った。
US キーボードだぜ、これでスタバでドヤ顔できるze!
行かないけど、おまけに中古だけど。

GNOME べったりな筆者に何が起こったのだ?
と思われても困る、ずっと前から欲しかったんだし。

サイトを持っていると Mac Safari での表示確認をしたくなるジャン。
プログラミングネタで Mac でのコンパイル結果も書きたいジャン。
US キーボードでないと打ち間違える筆者にはありがたい豊富な US キー中古。
しかも筆者は iPhone 持ちだ、欲しいに決まっている。

いや、MacBook を買おうか本気で迷って出るのを待っていたんだが。
実物に触りペコペコキーボードに萎えて勢いで中古を選んでしまったオチ。

中古だけどとっとと Yosemite に更新。
Safari で自サイトの表示確認、うん問題無かった。
WebKit だから CSS3 は問題ないと思っていたけど安心した。

さて、筆者がまず行うのは Linux との接続ですよね。
共有設定を開きコンピュータ名を決め [ファイル共有] を有効にする。

mac_setting

Fedora を立ち上げ Nautilus から [ネットワークを表示] をクリック。

nautilus_mba

あら、それしかやっていないのにアッサリ。
W クリックして Mac のユーザー名とパスワードを入力。

mba_connect

AFC だけでなく AFP プロトコルにも対応していたのか。
iPhone mount in GNOME | PaePoi

afp

Nautilus をもう一つ立ち上げ普通にドラッグアンドドロップ。
あたりまえのようにコピーできる、もちろん双方向で。
普通にファイル編集もできる、AFP はかなり柔軟なようで。
Mac からのアクセスは知らないけど別にイイよね、SELinux あるし。

Macintosh HD と表示されて驚いたけど /usr/bin とかは表示されない。
でも普通に Application ディレクトリにはアクセスできるという。

applications_directory

Mac のアプリ実体って実行パーミッションの付いたディレクトリなのね。
だからアプリを削除しただけでアンインストール終了なのか、ふむふむ。
同じ UNIX ベースとはいっても Linux とは随分違うんだな。

ということで、Linux は Mac にも普通にアクセスできる。

しかし、もっと早くコレを買えば良かった。
たまに Windows を使うみたいなイライラがまったく無い。

タッチパッドには驚愕した、マジでマウスはいらない。
二本指タップでコンテキストメニュー、三本指でウインドウの移動。
二本指スクロールは GNOME 同様にアクティブでなくとも使える、素晴らしい。

ウインドウは全部 command+Q で閉じる一貫性も GNOME 同様。
おかげで閉じるボタンが左にあっても困らない、まったく使わない。
Control を command に置き換えればほぼ GNOME アプリと同じに使える。
F11 がフルスクリーンならもっと良かったんだが。

ps, ls, grep 等 UNIX コマンドが一通り使えるのでありがたい。
bc も使える、計算もこれで困らないな。

Mac でさえ Linux 風に使おうとする筆者であった。

GtkBuilder

GtkBuilder を入れてみた。
見た目は凄い多機能に見える、どんな感じなんだろう。
ちなみに、コレも dnf コマンドからでないと入らない。

gnome_builder_install

あれ、clang 必須なのかな?
というかこの名前なのに Gtk+ ヘッダは依存関係にはないのかよ。
後で判るけど gcc でよかった、その他必要そうなものも導入しておこう。

早速新規プロジェクトを作ってみよう。
起動すると HDD 内の GPL プロジェクトを自動検索していた。
便利なんだか余計なお世話なのか、大半が参考用なのに。

あらかじめ作業用ディレクトリを作っておいく。
起動したら左上の [New] ボタン、フォルダアイコンのほうをクリック。
先程作ったディレクトリを指定し [Continue] する。

new_proj

configure.ac をプロジェクトファイルとして扱うようだ。
つまり autotools も必須ということみたい。
適当にコードを書いてプロジェクトを保存…

できなかった。

色々試したが autogen.sh 必須。
autotools にて自力で configure.ac を作った後に使うもののようだ。

というか、コイツのビルド機能は autogen.sh を実行するだけ。
そりゃコンパイラはどっちでもいいわ。

一応、autogen.sh は autotools のコマンドをまとめておくスクリプト。
最小限のサンプルを置いておくよ、README のとおりにやってね。
honda-0.0.1.tar.gz

そうそう、Build といっても configure スクリプトを作るまでです。
make 以降は自力。

小物を作って遊ぶには無駄すぎる。
デバッガもない、コレを IDE と言ってもいいのだろうか?
単なるテキストエディタだ。

コード補完や閉括弧自動挿入と初心者大喜びなエディタなのに。
私的に期待外れというかショボすぎて唖然とした。

うーん、今後に期待しとく。