[niepce] * Make undo easier to use.



commit d469ce30f1bb9c8e9a1325e09bb62cd9170f7227
Author: Hubert Figuiere <hub figuiere net>
Date:   Mon Apr 13 01:56:28 2009 -0400

    	* Make undo easier to use.
    	* Finished implementing labels.
---
 ChangeLog                                    |    5 +
 doc/database.txt                             |    6 +
 src/engine/db/Makefile.am                    |    5 +-
 src/engine/db/label.hpp                      |    1 +
 src/engine/db/library.cpp                    |   67 +++++++-
 src/engine/db/library.h                      |  223 ------------------------
 src/engine/db/library.hpp                    |  236 ++++++++++++++++++++++++++
 src/engine/db/test_library.cpp               |    4 +-
 src/engine/library/Makefile.am               |    4 +-
 src/engine/library/commands.cpp              |   33 +++-
 src/engine/library/commands.h                |   72 --------
 src/engine/library/commands.hpp              |   76 ++++++++
 src/engine/library/op.cpp                    |    6 +-
 src/engine/library/op.h                      |   65 -------
 src/engine/library/op.hpp                    |   65 +++++++
 src/engine/library/opqueue.h                 |    2 +-
 src/engine/library/test_opqueue.cpp          |    2 +-
 src/fwk/base/color.cpp                       |   18 ++
 src/fwk/base/color.hpp                       |    2 +-
 src/fwk/toolkit/application.cpp              |    9 +
 src/fwk/toolkit/application.hpp              |    1 +
 src/fwk/toolkit/command.hpp                  |   10 +-
 src/fwk/toolkit/undo.cpp                     |   10 +
 src/fwk/toolkit/undo.hpp                     |   11 +-
 src/libraryclient/Makefile.am                |    7 +-
 src/libraryclient/clientimpl.cpp             |   39 ++++-
 src/libraryclient/clientimpl.h               |   72 --------
 src/libraryclient/clientimpl.hpp             |   76 ++++++++
 src/libraryclient/libraryclient.cpp          |   23 +++-
 src/libraryclient/libraryclient.h            |   95 -----------
 src/libraryclient/libraryclient.hpp          |  101 +++++++++++
 src/libraryclient/locallibraryserver.cpp     |    4 +-
 src/libraryclient/locallibraryserver.h       |   55 ------
 src/libraryclient/locallibraryserver.hpp     |   55 ++++++
 src/libraryclient/test_worker.cpp            |    2 +-
 src/niepce/Makefile.am                       |    1 +
 src/niepce/modules/darkroom/darkroommodule.h |    2 +-
 src/niepce/ui/dialogs/editlabels.cpp         |   23 +++-
 src/niepce/ui/dialogs/editlabels.hpp         |    4 +-
 src/niepce/ui/filmstripcontroller.cpp        |    2 +-
 src/niepce/ui/imageliststore.cpp             |    2 +-
 src/niepce/ui/imageliststore.h               |    2 +-
 src/niepce/ui/librarymainviewcontroller.cpp  |    6 +-
 src/niepce/ui/librarymainviewcontroller.hpp  |    2 +-
 src/niepce/ui/niepcewindow.cpp               |   48 +++++-
 src/niepce/ui/niepcewindow.hpp               |    5 +-
 src/niepce/ui/selectioncontroller.cpp        |   19 +--
 src/niepce/ui/workspacecontroller.cpp        |    4 +-
 48 files changed, 930 insertions(+), 652 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f51f620..78907af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-04-13  Hubert Figuiere  <hub figuiere net>
+
+	* Make undo easier to use.
+	* Finished implementing labels.
+
 2009-04-12  Hubert Figuiere  <hub figuiere net>
 
 	* configure.ac: Add sv locale.
diff --git a/doc/database.txt b/doc/database.txt
index 8dec492..5fa3ccc 100644
--- a/doc/database.txt
+++ b/doc/database.txt
@@ -56,6 +56,12 @@ keywording	file_id	       The file ID it is linked to (= files.id)
 
 There shouldn't be more than one pair of identical (file_id,keyword_id)
 
+Labels for the file. There are very few of these.
+
+labels          id             The ID of the label
+                name           The name of the label (user displayed)
+		color          The RGB8 color in "R G B" format.
+
 The update queue for XMP. When an XMP is changed in the DB it is
 queued in the table.
 
diff --git a/src/engine/db/Makefile.am b/src/engine/db/Makefile.am
index 922120e..0e4e8f4 100644
--- a/src/engine/db/Makefile.am
+++ b/src/engine/db/Makefile.am
@@ -10,6 +10,7 @@ TEST_LIBS =  \
 	libniepcedb.a \
 	$(top_builddir)/src/fwk/utils/libniepceutils.a \
 	$(top_builddir)/src/fwk/toolkit/libniepceframework.a \
+	$(top_builddir)/src/fwk/libfwk.a \
 	@LIBGTKMM_LIBS@ @GNOMEVFS_LIBS@ \
 	@BOOST_UNIT_TEST_FRAMEWORK_LIBS@ \
 	@BOOST_FILESYSTEM_LIBS@ \
@@ -26,9 +27,7 @@ test_filebundle_LDADD = $(TEST_LIBS)
 
 noinst_LIBRARIES = libniepcedb.a
 
-noinst_HEADERS = library.h 
-
-libniepcedb_a_SOURCES = library.cpp \
+libniepcedb_a_SOURCES = library.hpp library.cpp \
 	libfile.h libfile.cpp \
 	libfolder.h \
 	label.hpp \
diff --git a/src/engine/db/label.hpp b/src/engine/db/label.hpp
index 85b0791..029a4e9 100644
--- a/src/engine/db/label.hpp
+++ b/src/engine/db/label.hpp
@@ -38,6 +38,7 @@ class Label
 public:
     typedef std::tr1::shared_ptr<Label> Ptr;
     typedef std::vector<Ptr> List;
+    typedef std::tr1::shared_ptr<List> ListPtr;
 
     Label(int _id, const std::string & _label, const std::string & _colorstring)
         : m_id(_id), m_label(_label)
