Dokončujeme textový editor v Gtkmm

Tomáš Velecký 19. 4. 2011

Tento díl seriálu o Gtkmm vylepšuje nás textový editor nutnými novými widgety. Většina z nich jsou prachobyčejné widgety, nicméně tři z nich ale tvoří hned několik widgetů najednou. Ano, jsou to standardizovaná dialogová okna. Pro rychlou úpravu textu se hodí schránka, která také nezůstane opomenuta.

Dialog na otevření souboru

Všechna dialogová okna, která něco dělají se soubory nebo složkami, je vlastně jedna a ta samá třída, FileChooserDialog. Hlavní informace, tedy, jaký bude mít dané dialogové okno název a co má dělat, předáváme přímo konstruktoru. Na výběr máme tyto typy:

  • FILE_CHOOSER_AC­TION_OPEN
  • FILE_CHOOSER_AC­TION_SAVE
  • FILE_CHOOSER_AC­TION_SELECT_FOL­DER
  • FILE_CHOOSER_AC­TION_CREATE_FOL­DER

Takto vypadá např. dialog na uložení souboru:

Dále můžeme pomocí metody add_button() přidávat tlačítka. To si buď pojmenujeme sami (typ Glib::ustring), nebo zvolíme jeden z BuiltinStockID. Těch je docela dost, proto je zde nebudu vypisovat, ale pouze na ně odkazuji. K tlačítkům se vždy přiřadí událost (signál), která se vygeneruje, když se na dané tlačítko klikne. Několik událostí už je předdefinovaných a jejich seznam vidíte níže. Lze však zadat jakékoli číslo (typu int), ovšem předchozí možnost je jaksi názornější.

  • RESPONSE_NONE
  • RESPONSE_REJECT
  • RESPONSE_ACCEPT
  • RESPONSE_DELE­TE_EVENT
  • RESPONSE_OK
  • RESPONSE_CANCEL
  • RESPONSE_CLOSE
  • RESPONSE_YES
  • RESPONSE_NO
  • RESPONSE_APPLY
  • RESPONSE_HELP

Abychom se dozvěděli, co uživatel s dialogovým oknem udělal, uložíme si návratovou hodnotu metody run() (ta dialog spouští) a použijeme běžný switch. Asi tak, jak to vidíte níže.

#include <gtkmm.h>

class Okno : public Gtk::Window {
    public:
        Okno();
        void VyberSoubor();

    protected:
        Gtk::VBox ram;
        Gtk::Button tlacitko;
        Gtk::Label cesta;
};

Okno::Okno() {
    tlacitko.set_label("Vyber soubor");
    tlacitko.signal_clicked().connect(sigc::mem_fun(*this, &Okno::VyberSoubor));
    cesta.set_text("Ještě nebyl vybrán žádný soubor.");

    add(ram);
    ram.pack_start(tlacitko);
    ram.pack_end(cesta);
    show_all_children();
}

void Okno::VyberSoubor() {
    Gtk::FileChooserDialog dialog("Výběr souboru", Gtk::FILE_CHOOSER_ACTION_SAVE);
    dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
    dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);

    int odpoved = dialog.run();
    switch(odpoved) {
        case(Gtk::RESPONSE_OK): {
            cesta.set_text(dialog.get_filename());
      break;
    }
    case(Gtk::RESPONSE_CANCEL): {
      break;
    }
    default: {
      break;
    }
  }
}

int main(int argc, char *argv[]) {
    Gtk::Main kit(argc, argv);
    Okno okno;
    Gtk::Main::run(okno);
    return 0;
}

Notebook

Notebook je kontejner, který může mít několik stránek, mezi kterými se dá přepínat.

Vše zaštiťuje třída Gtk::Notebook. Metoda get_current_page() vrátí číslo právě aktivní stránky, page_num() vrátí číslo stránky, ve které se nachází předaný widget. Tato čísla budeme potřebovat při zavírání a aktivování stránek metodami remove_page() a set_current_page(). set_current_page() musíme předat číslo stránky, remove_page() nám dává na výběr mezi číslem stránky a widgetem, který je v ní. get_n_pages() vrací počet stránek v notebooku.

Nakonec to nejdůležitější. O přidání nové stránky se postará append_page(), která požaduje jen widget, který má nová stránka obsahovat. Tuto stránku se také hodí nějak označit. Nejjednodušší je použít metodu set_tab_label_text(widget_v_dané_stránce, označení), jenž je však schopna nastavit pouhý text. Za to set_tab_label(widget_v_dané_stránce, widget_v_popisku) je oprávněna použít k označení stránky jakýkoli widget. V praxi tam tak můžeme vložit kontejner, který bude obsahovat třeba ikonku představující typ souboru, název souboru, hvězdičku, která značí, že byl soubor nějak upraven a křížek, který se postará o zavření stránky („tabu“).

SrolledWindow

