Logo Search packages:      
Sourcecode: passepartout version File versions  Download package

filesel.cc

///
// Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING
///
#include "filesel.h"
#include <cassert>
#include <gtkmm/image.h>
#include <gtkmm/box.h>
#include <gtkmm/stock.h>
#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) 
{
  disable_activate(); // don't pop down history when pressing enter
  // get_entry()->set_activates_default();
  // set_activates_default() does not work together with the call to
  // activate in FileEntry:filesel_done().
}

void EndEntry::set_text(const Glib::ustring &text) {
  get_entry()->set_text(text); 
  // move cursor to end so the filename is visible
  get_entry()->set_position(text.length());
}

void EndEntry::remember() {
  Glib::ustring text = get_entry()->get_text();
  for(History::iterator i = history.begin();
      i != history.end(); i++)
    if(*i == text) {
      History::iterator j = i++;
      history.erase(j);
    }
  history.push_front(text); 
  // put text in front, or the entry will be altered
  while(history.size() > history_max)
    history.pop_back();
  set_popdown_strings(history);
}

Glib::ustring EndEntry::get_text(bool remember_text) {
  if(remember_text) 
    remember();
  return get_entry()->get_text();
}

// *** FileEntry methods ***

FileEntry::FileEntry(const Glib::ustring& window_title_, 
                 const Glib::ustring& default_path_,
                 const bool file_prompt_):
  window_title(window_title_), default_path(default_path_),
  default_value(&default_path),
  filesel(0),
  file_prompt(file_prompt_)
{
  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(slot(*this, &FileEntry::show_filesel));
}

00080 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()) {
    if(file_prompt) {
      entry.set_text(filesel->get_filename());      
    } else {       //Get directory name
      //selection_text label format: "Some label: directory"
      std::string s = filesel->get_selection_text()->get_text();
      if(s.find_last_of("/") != s.length()-1 ) s += "/"; //Unnecessary check?
      int i = s.find_first_of("/");
      entry.set_text(s.substr(i)); //Remove label
    }
    entry.get_entry()->activate(); // in case of instant apply
  }
  filesel.reset();
}

void FileEntry::show_filesel() {
  Gtk::Window *toplevel = dynamic_cast<Gtk::Window*>(this->get_toplevel());
  assert(toplevel);

  if(!file_prompt) {
    filesel.reset(new Filesel(*toplevel, window_title, true, true));
    filesel->get_selection_entry()->hide();
    filesel->get_file_list()->get_parent()->hide();
    //A slightly more complicated way:
    //  gtk_widget_hide(GTK_WIDGET(GTK_FILE_SELECTION(filesel->gobj())->
    //file_list->parent));
  } else {
    filesel.reset(new Filesel(*toplevel, window_title, true, false));
  }
  filesel->signal_hide().connect(slot(*this, &FileEntry::filesel_done));
  if(entry.get_text() != *default_value) { //If non-default entry
    filesel->set_filename(entry.get_text().empty() 
                    ? default_path 
                    : entry.get_text());
  } else { //Default entry found -> browse to default_path
    filesel->set_filename(default_path.empty() 
                    ? entry.get_text() 
                    : 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 ***

00142 Filesel::Filesel(Gtk::Window &parent, const Glib::ustring& title,
             bool _accept_nonexistent, bool _accept_dir)
  :Gtk::FileSelection(title), cancelled(false),
   accept_nonexistent(_accept_nonexistent), 
   accept_dir(_accept_dir)
{
  set_modal(true);
  set_has_separator(false);
  set_transient_for(parent);
}

void Filesel::on_response(int response_id) {
  switch(response_id) {
  case Gtk::RESPONSE_OK:
    {
      std::string filename = get_filename();
      if(!accept_dir && filename.at(filename.length() - 1) == '/') 
      return;
      if(!accept_nonexistent && !exists(filename))
      throw UserError("Could not open file", filename + " does not exist.");
      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:
    warning << "Impossible error (you didn't see this)"
          << " in Filesel::on_response()" << std::endl;
    break;
  }
}

Generated by  Doxygen 1.6.0   Back to index