diff --git a/src/engine/db/library.cpp b/src/engine/db/library.cpp
index 6177e3a..f585174 100644
--- a/src/engine/db/library.cpp
+++ b/src/engine/db/library.cpp
@@ -1,5 +1,5 @@
 /*
- * niepce - db/library.cpp
+ * niepce - engine/db/library.cpp
  *
  * Copyright (C) 2007-2009 Hubert Figuiere
  *
@@ -27,8 +27,9 @@
 #include <boost/filesystem/path.hpp>
 #include <boost/filesystem/convenience.hpp>
 
+#include "fwk/base/color.hpp"
 #include "niepce/notifications.h"
-#include "library.h"
+#include "library.hpp"
 #include "metadata.h"
 #include "fwk/utils/exception.h"
 #include "fwk/utils/exempi.h"
@@ -40,6 +41,7 @@
 #include "fwk/toolkit/mimetype.hpp"
 
 using fwk::NotificationCenter;
+using eng::Label;
 
 namespace bfs = boost::filesystem;
 
@@ -176,6 +178,7 @@ bool Library::_initDb()
 
     m_dbdrv->execute_statement(fileUpdateTrigger);
     m_dbdrv->execute_statement(xmpUpdateTrigger);
+    notify(NOTIFY_NEW_LIBRARY_CREATED, boost::any());
     return true;
 }
 
@@ -752,6 +755,66 @@ bool Library::setMetaData(int file_id, int meta,
     return retval;
 }
 
+void Library::getAllLabels(const Label::ListPtr & l)
+{
+    SQLStatement sql("SELECT id,name,color FROM labels ORDER BY id");
+    try {
+        if(m_dbdrv->execute_statement(sql)) {
+            while(m_dbdrv->read_next_row()) {
+                int32_t id;
+                std::string name;
+                std::string color;
+                m_dbdrv->get_column_content(0, id);
+                m_dbdrv->get_column_content(1, name);
+                m_dbdrv->get_column_content(2, color);
+                l->push_back(Label::Ptr(new Label(id, name, color)));
+            }
+        }
+    }
+    catch(utils::Exception & e)
+    {
+        DBG_OUT("db exception %s", e.what());
+    }
+}
+
+
+int Library::addLabel(const std::string & name, const std::string & color)
+{
+    int ret = -1;
+
+    SQLStatement sql(boost::format("INSERT INTO labels (name,color)"
+                                   " VALUES ('%1%', '%2%')") 
+                     % name % color);
+    if(m_dbdrv->execute_statement(sql)) {
+        int64_t id = m_dbdrv->last_row_id();
+        DBG_OUT("last row inserted %d", (int)id);
+        ret = id;
+    }
+    return ret;
+}
+
+
+int Library::addLabel(const std::string & name, const fwk::RgbColor & c)
+{
+    return addLabel(name, c.to_string());
+}
+
+
+bool Library::renameLabel(int label_id, const std::string & name)
+{
+    SQLStatement sql(boost::format("UPDATE labels SET name='%2%'"
+                                   " WHERE id='%1%';") 
+                     % label_id % name);
+    try {
+        return m_dbdrv->execute_statement(sql);
+    }
+    catch(utils::Exception & e)
+    {
+        DBG_OUT("db exception %s", e.what());
+    }
+    return false;
+}
+
 
 bool Library::getXmpIdsInQueue(std::vector<int> & ids)
 {
diff --git a/src/engine/db/library.h b/src/engine/db/library.h
deleted file mode 100644
index 9e69a6a..0000000
--- a/src/engine/db/library.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * niepce - db/library.h
- *
- * Copyright (C) 2007-2009 Hubert Figuiere
- *
- * 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 3 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 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 _DB_LIBRARY_H_
-#define _DB_LIBRARY_H_
-
-#include <string>
-
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-#include <boost/any.hpp>
-#include <boost/filesystem/path.hpp>
-
-#include "fwk/toolkit/notificationcenter.hpp"
-#include "fwk/utils/db/iconnectiondriver.h"
-#include "fwk/utils/db/iconnectionmanagerdriver.h"
-#include "engine/db/libfolder.h"
-#include "engine/db/libfile.h"
-#include "engine/db/libmetadata.h"
-#include "engine/db/filebundle.hpp"
-#include "engine/db/keyword.h"
-
-// The database schema version. Increase at each change.
-// Some will be persistent and have a conversion TBD.
-#define DB_SCHEMA_VERSION 3
-
-namespace db {
-
-	class Library
-	{
-	public:
-		typedef boost::shared_ptr<Library> Ptr;
-
-		typedef enum {
-			NOTIFY_NONE = 0,
-			NOTIFY_ADDED_FOLDERS,
-			NOTIFY_ADDED_FILES,
-			NOTIFY_ADDED_KEYWORDS,
-			NOTIFY_ADDED_KEYWORD,
-			NOTIFY_FOLDER_CONTENT_QUERIED,
-			NOTIFY_KEYWORD_CONTENT_QUERIED,
-			NOTIFY_METADATA_QUERIED,
-      NOTIFY_METADATA_CHANGED,
-      NOTIFY_XMP_NEEDS_UPDATE,
-			NOTIFY_FOLDER_COUNTED
-		} NotifyType;
-
-		Library(const std::string & dir, const fwk::NotificationCenter::Ptr & nc);
-		virtual ~Library();
-
-		bool ok()
-			{ return m_inited; }
-		/** set the main library directory */
-//		void setMainDir(const std::string & dir)
-//			{ m_maindir = dir; }
-		/** return the main directory */
-		const boost::filesystem::path & mainDir() const
-			{ return m_maindir; }
-		/** get the path to the DB file */
-		const boost::filesystem::path & dbName() const
-			{ return m_dbname; }
-
-		void notify(NotifyType t, const boost::any & param);
-
-		/** add a file to the library
-		 * @param folder the path of the containing folder
-		 * @param file the file path
-		 * @param manage pass true it the library *manage* the file. Currently unsupported.
-		 */
-		int addFileAndFolder(const boost::filesystem::path & folder, 
-							 const boost::filesystem::path & file, bool manage);
-
-    /** add a fs file to the library  
-     * @param file the file path
-     * @return the id of the fs_file, -1 in case of error
-     */
-    int addFsFile(const boost::filesystem::path & file);
-
-    /** Get a FsFile from an id
-     * @param id the id of the FsFile
-     * @return the path. Empty if not found.
-     */
-    boost::filesystem::path getFsFile(int id);
-
-		/** add a file to the library
-		 * @param folder_id the id of the containing folder
-		 * @param file the file path
-		 * @param manage pass true it the library *manage* the file. Currently unsupported.
-		 */
-		int addFile(int folder_id, const boost::filesystem::path & file, 
-					bool manage);
-
-		/** add a bundle of files to the library
-		 * @param folder_id the id of the containing folder
-		 * @param bundle the bundle
-		 * @param manage pass true it the library *manage* the file. Currently unsupported.
-		 */
-    int addBundle(int folder_id, const db::FileBundle::Ptr & bundle, 
-                    bool manage);
-    /** add a sidecar fsfile to a bundle (file)
-     * @param file_id the id of the file bundle
-     * @param fsfile_id the id of the fsfile
-     * @return true if success
-     */
-    bool addSidecarFileToBundle(int file_id, int fsfile_id);
-    /** add a jpeg fsfile to a bundle (file)
-     * @param file_id the id of the file bundle
-     * @param fsfile_id the id of the fsfile
-     * @return true if success
-     */
-    bool addJpegFileToBundle(int file_id, int fsfile_id);
-		
-		/** Get a specific folder id from the library
-		 * @param folder the folder path to check
-		 * @return the folder, NULL if not found
-		 */
-		LibFolder::Ptr getFolder(const boost::filesystem::path & folder);
-
-		/** Add a folder
-		 * @param folder the folder path
-		 */
-		LibFolder::Ptr addFolder(const boost::filesystem::path & folder);
-		/** List all the folders.
-		 * @param l the list of LibFolder
-		 */
-		void getAllFolders(const LibFolder::ListPtr & l);
-
-		/** List the folder content
-		 * @param folder_id id of the folder
-		 * @param fl the resulting file list
-		 */
-		void getFolderContent(int folder_id, const LibFile::ListPtr & fl);
-		int countFolder(int folder_id);
-		void getAllKeywords(const Keyword::ListPtr & l);
-		void getKeywordContent(int keyword_id, const LibFile::ListPtr & fl);
-        /** get the metadata block (XMP) */
-		void getMetaData(int file_id, const LibMetadata::Ptr & );
-        /** set the metadata block (XMP) */
-        bool setMetaData(int file_id, const LibMetadata::Ptr & );
-        bool setMetaData(int file_id, int meta, const boost::any & value);
-
-        /** Trigger the processing of the XMP update queue */
-        bool processXmpUpdateQueue();
-
-		/** Locate the keyword, creating it if needed
-		 * @param keyword the keyword to locate
-		 * @return -1 if not found (shouldn't happen) or the id of the
-		 * keyword, either found or just created.
-		 */
-		int makeKeyword(const std::string & keyword);
-		/** Assign a keyword to a file.
-		 * @param kw_id the keyword id
-		 * @param file_id the file id
-		 * @return true if success, false if error
-		 */
-		bool assignKeyword(int kw_id, int file_id);
-
-		int checkDatabaseVersion();
-		
-		db::IConnectionDriver::Ptr dbDriver()
-			{ return m_dbdrv; }
-	private:
-		bool init();
-		bool _initDb();
-
-        /** external sqlite fucntion to trigger the rewrite of the XMP */
-        void triggerRewriteXmp(void);
-        bool getXmpIdsInQueue(std::vector<int> & ids);
-        /** rewrite the XMP sidecar for the file whose id is %id
-         * and remove it from the queue.
-         */
-        bool rewriteXmpForId(int id);
-
-        /** set an "internal" metadata of type int */
-        bool setInternalMetaDataInt(int file_id, const char* col,
-                                    int32_t value);
-
-		boost::filesystem::path           m_maindir;
-		boost::filesystem::path           m_dbname;
-		db::IConnectionManagerDriver::Ptr m_dbmgr;
-		db::IConnectionDriver::Ptr        m_dbdrv;
-		boost::weak_ptr<fwk::NotificationCenter>  m_notif_center;
-		bool                              m_inited;
-	};
-
-	
-	struct LibNotification
-	{
-		Library::NotifyType type;
-		boost::any          param;
-	};
-
-}
-
-#endif
-/*
-  Local Variables:
-  mode:c++
-  c-file-style:"stroustrup"
-  c-file-offsets:((innamespace . 0))
-  indent-tabs-mode:nil
-  fill-column:99
-  End:
-*/
-
diff --git a/src/engine/db/library.hpp b/src/engine/db/library.hpp
new file mode 100644
index 0000000..0f7852e
--- /dev/null
+++ b/src/engine/db/library.hpp
@@ -0,0 +1,236 @@
+/*
+ * niepce - engine/db/library.h
+ *
+ * Copyright (C) 2007-2009 Hubert Figuiere
+ *
+ * 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 3 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 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 _DB_LIBRARY_H_
+#define _DB_LIBRARY_H_
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/any.hpp>
+#include <boost/filesystem/path.hpp>
+
+#include "fwk/toolkit/notificationcenter.hpp"
+#include "fwk/utils/db/iconnectiondriver.h"
+#include "fwk/utils/db/iconnectionmanagerdriver.h"
+#include "engine/db/libfolder.h"
+#include "engine/db/libfile.h"
+#include "engine/db/libmetadata.h"
+#include "engine/db/filebundle.hpp"
+#include "engine/db/keyword.h"
+#include "engine/db/label.hpp"
+
+// The database schema version. Increase at each change.
+// Some will be persistent and have a conversion TBD.
+#define DB_SCHEMA_VERSION 3
+
+namespace fwk {
+class RgbColor;
+}
+
+namespace db {
+
+class Library
+{
+public:
+		typedef boost::shared_ptr<Library> Ptr;
+
+		typedef enum {
+        NOTIFY_NONE = 0,
+        NOTIFY_NEW_LIBRARY_CREATED,
+        NOTIFY_ADDED_FOLDERS,
+        NOTIFY_ADDED_FILES,
+        NOTIFY_ADDED_KEYWORDS,
+        NOTIFY_ADDED_KEYWORD,
+        NOTIFY_ADDED_LABELS,
+        NOTIFY_FOLDER_CONTENT_QUERIED,
+        NOTIFY_KEYWORD_CONTENT_QUERIED,
+        NOTIFY_METADATA_QUERIED,
+        NOTIFY_METADATA_CHANGED,
+        NOTIFY_LABEL_CHANGED,
+        NOTIFY_XMP_NEEDS_UPDATE,
+        NOTIFY_FOLDER_COUNTED
+		} NotifyType;
+
+		Library(const std::string & dir, const fwk::NotificationCenter::Ptr & nc);
+		virtual ~Library();
+
+		bool ok()
+        { return m_inited; }
+		/** set the main library directory */
+//		void setMainDir(const std::string & dir)
+//			{ m_maindir = dir; }
+		/** return the main directory */
+		const boost::filesystem::path & mainDir() const
+        { return m_maindir; }
+		/** get the path to the DB file */
+		const boost::filesystem::path & dbName() const
+        { return m_dbname; }
+
+		void notify(NotifyType t, const boost::any & param);
+
+		/** add a file to the library
+		 * @param folder the path of the containing folder
+		 * @param file the file path
+		 * @param manage pass true it the library *manage* the file. Currently unsupported.
+		 */
+		int addFileAndFolder(const boost::filesystem::path & folder, 
+                         const boost::filesystem::path & file, bool manage);
+
+    /** add a fs file to the library  
+     * @param file the file path
+     * @return the id of the fs_file, -1 in case of error
+     */
+    int addFsFile(const boost::filesystem::path & file);
+
+    /** Get a FsFile from an id
+     * @param id the id of the FsFile
+     * @return the path. Empty if not found.
+     */
+    boost::filesystem::path getFsFile(int id);
+
+		/** add a file to the library
+		 * @param folder_id the id of the containing folder
+		 * @param file the file path
+		 * @param manage pass true it the library *manage* the file. Currently unsupported.
+		 */
+		int addFile(int folder_id, const boost::filesystem::path & file, 
+                bool manage);
+
+		/** add a bundle of files to the library
+		 * @param folder_id the id of the containing folder
+		 * @param bundle the bundle
+		 * @param manage pass true it the library *manage* the file. Currently unsupported.
+		 */
+    int addBundle(int folder_id, const db::FileBundle::Ptr & bundle, 
+                  bool manage);
+    /** add a sidecar fsfile to a bundle (file)
+     * @param file_id the id of the file bundle
+     * @param fsfile_id the id of the fsfile
+     * @return true if success
+     */
+    bool addSidecarFileToBundle(int file_id, int fsfile_id);
+    /** add a jpeg fsfile to a bundle (file)
+     * @param file_id the id of the file bundle
+     * @param fsfile_id the id of the fsfile
+     * @return true if success
+     */
+    bool addJpegFileToBundle(int file_id, int fsfile_id);
+		
+		/** Get a specific folder id from the library
+		 * @param folder the folder path to check
+		 * @return the folder, NULL if not found
+		 */
+		LibFolder::Ptr getFolder(const boost::filesystem::path & folder);
+
+		/** Add a folder
+		 * @param folder the folder path
+		 */
+		LibFolder::Ptr addFolder(const boost::filesystem::path & folder);
+		/** List all the folders.
+		 * @param l the list of LibFolder
+		 */
+		void getAllFolders(const LibFolder::ListPtr & l);
+
+		/** List the folder content
+		 * @param folder_id id of the folder
+		 * @param fl the resulting file list
+		 */
+		void getFolderContent(int folder_id, const LibFile::ListPtr & fl);
+		int countFolder(int folder_id);
+		void getAllKeywords(const Keyword::ListPtr & l);
+		void getKeywordContent(int keyword_id, const LibFile::ListPtr & fl);
+    /** get the metadata block (XMP) */
+		void getMetaData(int file_id, const LibMetadata::Ptr & );
+    /** set the metadata block (XMP) */
+    bool setMetaData(int file_id, const LibMetadata::Ptr & );
+    bool setMetaData(int file_id, int meta, const boost::any & value);
+
+		void getAllLabels(const eng::Label::ListPtr & l);
+    int addLabel(const std::string & name, const std::string & color);
+    int addLabel(const std::string & name, const fwk::RgbColor & c);
+    bool renameLabel(int label_id, const std::string & name);
+
+    /** Trigger the processing of the XMP update queue */
+    bool processXmpUpdateQueue();
+
+		/** Locate the keyword, creating it if needed
+		 * @param keyword the keyword to locate
+		 * @return -1 if not found (shouldn't happen) or the id of the
+		 * keyword, either found or just created.
+		 */
+		int makeKeyword(const std::string & keyword);
+		/** Assign a keyword to a file.
+		 * @param kw_id the keyword id
+		 * @param file_id the file id
+		 * @return true if success, false if error
+		 */
+		bool assignKeyword(int kw_id, int file_id);
+
+		int checkDatabaseVersion();
+		
+		db::IConnectionDriver::Ptr dbDriver()
+        { return m_dbdrv; }
+private:
+		bool init();
+		bool _initDb();
+
+    /** external sqlite fucntion to trigger the rewrite of the XMP */
+    void triggerRewriteXmp(void);
+    bool getXmpIdsInQueue(std::vector<int> & ids);
+    /** rewrite the XMP sidecar for the file whose id is %id
+     * and remove it from the queue.
+     */
+    bool rewriteXmpForId(int id);
+
+    /** set an "internal" metadata of type int */
+    bool setInternalMetaDataInt(int file_id, const char* col,
+                                int32_t value);
+
+		boost::filesystem::path           m_maindir;
+		boost::filesystem::path           m_dbname;
+		db::IConnectionManagerDriver::Ptr m_dbmgr;
+		db::IConnectionDriver::Ptr        m_dbdrv;
+		boost::weak_ptr<fwk::NotificationCenter>  m_notif_center;
+		bool                              m_inited;
+};
+
+	
+struct LibNotification
+{
+		Library::NotifyType type;
+		boost::any          param;
+};
+
+}
+
+#endif
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+
diff --git a/src/engine/db/test_library.cpp b/src/engine/db/test_library.cpp
index 4d09124..bac915e 100644
--- a/src/engine/db/test_library.cpp
+++ b/src/engine/db/test_library.cpp
@@ -1,5 +1,5 @@
 /*
- * niepce - db/test_library.cpp
+ * niepce - engine/db/test_library.cpp
  *
  * Copyright (C) 2007-2009 Hubert Figuiere
  *
@@ -22,7 +22,7 @@
 
 #include "fwk/utils/db/sqlstatement.h"
 #include "fwk/utils/db/iconnectiondriver.h"
-#include "library.h"
+#include "library.hpp"
 #include "libfile.h"
 #include "libfolder.h"
 
diff --git a/src/engine/library/Makefile.am b/src/engine/library/Makefile.am
index 0872eaa..d82cdb2 100644
--- a/src/engine/library/Makefile.am
+++ b/src/engine/library/Makefile.am
@@ -21,7 +21,7 @@ test_opqueue_LDADD = $(TEST_LIBS)
 
 
 libniepcelibrary_a_SOURCES = clienttypes.h \
-	op.h op.cpp  \
-	commands.h commands.cpp \
+	op.hpp op.cpp  \
+	commands.hpp commands.cpp \
 	thumbnailcache.h thumbnailcache.cpp \
 	thumbnailnotification.h
diff --git a/src/engine/library/commands.cpp b/src/engine/library/commands.cpp
index 25103e7..f58b5cc 100644
--- a/src/engine/library/commands.cpp
+++ b/src/engine/library/commands.cpp
@@ -25,18 +25,17 @@
 
 
 #include "fwk/utils/debug.h"
-#include "engine/db/library.h"
+#include "engine/db/library.hpp"
 #include "engine/db/libfolder.h"
 #include "engine/db/libfile.h"
 #include "engine/db/libmetadata.h"
 #include "engine/db/filebundle.hpp"
 #include "engine/db/keyword.h"
-#include "commands.h"
+#include "engine/db/label.hpp"
+#include "commands.hpp"
 
 namespace bfs = boost::filesystem;
 
-using boost::any_cast;
-
 using db::Library;
 using db::LibFolder;
 using db::LibFile;
@@ -132,6 +131,32 @@ void Commands::cmdSetMetadata(const db::Library::Ptr & lib,
     lib->notify(Library::NOTIFY_METADATA_CHANGED, boost::any(m));
 }
 
+void Commands::cmdListAllLabels(const db::Library::Ptr & lib)
+{
+    eng::Label::ListPtr l(new eng::Label::List);
+    lib->getAllLabels(l);
+    lib->notify(Library::NOTIFY_ADDED_LABELS, boost::any(l));
+}
+
+void Commands::cmdCreateLabel(const db::Library::Ptr & lib,
+                              const std::string & s, const std::string & color)
+{
+    int id = lib->addLabel(s, color);
+    if(id != -1) {
+        eng::Label::ListPtr l(new eng::Label::List);
+        l->push_back(eng::Label::Ptr(new eng::Label(id, s, color)));
+        lib->notify(Library::NOTIFY_ADDED_LABELS, boost::any(l));
+    }
+}
+
+void Commands::cmdRenameLabel(const db::Library::Ptr & lib,
+                               int label_id, const std::string & name)
+{
+    lib->renameLabel(label_id, name);
+    lib->notify(Library::NOTIFY_LABEL_CHANGED, boost::any(label_id));
+}
+
+
 void Commands::cmdProcessXmpUpdateQueue(const db::Library::Ptr & lib)
 {
     lib->processXmpUpdateQueue();
diff --git a/src/engine/library/commands.h b/src/engine/library/commands.h
deleted file mode 100644
index 8d1769d..0000000
--- a/src/engine/library/commands.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * niepce - library/commands.h
- *
- * Copyright (C) 2007-2008 Hubert Figuiere
- *
- * 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 3 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 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 __LIBRARY_COMMANDS_H__
-#define __LIBRARY_COMMANDS_H__
-
-#include "op.h"
-#include "fwk/utils/files.h"
-#include "engine/db/library.h"
-
-namespace library {
-
-	/** Marshalling and demarshalling of commands ops */ 
-	class Commands 
-	{
-	public:
-
-		// commands: execute an op
-//		static void cmdQueryFiles(const db::Library::Ptr & lib);
-//		static void cmdUpdateFiles(const db::Library::Ptr & lib);
-
-		static void cmdListAllFolders(const db::Library::Ptr & lib);
-		static void cmdListAllKeywords(const db::Library::Ptr & lib);
-		static void cmdImportFiles(const db::Library::Ptr & lib, 
-								   const boost::filesystem::path & folder, 
-								   const utils::FileList::Ptr & files, 
-								   bool manage);
-		static void cmdQueryFolderContent(const db::Library::Ptr & lib, 
-										  int folder_id);
-		static void cmdCountFolder(const db::Library::Ptr & lib, 
-								   int folder_id);
-		static void cmdQueryKeywordContent(const db::Library::Ptr & lib, 
-										   int keyword_id);
-		static void cmdRequestMetadata(const db::Library::Ptr & lib,
-									   int file_id);
-        static void cmdSetMetadata(const db::Library::Ptr & lib,
-                                   int file_id, int meta, int value);
-		static void cmdProcessXmpUpdateQueue(const db::Library::Ptr & lib);
-
-	};
-
-}
-
-
-#endif
-/*
-  Local Variables:
-  mode:c++
-  c-file-style:"stroustrup"
-  c-file-offsets:((innamespace . 0))
-  indent-tabs-mode:nil
-  fill-column:99
-  End:
-*/
diff --git a/src/engine/library/commands.hpp b/src/engine/library/commands.hpp
new file mode 100644
index 0000000..20d6980
--- /dev/null
+++ b/src/engine/library/commands.hpp
@@ -0,0 +1,76 @@
+/*
+ * niepce - engine/library/commands.hpp
+ *
+ * Copyright (C) 2007-2009 Hubert Figuiere
+ *
+ * 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 3 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 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 __LIBRARY_COMMANDS_H__
+#define __LIBRARY_COMMANDS_H__
+
+#include "op.hpp"
+#include "fwk/utils/files.h"
+#include "engine/db/library.hpp"
+
+namespace library {
+
+/** Marshalling and demarshalling of commands ops */ 
+class Commands 
+{
+public:
+
+		// commands: execute an op
+//		static void cmdQueryFiles(const db::Library::Ptr & lib);
+//		static void cmdUpdateFiles(const db::Library::Ptr & lib);
+
+		static void cmdListAllFolders(const db::Library::Ptr & lib);
+		static void cmdListAllKeywords(const db::Library::Ptr & lib);
+		static void cmdImportFiles(const db::Library::Ptr & lib, 
+                               const boost::filesystem::path & folder, 
+                               const utils::FileList::Ptr & files, 
+                               bool manage);
+		static void cmdQueryFolderContent(const db::Library::Ptr & lib, 
+                                      int folder_id);
+		static void cmdCountFolder(const db::Library::Ptr & lib, 
+                               int folder_id);
+		static void cmdQueryKeywordContent(const db::Library::Ptr & lib, 
+                                       int keyword_id);
+		static void cmdRequestMetadata(const db::Library::Ptr & lib,
+                                   int file_id);
+    static void cmdSetMetadata(const db::Library::Ptr & lib,
+                               int file_id, int meta, int value);
+    static void cmdListAllLabels(const db::Library::Ptr & lib);
+    static void cmdCreateLabel(const db::Library::Ptr & lib, const std::string & s, 
+                               const std::string & color);
+    static void cmdRenameLabel(const db::Library::Ptr & lib,
+                               int label_id, const std::string & name);
+		static void cmdProcessXmpUpdateQueue(const db::Library::Ptr & lib);
+};
+
+}
+
+
+#endif
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
diff --git a/src/engine/library/op.cpp b/src/engine/library/op.cpp
index 6dcb03f..acd6c94 100644
--- a/src/engine/library/op.cpp
+++ b/src/engine/library/op.cpp
@@ -1,7 +1,7 @@
 /*
- * niepce - library/op.cpp
+ * niepce - engine/library/op.cpp
  *
- * Copyright (C) 2007-2008 Hubert Figuiere
+ * Copyright (C) 2007-2009 Hubert Figuiere
  *
  * 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
@@ -18,7 +18,7 @@
  */
 
 
