[solang] Reorganized the search module



commit a0a1a4b3d33cc9b19dbb50b48c557a3e10f43441
Author: Debarshi Ray <rishi gnu org>
Date:   Tue Jan 26 04:09:06 2010 +0200

    Reorganized the search module
    
    + Renamed SearchBasket as SearchManager.
    + Split out the Gtk::TreeView as a separate widget named SearchBasket.

 data/Makefile.am                 |    1 +
 data/solang-search-basket.ui     |    3 +-
 data/solang-search-manager.ui    |    9 +
 po/POTFILES.in                   |    2 +-
 src/application/application.cpp  |    6 +-
 src/attribute/Makefile.am        |    2 +
 src/attribute/search-basket.cpp  |  355 ++++---------------------------------
 src/attribute/search-basket.h    |   94 +---------
 src/attribute/search-manager.cpp |  370 ++++++++++++++++++++++++++++++++++++++
 src/attribute/search-manager.h   |  136 ++++++++++++++
 10 files changed, 563 insertions(+), 415 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 9c98f3a..f5ddaf9 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -48,6 +48,7 @@ ui_DATA = \
 	solang-tag-manager.ui \
 	solang-importer.ui \
 	solang-search-basket.ui \
+	solang-search-manager.ui \
 	solang-slideshow.ui \
 	solang-slideshow-renderer.ui \
 	solang-thumbnail-popup.ui
diff --git a/data/solang-search-basket.ui b/data/solang-search-basket.ui
index ea665ee..54e2483 100644
--- a/data/solang-search-basket.ui
+++ b/data/solang-search-basket.ui
@@ -1,7 +1,6 @@
 <!--*- xml -*-->
 <ui>
 	<popup name="SearchBasketPopup">
-		<menuitem action="ActionSelectAll"/>
-		<menuitem action="ActionRemoveSelected"/>
+		<placeholder name="PlaceholderSearchBasketPopup" />
 	</popup>
 </ui>
diff --git a/data/solang-search-manager.ui b/data/solang-search-manager.ui
new file mode 100644
index 0000000..dc9ec73
--- /dev/null
+++ b/data/solang-search-manager.ui
@@ -0,0 +1,9 @@
+<!--*- xml -*-->
+<ui>
+	<popup name="SearchBasketPopup">
+		<placeholder name="PlaceholderSearchBasketPopup">
+		<menuitem action="ActionSelectAll"/>
+		<menuitem action="ActionRemoveSelected"/>
+                </placeholder>
+	</popup>
+</ui>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b218418..4de8c97 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -6,7 +6,7 @@ src/application/main-window.cpp
 src/attribute/basic-exif-view.cpp
 src/attribute/date-manager.cpp
 src/attribute/property-manager.cpp
-src/attribute/search-basket.cpp
+src/attribute/search-manager.cpp
 src/attribute/tag-manager.cpp
 src/attribute/tag-new-dialog.cpp
 src/common/exif-data.cpp
diff --git a/src/application/application.cpp b/src/application/application.cpp
index b7c3391..202c478 100644
--- a/src/application/application.cpp
+++ b/src/application/application.cpp
@@ -46,7 +46,7 @@
 #include "photo.h"
 #include "progress-observer.h"
 #include "property-manager.h"
-#include "search-basket.h"
+#include "search-manager.h"
 #include "slideshow-renderer.h"
 #include "tag-manager.h"
 #include "thumbnailer.h"
@@ -290,8 +290,8 @@ Application::init() throw()
     plugins_.insert(std::make_pair("property-manager",
                                    property_manager));
 
-    IPluginPtr search_basket(new SearchBasket());
-    plugins_.insert(std::make_pair("search-basket", search_basket));
+    IPluginPtr search_manager(new SearchManager());
+    plugins_.insert(std::make_pair("search-manager", search_manager));
 
     IPluginPtr tag_manager(new TagManager( ));
     plugins_.insert(std::make_pair("tag-manager", tag_manager));
diff --git a/src/attribute/Makefile.am b/src/attribute/Makefile.am
index d680c04..d146c7d 100644
--- a/src/attribute/Makefile.am
+++ b/src/attribute/Makefile.am
@@ -27,6 +27,8 @@ libattribute_la_SOURCES = \
 	search-criterion-repo.h \
 	search-criterion-source.cpp \
 	search-criterion-source.h \
+	search-manager.cpp \
+	search-manager.h \
 	tag.cpp \
 	tag.h \
 	tag-manager.cpp \
