/// // Copyright (C) 2003, 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include "imagefilesel.h" #include #include "wmisc.h" #include #include #include "util/stringutil.h" const int ImageFilesel::maxwidth = 100; const int ImageFilesel::maxheight = 100; namespace { typedef std::vector MimeTypes; MimeTypes get_mime_types() { MimeTypes mime_types; std::vector formats = Gdk::Pixbuf::get_formats(); for(std::vector::const_iterator format = formats.begin(); format != formats.end(); format++) { MimeTypes tmp = format->get_mime_types(); mime_types.insert(mime_types.end(), tmp.begin(), tmp.end()); } return mime_types; } void add_images_filter(Gtk::FileChooser &fc) { Gtk::FileFilter filter; filter.set_name("Image files"); MimeTypes mime_types = get_mime_types(); for(MimeTypes::const_iterator i = mime_types.begin(); i != mime_types.end(); i++) filter.add_mime_type(*i); filter.add_pattern("*.eps"); // is there no mime type for eps? fc.add_filter(filter); } } ImageFilesel::ImageFilesel(Gtk::Window &parent, const ustring& title, float default_res, const ustring& unit_name, float unit_factor) : Filesel(parent, title), res(0, true) { unit.name = unit_name; unit.factor = unit_factor; // filters add_images_filter(*this); Gtk::FileFilter afilter; afilter.set_name("All files"); afilter.add_pattern("*"); add_filter(afilter); // *** The preview image *** Gtk::Box *box = manage(new Gtk::VBox(false, double_space)); Gtk::Alignment *alignment = manage(new Gtk::Alignment()); alignment->set_size_request(maxwidth, maxheight); Gtk::Box *inner_box = manage(new Gtk::VBox()); alignment->add(*inner_box); box->pack_start(*alignment, Gtk::PACK_SHRINK); box->pack_start(info, Gtk::PACK_SHRINK); inner_box->pack_start(preview); box->show_all(); set_preview_widget(*box); set_preview_widget_active(false); // *** The image resolution res.set(default_res); box = manage(new Gtk::HBox(false, double_space)); box->pack_start(*manage(new Gtk::Label("Image resolution:")), Gtk::PACK_SHRINK); box->pack_start(res, Gtk::PACK_SHRINK); box->pack_start(*manage(new Gtk::Label("ppi")), Gtk::PACK_SHRINK); box->show_all(); set_extra_widget(*box); // the preview is loaded in a separate thread, to avoid locking up the gui signal_update_preview().connect (sigc::mem_fun(*this, &ImageFilesel::start_loader)); signal_loaded.connect (sigc::mem_fun(*this, &ImageFilesel::update_preview)); res.signal_value_changed().connect (sigc::mem_fun(*this, &ImageFilesel::update_size)); } void ImageFilesel::update_size() { int w = image_size.width; int h = image_size.height; float resolution = res.get() / 72.0; // pixels per point std::ostringstream text; text << w << " x " << h << " pixels"; text.precision(2); text.setf(std::ios_base::fixed, std::ios_base::floatfield); if(!unit.name.empty()) text << '\n' << w / resolution / unit.factor << " x " << h / resolution / unit.factor << " " << std::string(unit.name); text << std::flush; info.set_text(text.str()); } void ImageFilesel::start_loader() { info.set_text("Loading\npreview ..."); set_preview_widget_active(true); preview.hide(); Glib::Thread::create(sigc::mem_fun(*this, &ImageFilesel::loader_thread), false /* not joinable */); } void ImageFilesel::loader_thread() { try { pixbuf.clear(); pixbuf = Gdk::Pixbuf::create_from_file(get_preview_filename()); // scale to appropriate size int w = pixbuf->get_width(); int h = pixbuf->get_height(); image_size.width = w; image_size.height = h; float fw = float(maxwidth) / w; float fh = float(maxheight) / h; float f = std::min(fw, fh); w = int(f * w); h = int(f * h); pixbuf = pixbuf->scale_simple(w, h, Gdk::INTERP_NEAREST); } catch (...) {} signal_loaded(); } void ImageFilesel::update_preview() { if(pixbuf) { update_size(); preview.set(pixbuf); preview.show(); set_preview_widget_active(); } else { set_preview_widget_active(false); } }