-#include "op.h"
+#include "op.hpp"
 
 
 namespace library {
diff --git a/src/engine/library/op.h b/src/engine/library/op.h
deleted file mode 100644
index 6f60f84..0000000
--- a/src/engine/library/op.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * niepce - library/op.h
- *
- * Copyright (C) 2007-2008 Hubert Figuiere
- *
- * 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 3 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 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 __NIEPCE_LIBRARY_OP_H__
-#define __NIEPCE_LIBRARY_OP_H__
-
-#include <boost/shared_ptr.hpp>
-#include <boost/function.hpp>
-
-#include "engine/library/clienttypes.h"
-#include "engine/db/library.h"
-
-namespace library {
-
-	/** a library operation */
-	class Op
-	{
-	public:
-		typedef boost::shared_ptr< Op > Ptr;
-		typedef boost::function<void (const db::Library::Ptr &)> function_t;
-
-		Op(tid_t id, const function_t & func);
-
-		tid_t id() const 
-			{ return m_id; }
-
-        void operator() (const db::Library::Ptr &);
-		const function_t & fn() const
-			{ return m_function; }
-	protected:
-	private:
-		tid_t   m_id;
-		function_t m_function;
-	};
-
-}
-
-
-#endif
-/*
-  Local Variables:
-  mode:c++
-  c-file-style:"stroustrup"
-  c-file-offsets:((innamespace . 0))
-  indent-tabs-mode:nil
-  fill-column:99
-  End:
-*/
diff --git a/src/engine/library/op.hpp b/src/engine/library/op.hpp
new file mode 100644
index 0000000..0f97cf1
--- /dev/null
+++ b/src/engine/library/op.hpp
@@ -0,0 +1,65 @@
+/*
+ * niepce - engine/library/op.h
+ *
+ * Copyright (C) 2007-2009 Hubert Figuiere
+ *
+ * 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 3 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 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 __NIEPCE_LIBRARY_OP_H__
+#define __NIEPCE_LIBRARY_OP_H__
+
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+
+#include "engine/library/clienttypes.h"
+#include "engine/db/library.hpp"
+
+namespace library {
+
+	/** a library operation */
+	class Op
+	{
+	public:
+		typedef boost::shared_ptr< Op > Ptr;
+		typedef boost::function<void (const db::Library::Ptr &)> function_t;
+
+		Op(tid_t id, const function_t & func);
+
+		tid_t id() const 
+			{ return m_id; }
+
+        void operator() (const db::Library::Ptr &);
+		const function_t & fn() const
+			{ return m_function; }
+	protected:
+	private:
+		tid_t   m_id;
+		function_t m_function;
+	};
+
+}
+
+
+#endif
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
diff --git a/src/engine/library/opqueue.h b/src/engine/library/opqueue.h
index a41d94d..a4fdb88 100644
--- a/src/engine/library/opqueue.h
+++ b/src/engine/library/opqueue.h
@@ -24,7 +24,7 @@
 
 
 #include "fwk/utils/mtqueue.h"