diff --git a/src/attribute/search-basket.cpp b/src/attribute/search-basket.cpp
index 221c0ec..4f13494 100644
--- a/src/attribute/search-basket.cpp
+++ b/src/attribute/search-basket.cpp
@@ -20,19 +20,7 @@
 #include "config.h"
 #endif // HAVE_CONFIG_H
 
-#include <vector>
-
-#include <glibmm/i18n.h>
-#include <gdkmm.h>
-
-#include "application.h"
-#include "browser-renderer.h"
-#include "console-renderer.h"
-#include "engine.h"
-#include "enlarged-renderer.h"
-#include "main-window.h"
 #include "search-basket.h"
-#include "search-basket-column-record.h"
 
 namespace Solang
 {
@@ -41,355 +29,78 @@ const std::string SearchBasket::uiFile_
     = PACKAGE_DATA_DIR"/"PACKAGE_TARNAME"/ui/"
           PACKAGE_TARNAME"-search-basket.ui";
 
-SearchBasket::SearchBasket() throw() :
-    Plugin(),
-    sigc::trackable(),
-    actionGroup_(Gtk::ActionGroup::create(
-                     Glib::ustring::compose("%1:%2",
-                                            __FILE__,
-                                            __LINE__))),
-    dockItemName_("search-basket-dock-item"),
-    dockItemTitle_(_("Search")),
-    dockItemBehaviour_(GDL_DOCK_ITEM_BEH_NORMAL),
-    dockItem_(NULL),
-    vBox_( false, 6 ),
-    scrolledWindow_(),
-    listStore_(Gtk::ListStore::create(SearchBasketColumnRecord())),
-    treeView_(listStore_),
-    application_( NULL ),
+SearchBasket::SearchBasket(const TreeModelPtr & model) throw() :
+    Gtk::TreeView(model),
     uiManager_(Gtk::UIManager::create()),
-    uiIDTreeView_(uiManager_->add_ui_from_file(uiFile_)),
-    menu_(0),
-    signalRendererChanged_()
+    uiID_(uiManager_->add_ui_from_file(uiFile_)),
+    menu_(0)
 {
-    actionGroup_->add(
-        Gtk::Action::create(
-            "ActionSelectAll", Gtk::Stock::SELECT_ALL,
-            _("Select _All"),
-            _("Select all the filters in this list")),
-        Gtk::AccelKey("<control>A"),
-        sigc::mem_fun(*this,
-                      &SearchBasket::on_action_select_all));
-
-    actionGroup_->add(
-        Gtk::Action::create(
-            "ActionRemoveSelected", Gtk::Stock::REMOVE,
-            _("_Remove"),
-            _("Remove the selected filters from this list")),
-        Gtk::AccelKey("Delete"),
-        sigc::mem_fun(*this,
-                      &SearchBasket::on_action_remove_selected));
-
-    uiManager_->insert_action_group(actionGroup_);
-
-    Gtk::Widget * menu = uiManager_->get_widget("/SearchBasketPopup");
-    menu_ = dynamic_cast<Gtk::Menu *>(menu);
-    menu_->accelerate(treeView_);
-
-    scrolledWindow_.set_policy(Gtk::POLICY_AUTOMATIC,
-                               Gtk::POLICY_AUTOMATIC);
+    set_enable_search(true);
+    set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_NONE);
+    set_headers_clickable(false);
+    set_headers_visible(false);
 
-    SearchBasketColumnRecord model_column_record;
-    treeView_.append_column("",
-        model_column_record.get_column_pixbuf());
-    treeView_.append_column("",
-        model_column_record.get_column_description());
-
-    treeView_.set_enable_search(true);
-    treeView_.set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_NONE);
-    treeView_.set_headers_clickable(false);
-    treeView_.set_headers_visible(false);
-    SearchBasketColumnRecord tmp;
-    treeView_.set_tooltip_column( tmp.get_column_description_num() );
-
-    const TreeSelectionPtr selection = treeView_.get_selection();
+    const TreeSelectionPtr selection = get_selection();
     selection->set_mode(Gtk::SELECTION_MULTIPLE);
 
