[solang/gsettings] Added One-key tagging support



commit bf6bf7c7b3c71dd74fff67f877a39fe28bd2c803
Author: Florent Thévenet <feuloren free fr>
Date:   Fri Jun 18 15:06:47 2010 +0200

    Added One-key tagging support

 configure.ac                       |    1 -
 src/application/application.cpp    |    9 ++-
 src/application/application.h      |    1 +
 src/attribute/Makefile.am          |    4 +-
 src/attribute/tag-key-manager.cpp  |  123 ++++++++++++++++++++++++++++++++++++
 src/attribute/tag-key-manager.h    |   67 +++++++++++++++++++
 src/attribute/tag-manager.cpp      |   86 ++++++++++++++++++++++---
 src/attribute/tag-manager.h        |   32 +++++++++
 src/attribute/tag-new-dialog.cpp   |  103 +++++++++++++++++++++++++++++-
 src/attribute/tag-new-dialog.h     |   35 +++++++++--
 src/renderer/browser-renderer.cpp  |    9 ++-
 src/renderer/browser-renderer.h    |    1 +
 src/renderer/enlarged-renderer.cpp |   34 ++++++++++
 src/renderer/enlarged-renderer.h   |    3 +
 14 files changed, 479 insertions(+), 29 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 0861120..ab40d9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,7 +46,6 @@ PKG_CHECK_MODULES(GEGLMM, [geglmm >= 0.1.0])
 PKG_CHECK_MODULES(GTKIMAGEVIEW, [gtkimageview])
 PKG_CHECK_MODULES(GTKMM, [gtkmm-2.4 >= 2.8])
 PKG_CHECK_MODULES(TRACKER, [tracker-client-0.8])
-PKG_CHECK_MODULES(GCONF, [gconf-2.0 >= 2.31.1])
 
 AC_ARG_ENABLE(
     [brasero-exporter],
diff --git a/src/application/application.cpp b/src/application/application.cpp
index da42adb..ffb8beb 100644
--- a/src/application/application.cpp
+++ b/src/application/application.cpp
@@ -1,6 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
  *
  * 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
@@ -273,7 +274,7 @@ Application::init() throw()
                       &Application::on_async_search));
 
     //we use the gconf backend for gsettings
-    g_setenv("GSETTINGS_BACKEND", "gconf", FALSE);
+    //g_setenv("GSETTINGS_BACKEND", "gconf", FALSE);
     settings_ = g_settings_new("org.gnome.solang");
 
     // Plugins.
@@ -291,9 +292,6 @@ Application::init() throw()
     IPluginPtr search_manager(new SearchManager());
     plugins_.push_back(search_manager);
 
