/// // Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include "filesel.h" #include #include #include #include #include #include "usererror.h" #include "util/stringutil.h" #include "util/warning.h" #include "util/filesys.h" #include "wmisc.h" // *** EndEntry methods *** EndEntry::EndEntry(int _history_max) : history_max(_history_max) {} void EndEntry::set_text(const Glib::ustring &text, bool remember_text) { if(get_text(false) == text) return; Gtk::Entry &entry = get_entry(); entry.set_text(text); // move cursor to end so the filename is visible entry.set_position(text.length()); if(remember_text) remember(); } Glib::ustring EndEntry::get_text(bool remember_text) { if(remember_text) remember(); return get_entry().get_text(); } Gtk::Entry& EndEntry::get_entry() { return *dynamic_cast(get_child()); } void EndEntry::remember() { Glib::ustring text = get_entry().get_text(); // remove duplicates History::iterator dup; while((dup = std::find(history.begin(), history.end(), text)) != history.end()) history.erase(dup); // add new history.push_front(text); // remove old while(history.size() > history_max) history.pop_back(); // update pop-down list Glib::RefPtr::cast_dynamic(get_model())->clear(); for(History::const_iterator i = history.begin(); i != history.end(); i++) append_text(*i); } // *** FileEntry methods *** FileEntry::FileEntry(const Glib::ustring& window_title_, const Glib::ustring& default_path_, Gtk::FileChooserAction action) : window_title(window_title_), default_path(default_path_), default_value(&default_path), filesel(0), action(action) { pack_start(entry, Gtk::PACK_EXPAND_WIDGET, 0); pack_start(button, Gtk::PACK_SHRINK, 0); Gtk::Box *button_box = manage(new Gtk::HBox(false, single_space)); Gtk::Image *open_img = manage(new Gtk::Image(Gtk::Stock::OPEN, Gtk::ICON_SIZE_BUTTON)); Gtk::Label *button_label = manage(new Gtk::Label("Browse ... ")); button_box->pack_start(*open_img); button_box->pack_start(*button_label); button.add(*button_box); button.show(); entry.show(); button.set_size_request(-1, entry.get_height()); button.signal_clicked().connect (sigc::mem_fun(*this, &FileEntry::show_filesel)); } bool FileEntry::on_mnemonic_activate(bool group_cycling) { // Not much documented in gtkmm, but it seems this metod gets called when // this widget is activated (by a mnemonic e.g. from a label) so I can put // focus on the proper part of the widget. entry.get_entry().grab_focus(); return true; } void FileEntry::filesel_done() { if(!filesel->was_cancelled()) { // get_filename does not return utf8 entry.set_text(Glib::filename_to_utf8(filesel->get_filename())); entry.get_entry().activate(); // in case of instant apply } filesel.reset(); } void FileEntry::show_filesel() { Gtk::Window *toplevel = dynamic_cast(this->get_toplevel()); assert(toplevel); filesel.reset(new Filesel(*toplevel, window_title, action)); filesel->signal_hide().connect (sigc::mem_fun(*this, &FileEntry::filesel_done)); Glib::ustring filename = entry.get_text(false /* don't save */); if(filename != *default_value) // If non-default entry filesel->set_filename(filename.empty() ? default_path : filename); else // Default entry found -> browse to default_path filesel->set_filename(default_path.empty() ? filename : default_path); filesel->show(); } const Glib::ustring& FileEntry::get_default_value() { return *default_value; } void FileEntry::set_default_value(const Glib::ustring &value) { default_value = &maybe_default_value; maybe_default_value = value; entry.set_text(*default_value); } // *** Filesel methods *** Filesel::Filesel(Gtk::Window &parent, const Glib::ustring& title, Gtk::FileChooserAction action) : Gtk::FileChooserDialog(parent, title, action), cancelled(false) { set_modal(true); add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK)->grab_default(); signal_file_activated().connect (sigc::bind(sigc::mem_fun(*this, &Filesel::on_response), Gtk::RESPONSE_OK)); } void Filesel::on_response(int response_id) { switch(response_id) { case Gtk::RESPONSE_OK: cancelled = false; hide(); break; case Gtk::RESPONSE_CANCEL: case Gtk::RESPONSE_DELETE_EVENT: // Gtk::RESPONSE_DELETE_EVENT is sent when the user tries to close // the window // set_filename(""); cancelled = true; hide(); break; default: throw std::runtime_error("Impossible error (you didn't see this)" " in Filesel::on_response()"); break; } }