/* * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath * * RawTherapee 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 3 of the License, or * (at your option) any later version. * * RawTherapee 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 RawTherapee. If not, see . */ #include #include #include #include PlacesBrowser::PlacesBrowser () : listener (NULL) { scrollw = Gtk::manage (new Gtk::ScrolledWindow ()); scrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); pack_start (*scrollw); add = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_ADD"))); del = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_DEL"))); add->set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::ADD, Gtk::ICON_SIZE_MENU))); del->set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::REMOVE, Gtk::ICON_SIZE_MENU))); Gtk::HBox* buttonBox = Gtk::manage (new Gtk::HBox ()); buttonBox->pack_start (*add); buttonBox->pack_start (*del); pack_start (*buttonBox, Gtk::PACK_SHRINK, 2); treeView = Gtk::manage (new Gtk::TreeView ()); treeView->unset_flags (Gtk::CAN_FOCUS); scrollw->add (*treeView); placesModel = Gtk::ListStore::create (placesColumns); treeView->set_model (placesModel); treeView->set_headers_visible (true); Gtk::TreeView::Column *iviewcol = Gtk::manage (new Gtk::TreeView::Column (M("MAIN_FRAME_PLACES"))); Gtk::CellRendererPixbuf *iconCR = Gtk::manage (new Gtk::CellRendererPixbuf()); Gtk::CellRendererText *labelCR = Gtk::manage (new Gtk::CellRendererText()); iviewcol->pack_start (*iconCR, false); iviewcol->pack_start (*labelCR, true); iviewcol->add_attribute (*iconCR, "gicon", 0); iviewcol->add_attribute (*labelCR, "text", placesColumns.label); treeView->append_column (*iviewcol); treeView->set_row_separator_func (sigc::mem_fun(*this, &PlacesBrowser::rowSeparatorFunc)); vm = Gio::VolumeMonitor::get(); vm->signal_mount_changed().connect (sigc::mem_fun(*this, &PlacesBrowser::mountChanged)); vm->signal_mount_added().connect (sigc::mem_fun(*this, &PlacesBrowser::mountChanged)); vm->signal_mount_removed().connect (sigc::mem_fun(*this, &PlacesBrowser::mountChanged)); vm->signal_volume_changed().connect (sigc::mem_fun(*this, &PlacesBrowser::volumeChanged)); vm->signal_volume_added().connect (sigc::mem_fun(*this, &PlacesBrowser::volumeChanged)); vm->signal_volume_removed().connect (sigc::mem_fun(*this, &PlacesBrowser::volumeChanged)); vm->signal_drive_connected().connect (sigc::mem_fun(*this, &PlacesBrowser::driveChanged)); vm->signal_drive_disconnected().connect (sigc::mem_fun(*this, &PlacesBrowser::driveChanged)); vm->signal_drive_changed().connect (sigc::mem_fun(*this, &PlacesBrowser::driveChanged)); treeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &PlacesBrowser::selectionChanged)); add->signal_clicked().connect(sigc::mem_fun(*this, &PlacesBrowser::addPressed)); del->signal_clicked().connect(sigc::mem_fun(*this, &PlacesBrowser::delPressed)); show_all (); } void PlacesBrowser::refreshPlacesList () { placesModel->clear (); // append home directory Glib::RefPtr hfile = Gio::File::create_for_path (Glib::get_home_dir ()); if (hfile && hfile->query_exists()) { try { Glib::RefPtr info = safe_query_file_info (hfile); if (info) { Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = info->get_display_name (); newrow[placesColumns.icon] = info->get_icon (); newrow[placesColumns.root] = hfile->get_parse_name (); newrow[placesColumns.type] = 4; newrow[placesColumns.rowSeparator] = false; } } catch (Gio::Error&) { /* This will be thrown if the path doesn't exist */ } } // append pictures directory hfile = Gio::File::create_for_path (Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES)); if (hfile && hfile->query_exists()) { try { Glib::RefPtr info = safe_query_file_info (hfile); if (info) { Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = info->get_display_name (); newrow[placesColumns.icon] = info->get_icon (); newrow[placesColumns.root] = hfile->get_parse_name (); newrow[placesColumns.type] = 4; newrow[placesColumns.rowSeparator] = false; } } catch (Gio::Error&) { /* This will be thrown if the path doesn't exist */ } } if (placesModel->children().size()>0) { Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.rowSeparator] = true; } // scan all drives std::vector > drives = vm->get_connected_drives (); for (int j=0; j > volumes = drives[j]->get_volumes (); if (volumes.size()==0) { Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = drives[j]->get_name (); newrow[placesColumns.icon] = drives[j]->get_icon (); newrow[placesColumns.root] = ""; newrow[placesColumns.type] = 3; newrow[placesColumns.rowSeparator] = false; } for (int i=0; i mount = volumes[i]->get_mount (); if (mount) { // placesed volumes Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = mount->get_name (); newrow[placesColumns.icon] = mount->get_icon (); newrow[placesColumns.root] = mount->get_root ()->get_parse_name (); newrow[placesColumns.type] = 1; newrow[placesColumns.rowSeparator] = false; } else { // unplacesed volumes Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = volumes[i]->get_name (); newrow[placesColumns.icon] = volumes[i]->get_icon (); newrow[placesColumns.root] = ""; newrow[placesColumns.type] = 2; newrow[placesColumns.rowSeparator] = false; } } } // volumes not belonging to drives std::vector > volumes = vm->get_volumes (); for (int i=0; iget_drive ()) { Glib::RefPtr mount = volumes[i]->get_mount (); if (mount) { // placesed volumes Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = mount->get_name (); newrow[placesColumns.icon] = mount->get_icon (); newrow[placesColumns.root] = mount->get_root ()->get_parse_name (); newrow[placesColumns.type] = 1; newrow[placesColumns.rowSeparator] = false; } else { // unplacesed volumes Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = volumes[i]->get_name (); newrow[placesColumns.icon] = volumes[i]->get_icon (); newrow[placesColumns.root] = ""; newrow[placesColumns.type] = 2; newrow[placesColumns.rowSeparator] = false; } } } // placess not belonging to volumes std::vector > mounts = vm->get_mounts (); for (int i=0; iget_volume ()) { Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = mounts[i]->get_name (); newrow[placesColumns.icon] = mounts[i]->get_icon (); newrow[placesColumns.root] = mounts[i]->get_root ()->get_parse_name (); newrow[placesColumns.type] = 1; newrow[placesColumns.rowSeparator] = false; } } // append favorites if (placesModel->children().size()>0) { Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.rowSeparator] = true; } for (int i=0; i hfile = Gio::File::create_for_path (options.favoriteDirs[i]); if (hfile && hfile->query_exists()) { Glib::RefPtr info = safe_query_file_info (hfile); if (info) { Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = info->get_display_name (); newrow[placesColumns.icon] = info->get_icon (); newrow[placesColumns.root] = hfile->get_parse_name (); newrow[placesColumns.type] = 5; newrow[placesColumns.rowSeparator] = false; } } } } bool PlacesBrowser::rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter) { return iter->get_value (placesColumns.rowSeparator); } void PlacesBrowser::mountChanged (const Glib::RefPtr& m) { gdk_threads_enter (); refreshPlacesList (); gdk_threads_leave (); } void PlacesBrowser::volumeChanged (const Glib::RefPtr& m) { gdk_threads_enter (); refreshPlacesList (); gdk_threads_leave (); } void PlacesBrowser::driveChanged (const Glib::RefPtr& m) { gdk_threads_enter (); refreshPlacesList (); gdk_threads_leave (); } void PlacesBrowser::selectionChanged () { Glib::RefPtr selection = treeView->get_selection(); Gtk::TreeModel::iterator iter = selection->get_selected(); if (iter) { if (iter->get_value (placesColumns.type)==2) { std::vector > volumes = vm->get_volumes (); for (int i=0; iget_name () == iter->get_value (placesColumns.label)) { volumes[i]->mount (); break; } } else if (iter->get_value (placesColumns.type)==3) { std::vector > drives = vm->get_connected_drives (); for (int i=0; iget_name () == iter->get_value (placesColumns.label)) { drives[i]->poll_for_media (); break; } } else if (listener) listener->selectDir (iter->get_value (placesColumns.root)); } } void PlacesBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { lastSelectedDir = dirname; } void PlacesBrowser::addPressed () { if (lastSelectedDir=="") return; // check if the dirname is already in the list. If yes, return. for (int i=0; i hfile = Gio::File::create_for_path (lastSelectedDir); if (hfile && hfile->query_exists()) { Glib::RefPtr info = safe_query_file_info (hfile); if (info) { options.favoriteDirs.push_back (hfile->get_parse_name ()); refreshPlacesList (); } } } void PlacesBrowser::delPressed () { // lookup the selected item in the bookmark Glib::RefPtr selection = treeView->get_selection(); Gtk::TreeModel::iterator iter = selection->get_selected(); if (iter && iter->get_value (placesColumns.type)==5) { std::vector::iterator i = std::find (options.favoriteDirs.begin(), options.favoriteDirs.end(), iter->get_value (placesColumns.root)); if (i != options.favoriteDirs.end()) options.favoriteDirs.erase (i); } refreshPlacesList (); }