-    scrolledWindow_.add(treeView_);
-
-    dockItem_ = gdl_dock_item_new_with_stock(dockItemName_.c_str(),
-                                             dockItemTitle_.c_str(),
-                                             GTK_STOCK_FIND,
-                                             dockItemBehaviour_);
-    gtk_container_add(GTK_CONTAINER(dockItem_),
-                      GTK_WIDGET(vBox_.gobj()));
-
-    vBox_.pack_start( scrolledWindow_, Gtk::PACK_EXPAND_WIDGET,0 );
-
-    std::vector<Gtk::TargetEntry> targets;
-    targets.push_back(Gtk::TargetEntry("STRING",
-                                       Gtk::TARGET_SAME_APP, 0));
-    targets.push_back(Gtk::TargetEntry("UTF8_STRING",
-                                       Gtk::TARGET_SAME_APP, 0));
-    treeView_.enable_model_drag_dest(targets, Gdk::ACTION_COPY);
-
-    treeView_.signal_button_press_event().connect(
-        sigc::mem_fun(*this, &SearchBasket::on_button_press_event),
-        false);
-
-    treeView_.signal_drag_data_received().connect_notify(
-        sigc::mem_fun(
-            *this, &SearchBasket::on_drag_data_received));
+    Gtk::Widget * const menu = uiManager_->get_widget(
+                                               "/SearchBasketPopup");
+    menu_ = dynamic_cast<Gtk::Menu *>(menu);
+    menu_->accelerate(*this);
 }
 
 SearchBasket::~SearchBasket() throw()
 {
-    uiManager_->remove_action_group(actionGroup_);
-    uiManager_->remove_ui(uiIDTreeView_);
-    treeView_.unset_model();
-    //g_object_unref(dockItem_);
-}
-
-void
-SearchBasket::init(Application & application) throw()
-{
-    application_ = &application;
-    Engine & engine = application.get_engine();
-    engine.get_criterion_repo().register_source( this );
-
-    RendererRegistry & renderer_registry
-                           = application.get_renderer_registry();
-
-    signalRendererChanged_
-        = renderer_registry.changed().connect(
-              sigc::mem_fun(*this,
-                            &SearchBasket::on_renderer_changed));
-
-    MainWindow & main_window = application.get_main_window();
-    main_window.add_dock_object_left_bottom(
-                    GDL_DOCK_OBJECT(dockItem_));
-
-    initialized_.emit(*this);
-}
-
-void
-SearchBasket::final(Application & application) throw()
-{
-    signalRendererChanged_.disconnect();
-
-    finalized_.emit(*this);
-}
-
-void
-SearchBasket::visit_renderer(BrowserRenderer & browser_renderer)
-                             throw()
-{
-    ui_show();
-}
-
-void
-SearchBasket::visit_renderer(ConsoleRenderer & console_renderer)
-                             throw()
-{
-    ui_hide();
-}
-
-void
-SearchBasket::visit_renderer(EnlargedRenderer & enlarged_renderer)
-                             throw()
-{
-    ui_show();
-}
-
-void
-SearchBasket::visit_renderer(SlideshowRenderer & slideshow_renderer)
-                             throw()
-{
+    uiManager_->remove_ui(uiID_);
 }
 