-#include "op.h"
+#include "op.hpp"
 
 namespace library {
 
diff --git a/src/engine/library/test_opqueue.cpp b/src/engine/library/test_opqueue.cpp
index d7e1e15..767f6bd 100644
--- a/src/engine/library/test_opqueue.cpp
+++ b/src/engine/library/test_opqueue.cpp
@@ -18,7 +18,7 @@
  */
 
 
-#include "op.h"
+#include "op.hpp"
 #include "opqueue.h"
 
 #include <boost/bind.hpp>
diff --git a/src/fwk/base/color.cpp b/src/fwk/base/color.cpp
index 47e5390..2d4d398 100644
--- a/src/fwk/base/color.cpp
+++ b/src/fwk/base/color.cpp
@@ -1,3 +1,21 @@
+/*
+ * niepce - fwk/base/color.hpp
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * 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 3 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 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/>.
+ */
 
 
 #include <vector>
diff --git a/src/fwk/base/color.hpp b/src/fwk/base/color.hpp
index d6a3462..e202798 100644
--- a/src/fwk/base/color.hpp
+++ b/src/fwk/base/color.hpp
@@ -35,7 +35,7 @@ namespace fwk {
   {
   public:
     RgbColor(value_type r = 0, value_type g = 0, value_type b = 0);
-    RgbColor(const std::string & );
+    explicit RgbColor(const std::string & );
     
     std::string to_string() const;
   };
diff --git a/src/fwk/toolkit/application.cpp b/src/fwk/toolkit/application.cpp
index 38897e6..34fdb21 100644
--- a/src/fwk/toolkit/application.cpp
+++ b/src/fwk/toolkit/application.cpp
@@ -174,6 +174,15 @@ void Application::on_about()
     dlg.run();
 }
 
+UndoTransaction * Application::begin_undo(const std::string & label)
+{
+    fwk::UndoTransaction *undo = new fwk::UndoTransaction(label);
+    undo_history().add(undo);
+    return undo;
+}
+
+
+
 }
 
 