-    IPluginPtr tag_manager(new TagManager( ));
-    plugins_.push_back(tag_manager);
-
     IPhotoDestinationPtr directory_destination(
                              new DirectoryDestination());
     IPluginPtr directory_exporter(new Exporter(directory_destination,
@@ -331,6 +329,9 @@ Application::init() throw()
     IPluginPtr slideshow_renderer(new SlideshowRenderer());
     plugins_.push_back(slideshow_renderer);
 
+    IPluginPtr tag_manager(new TagManager( ));
+    plugins_.push_back(tag_manager);
+
     std::for_each(plugins_.begin(), plugins_.end(),
                   Initializer<IPluginPtr>(this));
 
diff --git a/src/application/application.h b/src/application/application.h
index 177ec28..163e52e 100644
--- a/src/application/application.h
+++ b/src/application/application.h
@@ -1,6 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * Copyright (C) 2009 Debarshi Ray <rishi gnu org>
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
  *
  * 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
diff --git a/src/attribute/Makefile.am b/src/attribute/Makefile.am
index 822bdd2..bbe1c18 100644
--- a/src/attribute/Makefile.am
+++ b/src/attribute/Makefile.am
@@ -33,6 +33,8 @@ libattribute_la_SOURCES = \
 	search-manager.h \
 	tag.cpp \
 	tag.h \
+	tag-key-manager.cpp \
+	tag-key-manager.h \
 	tag-manager.cpp \
 	tag-manager.h \
 	tag-new-dialog.cpp \
@@ -42,4 +44,4 @@ libattribute_la_SOURCES = \
 	tag-view-model-column-record.h \
 	tag-view-model-column-record.cpp
 
-include $(top_srcdir)/src/build-flags.mk
\ No newline at end of file
+include $(top_srcdir)/src/build-flags.mk
diff --git a/src/attribute/tag-key-manager.cpp b/src/attribute/tag-key-manager.cpp
new file mode 100644
index 0000000..f9dcba5
--- /dev/null
+++ b/src/attribute/tag-key-manager.cpp
@@ -0,0 +1,123 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
+ *
+ * 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 <glibmm.h>
+#include <glibmm/i18n.h>
+#include <sigc++/sigc++.h>
+
+#include "tag-key-manager.h"
+#include "tag.h"
+
+#define NBR_KEYS 36
+
+namespace Solang
+{
+
+const Glib::ustring valid_keys[NBR_KEYS] = {"0", "1", "2", "3", "4", "5", "6", "7", "8",
+      "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
+      "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
+
+TagKeyManager::TagKeyManager() throw()
+{
+    gsettings_ = g_settings_new("org.gnome.solang.keys");
+}
+
+TagKeyManager::~TagKeyManager() throw()
+{
+}
+
+bool
+TagKeyManager::is_key_valid(const Glib::ustring key)
+{
+    for(int i = 0; i<NBR_KEYS-1; i++)
+    {
+        if (valid_keys[i] == key)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+TagKeyManager::is_key_used(const Glib::ustring key)
+{
+    return get_tag_for_key(key) != "";
+}
+
+Glib::ustring
+TagKeyManager::get_tag_for_key(const Glib::ustring key)
+{
+    if (is_key_valid(key))
+    {
+        gchar * tag_urn = g_settings_get_string(gsettings_,
+                                Glib::ustring::compose("key-%1", key).c_str());
+        return Glib::ustring(tag_urn);
+    }
+    return "";
+}
+
+Glib::ustring
+TagKeyManager::get_key_for_tag(const Glib::ustring tag_urn)
+{
+    for(int i = 0; i<NBR_KEYS-1; i++)
+    {
+        if (Glib::ustring(g_settings_get_string(gsettings_,
+            Glib::ustring::compose("key-%1", valid_keys[i]).c_str()))
+            == tag_urn)
+        {
+            return valid_keys[i];
+        }
+    }
+    return "";
+}
+
+void
+TagKeyManager::set_tag_for_key(const Glib::ustring key,
+                               const Glib::ustring tag_urn)
+{
+    if (is_key_valid(key))
+    {
+        g_settings_set_string(gsettings_,
+                              Glib::ustring::compose("key-%1", key).c_str(),
+                              tag_urn.c_str());
+    }
+}
+
+void
+TagKeyManager::save_tag(const Glib::ustring new_key,
+                        const Glib::ustring tag_urn)
+{
+    if (new_key != "")
+    {
+        set_tag_for_key(new_key, tag_urn);
+    }
+    else
+    {
+        if (get_key_for_tag(tag_urn) != "")
+        {
+            set_tag_for_key(new_key, "");
+        }
+    }
+}
+
+} // namespace Solang
diff --git a/src/attribute/tag-key-manager.h b/src/attribute/tag-key-manager.h
new file mode 100644
index 0000000..72cad36
--- /dev/null
+++ b/src/attribute/tag-key-manager.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
+ *
+ * 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_TAG_KEY_MANAGER_H
+#define SOLANG_TAG_KEY_MANAGER_H
+
+#include <string>
+#include <map>
+
+#include <glibmm.h>
+#include <gtkmm.h>
+
+#include "types.h"
+
+namespace Solang
+{
+
+class TagKeyManager
+{
+    public:
+        TagKeyManager() throw();
+
+        virtual
+        ~TagKeyManager() throw();
+
+        bool
+        is_key_valid(const Glib::ustring key);
+
+        bool
+        is_key_used(const Glib::ustring key);
+
+        Glib::ustring
+        get_tag_for_key(const Glib::ustring key);
+
+        Glib::ustring
+        get_key_for_tag(const Glib::ustring tag_urn);
+
+        void
+        set_tag_for_key(const Glib::ustring key, const Glib::ustring tag_urn);
+
+        void
+        save_tag(const Glib::ustring new_key, const Glib::ustring tag_urn);
+
+    protected:
+        GSettings* gsettings_;
+
+    private:
+};
+
+} // namespace Solang
+
+#endif // SOLANG_TAG_KEY_MANAGER_H
diff --git a/src/attribute/tag-manager.cpp b/src/attribute/tag-manager.cpp
index 5d5e0f8..8f21c9d 100644
--- a/src/attribute/tag-manager.cpp
+++ b/src/attribute/tag-manager.cpp
@@ -1,17 +1,18 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
- * 
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
+ *
  * 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/>.
  */
@@ -20,6 +21,7 @@
 #include "config.h"
 #endif // HAVE_CONFIG_H
 
+#include <stdexcept>
 #include <glibmm/i18n.h>
 #include <sigc++/sigc++.h>
 
@@ -33,6 +35,8 @@
 #include "tag.h"
 #include "tag-manager.h"
 #include "tag-new-dialog.h"
+#include "tag-key-manager.h"
+#include "tag-view-model-column-record.h"
 
 namespace Solang
 {
@@ -58,6 +62,7 @@ TagManager::TagManager() throw() :
     scrolledWindow_(),
     tagView_( ),
     showAll_(false),
+    keyManager_(),
     signalRendererChanged_()
 {
     Gtk::IconSource icon_source;
@@ -206,6 +211,17 @@ TagManager::init(Application & application)
             &TagManager::populate_view),
         Glib::PRIORITY_DEFAULT_IDLE);
 
+    IRendererPtr i_enlarged_renderer
+        = renderer_registry.select<EnlargedRenderer>();
+    EnlargedRenderer *enlarged_renderer
+        = static_cast<EnlargedRenderer*>(i_enlarged_renderer);
+
+    if (enlarged_renderer != 0)
+    {
+        enlarged_renderer->signal_key_press.connect(sigc::mem_fun(
+            *this, &TagManager::on_enlarged_renderer_key_press));
+    }
+
     initialized_.emit(*this);
 }
 
@@ -247,7 +263,7 @@ TagManager::visit_renderer(SlideshowRenderer & slideshow_renderer)
 void
 TagManager::on_action_tag_new() throw()
 {
-    TagNewDialog tag_new_dialog;
+    TagNewDialog tag_new_dialog( this );
     tag_new_dialog.set_transient_for(application_->get_main_window());
 
     const gint response = tag_new_dialog.run();
@@ -298,7 +314,7 @@ TagManager::on_action_tag_edit() throw()
         Gtk::TreeModel::Row row = *model_iter;
         TagPtr tag = row[ rec.get_column_tag() ];
 
-        TagNewDialog tag_new_dialog( tag );
+        TagNewDialog tag_new_dialog( this, tag );
         tag_new_dialog.set_transient_for(
                                 application_->get_main_window());
 
@@ -308,6 +324,8 @@ TagManager::on_action_tag_edit() throw()
         {
             case Gtk::RESPONSE_OK:
             {
+                keyManager_.save_tag(tag_new_dialog.get_key(), tag->get_urn());
+
                 DatabasePtr db = application_->get_engine().get_db();
                 tag->edit_async(
                     tag_new_dialog.get_name(),
@@ -380,18 +398,25 @@ TagManager::on_action_apply_tag() throw()
         = application_->get_renderer_registry();
     const IRendererPtr renderer = renderer_registry.get_current();
 
-    const DatabasePtr db = application_->get_engine().get_db();
     PhotoList photos = renderer->get_current_selection();
 
-    for (PhotoList::const_iterator photos_iter = photos.begin();
-         photos.end() != photos_iter;
+    apply_tag(tag, &photos);
+
+    return;
+}
+
+void
+TagManager::apply_tag(TagPtr tag, PhotoList *photos)
+{
+    const DatabasePtr db = application_->get_engine().get_db();
+
+    for (PhotoList::const_iterator photos_iter = photos->begin();
+         photos->end() != photos_iter;
          photos_iter++)
     {
         PhotoTag photo_tag(*photos_iter, tag);
         photo_tag.save_async(*db, sigc::slot<void>());
     }
-
-    return;
 }
 
 void
@@ -471,6 +496,30 @@ TagManager::populate_view() throw()
                               &TagManager::on_get_tags));
 }
 
+TagPtr
+TagManager::get_tag_for_urn(std::string urn) throw(std::runtime_error)
+{
+    //THERE IS a better way to do it !
+    const TagViewModelColumnRecord &rec
+                                = tagView_.get_column_records();
+
+    typedef Gtk::TreeModel::Children type_children;
+    type_children children = tagView_.get_model()->children();
+
+    for(type_children::iterator iter = children.begin();
+        iter != children.end(); ++iter)
+    {
+        Gtk::TreeModel::Row row = *iter;
+
+        const TagPtr & tag = row[rec.get_column_tag()];
+        if (tag->get_urn() == urn)
+        {
+            return tag;
+        }
+    }
+    throw std::runtime_error("No such Tag");
+}
+
 void
 TagManager::ui_hide() throw()
 {
@@ -497,4 +546,21 @@ TagManager::ui_show() throw()
     }
 }
 
+void
+TagManager::on_enlarged_renderer_key_press(PhotoList *photos, Glib::ustring key)
+{
+    if (keyManager_.is_key_valid(key) && keyManager_.is_key_used(key))
+    {
+        try
+        {
+            TagPtr tag = get_tag_for_urn(keyManager_.get_tag_for_key(key));
+            apply_tag(tag, photos);
+        }
+        catch(std::runtime_error)
+        {
+            return;
+        }
+    }
+}
+
 } // namespace Solang
diff --git a/src/attribute/tag-manager.h b/src/attribute/tag-manager.h
index 07f3993..5bd448d 100644
--- a/src/attribute/tag-manager.h
+++ b/src/attribute/tag-manager.h
@@ -1,6 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
  *
  * 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
@@ -20,6 +21,7 @@
 #define SOLANG_TAG_MANAGER_H
 
 #include <string>
+#include <stdexcept>
 
 #include <gdl/gdl.h>
 #include <glibmm.h>
@@ -27,6 +29,7 @@
 
 #include "plugin.h"
 #include "tag-view.h"
+#include "tag-key-manager.h"
 
 namespace Solang
 {
@@ -58,6 +61,15 @@ class TagManager :
         virtual void
         visit_renderer(SlideshowRenderer & slideshow_renderer) throw();
 
+        virtual TagPtr
+        get_tag_for_urn(std::string) throw(std::runtime_error);
+
+        virtual inline TagKeyManager*
+        get_key_manager();
+
+        virtual inline Application*
+        get_application();
+
     protected:
         void
         on_action_tag_new() throw();
@@ -72,6 +84,9 @@ class TagManager :
         on_action_apply_tag() throw();
 
         void
+        apply_tag(TagPtr tag, PhotoList *photos);
+
+        void
         on_action_remove_tag() throw();
 
         void
@@ -96,6 +111,9 @@ class TagManager :
         void
         ui_show() throw();
 
+        void
+        on_enlarged_renderer_key_press(PhotoList *photos, Glib::ustring key);
+
         ApplicationPtr application_;
 
         IconFactoryPtr iconFactory_;
@@ -120,11 +138,25 @@ class TagManager :
 
         bool showAll_;
 
+        TagKeyManager keyManager_;
+
         sigc::connection signalRendererChanged_;
 
     private:
 };
 
+inline TagKeyManager*
+TagManager::get_key_manager()
+{
+    return &keyManager_;
+}
+
+inline Application*
+TagManager::get_application()
+{
+    return application_;
+}
+
 } // namespace Solang
 
 #endif // SOLANG_TAG_MANAGER_H
diff --git a/src/attribute/tag-new-dialog.cpp b/src/attribute/tag-new-dialog.cpp
index 5d451ae..e4e8de1 100644
--- a/src/attribute/tag-new-dialog.cpp
+++ b/src/attribute/tag-new-dialog.cpp
@@ -1,6 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
  *
  * 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
@@ -21,18 +22,23 @@
 #endif // HAVE_CONFIG_H
 
 #include <glibmm.h>
+#include <gtkmm.h>
 #include <glibmm/i18n.h>
 #include <sigc++/sigc++.h>
 
 #include "tag-new-dialog.h"
 #include "tag.h"
+#include "tag-manager.h"
+#include "tag-key-manager.h"
 
 namespace Solang
 {
 
-TagNewDialog::TagNewDialog() throw() :
+TagNewDialog::TagNewDialog( TagManager *tagmanager ) throw() :
     Gtk::Dialog(),
     iconPath_(""),
+    tagManager_(tagmanager),
+    keyManager_(tagmanager->get_key_manager()),
     mainTable_(3, 3, false),
     iconButton_(),
     iconImage_(Gtk::Stock::MISSING_IMAGE, Gtk::ICON_SIZE_BUTTON),
@@ -51,18 +57,29 @@ TagNewDialog::TagNewDialog() throw() :
                       Gtk::ALIGN_CENTER,
                       false),
     descriptionScrolledWindow_(),
-    descriptionTextView_()
+    descriptionTextView_(),
+    keyLabel_(_("Key:"),
+              Gtk::ALIGN_LEFT,
+              Gtk::ALIGN_CENTER,
+              false),
+    keyEntry_()
 {
     set_title(_("Create New Tag"));
 
+    keyEntry_.set_sensitive(false);
+
     setup_gui();
 
     show_all_children();
 }
 
-TagNewDialog::TagNewDialog( const TagPtr &tag ) throw() :
+TagNewDialog::TagNewDialog( TagManager *tagmanager,
+                            const TagPtr &tag ) throw() :
     Gtk::Dialog(),
     iconPath_( ),
+    tagManager_(tagmanager),
+    keyManager_(tagmanager->get_key_manager()),
+    tag_urn_(tag->get_urn()),
     mainTable_(3, 3, false),
     iconButton_(),
     iconImage_(Gtk::Stock::MISSING_IMAGE, Gtk::ICON_SIZE_BUTTON),
@@ -81,7 +98,12 @@ TagNewDialog::TagNewDialog( const TagPtr &tag ) throw() :
                       Gtk::ALIGN_CENTER,
                       false),
     descriptionScrolledWindow_(),
-    descriptionTextView_()
+    descriptionTextView_(),
+    keyLabel_(_("Key:"),
+              Gtk::ALIGN_LEFT,
+              Gtk::ALIGN_CENTER,
+              false),
+    keyEntry_()
 {
     set_title(_("Edit Tag"));
 
@@ -95,6 +117,7 @@ TagNewDialog::TagNewDialog( const TagPtr &tag ) throw() :
         description->set_text( tag->get_description() );
         descriptionTextView_.set_buffer(description);
         set_icon(tag->get_icon_path());
+        keyEntry_.set_text(keyManager_->get_key_for_tag(tag->get_urn()));
     }
 
     show_all_children();
@@ -192,6 +215,65 @@ TagNewDialog::on_icon_button_clicked() throw()
 }
 
 void