-void
-SearchBasket::on_action_select_all() throw()
+const UIManagerPtr &
+SearchBasket::get_ui_manager() throw()
 {
-    const TreeSelectionPtr selection = treeView_.get_selection();
-    selection->select_all();
-}
-
-void
-SearchBasket::on_action_remove_selected() throw()
-{
-    const ConstTreeSelectionPtr selection = treeView_.get_selection();
-
-    const TreePathList selected_rows = selection->get_selected_rows();
-
-    // NB: Erase the paths by traversing the list backwards. Otherwise
-    //     on erasing each path the remaining ones will be
-    //     invalidated.
-
-    for (TreePathList::const_reverse_iterator iter
-             = selected_rows.rbegin();
-         selected_rows.rend() != iter;
-         iter++)
-    {
-        const Gtk::TreeModel::iterator model_iter
-            = listStore_->get_iter(*iter);
-        listStore_->erase(model_iter);
-    }
-
-    apply_criterion();
-    return;
+    return uiManager_;
 }
 
 bool
 SearchBasket::on_button_press_event(GdkEventButton * event) throw()
 {
+    bool return_value;
+    const TreeModelPtr model = get_model();
+    const TreeSelectionPtr selection = get_selection();
+
     if (3 == event->button
         && GDK_BUTTON_PRESS == event->type
-        && false == listStore_->children().empty())
+        && false == model->children().empty())
     {
-        const ActionPtr action = actionGroup_->get_action(
-                                     "ActionRemoveSelected");
         Gtk::TreeModel::Path path;
-        const bool result = treeView_.get_path_at_pos(
+        const bool result = get_path_at_pos(
                                 static_cast<gint>(event->x),
                                 static_cast<gint>(event->y),
                                 path);
 
-        if (false == result || true == path.empty())
+        if (true == result && false == path.empty())
         {
-            action->set_visible(false);
-        }
-        else
-        {
-            action->set_visible(true);
-
-            const TreeSelectionPtr selection
-                                       = treeView_.get_selection();
-
             if (false == selection->is_selected(path))
             {
                 selection->unselect_all();
                 selection->select(path);
-                // treeView_.set_cursor(path, 0, false);
+                // set_cursor(path, 0, false);
             }
         }
-
-        menu_->popup(event->button, event->time);
-        return true;
-    }
-
-    return false;
-}
-
-void
-SearchBasket::on_drag_data_received(
-                  const DragContextPtr & drag_context,
-                  gint x, gint y,
-                  const Gtk::SelectionData & data,
-                  guint info, guint time) throw()
-{
-    Glib::ustring key = data.get_data_as_string();
-    bool status = add_item_to_list( key );
-    drag_context->drag_finish(status, false, 0);
-    return;
-}
-
-void
-SearchBasket::on_renderer_changed(
-                  RendererRegistry & renderer_registry) throw()
-{
-    if (false == gdl_dock_object_is_bound(GDL_DOCK_OBJECT(dockItem_)))
-    {
-        return;
-    }
-
-    const IRendererPtr & renderer = renderer_registry.get_current();
-    renderer->receive_plugin(*this);
-}
-
-bool
-SearchBasket::add_item_to_list( const Glib::ustring &key )
-{
-    DragDropCriteriaMap &dragItemMap
-                    = application_->get_drag_drop_map();
-    DragDropCriteriaMap::iterator it = dragItemMap.find( key );
-
-    if( it == dragItemMap.end() )
-        return false;
-
-    SearchBasketColumnRecord model_column_record;
-
-    PhotoSearchCriteriaPtr criteria = (*it).second;
-    Glib::ustring iconPath = criteria->get_criteria_icon_path();
-    Glib::ustring description
-                    = criteria->get_criteria_description();
-
-    //Check for duplicate
-    Gtk::TreeModel::Children children = listStore_->children();
-    for( Gtk::TreeModel::const_iterator current = children.begin();
-                                current != children.end(); current++)
-    {
-        Gtk::TreeModel::Row row = (*current);
-        PhotoSearchCriteriaPtr tag
-                = row[ model_column_record.get_column_criteria()];
-
-        if( tag->get_criteria_description() == description )
+        else
         {
-            return false;
+            selection->unselect_all();
         }
-    }
-
-    //Add
-    Gtk::TreeModel::iterator model_iter = listStore_->append();
-    Gtk::TreeModel::Row row = *model_iter;
-    PixbufPtr icon = Gdk::Pixbuf::create_from_file( iconPath );
-
-    row[ model_column_record.get_column_pixbuf() ] = icon;
-    row[ model_column_record.get_column_description() ] = description;
-    row[ model_column_record.get_column_criteria() ] = criteria;
-
-    //remove this entry from the map
-    dragItemMap.erase( it );
-
-    apply_criterion();
-    return true;
-}
-
-void
-SearchBasket::apply_criterion()
-{
-    Engine & engine = application_->get_engine();
-    engine.criteria_changed();
-    return;
-
-}
 
-void
-SearchBasket::get_criterion(
-                    PhotoSearchCriteriaList &criterion) const throw()
-{
-    SearchBasketColumnRecord model_column_record;
-    Gtk::TreeModel::Children children = listStore_->children();
-    for( Gtk::TreeModel::const_iterator current = children.begin();
-                                current != children.end(); current++)
-    {
-        Gtk::TreeModel::Row row = (*current);
-        PhotoSearchCriteriaPtr tag
-                = row[ model_column_record.get_column_criteria()];
-        criterion.push_back( tag );
+        menu_->popup(event->button, event->time);
+        return_value = true;
     }
-    return;
-}
-
-void
-SearchBasket::ui_hide() throw()
-{
-    GdlDockItem * const dock_item = GDL_DOCK_ITEM(dockItem_);
-
-    if (true == GDL_DOCK_OBJECT_ATTACHED(dock_item))
+    else
     {
-        gdl_dock_item_hide_item(GDL_DOCK_ITEM(dockItem_));
+        selection->unselect_all();
+        return_value = Gtk::TreeView::on_button_press_event(event);
     }
-}
-
-void
-SearchBasket::ui_show() throw()
-{
-    GdlDockItem * const dock_item = GDL_DOCK_ITEM(dockItem_);
 
-    if (false == GDL_DOCK_OBJECT_ATTACHED(dock_item))
-    {
-        gdl_dock_item_show_item(GDL_DOCK_ITEM(dockItem_));
-    }
+    return return_value;
 }
 
 } // namespace Solang