diff --git a/src/fwk/toolkit/application.hpp b/src/fwk/toolkit/application.hpp
index 69f4e6e..28bcd41 100644
--- a/src/fwk/toolkit/application.hpp
+++ b/src/fwk/toolkit/application.hpp
@@ -77,6 +77,7 @@ public:
 
     UndoHistory & undo_history()
         { return m_undo; }
+    UndoTransaction * begin_undo(const std::string & label);
 protected:
     Application(const char *);
     static Application::Ptr m_application; 
diff --git a/src/fwk/toolkit/command.hpp b/src/fwk/toolkit/command.hpp
index b313718..39871d2 100644
--- a/src/fwk/toolkit/command.hpp
+++ b/src/fwk/toolkit/command.hpp
@@ -1,7 +1,7 @@
 /*
  * niepce - fwk/command.h
  *
- * Copyright (C) 2008 Hubert Figuiere
+ * Copyright (C) 2008-2009 Hubert Figuiere
  *
  * 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
@@ -28,15 +28,15 @@ namespace fwk {
 class Command
 {
 public:
-    boost::function<void (void)> undo;
-    boost::function<void (void)> redo;
+    typedef boost::function<void (void)> Function;
+    Function undo;
+    Function redo;
 };
 
+}
 
 #endif
 
-}
-
 /*
   Local Variables:
   mode:c++
diff --git a/src/fwk/toolkit/undo.cpp b/src/fwk/toolkit/undo.cpp
index 8277d36..8973e8c 100644
--- a/src/fwk/toolkit/undo.cpp
+++ b/src/fwk/toolkit/undo.cpp
@@ -38,6 +38,16 @@ UndoTransaction::~UndoTransaction()
                   boost::bind(&boost::checked_delete<Command>, _1));
 }
 
+Command *UndoTransaction::new_command(const Command::Function & _redo, 
+                                      const Command::Function & _undo)
+{
+    fwk::Command *cmd = new fwk::Command;
+    cmd->redo = _redo;
+    cmd->undo = _undo;
+    add(cmd);
+    return cmd;
+}
+
 void UndoTransaction::add(Command * cmd)
 {
     m_operations.push_back(cmd);
diff --git a/src/fwk/toolkit/undo.hpp b/src/fwk/toolkit/undo.hpp
index ab55cbb..27f5b29 100644
--- a/src/fwk/toolkit/undo.hpp
+++ b/src/fwk/toolkit/undo.hpp
@@ -28,20 +28,27 @@
 
 #include <sigc++/signal.h>
 
+#include "fwk/toolkit/command.hpp"
+
 namespace fwk {
 
-class Command;
 
 class UndoTransaction
 {
 public:
     UndoTransaction(const std::string & n);
     ~UndoTransaction();
-    void add(Command *);
+    Command *new_command(const Command::Function &, const Command::Function &);
     void undo();
     void redo();
+    /** execute the transaction after adding it. (calls %undo) */
+    void execute()
+        { redo(); }
     const std::string & name() const
         { return m_name; }
+protected:
+    /** add the command. Use %new_command instead */
+    void add(Command *);
 private:
     std::list<Command *> m_operations;
     std::string m_name;
diff --git a/src/libraryclient/Makefile.am b/src/libraryclient/Makefile.am
index d768689..c58e789 100644
--- a/src/libraryclient/Makefile.am
+++ b/src/libraryclient/Makefile.am
@@ -12,6 +12,7 @@ TEST_LIBS =  \
 	$(top_builddir)/src/engine/db/libniepcedb.a \
         $(top_builddir)/src/fwk/utils/libniepceutils.a \
 	$(top_builddir)/src/fwk/toolkit/libniepceframework.a \
+	$(top_builddir)/src/fwk/libfwk.a \
         @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ \
 	@BOOST_THREAD_LIBS@ @BOOST_FILESYSTEM_LIBS@ \
 	@LIBGTKMM_LIBS@ @SQLITE3_LIBS@ @OPENRAW_LIBS@ \
@@ -20,6 +21,6 @@ TEST_LIBS =  \
 test_worker_SOURCES = test_worker.cpp
 test_worker_LDADD = $(TEST_LIBS)
 
-liblibraryclient_a_SOURCES = libraryclient.h  libraryclient.cpp \
-	clientimpl.h clientimpl.cpp \
-	locallibraryserver.h locallibraryserver.cpp
+liblibraryclient_a_SOURCES = libraryclient.hpp  libraryclient.cpp \
+	clientimpl.hpp clientimpl.cpp \
+	locallibraryserver.hpp locallibraryserver.cpp
diff --git a/src/libraryclient/clientimpl.cpp b/src/libraryclient/clientimpl.cpp
index 039938f..d3c7b12 100644
--- a/src/libraryclient/clientimpl.cpp
+++ b/src/libraryclient/clientimpl.cpp
@@ -20,11 +20,11 @@
 
 #include "fwk/utils/debug.h"
 #include "fwk/utils/files.h"
-#include "engine/library/op.h"
-#include "engine/library/commands.h"
-#include "libraryclient.h"
-#include "clientimpl.h"
-#include "locallibraryserver.h"
+#include "engine/library/op.hpp"
+#include "engine/library/commands.hpp"
+#include "libraryclient.hpp"
+#include "clientimpl.hpp"
+#include "locallibraryserver.hpp"
 
 using utils::FileList;
 using library::Op;
@@ -120,6 +120,35 @@ tid_t ClientImpl::setMetadata(int file_id, int meta, int value)
 }
 
 