+TagNewDialog::on_key_entry_changed() throw()
+{
+    const Glib::ustring chosen_key = keyEntry_.get_text();
+
+    //we disable the OK button so user can't save with a non-valid key
+    GtkWidget * ok_button = gtk_dialog_get_widget_for_response(gobj(),
+                                                               GTK_RESPONSE_OK);
+    //it doesn't work with the C++ API !
+
+    if (chosen_key == "")
+    {
+        gtk_entry_set_icon_from_stock(keyEntry_.gobj(),
+                                      GTK_ENTRY_ICON_SECONDARY, NULL);
+        gtk_widget_set_sensitive(ok_button, TRUE);
+    }
+    else
+    {
+        if (keyManager_->is_key_valid(chosen_key))
+        {
+            Glib::ustring cur_tag = keyManager_->get_tag_for_key(chosen_key);
+            if (cur_tag != "" && cur_tag != tag_urn_)
+            {
+                Glib::ustring cur_tag_name;
+                try
+                {
+                    cur_tag_name = tagManager_->get_tag_for_urn(
+                                                           cur_tag)->get_name();
+                }
+                catch(std::runtime_error)
+                {
+                    Glib::ustring &cur_tag_name = cur_tag;
+                }
+
+                keyEntry_.set_icon_from_stock(Gtk::Stock::DIALOG_WARNING,
+                                            Gtk::ENTRY_ICON_SECONDARY);
+                keyEntry_.set_icon_tooltip_text(Glib::ustring::compose(
+                            _("This key is already binded to the tag '%1'\n"
+                            "You can bind this key to the tag '%2'\nbut the "
+                            "key will be unbinded from the old tag."),
+                            cur_tag_name,
+                            get_name()),
+                                            Gtk::ENTRY_ICON_SECONDARY);
+            }
+            gtk_widget_set_sensitive(ok_button, TRUE);
+        }
+        else
+        {
+            keyEntry_.set_icon_from_stock(Gtk::Stock::DIALOG_ERROR,
+                                        Gtk::ENTRY_ICON_SECONDARY);
+            keyEntry_.set_icon_tooltip_text(_("This is not a valid key"),
+                                        Gtk::ENTRY_ICON_SECONDARY);
+
+            gtk_widget_set_sensitive(ok_button, FALSE);
+        }
+
+    }
+}
+
+void
 TagNewDialog::setup_gui() throw()
 {
     set_border_width(12);
@@ -249,6 +331,19 @@ TagNewDialog::setup_gui() throw()
 
     descriptionScrolledWindow_.add(descriptionTextView_);
 
+    mainTable_.attach(keyLabel_, 1, 2, 3, 4,
+                      Gtk::FILL | Gtk::EXPAND,
+                      Gtk::FILL | Gtk::EXPAND,
+                      0, 0);
+
+    keyEntry_.set_max_length(1);
+    keyEntry_.signal_changed().connect(
+        sigc::mem_fun(*this, &TagNewDialog::on_key_entry_changed));
+    mainTable_.attach(keyEntry_, 2, 3, 3, 4,
+                      Gtk::FILL | Gtk::EXPAND,
+                      Gtk::FILL | Gtk::EXPAND,
+                      0, 0);
+
     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
     add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
 
diff --git a/src/attribute/tag-new-dialog.h b/src/attribute/tag-new-dialog.h
index a276b31..91b3ca7 100644
--- a/src/attribute/tag-new-dialog.h
+++ b/src/attribute/tag-new-dialog.h
@@ -1,17 +1,18 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * Copyright (C) 2009 Debarshi Ray <rishi gnu org>
- * 
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
+ *
  * 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/>.
  */
@@ -24,6 +25,8 @@
 #include <gtkmm.h>
 
 #include "types.h"
+#include "tag-key-manager.h"
+#include "tag-manager.h"
 
 namespace Solang
 {
@@ -32,8 +35,8 @@ class TagNewDialog :
     public Gtk::Dialog
 {
     public:
-        TagNewDialog() throw();
-        TagNewDialog( const TagPtr &tag ) throw();
+        TagNewDialog( TagManager *tagmanager ) throw();
+        TagNewDialog( TagManager *tagmanager, const TagPtr &tag ) throw();
 
         virtual
         ~TagNewDialog() throw();
@@ -41,6 +44,9 @@ class TagNewDialog :
         inline Glib::ustring
         get_name() const;
 
+        inline Glib::ustring
+        get_key() const;
+
         inline const std::string &
         get_icon_path() const;
 
@@ -58,6 +64,9 @@ class TagNewDialog :
         on_icon_button_clicked() throw();
 
         void
+        on_key_entry_changed() throw();
+
+        void
         setup_gui() throw();
 
         void
@@ -65,6 +74,12 @@ class TagNewDialog :
 
         std::string iconPath_;
 
+        TagManager * tagManager_;
+
+        TagKeyManager * keyManager_;
+
+        const Glib::ustring tag_urn_;
+
         Gtk::Table mainTable_;
 
         Gtk::Button iconButton_;
@@ -85,6 +100,10 @@ class TagNewDialog :
 
         Gtk::TextView descriptionTextView_;
 
+        Gtk::Label keyLabel_;
+
+        Gtk::Entry keyEntry_;
+
     private:
 };
 
@@ -94,6 +113,12 @@ TagNewDialog::get_name() const
     return nameEntry_.get_text();
 }
 
+inline Glib::ustring
+TagNewDialog::get_key() const
+{
+    return keyEntry_.get_text();
+}
+
 inline const std::string &
 TagNewDialog::get_icon_path() const
 {
diff --git a/src/renderer/browser-renderer.cpp b/src/renderer/browser-renderer.cpp
index 27d26bc..f6042ea 100644
--- a/src/renderer/browser-renderer.cpp
+++ b/src/renderer/browser-renderer.cpp
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
  * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
  *
  * 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
@@ -202,7 +203,7 @@ BrowserRenderer::BrowserRenderer() throw() :
             Gtk::Action::create(
                 "ActionViewBrowserColorUnset", _("Use _Theme Color"),
                 _("Set the background color to theme color.")),
-            sigc::mem_fun(*this, 
+            sigc::mem_fun(*this,
                 &BrowserRenderer::on_action_unset_background_color));
 
         actionGroup_->add(
@@ -409,7 +410,7 @@ BrowserRenderer::init(Application & application) throw()
     RendererRegistry & renderer_registry
         = application.get_renderer_registry();
     renderer_registry.add(this);
-    
+
     //we set the background color of the thumbnailView from GSettings
     GSettings * settings = application.get_settings();
     if (g_settings_get_boolean(settings, "use-background-color")) {
@@ -623,7 +624,7 @@ BrowserRenderer::on_action_change_background_color(
                     Glib::ustring color_code) throw()
 {
     thumbnailView_.set_base_color(color_code);
-    
+
     //then we store it with GSettings
     GSettings * settings = application_->get_settings();
     g_settings_set_boolean(settings, "use-background-color", TRUE);
@@ -634,7 +635,7 @@ void
 BrowserRenderer::on_action_unset_background_color() throw()
 {
     thumbnailView_.unset_base_color();
-    
+
     GSettings * settings = application_->get_settings();
     g_settings_set_boolean(settings, "use-background-color", FALSE);
 }
diff --git a/src/renderer/browser-renderer.h b/src/renderer/browser-renderer.h
index 73e18a8..a73954e 100644
--- a/src/renderer/browser-renderer.h
+++ b/src/renderer/browser-renderer.h
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
  * Copyright (C) 2009 Santanu Sinha <santanu sinha gmail com>
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
  *
  * 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
diff --git a/src/renderer/enlarged-renderer.cpp b/src/renderer/enlarged-renderer.cpp
index d017141..062530f 100644
--- a/src/renderer/enlarged-renderer.cpp
+++ b/src/renderer/enlarged-renderer.cpp
@@ -1,6 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
  *
  * 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
@@ -34,6 +35,8 @@
 #include "main-window.h"
 #include "photo.h"
 #include "pixbuf-maker.h"
+#include "tag-manager.h"
+#include "tag-key-manager.h"
 #include "types.h"
 
 namespace Solang
@@ -60,6 +63,25 @@ image_view_on_scroll_event(GtkImageView * view,
     enlarged_renderer->on_scroll_event(direction);
 }
 
+static void
+image_view_on_key_press_event(GtkImageView * view,
+                           GdkEventKey * event,
+                           gpointer user_data) throw()
+{
+    if (0 == user_data)
+    {
+        g_warning("Not an instance of EnlargedRenderer");
+        return;
+    }
+
+    EnlargedRenderer * enlarged_renderer
+        = static_cast<EnlargedRenderer *>(user_data);
+
+    enlarged_renderer->signal_key_press.emit(
+        &(enlarged_renderer->get_current_selection()),
+        Glib::ustring(event->string));
+}
+
 EnlargedRenderer::EnlargedRenderer() throw() :
     IRenderer(),
     Plugin(),
@@ -228,6 +250,9 @@ EnlargedRenderer::on_pixbuf_maker_async_ready(
             return;
         }
 
+        int events = GDK_KEY_PRESS_MASK;
+        gtk_widget_add_events(imageView_, static_cast<GdkEventMask>(events));
+
         gtk_image_view_set_show_frame(GTK_IMAGE_VIEW(imageView_),
                                       FALSE);
 
@@ -260,6 +285,11 @@ EnlargedRenderer::on_pixbuf_maker_async_ready(
                          "mouse-wheel-scroll",
                          G_CALLBACK(image_view_on_scroll_event),
                          this);
+
+        g_signal_connect(GTK_IMAGE_VIEW(imageView_),
+                         "key-press-event",
+                         G_CALLBACK(image_view_on_key_press_event),
+                         this);
     }
 
     if (0 == imageScrollWin_)
@@ -282,6 +312,8 @@ EnlargedRenderer::on_pixbuf_maker_async_ready(
 
     gtk_image_view_set_pixbuf(GTK_IMAGE_VIEW(imageView_),
                               pixbuf->gobj(), TRUE);
+
+    gtk_widget_grab_focus(imageView_);
 }
 
 void
@@ -536,6 +568,8 @@ EnlargedRenderer::present() throw()
 
     MainWindow & main_window = application_->get_main_window();
     main_window.present_dock_object(GDL_DOCK_OBJECT(dockItem_));
+
+    gtk_widget_grab_focus(imageView_);
 }
 
 void
diff --git a/src/renderer/enlarged-renderer.h b/src/renderer/enlarged-renderer.h
index a3b2087..409b4e1 100644
--- a/src/renderer/enlarged-renderer.h
+++ b/src/renderer/enlarged-renderer.h
@@ -1,6 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * Copyright (C) 2009, 2010 Debarshi Ray <rishi gnu org>
+ * Copyright (C) 2010 Florent Thévenet <feuloren free fr>
  *
  * 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
@@ -84,6 +85,8 @@ class EnlargedRenderer :
         receive_selector(IRendererSelector & selector,
                          const IRendererPtr & renderer) throw();
 
+        sigc::signal<void, PhotoList*, Glib::ustring> signal_key_press;
+
     protected:
         void
         create_action_group() throw();



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