/* * Copyright 2005,2006 Fabrice Colin * * 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include "Url.h" #include "config.h" #include "NLS.h" #include "PinotSettings.h" #include "PinotUtils.h" #include "EnginesTree.h" using namespace std; using namespace Glib; using namespace Gdk; using namespace Gtk; EnginesTree::EnginesTree(VBox *enginesVbox, PinotSettings &settings) : TreeView(), m_settings(settings) { ScrolledWindow *enginesScrolledwindow = manage(new ScrolledWindow()); // This is the actual engines tree set_events(Gdk::BUTTON_PRESS_MASK); set_flags(CAN_FOCUS); set_headers_clickable(true); set_headers_visible(true); set_reorderable(false); set_enable_search(false); get_selection()->set_mode(SELECTION_MULTIPLE); enginesScrolledwindow->set_flags(CAN_FOCUS); enginesScrolledwindow->set_shadow_type(SHADOW_NONE); enginesScrolledwindow->set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC); enginesScrolledwindow->property_window_placement().set_value(CORNER_TOP_LEFT); enginesScrolledwindow->add(*this); // Position the scrolled window enginesVbox->pack_start(*enginesScrolledwindow, Gtk::PACK_EXPAND_WIDGET, 0); // Associate the columns model to the engines tree m_refStore = TreeStore::create(m_enginesColumns); set_model(m_refStore); TreeViewColumn *pColumn = new TreeViewColumn(_("Search Engines")); // Pack an icon renderer for engines icons CellRendererPixbuf *pIconRenderer = new CellRendererPixbuf(); pColumn->pack_start(*manage(pIconRenderer), false); pColumn->set_cell_data_func(*pIconRenderer, sigc::mem_fun(*this, &EnginesTree::renderEngineIcon)); pColumn->pack_end(m_enginesColumns.m_name, false); pColumn->set_sizing(TREE_VIEW_COLUMN_AUTOSIZE); append_column(*manage(pColumn)); // Handle button presses signal_button_press_event().connect_notify(sigc::mem_fun(*this, &EnginesTree::onButtonPressEvent)); // Control which rows can be selected get_selection()->set_select_function(sigc::mem_fun(*this, &EnginesTree::onSelectionSelect)); // Listen for style changes signal_style_changed().connect_notify(sigc::mem_fun(*this, &EnginesTree::onStyleChanged)); // Render the icons m_engineFolderIconPixbuf = render_icon(Stock::DIRECTORY, ICON_SIZE_MENU, "MetaSE-pinot"); // Populate populate(); // Show all show(); enginesScrolledwindow->show(); } EnginesTree::~EnginesTree() { } void EnginesTree::save(void) { std::map &channels = m_settings.getSearchEnginesChannels(); TreeModel::Children children = m_refStore->children(); for (TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) { TreeModel::Row row = *iter; if (row[m_enginesColumns.m_type] == EnginesModelColumns::ENGINE_FOLDER) { ustring channelName(row[m_enginesColumns.m_name]); TreeModel::Path channelPath = m_refStore->get_path(iter); std::map::iterator channelIter = channels.find(from_utf8(channelName)); if (channelIter != channels.end()) { #ifdef DEBUG cout << "EnginesTree::save: " << channelName << " is " << row_expanded(channelPath) << endl; #endif channelIter->second = row_expanded(channelPath); } } } } void EnginesTree::renderEngineIcon(Gtk::CellRenderer *renderer, const Gtk::TreeModel::iterator &iter) { TreeModel::Row row = *iter; if (renderer == NULL) { return; } CellRendererPixbuf *pIconRenderer = dynamic_cast(renderer); if (pIconRenderer != NULL) { // Is this an engine folder ? if (row[m_enginesColumns.m_type] == EnginesModelColumns::ENGINE_FOLDER) { pIconRenderer->property_pixbuf() = m_engineFolderIconPixbuf; } else { pIconRenderer->property_pixbuf().reset_value(); } } } // // Handles button presses. // void EnginesTree::onButtonPressEvent(GdkEventButton *ev) { list selectedEngines = get_selection()->get_selected_rows(); // If there are more than one row selected, don't bother if (selectedEngines.size() != 1) { return; } list::iterator enginePath = selectedEngines.begin(); if (enginePath == selectedEngines.end()) { return; } TreeModel::iterator engineIter = m_refStore->get_iter(*enginePath); TreeModel::Row engineRow = *engineIter; // Check for double clicks if (ev->type == GDK_2BUTTON_PRESS) { #ifdef DEBUG cout << "EnginesTree::onButtonPressEvent: double click on button " << ev->button << endl; #endif // Make sure the engine is an external index EnginesModelColumns::EngineType engineType = engineRow[m_enginesColumns.m_type]; if (engineType == EnginesModelColumns::INDEX_ENGINE) { ustring name = engineRow[m_enginesColumns.m_name]; ustring location = engineRow[m_enginesColumns.m_option]; m_signalDoubleClick(name, location); } else { // Is the row already expanded ? if (row_expanded(*enginePath) == false) { // Expand it expand_row(*enginePath, true); } else { // Collapse it collapse_row(*enginePath); } } } } // // Handles attempts to select rows. // bool EnginesTree::onSelectionSelect(const RefPtr& model, const TreeModel::Path& node_path, bool path_currently_selected) { // All nodes can be selected return true; } // // Handles GTK style changes. // void EnginesTree::onStyleChanged(const RefPtr