+tid_t ClientImpl::getAllLabels()
+{
+    tid_t id = LibraryClient::newTid();
+    Op::Ptr op(new Op(id, boost::bind(&Commands::cmdListAllLabels,
+                                      _1)));
+    m_localLibrary->schedule(op);
+    return id;    
+}
+
+
+tid_t ClientImpl::createLabel(const std::string & s, const std::string & color)
+{
+    tid_t id = LibraryClient::newTid();
+    Op::Ptr op(new Op(id, boost::bind(&Commands::cmdCreateLabel,
+                                      _1, s, color)));
+    m_localLibrary->schedule(op);
+    return id;    
+}
+
+tid_t ClientImpl::renameLabel(int label_id, const std::string & new_name)
+{
+    tid_t id = LibraryClient::newTid();
+    Op::Ptr op(new Op(id, boost::bind(&Commands::cmdRenameLabel,
+                                      _1, label_id, new_name)));
+    m_localLibrary->schedule(op);
+    return id;    
+}
+
+
 tid_t ClientImpl::processXmpUpdateQueue()
 {
     tid_t id = LibraryClient::newTid();
diff --git a/src/libraryclient/clientimpl.h b/src/libraryclient/clientimpl.h
deleted file mode 100644
index b1e0aec..0000000
--- a/src/libraryclient/clientimpl.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * niepce - libraryclient/clientimpl.h
- *
- * Copyright (C) 2007-2008 Hubert Figuiere
- *
- * 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 3 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 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 _LIBRARYCLIENT_CLIENTIMPL_H_
-#define _LIBRARYCLIENT_CLIENTIMPL_H_
-
-#include <string>
-
-#include "fwk/utils/moniker.h"
-#include "engine/library/clienttypes.h"
-
-
-namespace libraryclient {
-
-	class LocalLibraryServer;
-
-	class ClientImpl
-	{
-	public:
-		static ClientImpl *makeClientImpl(const utils::Moniker & moniker, 
-										  const fwk::NotificationCenter::Ptr & nc);
-		
-		ClientImpl(const utils::Moniker & moniker, const fwk::NotificationCenter::Ptr & nc);
-		virtual ~ClientImpl();
-
-		library::tid_t getAllKeywords();
-		library::tid_t queryKeywordContent(int id);
-		library::tid_t getAllFolders();
-		library::tid_t queryFolderContent(int id);
-		library::tid_t countFolder(int id);
-		library::tid_t requestMetadata(int id);
-        library::tid_t setMetadata(int id, int meta, int value);
-
-        library::tid_t processXmpUpdateQueue();
-
-		library::tid_t importFromDirectory(const std::string & dir, bool manage);
-
-	protected:
-		const utils::Moniker m_moniker;
-		LocalLibraryServer *m_localLibrary;
-	};
-
-}
-
-
-#endif
-/*
-  Local Variables:
-  mode:c++
-  c-file-style:"stroustrup"
-  c-file-offsets:((innamespace . 0))
-  indent-tabs-mode:nil
-  fill-column:99
-  End:
-*/
diff --git a/src/libraryclient/clientimpl.hpp b/src/libraryclient/clientimpl.hpp
new file mode 100644
index 0000000..782308f
--- /dev/null
+++ b/src/libraryclient/clientimpl.hpp
@@ -0,0 +1,76 @@
+/*
+ * niepce - libraryclient/clientimpl.hpp
+ *
+ * Copyright (C) 2007-2008 Hubert Figuiere
+ *
+ * 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 3 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 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 _LIBRARYCLIENT_CLIENTIMPL_H_
+#define _LIBRARYCLIENT_CLIENTIMPL_H_
+
+#include <string>
+
+#include "fwk/utils/moniker.h"
+#include "engine/library/clienttypes.h"
+
+
+namespace libraryclient {
+
+class LocalLibraryServer;
+
+class ClientImpl
+{
+public:
+    static ClientImpl *makeClientImpl(const utils::Moniker & moniker, 
+                                      const fwk::NotificationCenter::Ptr & nc);
+		
+		ClientImpl(const utils::Moniker & moniker, const fwk::NotificationCenter::Ptr & nc);
+		virtual ~ClientImpl();
+
+		library::tid_t getAllKeywords();
+		library::tid_t queryKeywordContent(int id);
+		library::tid_t getAllFolders();
+		library::tid_t queryFolderContent(int id);
+		library::tid_t countFolder(int id);
+		library::tid_t requestMetadata(int id);
+    library::tid_t setMetadata(int id, int meta, int value);
+
+    library::tid_t getAllLabels();
+    library::tid_t createLabel(const std::string & s, const std::string & color);
+    library::tid_t renameLabel(int id, const std::string & new_name);
+
+    library::tid_t processXmpUpdateQueue();
+
+		library::tid_t importFromDirectory(const std::string & dir, bool manage);
+
+protected:
+		const utils::Moniker m_moniker;
+		LocalLibraryServer *m_localLibrary;
+};
+
+}
+
+
+#endif
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
diff --git a/src/libraryclient/libraryclient.cpp b/src/libraryclient/libraryclient.cpp
index 9815aab..ec67969 100644
--- a/src/libraryclient/libraryclient.cpp
+++ b/src/libraryclient/libraryclient.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - libraryclient/libraryclient.cpp
  *
- * Copyright (C) 2007-2008 Hubert Figuiere
+ * Copyright (C) 2007-2009 Hubert Figuiere
  *
  * 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
@@ -21,8 +21,8 @@
 
 #include "fwk/utils/moniker.h"
 
-#include "libraryclient.h"
-#include "clientimpl.h"
+#include "libraryclient.hpp"
+#include "clientimpl.hpp"
 
 using library::tid_t;
 
@@ -90,6 +90,23 @@ library::tid_t LibraryClient::setMetadata(int id, int meta, int value)
     return m_pImpl->setMetadata(id, meta, value);
 }
 
+library::tid_t LibraryClient::getAllLabels()
+{
+    return m_pImpl->getAllLabels();
+}
+
+
+library::tid_t LibraryClient::createLabel(const std::string & s, const std::string & color)
+{
+    return m_pImpl->createLabel(s, color);
+}
+
+
+library::tid_t LibraryClient::renameLabel(int id, const std::string & new_name)
+{
+    return m_pImpl->renameLabel(id, new_name);
+}
+
 library::tid_t LibraryClient::processXmpUpdateQueue()
 {
     return m_pImpl->processXmpUpdateQueue();
diff --git a/src/libraryclient/libraryclient.h b/src/libraryclient/libraryclient.h
deleted file mode 100644
index 4cb0f4e..0000000
--- a/src/libraryclient/libraryclient.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * niepce - libraryclient/libraryclient.h
- *
- * Copyright (C) 2007-2008 Hubert Figuiere
- *
- * 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 3 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 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 _LIBRARYCLIENT_H_
-#define _LIBRARYCLIENT_H_
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-
-#include "engine/library/clienttypes.h"
-#include "engine/library/thumbnailcache.h"
-#include "engine/db/storage.h"
-
-namespace utils {
-	class Moniker;
-}
-
-namespace fwk {
-	class NotificationCenter;
-}
-
-namespace libraryclient {
-
-	class ClientImpl;
-
-	class LibraryClient
-		: public db::Storage
-	{
-	public:
-		typedef boost::shared_ptr< LibraryClient > Ptr;
-
-		LibraryClient(const utils::Moniker & moniker, const fwk::NotificationCenter::Ptr & nc);
-		virtual ~LibraryClient();
-
-		static library::tid_t newTid();
-		/** get all the keywords 
-		 * @return transaction ID
-		 */
-		library::tid_t getAllKeywords();
-		/** get all the folder
-		 * @return transaction ID
-		 */
-		library::tid_t getAllFolders();
-
-		library::tid_t queryFolderContent(int id);
-		library::tid_t queryKeywordContent(int id);
-		library::tid_t countFolder(int id);
-		library::tid_t requestMetadata(int id);
-
-        /** set the metadata */
-        library::tid_t setMetadata(int id, int meta, int value);
-
-        /** tell to process the Xmp update Queue */
-        library::tid_t processXmpUpdateQueue();
-
-		/** Import files from a directory
-		 * @param dir the directory
-		 * @param manage true if imports have to be managed
-		 */
-		void importFromDirectory(const std::string & dir, bool manage);
-		
-		library::ThumbnailCache & thumbnailCache()
-			{ return m_thumbnailCache; }
-
-		/* sync call */
-		virtual bool fetchKeywordsForFile(int file, db::Keyword::IdList &keywords);
-
-	private:
-		ClientImpl* m_pImpl;
-
-		library::ThumbnailCache                    m_thumbnailCache;
-
-		LibraryClient(const LibraryClient &);
-		LibraryClient & operator=(const LibraryClient &);
-	};
-
-}
-
-#endif
diff --git a/src/libraryclient/libraryclient.hpp b/src/libraryclient/libraryclient.hpp
new file mode 100644
index 0000000..51d4728
--- /dev/null
+++ b/src/libraryclient/libraryclient.hpp
@@ -0,0 +1,101 @@
+/*
+ * niepce - libraryclient/libraryclient.hpp
+ *
+ * Copyright (C) 2007-2009 Hubert Figuiere
+ *
+ * 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 3 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 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 _LIBRARYCLIENT_H_
+#define _LIBRARYCLIENT_H_
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+#include "engine/library/clienttypes.h"
+#include "engine/library/thumbnailcache.h"
+#include "engine/db/storage.h"
+
+namespace utils {
+	class Moniker;
+}
+
+namespace fwk {
+	class NotificationCenter;
+}
+
+namespace libraryclient {
+
+	class ClientImpl;
+
+	class LibraryClient
+		: public db::Storage
+	{
+	public:
+		typedef boost::shared_ptr< LibraryClient > Ptr;
+
+		LibraryClient(const utils::Moniker & moniker, const fwk::NotificationCenter::Ptr & nc);
+		virtual ~LibraryClient();
+
+		static library::tid_t newTid();
+		/** get all the keywords 
+		 * @return transaction ID
+		 */
+		library::tid_t getAllKeywords();
+		/** get all the folder
+		 * @return transaction ID
+		 */
+		library::tid_t getAllFolders();
+
+		library::tid_t queryFolderContent(int id);
+		library::tid_t queryKeywordContent(int id);
+		library::tid_t countFolder(int id);
+		library::tid_t requestMetadata(int id);
+
+    /** set the metadata */
+    library::tid_t setMetadata(int id, int meta, int value);
+
+    /** get all the labels */
+    library::tid_t getAllLabels();
+    library::tid_t createLabel(const std::string & s, const std::string & color);
+    /** rename a label */
+    library::tid_t renameLabel(int id, const std::string & new_name);
+
+    /** tell to process the Xmp update Queue */
+    library::tid_t processXmpUpdateQueue();
+
+		/** Import files from a directory
+		 * @param dir the directory
+		 * @param manage true if imports have to be managed
+		 */
+		void importFromDirectory(const std::string & dir, bool manage);
+		
+		library::ThumbnailCache & thumbnailCache()
+			{ return m_thumbnailCache; }
+
+		/* sync call */
+		virtual bool fetchKeywordsForFile(int file, db::Keyword::IdList &keywords);
+
+	private:
+		ClientImpl* m_pImpl;
+
+		library::ThumbnailCache                    m_thumbnailCache;
+
+		LibraryClient(const LibraryClient &);
+		LibraryClient & operator=(const LibraryClient &);
+	};
+
+}
+
+#endif
diff --git a/src/libraryclient/locallibraryserver.cpp b/src/libraryclient/locallibraryserver.cpp
index 7c3dc59..287dd94 100644
--- a/src/libraryclient/locallibraryserver.cpp
+++ b/src/libraryclient/locallibraryserver.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - libraryclient/locallibraryserver.cpp
  *
- * Copyright (C) 2007-2008 Hubert Figuiere
+ * Copyright (C) 2007-2009 Hubert Figuiere
  *
  * 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
@@ -19,7 +19,7 @@
  * 02110-1301, USA
  */
 
-#include "locallibraryserver.h"
+#include "locallibraryserver.hpp"
 
 using library::Op;
 
