[gtkmm] ダイアログ | ぽんのブログ

ぽんのブログ

自分用の備忘録ブログです。書いてある内容、とくにソースは、後で自分で要点が分かるよう、かなり簡略化してます(というか、いい加減)。あまり信用しないように(汗

今回は「検索」、「置換/検索」用のダイアログを準備します。

このダイアログで、検索文字列、置換文字列の指定、文頭に向かって検索するか否かを指定します。
これを行うため自作のダイアログを作り、文字列入力用Gtk::EntryとGtk::CheckButtonを持たせる事とします。

以下は「検索」と「置換/検索」用それぞれのダイアログのクラスで、Gtk::Dialog を継承しています。
またGtk::Entryに入力された文字列、checkbuttonの状態を取得するための public な関数を持たせています。

== dialogs.h ==

#include <gtkmm.h>

// 「検索」ダイアログ
class FindDialog : public Gtk::Dialog
{
    Gtk::Entry            *find_entry;    // 検索文字入力
    Gtk::CheckButton    *backwards_checkbutton;

    public:
    FindDialog (const Glib::ustring &title, Gtk::Window &parent);
    ~FindDialog () {}

    const Glib::ustring    get_find_keyword () { return find_entry->get_text (); }
    bool    is_find_backwards () { return backwards_checkbutton->get_active (); }
};

//「置換/検索」ダイアログ
class ReplaceDialog : public Gtk::Dialog
{
    Gtk::Entry            *replace_find_entry;      // 検索文字入力
    Gtk::Entry            *replace_replace_entry;  // 置換文字入力
    Gtk::CheckButton    *replace_backwards_checkbutton;

    public:
    ReplaceDialog (const Glib::ustring &title, Gtk::Window &parent);
    ~ReplaceDialog () {}

    const Glib::ustring    get_find_keyword () { return replace_find_entry->get_text (); }
    const Glib::ustring    get_replace_keyword () { return replace_replace_entry->get_text (); }
    bool    is_replace_backwards () { return replace_backwards_checkbutton->get_active (); }
};


Gtk::CheckButton の状態は get_active () で得られます(checkbuttonが押されていたら true、そうでないなら false)。
それぞれのコンストラクタは以下のようにしました。

== dialogs.cc ==
#include "dialogs.h"

FindDialog::FindDialog (const Glib::ustring &title, Gtk::Window &parent)
    : Gtk::Dialog (title, parent) // 親(Gtk::Dialog)のコンストラクタ呼び出し
{
    Gtk::VBox    *vbox_find_dialog = Gtk::manage (new Gtk::VBox);
    get_vbox ()->add (*vbox_find_dialog);

    Gtk::HBox    *hbox_find_entry = Gtk::manage (new Gtk::HBox);
    vbox_find_dialog->pack_start (*hbox_find_entry, true, true, 0);

    Gtk::Label    *label_find_entry = Gtk::manage (new Gtk::Label ("検索文字列"));
    hbox_find_entry->pack_start (*label_find_entry, false, false, 10);

    find_entry = Gtk::manage (new Gtk::Entry);
    hbox_find_entry->pack_start (*find_entry, false, false, 0);

    backwards_checkbutton = Gtk::manage (new Gtk::CheckButton ("先頭に向かって検索"));
    vbox_find_dialog->pack_start (*backwards_checkbutton, true, true, 0);

    add_button (Gtk::Stock::FIND, Gtk::RESPONSE_APPLY);        // 検索ボタン
    add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);  // キャンセルボタン

    show_all_children ();
}

ReplaceDialog::ReplaceDialog (const Glib::ustring &title, Gtk::Window &parent)
    : Gtk::Dialog (title, parent)
// 親(Gtk::Dialog)のコンストラクタ呼び出し
{
    Gtk::VBox    *vbox_replace_dialog = Gtk::manage (new Gtk::VBox);
    get_vbox ()->add (*vbox_replace_dialog);

    Gtk::HBox    *hbox_replace_find_entry = Gtk::manage (new Gtk::HBox);
    vbox_replace_dialog->pack_start (*hbox_replace_find_entry, true, true, 0);

    Gtk::Label    *label_replace_find_entry = Gtk::manage (new Gtk::Label ("検索文字列"));
    hbox_replace_find_entry->pack_start (*label_replace_find_entry, false, false, 10);

    replace_find_entry = Gtk::manage (new Gtk::Entry);
    hbox_replace_find_entry->pack_start (*replace_find_entry, false, false, 0);

    Gtk::HBox    *hbox_replace_replace_entry = Gtk::manage (new Gtk::HBox);
    vbox_replace_dialog->pack_start (*hbox_replace_replace_entry, true, true, 0);

    Gtk::Label    *label_replace_replace_entry = Gtk::manage (new Gtk::Label ("置換文字列"));
    hbox_replace_replace_entry->pack_start (*label_replace_replace_entry, false, false, 10);

    replace_replace_entry = Gtk::manage (new Gtk::Entry);
    hbox_replace_replace_entry->pack_start (*replace_replace_entry, false, false, 0);

    replace_backwards_checkbutton = Gtk::manage (new Gtk::CheckButton ("先頭に向かって検索"));
    vbox_replace_dialog->pack_start (*replace_backwards_checkbutton, true, true, 0);

    add_button (Gtk::Stock::FIND_AND_REPLACE, Gtk::RESPONSE_APPLY); // 検索/置換ボタン
    add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);                 // キャンセルボタン

    show_all_children ();
}


ラベルの中身は日本語でベタに入れてますが。。。まぁ、日本人向けということで(汗
あと名前は一応 simple-editor.glade のつけ方を真似しています。

大元の simple-editor.rb では、ダイアログのボタンを押した時のハンドラを用意している(?)ようですが、こちらでは ダイアログのレスポンスに動作を決めさせるようにします。
例えば検索ダイアログを呼び出すなら

    FindDialog  diag ("タイトル", parent);

    while (diag.run () == Gtk::RESPONSE_APPLY) {
        Glib::ustring   find_keyward = diag.get_find_keyword ();
        bool find_backwards = diag.is_find_backwards ();

        // 検索の操作

    }

などとして、ダイアログのキャンセルボタンを押す(或いはダイアログを閉じてしまう)まで検索をし続けるようにします。