diff --git a/src/attribute/search-basket.h b/src/attribute/search-basket.h
index 6fd3bba..611c3c0 100644
--- a/src/attribute/search-basket.h
+++ b/src/attribute/search-basket.h
@@ -22,115 +22,35 @@
 #include <string>
 
 #include <gdkmm.h>
-#include <gdl/gdl.h>
-#include <glibmm.h>
 #include <gtkmm.h>
-#include <sigc++/sigc++.h>
 
-#include "plugin.h"
-#include "search-criterion-source.h"
+#include "types.h"
 
 namespace Solang
 {
 
-class Application;
-class RendererRegistry;
-
 class SearchBasket :
-    public Plugin,
-    public sigc::trackable,
-    public SearchCriterionSource
+    public Gtk::TreeView
 {
     public:
-        SearchBasket() throw();
+        SearchBasket(const TreeModelPtr & model) throw();
 
         virtual
         ~SearchBasket() throw();
 
-        virtual void
-        init(Application & application) throw();
-
-        virtual void
-        final(Application & application) throw();
-
-        virtual void
-        visit_renderer(BrowserRenderer & browser_renderer) throw();
-
-        virtual void
-        visit_renderer(ConsoleRenderer & console_renderer) throw();
-
-        virtual void
-        visit_renderer(EnlargedRenderer & enlarged_renderer) throw();
-
-        virtual void
-        visit_renderer(SlideshowRenderer & slideshow_renderer) throw();
-
-        bool
-        add_item_to_list( const Glib::ustring &key );
-
-        virtual void
-        get_criterion(PhotoSearchCriteriaList &) const throw();
+        const UIManagerPtr &
+        get_ui_manager() throw();
 
     protected:
-        void
-        remove_selected();
-
-        void
-        apply_criterion();
-
-        void
-        on_action_select_all() throw();
-
-        void
-        on_action_remove_selected() throw();
-
-        bool
+        virtual bool
         on_button_press_event(GdkEventButton * event) throw();
 
-        void
-        on_drag_data_received(const DragContextPtr & drag_context,
-                              gint x, gint y,
-                              const Gtk::SelectionData & data,
-                              guint info, guint time) throw();
-
-        void
-        on_renderer_changed(RendererRegistry & renderer_registry)
-                            throw();
-
-        void
-        ui_hide() throw();
-
-        void
-        ui_show() throw();
-
-        ActionGroupPtr actionGroup_;
-
-        const std::string dockItemName_;
-
-        const Glib::ustring dockItemTitle_;
-
-        GdlDockItemBehavior dockItemBehaviour_;
-
-        GtkWidget * dockItem_;
-
-        Gtk::VBox vBox_;
-
-        Gtk::ScrolledWindow scrolledWindow_;
-
-        ListStorePtr listStore_;
-
-        Gtk::TreeView treeView_;
-
-        ApplicationPtr application_;
-
         UIManagerPtr uiManager_;
 
-        Gtk::UIManager::ui_merge_id uiIDTreeView_;
+        Gtk::UIManager::ui_merge_id uiID_;
 
         Gtk::Menu * menu_;
 
-        sigc::connection signalRendererChanged_;
-
     private:
         static const std::string uiFile_;
 };
diff --git a/src/attribute/search-manager.cpp b/src/attribute/search-manager.cpp
new file mode 100644
index 0000000..96aec53
--- /dev/null
+++ b/src/attribute/search-manager.cpp
@@ -0,0 +1,370 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang 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.
+ *
+ * Solang 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#include <vector>
+
+#include <glibmm/i18n.h>
+#include <gdkmm.h>
+
+#include "application.h"
+#include "browser-renderer.h"
+#include "console-renderer.h"
+#include "engine.h"
+#include "enlarged-renderer.h"
+#include "main-window.h"
+#include "search-basket-column-record.h"
+#include "search-manager.h"
+
+namespace Solang
+{
+
+const std::string SearchManager::uiFile_
+    = PACKAGE_DATA_DIR"/"PACKAGE_TARNAME"/ui/"
+          PACKAGE_TARNAME"-search-manager.ui";
+
+SearchManager::SearchManager() throw() :
+    Plugin(),
+    sigc::trackable(),
+    actionGroup_(Gtk::ActionGroup::create(
+                     Glib::ustring::compose("%1:%2",
+                                            __FILE__,
+                                            __LINE__))),
+    uiIDBasket_(0),
+    dockItemName_("search-basket-dock-item"),
+    dockItemTitle_(_("Search")),
+    dockItemBehaviour_(GDL_DOCK_ITEM_BEH_NORMAL),
+    dockItem_(NULL),
+    vBox_( false, 6 ),
+    scrolledWindow_(),
+    listStore_(Gtk::ListStore::create(SearchBasketColumnRecord())),
+    searchBasket_(listStore_),
+    application_( NULL ),
+    signalRendererChanged_()
+{
+    actionGroup_->add(
+        Gtk::Action::create(
+            "ActionSelectAll", Gtk::Stock::SELECT_ALL,
+            _("Select _All"),
+            _("Select all the filters in this list")),
+        Gtk::AccelKey("<control>A"),
+        sigc::mem_fun(*this,
+                      &SearchManager::on_action_select_all));
+
+    {
+        const ActionPtr action = Gtk::Action::create(
+            "ActionRemoveSelected", Gtk::Stock::REMOVE,
+            _("_Remove"),
+            _("Remove the selected filters from this list"));
+
+        action->set_visible(false);
+        actionGroup_->add(
+            action, Gtk::AccelKey("Delete"),
+            sigc::mem_fun(*this,
+                          &SearchManager::on_action_remove_selected));
+    }
+
+    scrolledWindow_.set_policy(Gtk::POLICY_AUTOMATIC,
+                               Gtk::POLICY_AUTOMATIC);
+
+    SearchBasketColumnRecord model_column_record;
+    searchBasket_.append_column("",
+        model_column_record.get_column_pixbuf());
+    searchBasket_.append_column("",
+        model_column_record.get_column_description());
+
+    SearchBasketColumnRecord tmp;
+    searchBasket_.set_tooltip_column( tmp.get_column_description_num() );
+
+    scrolledWindow_.add(searchBasket_);
+
+    dockItem_ = gdl_dock_item_new_with_stock(dockItemName_.c_str(),
+                                             dockItemTitle_.c_str(),
+                                             GTK_STOCK_FIND,
+                                             dockItemBehaviour_);
+    gtk_container_add(GTK_CONTAINER(dockItem_),
+                      GTK_WIDGET(vBox_.gobj()));
+
+    vBox_.pack_start( scrolledWindow_, Gtk::PACK_EXPAND_WIDGET,0 );
+
+    std::vector<Gtk::TargetEntry> targets;
+    targets.push_back(Gtk::TargetEntry("STRING",
+                                       Gtk::TARGET_SAME_APP, 0));
+    targets.push_back(Gtk::TargetEntry("UTF8_STRING",
+                                       Gtk::TARGET_SAME_APP, 0));
+    searchBasket_.enable_model_drag_dest(targets, Gdk::ACTION_COPY);
+
+    searchBasket_.signal_drag_data_received().connect_notify(
+        sigc::mem_fun(
+            *this, &SearchManager::on_drag_data_received));
+
+    const TreeSelectionPtr selection = searchBasket_.get_selection();
+    selection->signal_changed().connect(
+        sigc::mem_fun(*this, &SearchManager::on_selection_changed));
+
+    const UIManagerPtr & ui_manager = searchBasket_.get_ui_manager();
+    uiIDBasket_ = ui_manager->add_ui_from_file(uiFile_);
+
+    if (0 != uiIDBasket_)
+    {
+        ui_manager->insert_action_group(actionGroup_);
+    }
+}
+
+SearchManager::~SearchManager() throw()
+{
+    //g_object_unref(dockItem_);
+
+    const UIManagerPtr & ui_manager = searchBasket_.get_ui_manager();
+
+    if (0 != uiIDBasket_)
+    {
+        ui_manager->remove_action_group(actionGroup_);
+        ui_manager->remove_ui(uiIDBasket_);
+        uiIDBasket_ = 0;
+    }
+}
+
+void
+SearchManager::init(Application & application) throw()
+{
+    application_ = &application;
+    Engine & engine = application.get_engine();
+    engine.get_criterion_repo().register_source( this );
+
+    RendererRegistry & renderer_registry
+                           = application.get_renderer_registry();
+
+    signalRendererChanged_
+        = renderer_registry.changed().connect(
+              sigc::mem_fun(*this,
+                            &SearchManager::on_renderer_changed));
+
+    MainWindow & main_window = application.get_main_window();
+    main_window.add_dock_object_left_bottom(
+                    GDL_DOCK_OBJECT(dockItem_));
+
+    initialized_.emit(*this);
+}
+
+void
+SearchManager::final(Application & application) throw()
+{
+    signalRendererChanged_.disconnect();
+
+    finalized_.emit(*this);
+}
+
+void
+SearchManager::visit_renderer(BrowserRenderer & browser_renderer)
+                             throw()
+{
+    ui_show();
+}
+
+void
+SearchManager::visit_renderer(ConsoleRenderer & console_renderer)
+                             throw()
+{
+    ui_hide();
+}
+
+void
+SearchManager::visit_renderer(EnlargedRenderer & enlarged_renderer)
+                             throw()
+{
+    ui_show();
+}
+
+void
+SearchManager::visit_renderer(SlideshowRenderer & slideshow_renderer)
+                             throw()
+{
+}
+
+void
+SearchManager::on_action_select_all() throw()
+{
+    const TreeSelectionPtr selection = searchBasket_.get_selection();
+    selection->select_all();
+}
+
+void
+SearchManager::on_action_remove_selected() throw()
+{
+    const ConstTreeSelectionPtr selection
+                                    = searchBasket_.get_selection();
+
+    const TreePathList selected_rows = selection->get_selected_rows();
+
+    // NB: Erase the paths by traversing the list backwards. Otherwise
+    //     on erasing each path the remaining ones will be
+    //     invalidated.
+
+    for (TreePathList::const_reverse_iterator iter
+             = selected_rows.rbegin();
+         selected_rows.rend() != iter;
+         iter++)
+    {
+        const Gtk::TreeModel::iterator model_iter
+            = listStore_->get_iter(*iter);
+        listStore_->erase(model_iter);
+    }
+
+    apply_criterion();
+    return;
+}
+
+void
+SearchManager::on_drag_data_received(
+                  const DragContextPtr & drag_context,
+                  gint x, gint y,
+                  const Gtk::SelectionData & data,
+                  guint info, guint time) throw()
+{
+    Glib::ustring key = data.get_data_as_string();
+    bool status = add_item_to_list( key );
+    drag_context->drag_finish(status, false, 0);
+    return;
+}
+
+void
+SearchManager::on_renderer_changed(
+                  RendererRegistry & renderer_registry) throw()
+{
+    if (false == gdl_dock_object_is_bound(GDL_DOCK_OBJECT(dockItem_)))
+    {
+        return;
+    }
+
+    const IRendererPtr & renderer = renderer_registry.get_current();
+    renderer->receive_plugin(*this);
+}
+
+void
+SearchManager::on_selection_changed() throw()
+{
+    const ActionPtr action = actionGroup_->get_action(
+                                 "ActionRemoveSelected");
+    const TreeSelectionPtr selection = searchBasket_.get_selection();
+
+    action->set_visible((0 == selection->count_selected_rows())
+                        ? false
+                        : true);
+}
+
+bool
+SearchManager::add_item_to_list( const Glib::ustring &key )
+{
+    DragDropCriteriaMap &dragItemMap
+                    = application_->get_drag_drop_map();
+    DragDropCriteriaMap::iterator it = dragItemMap.find( key );
+
+    if( it == dragItemMap.end() )
+        return false;
+
+    SearchBasketColumnRecord model_column_record;
+
+    PhotoSearchCriteriaPtr criteria = (*it).second;
+    Glib::ustring iconPath = criteria->get_criteria_icon_path();
+    Glib::ustring description
+                    = criteria->get_criteria_description();
+
+    //Check for duplicate
+    Gtk::TreeModel::Children children = listStore_->children();
+    for( Gtk::TreeModel::const_iterator current = children.begin();
+                                current != children.end(); current++)
+    {
+        Gtk::TreeModel::Row row = (*current);
+        PhotoSearchCriteriaPtr tag
+                = row[ model_column_record.get_column_criteria()];
+
+        if( tag->get_criteria_description() == description )
+        {
+            return false;
+        }
+    }
+
+    //Add
+    Gtk::TreeModel::iterator model_iter = listStore_->append();
+    Gtk::TreeModel::Row row = *model_iter;
+    PixbufPtr icon = Gdk::Pixbuf::create_from_file( iconPath );
+
+    row[ model_column_record.get_column_pixbuf() ] = icon;
+    row[ model_column_record.get_column_description() ] = description;
+    row[ model_column_record.get_column_criteria() ] = criteria;
+
+    //remove this entry from the map
+    dragItemMap.erase( it );
+
+    apply_criterion();
+    return true;
+}
+
+void
+SearchManager::apply_criterion()
+{
+    Engine & engine = application_->get_engine();
+    engine.criteria_changed();
+    return;
+
+}
+
+void
+SearchManager::get_criterion(
+                    PhotoSearchCriteriaList &criterion) const throw()
+{
+    SearchBasketColumnRecord model_column_record;
+    Gtk::TreeModel::Children children = listStore_->children();
+    for( Gtk::TreeModel::const_iterator current = children.begin();
+                                current != children.end(); current++)
+    {
+        Gtk::TreeModel::Row row = (*current);
+        PhotoSearchCriteriaPtr tag
+                = row[ model_column_record.get_column_criteria()];
+        criterion.push_back( tag );
+    }
+    return;
+}
+
+void
+SearchManager::ui_hide() throw()
+{
+    GdlDockItem * const dock_item = GDL_DOCK_ITEM(dockItem_);
+
+    if (true == GDL_DOCK_OBJECT_ATTACHED(dock_item))
+    {
+        gdl_dock_item_hide_item(GDL_DOCK_ITEM(dockItem_));
+    }
+}
+
+void
+SearchManager::ui_show() throw()
+{
+    GdlDockItem * const dock_item = GDL_DOCK_ITEM(dockItem_);
+
+    if (false == GDL_DOCK_OBJECT_ATTACHED(dock_item))
+    {
+        gdl_dock_item_show_item(GDL_DOCK_ITEM(dockItem_));
+    }
+}
+
+} // namespace Solang
diff --git a/src/attribute/search-manager.h b/src/attribute/search-manager.h
new file mode 100644
index 0000000..a2afe57
--- /dev/null
+++ b/src/attribute/search-manager.h
@@ -0,0 +1,136 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
+ *
+ * Solang 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.
+ *
+ * Solang 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SOLANG_SEARCH_MANAGER_H
+#define SOLANG_SEARCH_MANAGER_H
+
+#include <string>
+
+#include <gdl/gdl.h>
+#include <glibmm.h>
+#include <gtkmm.h>
+#include <sigc++/sigc++.h>
+
+#include "plugin.h"
+#include "search-basket.h"
+#include "search-criterion-source.h"
+
+namespace Solang
+{
+
+class Application;
+class RendererRegistry;
+
+class SearchManager :
+    public Plugin,
+    public sigc::trackable,
+    public SearchCriterionSource
+{
+    public:
+        SearchManager() throw();
+
+        virtual
+        ~SearchManager() throw();
+
+        virtual void
+        init(Application & application) throw();
+
+        virtual void
+        final(Application & application) throw();
+
+        virtual void
+        visit_renderer(BrowserRenderer & browser_renderer) throw();
+
+        virtual void
+        visit_renderer(ConsoleRenderer & console_renderer) throw();
+
+        virtual void
+        visit_renderer(EnlargedRenderer & enlarged_renderer) throw();
+
+        virtual void
+        visit_renderer(SlideshowRenderer & slideshow_renderer) throw();
+
+        bool
+        add_item_to_list( const Glib::ustring &key );
+
+        virtual void
+        get_criterion(PhotoSearchCriteriaList &) const throw();
+
+    protected:
+        void
+        remove_selected();
+
+        void
+        apply_criterion();
+
+        void
+        on_action_select_all() throw();
+
+        void
+        on_action_remove_selected() throw();
+
+        void
+        on_drag_data_received(const DragContextPtr & drag_context,
+                              gint x, gint y,
+                              const Gtk::SelectionData & data,
+                              guint info, guint time) throw();
+
+        void
+        on_renderer_changed(RendererRegistry & renderer_registry)
+                            throw();
+
+        void
+        on_selection_changed() throw();
+
+        void
+        ui_hide() throw();
+
+        void
+        ui_show() throw();
+
+        ActionGroupPtr actionGroup_;
+
+        Gtk::UIManager::ui_merge_id uiIDBasket_;
+
+        const std::string dockItemName_;
+
+        const Glib::ustring dockItemTitle_;
+
+        GdlDockItemBehavior dockItemBehaviour_;
+
+        GtkWidget * dockItem_;
+
+        Gtk::VBox vBox_;
+
+        Gtk::ScrolledWindow scrolledWindow_;
+
+        ListStorePtr listStore_;
+
+        SearchBasket searchBasket_;
+
+        ApplicationPtr application_;
+
+        sigc::connection signalRendererChanged_;
+
+    private:
+        static const std::string uiFile_;
+};
+
+} // namespace Solang
+
+#endif // SOLANG_SEARCH_MANAGER_H



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]