diff --git a/src/libraryclient/locallibraryserver.h b/src/libraryclient/locallibraryserver.h
deleted file mode 100644
index cd4b28d..0000000
--- a/src/libraryclient/locallibraryserver.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * niepce - libraryclient/locallibraryserver.h
- *
- * Copyright (C) 2007 Hubert Figuiere
- *
- * 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 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., 51 Franklin Street, Fifth Floor, Boston, MA  
- * 02110-1301, USA
- */
-
-
-
-#ifndef _LIBRARYCLIENT_LOCALLIBRARYSERVER_H_
-#define _LIBRARYCLIENT_LOCALLIBRARYSERVER_H_
-
-#include "fwk/utils/worker.h"
-#include "engine/library/op.h"
-#include "engine/db/library.h"
-
-namespace libraryclient {
-
-	class LocalLibraryServer
-		: public utils::Worker< library::Op::Ptr >
-	{
-	public:
-		/** create the local server for the library whose dir is specified */
-		LocalLibraryServer(const std::string & dir, 
-						   const fwk::NotificationCenter::Ptr & nc)
-			: utils::Worker< library::Op::Ptr >()
-			, m_library(db::Library::Ptr(new db::Library(dir, nc)))
-			{
-			}
-
-	protected:
-		virtual void execute(const library::Op::Ptr & _op);
-
-	private:
-		db::Library::Ptr m_library;
-	};
-
-}
-
-
-#endif
diff --git a/src/libraryclient/locallibraryserver.hpp b/src/libraryclient/locallibraryserver.hpp
new file mode 100644
index 0000000..8e2bdb8
--- /dev/null
+++ b/src/libraryclient/locallibraryserver.hpp
@@ -0,0 +1,55 @@
+/*
+ * niepce - libraryclient/locallibraryserver.h
+ *
+ * Copyright (C) 2007 Hubert Figuiere
+ *
+ * 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 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., 51 Franklin Street, Fifth Floor, Boston, MA  
+ * 02110-1301, USA
+ */
+
+
+
+#ifndef _LIBRARYCLIENT_LOCALLIBRARYSERVER_H_
+#define _LIBRARYCLIENT_LOCALLIBRARYSERVER_H_
+
+#include "fwk/utils/worker.h"
+#include "engine/library/op.hpp"
+#include "engine/db/library.hpp"
+
+namespace libraryclient {
+
+	class LocalLibraryServer
+		: public utils::Worker< library::Op::Ptr >
+	{
+	public:
+		/** create the local server for the library whose dir is specified */
+		LocalLibraryServer(const std::string & dir, 
+						   const fwk::NotificationCenter::Ptr & nc)
+			: utils::Worker< library::Op::Ptr >()
+			, m_library(db::Library::Ptr(new db::Library(dir, nc)))
+			{
+			}
+
+	protected:
+		virtual void execute(const library::Op::Ptr & _op);
+
+	private:
+		db::Library::Ptr m_library;
+	};
+
+}
+
+
+#endif
diff --git a/src/libraryclient/test_worker.cpp b/src/libraryclient/test_worker.cpp
index 4184ba7..0157254 100644
--- a/src/libraryclient/test_worker.cpp
+++ b/src/libraryclient/test_worker.cpp
@@ -21,7 +21,7 @@
 #include "fwk/utils/fsutils.h"
 
 #define BOOST_AUTO_TEST_MAIN
-#include "locallibraryserver.h"
+#include "locallibraryserver.hpp"
 
 #include <boost/bind.hpp>
 #include <boost/test/minimal.hpp>
diff --git a/src/niepce/Makefile.am b/src/niepce/Makefile.am
index d431a3f..b9584f6 100644
--- a/src/niepce/Makefile.am
+++ b/src/niepce/Makefile.am
@@ -18,6 +18,7 @@ niepce_LDADD = \
 	$(top_builddir)/src/engine/library/libniepcelibrary.a \
 	$(top_builddir)/src/engine/db/libniepcedb.a \
 	$(top_builddir)/src/niepce/modules/darkroom/libmoduledarkroom.a \
+	$(top_builddir)/src/fwk/libfwk.a \
 	$(top_builddir)/src/fwk/toolkit/libniepceframework.a \
 	$(top_builddir)/src/fwk/utils/libniepceutils.a \
 	$(top_builddir)/src/ncr/libncr.a \
diff --git a/src/niepce/modules/darkroom/darkroommodule.h b/src/niepce/modules/darkroom/darkroommodule.h
index aba936f..2dd8b5f 100644
--- a/src/niepce/modules/darkroom/darkroommodule.h
+++ b/src/niepce/modules/darkroom/darkroommodule.h
@@ -31,7 +31,7 @@
 
 #include "fwk/toolkit/controller.hpp"
 #include "engine/db/libfile.h"
-#include "libraryclient/libraryclient.h"
+#include "libraryclient/libraryclient.hpp"
 #include "ncr/image.h"
 #include "modules/darkroom/imagecanvas.h"
 #include "modules/darkroom/toolboxcontroller.h"
diff --git a/src/niepce/ui/dialogs/editlabels.cpp b/src/niepce/ui/dialogs/editlabels.cpp
index 4d29626..50a5552 100644
--- a/src/niepce/ui/dialogs/editlabels.cpp
+++ b/src/niepce/ui/dialogs/editlabels.cpp
@@ -18,20 +18,28 @@
  */
 
 
+#include <boost/bind.hpp>
 #include <boost/format.hpp>
 
 #include <glibmm/i18n.h>
 #include <gtkmm/entry.h>
 #include <gtkmm/label.h>
 
+#include "fwk/utils/debug.h"
 #include "editlabels.hpp"
