/* * GuiLoader/C++ examples * Copyright (c) 2006 Maxim Udushlivy * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "application.h" namespace GuiExample { Application::Application() { loader= Gui::Loader::create(); GUIXML_DECL #include "typical.gui.h" GUIXML_LOAD_CPP(loader) loader->bind_object("window1", &window); loader->bind_object("actionGroup1", &actions); loader->bind_object("textView1", &textView); loader->bind_object("statusbar1", &statusbar); loader->bind_object("openDialog1", &openDialog); loader->bind_object("saveDialog1", &saveDialog); loader->bind_object("proceedDialog1", &proceedDialog); textView->modify_font(Pango::FontDescription("Monospace 10")); loader->connect_signals("onNew", sigc::mem_fun(*this, &Application::onNew)); loader->connect_signals("onOpen", sigc::mem_fun(*this, &Application::onOpen)); loader->connect_signals("onSave", sigc::mem_fun(*this, &Application::onSave)); loader->connect_signals("onSaveAs", sigc::mem_fun(*this, &Application::onSaveAs)); loader->connect_signals("onQuit", sigc::mem_fun(*this, &Application::onQuit)); loader->connect_signals("onCut", sigc::mem_fun(*this, &Application::onCut)); loader->connect_signals("onCopy", sigc::mem_fun(*this, &Application::onCopy)); loader->connect_signals("onPaste", sigc::mem_fun(*this, &Application::onPaste)); loader->connect_signals("onDelete", sigc::mem_fun(*this, &Application::onDelete)); loader->connect_signals("onAbout", sigc::mem_fun(*this, &Application::onAbout)); loader->connect_signals("onDeleteEvent", sigc::mem_fun(*this, &Application::onDeleteEvent)); modified= false; lock= false; con1= textView->get_buffer()->signal_changed().connect(sigc::mem_fun(*this, &Application::onChanged)); con2= textView->get_buffer()->signal_mark_set().connect(sigc::mem_fun(*this, &Application::onMarkSet)); statusbar->push(""); updateUi(); } Application::~Application() { con1.disconnect(); con2.disconnect(); } void Application::updateUi() { Glib::ustring name= file.empty() ? "" : " - " + Glib::filename_to_utf8(file); window->set_title("Typical Example" + name); actions->get_action("Save")->set_sensitive(modified || file.empty()); Gtk::TextBuffer::iterator it1, it2; bool selection= textView->get_buffer()->get_selection_bounds(it1, it2); actions->get_action("Cut")->set_sensitive(selection); actions->get_action("Copy")->set_sensitive(selection); actions->get_action("Delete")->set_sensitive(selection); Gtk::TextBuffer::iterator pos= textView->get_buffer()->get_iter_at_mark(textView->get_buffer()->get_insert()); std::ostringstream oss; oss << "Cursor: " << pos.get_line()+1 << ":" << pos.get_line_offset()+1; statusbar->pop(); statusbar->push(oss.str()); } void Application::setText(const Glib::ustring & text) { lock= true; textView->get_buffer()->set_text(text); textView->get_buffer()->place_cursor(textView->get_buffer()->begin()); lock= false; modified= false; } void Application::onChanged() { if(!lock) { modified= true; updateUi(); } } void Application::onMarkSet(const Gtk::TextBuffer::iterator &, const Glib::RefPtr &) { updateUi(); } void Application::onNew() { if(askProceed()) { file.clear(); setText(""); updateUi(); } } void Application::onOpen() { if(askProceed()) { std::string name= askFilename(Gtk::FILE_CHOOSER_ACTION_OPEN); if(!name.empty()) { Glib::ustring data; bool ok= loadFile(name, &data); if(ok) { setText(data); file= name; updateUi(); } } } } void Application::onSave() { std::string name= file; if(name.empty()) name= askFilename(Gtk::FILE_CHOOSER_ACTION_SAVE); if(!name.empty()) { Glib::ustring data= textView->get_buffer()->get_text(); bool ok= saveFile(name, data); if(ok) { file= name; modified= false; updateUi(); } } } void Application::onSaveAs() { std::string name= askFilename(Gtk::FILE_CHOOSER_ACTION_SAVE); if(!name.empty()) { Glib::ustring data= textView->get_buffer()->get_text(); bool ok= saveFile(name, data); if(ok) { file= name; modified= false; updateUi(); } } } void Application::onQuit() { if(askProceed()) window->hide(); } void Application::onCut() { textView->get_buffer()->cut_clipboard(Gtk::Clipboard::get()); } void Application::onCopy() { textView->get_buffer()->copy_clipboard(Gtk::Clipboard::get()); } void Application::onPaste() { textView->get_buffer()->paste_clipboard(Gtk::Clipboard::get()); } void Application::onDelete() { textView->get_buffer()->erase_selection(); } void Application::onAbout() { Gtk::AboutDialog dialog; dialog.set_name("Typical Example"); dialog.set_comments("Simple text editor"); dialog.set_version("1.0"); dialog.set_transient_for(*window); dialog.run(); } bool Application::onDeleteEvent(GdkEventAny *) { onQuit(); return true; } bool Application::loadFile(const std::string & name, Glib::ustring * data) { gchar * contents; if(g_file_get_contents(name.c_str(), &contents, NULL, NULL)) { *data= contents; g_free(contents); return true; } else { showMessage("Loading failed"); *data= ""; return false; } } bool Application::saveFile(const std::string & name, const Glib::ustring & data) { if(g_file_set_contents(name.c_str(), data.c_str(), data.bytes(), NULL)) { return true; } else { showMessage("Saving failed"); return false; } } std::string Application::askFilename(Gtk::FileChooserAction action) { Gtk::FileChooserDialog * dialog= action==Gtk::FILE_CHOOSER_ACTION_SAVE ? saveDialog : openDialog; if(!file.empty()) dialog->set_filename(file); else dialog->set_current_folder(Glib::get_home_dir()); int result= dialog->run(); dialog->hide(); if(result == Gtk::RESPONSE_OK) { std::string F(dialog->get_filename()); if(action==Gtk::FILE_CHOOSER_ACTION_SAVE) if(Glib::path_get_basename(F).find('.') == std::string::npos) F += ".txt"; return F; } else return std::string(); } bool Application::askProceed() { if(modified) { int result= proceedDialog->run(); proceedDialog->hide(); return result == Gtk::RESPONSE_OK; } else return true; } void Application::showMessage(const Glib::ustring & message) { Gtk::MessageDialog dialog(*window, message); dialog.run(); } }