システム上の全ディスク(disk)の各パーティションにあるファイルシステムのUUIDをGUI上で確認・クリップボードにコピーできるツールを作成
「GUdevライブラリでGNU/Linuxシステム上のデバイス情報を取得する(ページ1/3)」とその続きの記事ではGUdevライブラリを用いてシステム上のデバイスの各種情報を表示するテストを行ったが、これを応用したものとして、システム上の全ディスク(disk)の各パーティションにあるファイルシステムのUUIDをGUI上でツリー構造で確認できるツールを作成した。
選択した項目のUUIDもメニュー項目からクリップボードに簡単にコピーできる。データはGTK+のTreeStoreに格納し、表示はそれに関連付けたツリービューで行っている。並ぶ順番はディスク内の位置(項目UDISKS_PARTITION_OFFSETの値)の並びと同じになるように工夫した。
コンパイルにはVala本体(Valaコンパイラ)の他、GTK+とGUdevの両方の開発パッケージが必要。
画像は仮想マシン上のもの(sdbのディスクはこの画像のために適当に構成/フォーマットしただけ)だが、「VBOX_HARDDISK」の部分はディスクのモデル名となる。
[任意]ファイル名: list-uuid-gtk.vala ライセンス: GPL-3 (or lator)
/* * 全ディスクの各パーティションにあるファイルシステムのUUIDをツリー表示するGUIツール * version 20101108 * (C) 2010 kakurasan * Licensed under GPLv3+ * * valac --pkg posix --pkg gudev-1.0 --pkg gtk+-2.0 list-uuid-gtk.vala -o list-uuid-gtk */ using Posix; using GUdev; using Gtk; using Gdk; namespace ListUuidGtk { class UuidView : Gtk.TreeView { public enum Column { NAME, // デバイス FSTYPE, // ファイルシステム UUID, // UUID OFFSET, // オフセット NUMBER // 項目数 } Gtk.TreeViewColumn col_name; Gtk.TreeViewColumn col_fstype; Gtk.TreeViewColumn col_uuid; Gtk.ImageMenuItem item_copy; Gtk.Menu menu_popup; weak MainWindow win; // weakは参照の循環防止 public UuidView (MainWindow win, Gtk.TreeModel model) { GLib.Object (model: model); // ツリーモデルの関連付け this.win = win; // コラムの作成 this.col_name = new Gtk.TreeViewColumn.with_attributes ("Device/Name", new Gtk.CellRendererText (), "text", UuidView.Column.NAME); this.col_fstype = new Gtk.TreeViewColumn.with_attributes ("File system", new Gtk.CellRendererText (), "text", UuidView.Column.FSTYPE); this.col_uuid = new Gtk.TreeViewColumn.with_attributes ("UUID", new Gtk.CellRendererText (), "text", UuidView.Column.UUID); #if DEBUG var col_offset = new Gtk.TreeViewColumn.with_attributes ("Offset", new Gtk.CellRendererText (), "text", UuidView.Column.OFFSET); #endif // コラムヘッダの中央寄せ this.col_name.alignment = this.col_fstype.alignment = this.col_uuid.alignment = 0.5f; // コラムの追加 this.append_column (this.col_name); this.append_column (this.col_fstype); this.append_column (this.col_uuid); #if DEBUG this.append_column (col_offset); #endif // コンテキストメニュー this.item_copy = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_COPY, null); this.menu_popup = new Gtk.Menu (); this.menu_popup.add (this.item_copy); this.menu_popup.show_all (); // メニューのポップアップ this.button_press_event.connect ((ev) => { if (ev.button == 3) { // データがない部分でコンテキストメニューが開けないようにする // get_path_at_pos()はTreeView内の座標から項目のパスを取得 bool path_at_pos = this.get_path_at_pos ((int) ev.x, (int) ev.y, null, null, null, null); // クリックした場所に項目があるのが確認できた場合のみポップアップする if (path_at_pos) this.menu_popup.popup (null, null, null, ev.button, ev.time); } return false; }); // メニュー項目のハンドラ this.item_copy.activate.connect (this.win.copy_uuid); // シマシマを付ける this.rules_hint = true; // ツリーを展開する this.expand_all (); } } class MainWindow : Gtk.Window { Gtk.AccelGroup accelgroup; Gtk.ImageMenuItem item_quit; Gtk.Menu menu_file; Gtk.Menu menu_edit; Gtk.MenuItem item_file; Gtk.MenuItem item_edit; Gtk.MenuItem item_copy; Gtk.MenuBar menubar; Gtk.ScrolledWindow sw; Gtk.VBox vbox; Gtk.Clipboard cb; UuidView tv; public MainWindow (Gtk.TreeStore ts) { // クリップボード this.cb = Gtk.Clipboard.get (Gdk.SELECTION_CLIPBOARD); // ショートカットキー(アクセラレータ) this.accelgroup = new Gtk.AccelGroup (); this.add_accel_group (this.accelgroup); // メニュー this.item_quit = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_QUIT, accelgroup); this.item_copy = new Gtk.ImageMenuItem.from_stock (Gtk.STOCK_COPY, accelgroup); this.menu_file = new Gtk.Menu (); this.menu_file.add (item_quit); this.menu_edit = new Gtk.Menu (); this.menu_edit.add (item_copy); this.item_file = new Gtk.MenuItem.with_mnemonic ("_File"); this.item_edit = new Gtk.MenuItem.with_mnemonic ("_Edit"); this.item_file.set_submenu (menu_file); this.item_edit.set_submenu (menu_edit); this.menubar = new Gtk.MenuBar (); this.menubar.append (item_file); this.menubar.append (item_edit); // ツリービュー this.tv = new UuidView (this, ts); this.sw = new Gtk.ScrolledWindow (null, null); this.sw.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC); this.sw.add (this.tv); // レイアウト this.vbox = new Gtk.VBox (false, 0); this.vbox.pack_start (this.menubar, false, false, 0); this.vbox.pack_start (this.sw, true, true, 0); this.add (this.vbox); this.set_size_request (100, 50); this.resize (640, 300); // シグナル this.delete_event.connect ((ev) => { Gtk.main_quit (); return false; }); this.item_quit.activate.connect (Gtk.main_quit); this.item_copy.activate.connect (this.copy_uuid); } /** * アクティブなツリービュー項目に相当するTreeStore上の項目のUUID部分をクリップボードにコピー */ public void copy_uuid () { Gtk.TreeIter iter; string uuid; unowned Gtk.TreeModel model; unowned Gtk.TreeSelection selection = this.tv.get_selection (); selection.get_selected (out model, out iter); model.get (iter, UuidView.Column.UUID, out uuid); if (uuid != null) this.cb.set_text (uuid, (int) uuid.length); } } int main (string[] args) { MainWindow win; Gtk.TreeStore ts_disks; Gtk.TreeIter iter_partition, iter_disk = Gtk.TreeIter (), iter = Gtk.TreeIter (); // デバイス情報を問い合わせるクライアント(GUdev.Clientクラス) var c = new GUdev.Client (null); // GTK+の初期化 Gtk.init (ref args); // blockサブシステムの全てのデバイス情報(GUdev.Deviceオブジェクトのリスト)を得る GLib.List<GUdev.Device> devs = c.query_by_subsystem ("block"); if (devs.length () == 0) { printerr ("No devices found in subsystem \"block\"\n"); return EXIT_FAILURE; } // ツリー構造の初期化 ts_disks = new Gtk.TreeStore (UuidView.Column.NUMBER, // 項目数 typeof (string), // デバイス名/表示 typeof (string), // ファイルシステム名/表示 typeof (string), // UUID/表示 typeof (uint64)); // オフセット/非表示 // 各デバイスごとに処理 foreach (GUdev.Device d in devs) { string? devname, devtype; devtype = d.get_devtype (); if (devtype == null) continue; devname = d.get_name (); if (devtype == "disk") { // ディスクのデバイス(sd*, hd*) if (devname.has_prefix ("sd") || devname.has_prefix ("hd")) { // ツリーのトップレベルにディスクのデバイスの項目を追加 // 名前はID_MODELを使用・他の項目は空のまま ts_disks.append (out iter_disk, null); ts_disks.set (iter_disk, UuidView.Column.NAME, "%s - %s".printf (d.get_name (), d.get_property ("ID_MODEL"))); } } else if (devtype == "partition") { string name_disk; // 拡張パーティション(IDが0x05, 0x0f, 0x85のいずれか)は飛ばす if (d.get_property ("UDISKS_PARTITION_TYPE") == "0x05" || d.get_property ("UDISKS_PARTITION_TYPE") == "0x0f" || d.get_property ("UDISKS_PARTITION_TYPE") == "0x85") continue; // ディスクのデバイス名から始まる名前の場合、それにぶら下げる // 例: devname:"sda5" name_parent:"sda - MODELNAME" ts_disks.get (iter_disk, UuidView.Column.NAME, out name_disk); if (devname.has_prefix (name_disk[0:2])) { // ディスクのツリー項目の子を全て読み込んで // オフセット(ディスクの先頭からの位置)値の順になるように適切な位置に追加する // 指し示す項目のオフセット値が現在のデバイスの値より小さければ // そこをinsert_after()の対象にして以下同様に繰り返していく // (ループを抜けたら一番オフセット値が大きな項目の後ろに追加するようにする) // オフセット値が現在のデバイスより大きいものに当たったら // それを対象にinsert_before()で入れてforeach文の次の項目へ(continue) Gtk.TreeIter iter_partition_new; bool insert_after = true; uint64 offset, o; offset = d.get_property ("UDISKS_PARTITION_OFFSET").to_uint64 (); if (ts_disks.iter_has_child (iter_disk)) { // ディスクの項目が子を持っている場合 ts_disks.iter_children (out iter_partition, iter_disk); // 親から最初の子にたどる ts_disks.get (iter_partition, UuidView.Column.OFFSET, out o); if (o < offset) iter = iter_partition; else if (o > offset) { ts_disks.insert_before (out iter_partition_new, iter_disk, iter_partition); ts_disks.set (iter_partition_new, UuidView.Column.NAME, d.get_name (), UuidView.Column.FSTYPE, d.get_property ("ID_FS_TYPE"), UuidView.Column.UUID, d.get_property ("ID_FS_UUID"), UuidView.Column.OFFSET, offset); continue; } else // 通常は同じオフセットのパーティションが複数存在することはない continue; // ディスク項目の子を次へ次へとたどっていく // 中の比較は上と同様 while (ts_disks.iter_next (ref iter_partition)) { ts_disks.get (iter_partition, UuidView.Column.OFFSET, out o); if (o < offset) iter = iter_partition; else if (o > offset) { ts_disks.insert_before (out iter_partition_new, iter_disk, iter_partition); ts_disks.set (iter_partition_new, UuidView.Column.NAME, d.get_name (), UuidView.Column.FSTYPE, d.get_property ("ID_FS_TYPE"), UuidView.Column.UUID, d.get_property ("ID_FS_UUID"), UuidView.Column.OFFSET, offset); insert_after = false; break; } else // 通常は同じオフセットのパーティションが複数存在することはない continue; } // while (ts_disks.iter_next (ref iter_partition)) // ディスクの子に現在のデバイスのオフセット値より小さいものしかなかった場合 // その中の最大(最後)のものの後ろに現在のデバイスを追加する if (insert_after) { ts_disks.insert_after (out iter_partition_new, iter_disk, iter); ts_disks.set (iter_partition_new, UuidView.Column.NAME, d.get_name (), UuidView.Column.FSTYPE, d.get_property ("ID_FS_TYPE"), UuidView.Column.UUID, d.get_property ("ID_FS_UUID"), UuidView.Column.OFFSET, offset); } } else { // まだディスクの項目に子がなければそのまま(そのディスクの項目に)ぶら下げる ts_disks.append (out iter_partition, iter_disk); ts_disks.set (iter_partition, UuidView.Column.NAME, d.get_name (), UuidView.Column.FSTYPE, d.get_property ("ID_FS_TYPE"), UuidView.Column.UUID, d.get_property ("ID_FS_UUID"), UuidView.Column.OFFSET, offset); } // if (! ts_disks.iter_has_child (iter_disk)) } // if (devname.has_prefix (name_disk[0:2])) } // else if (devtype == "partition") } // foreach (GUdev.Device d in devs) win = new MainWindow (ts_disks); win.show_all (); Gtk.main (); return EXIT_SUCCESS; } }
上のVala言語のソースをC言語に処理した段階のものも貼り付ける(XZ圧縮 + Base64)。
[任意]ファイル名: list-uuid-gtk.c.xz.b64 ライセンス: GPL-3 (or lator)
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 0bHEZ/sCAAAAAARZWg==
こちらはValaのない環境でも各ライブラリの開発パッケージだけあれば下のようにしてコンパイルできる。
$ base64 -d list-uuid-gtk.c.xz.b64 | unxz | gcc -O2 -Wall $(pkg-config --cflags --libs gtk+-2.0 gudev-1.0) -o list-uuid-gtk -x c -
関連記事:
- ファイルをBase64エンコード/デコードする
- PyGTKでツリービューにリストのデータ(ListStore)を表示(データを変更可能にする・メモ)
- PyGTKでツリービューにリストのデータ(ListStore)を表示(データを変更可能にする・コード例)
- PyGTKでツリービューに階層を持ったデータ(TreeStore)を表示
- XZ圧縮されたファイルの扱いについて(前半)
- XZ圧縮されたファイルの扱いについて(後半)
- PyGTKでクリップボード上のテキストの内容を扱う
- GUdevライブラリでGNU/Linuxシステム上のデバイス情報を取得する(ページ1/3)
- GUdevライブラリでGNU/Linuxシステム上のデバイス情報を取得する(ページ2/3)
- GUdevライブラリでGNU/Linuxシステム上のデバイス情報を取得する(ページ3/3)
使用したバージョン:
- Vala 0.10.1
- GTK+ 2.20.1
- GUdev 151