+#include "libraryclient/libraryclient.hpp"
+#include "fwk/toolkit/application.hpp"
+#include "fwk/toolkit/undo.hpp"
 
 
+using libraryclient::LibraryClient;
+
 namespace ui {
 
-EditLabels::EditLabels(const eng::Label::List & labels)
+EditLabels::EditLabels(const eng::Label::List & labels, const LibraryClient::Ptr & libclient)
     : fwk::Dialog(GLADEDIR"editlabels.ui", "editLabels")
     , m_labels(labels)
+    , m_lib_client(libclient)
 {
 }
 
@@ -52,16 +60,25 @@ void EditLabels::setup_widget()
         Gtk::Entry *labelentry;
         _builder->get_widget(str(boost::format(color_fmt) % (i+1)), colorlbl);
         _builder->get_widget(str(boost::format(value_fmt) % (i+1)), labelentry);
+        DBG_ASSERT(labelentry, "couldn't find label");
         labelentry->set_text(m_labels[i]->label());
         labelentry->signal_changed().connect(
-            sigc::bind(sigc::mem_fun(*this, &EditLabels::label_name_changed), labelentry, i+1));
+            sigc::bind(sigc::mem_fun(*this, &EditLabels::label_name_changed), labelentry, i));
     }
 }
 
 
 void EditLabels::label_name_changed(Gtk::Entry *w, size_t idx)
 {
-    m_labels[idx]->set_label(w->get_text());
+    std::string current_name = m_labels[idx]->label();
+    std::string new_name = w->get_text();
+    DBG_OUT("setting to %s", new_name.c_str());
+    fwk::UndoTransaction *undo = fwk::Application::app()->begin_undo(_("Change Label name"));
+    undo->new_command(boost::bind(&libraryclient::LibraryClient::renameLabel, 
+                                  m_lib_client, m_labels[idx]->id(), new_name),
+                      boost::bind(&libraryclient::LibraryClient::renameLabel, 
+                                  m_lib_client, m_labels[idx]->id(), current_name));
+    undo->execute();
 }
 
 /*
diff --git a/src/niepce/ui/dialogs/editlabels.hpp b/src/niepce/ui/dialogs/editlabels.hpp
index a2d2f1d..acdfe13 100644
--- a/src/niepce/ui/dialogs/editlabels.hpp
+++ b/src/niepce/ui/dialogs/editlabels.hpp
@@ -24,6 +24,7 @@
 #include <gtkmm/label.h>
 
 #include "engine/db/label.hpp"
+#include "libraryclient/libraryclient.hpp"
 #include "fwk/toolkit/dialog.hpp"
 
 namespace ui {
@@ -34,12 +35,13 @@ class EditLabels
 {
 public:
     typedef boost::shared_ptr<EditLabels> Ptr;
-    EditLabels(const eng::Label::List &);
+    EditLabels(const eng::Label::List &, const libraryclient::LibraryClient::Ptr &);
 
     virtual void setup_widget();
 private:
     void label_name_changed(Gtk::Entry *, size_t idx);
     eng::Label::List m_labels;
+    libraryclient::LibraryClient::Ptr m_lib_client;
 };
 
 
diff --git a/src/niepce/ui/filmstripcontroller.cpp b/src/niepce/ui/filmstripcontroller.cpp
index a37b292..8afd824 100644
--- a/src/niepce/ui/filmstripcontroller.cpp
+++ b/src/niepce/ui/filmstripcontroller.cpp
@@ -21,7 +21,7 @@
 #include <gtkmm/iconview.h>
 
 #include "niepce/notifications.h"
-#include "engine/db/library.h"
+#include "engine/db/library.hpp"
 #include "engine/library/thumbnailnotification.h"
 #include "fwk/utils/debug.h"
 
diff --git a/src/niepce/ui/imageliststore.cpp b/src/niepce/ui/imageliststore.cpp
index 9d98150..45a9dc5 100644
--- a/src/niepce/ui/imageliststore.cpp
+++ b/src/niepce/ui/imageliststore.cpp
@@ -24,7 +24,7 @@
 #include "fwk/toolkit/application.hpp"
 #include "fwk/toolkit/gdkutils.hpp"
 #include "niepce/notifications.h"
-#include "engine/db/library.h"
+#include "engine/db/library.hpp"
 #include "engine/library/thumbnailnotification.h"
 #include "niepcewindow.hpp"
 
diff --git a/src/niepce/ui/imageliststore.h b/src/niepce/ui/imageliststore.h
index 9550789..a76248f 100644
--- a/src/niepce/ui/imageliststore.h
+++ b/src/niepce/ui/imageliststore.h
@@ -29,7 +29,7 @@
 #include "fwk/toolkit/notification.hpp"
 #include "fwk/toolkit/controller.hpp"
 #include "engine/db/libfile.h"
-#include "libraryclient/libraryclient.h"
+#include "libraryclient/libraryclient.hpp"
 
 namespace ui {
 
diff --git a/src/niepce/ui/librarymainviewcontroller.cpp b/src/niepce/ui/librarymainviewcontroller.cpp
index 1af9fd3..c49725f 100644
--- a/src/niepce/ui/librarymainviewcontroller.cpp
+++ b/src/niepce/ui/librarymainviewcontroller.cpp
@@ -1,7 +1,7 @@
 /*
- * niepce - ui/librarymainviewcontroller.cpp
+ * niepce - niepce/ui/librarymainviewcontroller.cpp
  *
- * Copyright (C) 2007-2008 Hubert Figuiere
+ * Copyright (C) 2007-2009 Hubert Figuiere
  *
  * 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
@@ -28,7 +28,7 @@
 
 #include "fwk/utils/debug.h"
 #include "niepce/notifications.h"
-#include "engine/db/library.h"
+#include "engine/db/library.hpp"
 #include "fwk/toolkit/application.hpp"
 #include "fwk/toolkit/widgets/dock.hpp"
 #include "librarymainviewcontroller.hpp"
diff --git a/src/niepce/ui/librarymainviewcontroller.hpp b/src/niepce/ui/librarymainviewcontroller.hpp
index ea9e347..153c8fd 100644
--- a/src/niepce/ui/librarymainviewcontroller.hpp
+++ b/src/niepce/ui/librarymainviewcontroller.hpp
@@ -30,7 +30,7 @@
 
 #include "librarymainview.h"
 #include "engine/db/libfile.h"
-#include "libraryclient/libraryclient.h"
+#include "libraryclient/libraryclient.hpp"
 #include "fwk/toolkit/controller.hpp"
 #include "fwk/toolkit/notification.hpp"
 #include "metadatapanecontroller.hpp"
diff --git a/src/niepce/ui/niepcewindow.cpp b/src/niepce/ui/niepcewindow.cpp
index e63ddc3..5c92282 100644
--- a/src/niepce/ui/niepcewindow.cpp
+++ b/src/niepce/ui/niepcewindow.cpp
@@ -34,8 +34,7 @@
 #include "fwk/utils/debug.h"
 #include "fwk/utils/moniker.h"
 #include "fwk/utils/boost.h"
-#include "engine/db/library.h"
-#include "libraryclient/libraryclient.h"
+#include "engine/db/library.hpp"
 #include "fwk/toolkit/application.hpp"
 #include "fwk/toolkit/configuration.hpp"
 #include "fwk/toolkit/notificationcenter.hpp"
@@ -89,6 +88,9 @@ NiepceWindow::buildWidget()
     set_icon_from_theme(name);		
 
     m_lib_notifcenter->subscribe(niepce::NOTIFICATION_LIB,
+                                 boost::bind(&NiepceWindow::on_lib_notification, 
+                                             this, _1));
+    m_lib_notifcenter->subscribe(niepce::NOTIFICATION_LIB,
                                  boost::bind(&ImageListStore::on_lib_notification, 
                                              m_selection_controller->list_store(), _1));
     m_lib_notifcenter->subscribe(niepce::NOTIFICATION_THUMBNAIL,
@@ -490,18 +492,58 @@ void NiepceWindow::on_preferences()
 }
 
 
+
+void NiepceWindow::create_initial_labels()
+{
+    m_libClient->createLabel(_("Label 1"), "");
+    m_libClient->createLabel(_("Label 2"), "");
+    m_libClient->createLabel(_("Label 3"), "");
+    m_libClient->createLabel(_("Label 4"), "");
+    m_libClient->createLabel(_("Label 5"), "");
+}
+
+
+void NiepceWindow::on_lib_notification(const fwk::Notification::Ptr &n)
+{
+    DBG_ASSERT(n->type() == niepce::NOTIFICATION_LIB, 
+               "wrong notification type");
+    if(n->type() == niepce::NOTIFICATION_LIB) {
+        db::LibNotification ln = boost::any_cast<db::LibNotification>(n->data());
+        switch(ln.type) {
+        case db::Library::NOTIFY_NEW_LIBRARY_CREATED:
+            create_initial_labels();
+            break;
+        case db::Library::NOTIFY_ADDED_LABELS:
+        {
+            eng::Label::ListPtr l 
+                = boost::any_cast<eng::Label::ListPtr>(ln.param);
+            for(eng::Label::List::const_iterator iter = l->begin();
+                iter != l->end(); ++iter) {
+                
+                m_labels.push_back(*iter);
+            }
+            break;
+            }
+        default:
+            break;
+        }
+    }
+}
+
+
 void NiepceWindow::open_library(const std::string & libMoniker)
 {
     m_libClient = LibraryClient::Ptr(new LibraryClient(utils::Moniker(libMoniker),
                                                        m_lib_notifcenter));
     set_title(libMoniker);
+    m_libClient->getAllLabels();
 }
 
 void NiepceWindow::on_action_edit_labels()
 {
     DBG_OUT("edit labels");
     // get the labels.
-    EditLabels::Ptr dlg(new EditLabels(get_labels()));
+    EditLabels::Ptr dlg(new EditLabels(get_labels(), getLibraryClient()));
     int result = dlg->run_modal(shared_frame_ptr());
     switch(result) {
     case 0:
diff --git a/src/niepce/ui/niepcewindow.hpp b/src/niepce/ui/niepcewindow.hpp
index a76652c..ceca558 100644
--- a/src/niepce/ui/niepcewindow.hpp
+++ b/src/niepce/ui/niepcewindow.hpp
@@ -33,7 +33,7 @@
 #include "fwk/toolkit/notificationcenter.hpp"
 #include "fwk/toolkit/configdatabinder.hpp"
 #include "engine/db/label.hpp"
-#include "libraryclient/libraryclient.h"
+#include "libraryclient/libraryclient.hpp"
 #include "ui/librarymainviewcontroller.hpp"
 #include "ui/workspacecontroller.h"
 #include "ui/selectioncontroller.hpp"
@@ -75,6 +75,9 @@ private:
                                  Gtk::Dialog *);
     void on_preferences();
 
+    void create_initial_labels();
+    void on_lib_notification(const fwk::Notification::Ptr &n);
+
     void init_ui();
     void init_actions();
 
diff --git a/src/niepce/ui/selectioncontroller.cpp b/src/niepce/ui/selectioncontroller.cpp
index 8f6f5b9..e2fb901 100644
--- a/src/niepce/ui/selectioncontroller.cpp
+++ b/src/niepce/ui/selectioncontroller.cpp
@@ -28,7 +28,7 @@
 #include "fwk/toolkit/command.hpp"
 #include "fwk/toolkit/application.hpp"
 #include "engine/db/metadata.h"
-#include "libraryclient/libraryclient.h"
+#include "libraryclient/libraryclient.hpp"
 #include "niepcewindow.hpp"
 #include "selectioncontroller.hpp"
 
@@ -158,17 +158,12 @@ void SelectionController::rotate(int angle)
 bool SelectionController::_set_metadata(const std::string & undo_label, const db::LibFile::Ptr & file,
                                         int meta, int old_value, int new_value)
 {
-    fwk::UndoTransaction *undo = new fwk::UndoTransaction(undo_label);
-    fwk::Application::app()->undo_history().add(undo);
-    fwk::Command *cmd = new fwk::Command;
-    cmd->redo = boost::bind(&libraryclient::LibraryClient::setMetadata,
-                            getLibraryClient(), file->id(), 
-                            meta, new_value);
-    cmd->undo = boost::bind(&libraryclient::LibraryClient::setMetadata,
-                            getLibraryClient(), file->id(),
-                            meta, old_value);
-    undo->add(cmd);
-    undo->redo();
+    fwk::UndoTransaction *undo = fwk::Application::app()->begin_undo(undo_label);
+    undo->new_command(boost::bind(&libraryclient::LibraryClient::setMetadata,
+                                  getLibraryClient(), file->id(), meta, new_value),
+                      boost::bind(&libraryclient::LibraryClient::setMetadata,
+                                  getLibraryClient(), file->id(), meta, old_value));
+    undo->execute();
     return true;
 }
 
diff --git a/src/niepce/ui/workspacecontroller.cpp b/src/niepce/ui/workspacecontroller.cpp
index ae423c6..327b956 100644
--- a/src/niepce/ui/workspacecontroller.cpp
+++ b/src/niepce/ui/workspacecontroller.cpp
@@ -27,8 +27,8 @@
 
 #include "fwk/utils/debug.h"
 #include "niepce/notifications.h"
-#include "engine/db/library.h" // FIXME uh oh. this shouldn't be
-#include "libraryclient/libraryclient.h"
+#include "engine/db/library.hpp" // FIXME uh oh. this shouldn't be
+#include "libraryclient/libraryclient.hpp"
 #include "fwk/toolkit/application.hpp"
 #include "niepcewindow.hpp"
 #include "workspacecontroller.h"



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