Textový editor je od toho, aby se v něm psal text. Většinou dlouh. Někdy dost dlouhý. Aby se v něm uživatel vyznal, byly vynalezeny posuvníky. Těmi „obalíme“ vstupní pole. Jak? Stačí jej vložit do kontejneru ScrolledWindow ( add(Gtk::Widget&)). K základnímu nastavení chování ScrolledWindow slouží metoda set_policy(), kde první argument nastavuje vodorovný, druhý svislý posuvník. I tady máme na výběz z několika možností.

  • Gtk::POLICY_ALWAYS
  • Gtk::POLICY_A­UTOMATIC
  • Gtk::POLICY_NEVER

POLICY_ALWAYS posuvník zobrazí za jakýchkoli okolností, POLICY_NEVER jej nezobrazí vůbec, POLICY_AUTOMATIC jen tehdy, když bude v poli příliš mnoho textu (tzn., že se do tohoto pole nevejde) a pokud metodu set_policy() nepoužijeme vůbec, zobrazí se oba posuvníky i při prázdném vstupním poli.

Schránka

Při práci se schránkou se využívá třídy chytrého ukazatele Glib::RefPtr. Deklarace vypadá nějak takto: Glib::RefPtr<Gtk::Clipboard> schranka;. V konstruktoru hlavního okna našeho editoru bude akorát schranka = Gtk::Clipboard::get();  – tímto získáme ukazatel na schránku. To bylo z přípravy práce se schránkou vše. K samotné práci s textem se většinou použije vždy jeden z těchto tří příkazů:

editacni_pole.get_buffer()->cut_clipboard(schranka, true);
editacni_pole.get_buffer()->copy_clipboard(schranka);
editacni_pole.get_buffer()->paste_clipboard(schranka, true);

Metoda get_buffer() vrací ukazatel na Gtk::TextBuffer, třídu obsahující text obsažený např. v Gtk::TextView.

Stavový řádek

Stavový řádek je většinou ten úzký pruh dole na úplném okraji okna, kde dostáváme základní informace o běhu programu, nějakou nápovědu, případně informace o pozici kurzoru apod.

Práce s ním je velmi jednoduchá. Jedná se o třídu Gtk::Statusbar a nový text do něj dostaneme za použití metody push(), které předáme požadovaný řetězec a „číslo kontextu“ (int). To znamená, že tam můžeme zobrazit nějaký text, ten následně přepsat a až se to bude hodit, zobrazit bez opětovného předávání řetězce ten původní. Řetězec s nějakým „číslem kontextu“ se maže metodou pop(guint context_id).

widgety

Ukázkový program

Tentokrát je pro přehlednost ukázkový program rozložen na tři díly. Prvním dílem je třída hlavního okna editoru, dalším metody pro práci se soubory a poslední obsahuje funkci main a několik různých metod.

Pokračování

Příště se pravděpodobně naučíme pracovat s Glade. Mám v plánu podívat se na práci s tiskárnou, popř. na novinky v Gtkmm 3. Další náměty můžete psát do diskuze.

Našli jste v článku chybu?
DigiZone.cz: Rapl: seriál, který vás smíří s ČT

Rapl: seriál, který vás smíří s ČT

Lupa.cz: Proč jsou firemní počítače pomalé?

Proč jsou firemní počítače pomalé?

Vitalia.cz: Muž, který miluje příliš. Ženám neimponuje

Muž, který miluje příliš. Ženám neimponuje

Lupa.cz: Kde leží hardwarový pupek světa?

Kde leží hardwarový pupek světa?

Podnikatel.cz: Instalatér, malíř a elektrikář. "Vymřou"?

Instalatér, malíř a elektrikář. "Vymřou"?

Lupa.cz: Jak se prodává firma za miliardu?

Jak se prodává firma za miliardu?

Podnikatel.cz: Letáky? Lidi zuří, ale ony stále fungují

Letáky? Lidi zuří, ale ony stále fungují

Podnikatel.cz: ČSSZ posílá přehled o důchodovém kontě

ČSSZ posílá přehled o důchodovém kontě

Vitalia.cz: dTest odhalil ten nejlepší kečup

dTest odhalil ten nejlepší kečup

Vitalia.cz: Tesco nabízí desítky tun jídla zdarma

Tesco nabízí desítky tun jídla zdarma

Vitalia.cz: Tradiční čínská medicína a rakovina

Tradiční čínská medicína a rakovina

Lupa.cz: Cimrman má hry na YouTube i vlastní doodle

Cimrman má hry na YouTube i vlastní doodle

Podnikatel.cz: Byla finanční manažerka, teď cvičí jógu

Byla finanční manažerka, teď cvičí jógu

Podnikatel.cz: Nemá dluhy? Zjistíte to na poště

Nemá dluhy? Zjistíte to na poště

Lupa.cz: Další Češi si nechali vložit do těla čip

Další Češi si nechali vložit do těla čip

DigiZone.cz: Parlamentní listy: kde končí PR...

Parlamentní listy: kde končí PR...

120na80.cz: Galerie: Čínští policisté testují českou minerálku

Galerie: Čínští policisté testují českou minerálku

Vitalia.cz: 5 chyb, které děláme při skladování potravin

5 chyb, které děláme při skladování potravin

Podnikatel.cz: Udělali jsme velkou chybu, napsal Čupr

Udělali jsme velkou chybu, napsal Čupr

DigiZone.cz: Digi Slovakia zařazuje stanice SPI

Digi Slovakia zařazuje stanice SPI