[niepce] Write external metadata to XMP Properties typing.



commit 3b7994c7e1bf594c689fad50b6df973fab878209
Author: Hub Figuiere <hub figuiere net>
Date:   Fri Nov 11 21:28:27 2011 -0800

    Write external metadata to XMP
    Properties typing.

 src/engine/db/libmetadata.cpp       |   51 +++++++---------------------------
 src/engine/db/libmetadata.hpp       |   39 +++++++++++++-------------
 src/engine/db/library.cpp           |   34 +++++++++++++----------
 src/engine/db/library.hpp           |    2 +-
 src/engine/db/properties-def.hpp    |   41 ++++++++++++++-------------
 src/engine/db/properties.cpp        |   47 +++++++++++++++++++++++++++++---
 src/engine/db/properties.hpp        |   16 +++++++++-
 src/engine/db/xmpproperties.cpp     |   35 ++++++++++++-----------
 src/engine/db/xmpproperties.hpp     |    2 +
 src/engine/library/clienttypes.hpp  |   13 +++++----
 src/engine/library/commands.cpp     |    3 +-
 src/engine/library/commands.hpp     |    3 +-
 src/fwk/toolkit/metadatawidget.cpp  |   10 +++---
 src/fwk/toolkit/metadatawidget.hpp  |    2 +-
 src/libraryclient/clientimpl.cpp    |    2 +-
 src/libraryclient/clientimpl.hpp    |    2 +-
 src/libraryclient/libraryclient.cpp |    3 +-
 src/niepce/ui/imageliststore.cpp    |   31 ++++++++++++++-------
 src/niepce/ui/imageliststore.hpp    |    1 +
 19 files changed, 191 insertions(+), 146 deletions(-)
---
diff --git a/src/engine/db/libmetadata.cpp b/src/engine/db/libmetadata.cpp
index 8b98055..af9a474 100644
--- a/src/engine/db/libmetadata.cpp
+++ b/src/engine/db/libmetadata.cpp
@@ -23,6 +23,7 @@
 
 #include "fwk/base/debug.hpp"
 #include "libmetadata.hpp"
+#include "xmpproperties.hpp"
 
 namespace eng {
 
@@ -33,53 +34,23 @@ LibMetadata::LibMetadata(library_id_t _id)
 {
 }
 
-namespace {
 
-bool xmpPropertyNameFromIndex(int meta, std::string & ns, std::string & property)
+bool LibMetadata::setMetaData(fwk::PropertyIndex meta, const fwk::PropertyValue & value)
 {
-    bool found = true;
-    switch(meta) {
-    case MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_RATING):
-        ns = NS_XAP;
-        property = "Rating";
-        break;
-    case MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_LABEL):
-        ns = NS_XAP;
-        property = "Label";
-        break;
-    case MAKE_METADATA_IDX(eng::META_NS_TIFF, eng::META_TIFF_ORIENTATION):
-        ns = NS_TIFF;
-        property = "Orientation";
-        break;
-    case MAKE_METADATA_IDX(eng::META_NS_NIEPCE, eng::META_NIEPCE_FLAG):
-        ns = xmp::NIEPCE_XMP_NAMESPACE;
-        property = "Flag";
-        break;
-    default:
-        found = false;
-        break;
-    }
-   
-    return found;
-}
-
-}
-
-bool LibMetadata::setMetaData(int meta, const boost::any & value)
-{
-    std::string ns;
-    std::string property;
+    const char * ns = NULL;
+    const char * property = NULL;
     bool result = false;
 
-    result = xmpPropertyNameFromIndex(meta, ns, property);
+    result = property_index_to_xmp(meta, ns, property);
     if(result) {
-        if(value.type() == typeid(int32_t)) {
-            result = xmp_set_property_int32(xmp(), ns.c_str(), property.c_str(), 
-                                            boost::any_cast<int32_t>(value), 0);
+        
+        if(value.type() == typeid(int)) {
+            result = xmp_set_property_int32(xmp(), ns, property, 
+                                            boost::get<int>(value), 0);
         }
         else if(value.type() == typeid(std::string)) {
-            result = xmp_set_property(xmp(), ns.c_str(), property.c_str(), 
-                                      boost::any_cast<std::string>(value).c_str(), 0);
+            result = xmp_set_property(xmp(), ns, property, 
+                                      boost::get<std::string>(value).c_str(), 0);
         }
     }
     else {
diff --git a/src/engine/db/libmetadata.hpp b/src/engine/db/libmetadata.hpp
index f4f7a79..55b865f 100644
--- a/src/engine/db/libmetadata.hpp
+++ b/src/engine/db/libmetadata.hpp
@@ -25,31 +25,32 @@
 #include <tr1/memory>
 #include <boost/any.hpp>
 
+#include "fwk/base/propertybag.hpp"
 #include "fwk/utils/exempi.hpp"
 #include "engine/db/librarytypes.hpp"
 #include "engine/db/metadata.hpp"
 
 namespace eng {
 
-	class LibMetadata
-		: public fwk::XmpMeta
-	{
-	public:
-		typedef std::tr1::shared_ptr<LibMetadata> Ptr;
-
-		LibMetadata(library_id_t _id);
-
-        library_id_t id() const
-            { return m_id; }
-        bool setMetaData(int meta, const boost::any & value);
-        /** do like the unix "touch". Update the MetadataDate 
-         * to the current time, in UTC.
-         */
-        bool touch();
-    private:
-        LibMetadata(const LibMetadata &);
-        library_id_t m_id;
-	};
+class LibMetadata
+    : public fwk::XmpMeta
+{
+public:
+    typedef std::tr1::shared_ptr<LibMetadata> Ptr;
+    
+    LibMetadata(library_id_t _id);
+    
+    library_id_t id() const
+        { return m_id; }
+    bool setMetaData(fwk::PropertyIndex meta, const fwk::PropertyValue & value);
+    /** do like the unix "touch". Update the MetadataDate 
+     * to the current time, in UTC.
+     */
+    bool touch();
+private:
+    LibMetadata(const LibMetadata &);
+    library_id_t m_id;
+};
 
 }
 
diff --git a/src/engine/db/library.cpp b/src/engine/db/library.cpp
index 91afce3..dcdc164 100644
--- a/src/engine/db/library.cpp
+++ b/src/engine/db/library.cpp
@@ -31,6 +31,7 @@
 #include "niepce/notifications.hpp"
 #include "library.hpp"
 #include "metadata.hpp"
+#include "properties.hpp"
 #include "fwk/base/debug.hpp"
 #include "fwk/utils/exception.hpp"
 #include "fwk/utils/exempi.hpp"
@@ -721,32 +722,34 @@ bool Library::setMetaData(library_id_t file_id, const LibMetadata::Ptr & meta)
  * @param value the value to set
  * @return false on error
  */
-bool Library::setMetaData(library_id_t file_id, int meta, 
-                          const boost::any & value)
+bool Library::setMetaData(library_id_t file_id, fwk::PropertyIndex meta, 
+                          const fwk::PropertyValue & value)
 {
     bool retval = false;
-    DBG_OUT("setting metadata in column %x", meta);
+    DBG_OUT("setting metadata %x", meta);
+    DBG_ASSERT(check_property_type(meta, value.type()), 
+               "wrong property value type");
     switch(meta) {
-    case MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_RATING):
-    case MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_LABEL):
-    case MAKE_METADATA_IDX(eng::META_NS_TIFF,    eng::META_TIFF_ORIENTATION):
-    case MAKE_METADATA_IDX(eng::META_NS_NIEPCE,  eng::META_NIEPCE_FLAG):
+    case eng::NpXmpRatingProp:
+    case eng::NpXmpLabelProp:
+    case eng::NpTiffOrientationProp:
+    case eng::NpNiepceFlagProp:
         if(value.type() == typeid(int32_t)) {
             // internal.
-            int32_t nvalue = boost::any_cast<int32_t>(value);
+            int nvalue = boost::get<int>(value);
             // make the column mapping more generic.
             const char * col = NULL;
             switch(meta) {
-            case MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_RATING):
+            case eng::NpXmpRatingProp:
                 col = "rating";
                 break;
-            case MAKE_METADATA_IDX(eng::META_NS_TIFF, eng::META_TIFF_ORIENTATION):
+            case eng::NpTiffOrientationProp:
                 col = "orientation";
                 break;
-            case MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_LABEL):
+            case eng::NpXmpLabelProp:
                 col = "label";
                 break;
-            case MAKE_METADATA_IDX(eng::META_NS_NIEPCE, eng::META_NIEPCE_FLAG):
+            case eng::NpNiepceFlagProp:
                 col = "flag";
                 break;
             }
@@ -756,9 +759,10 @@ bool Library::setMetaData(library_id_t file_id, int meta,
         }
         break;
     default:
-        // external.
-        ERR_OUT("unknown metadata to set");
-        return false;
+        // external
+        // TODO add the external metadata
+        // 
+        break;
     }
     LibMetadata::Ptr metablock(new LibMetadata(file_id));
     getMetaData(file_id, metablock);
diff --git a/src/engine/db/library.hpp b/src/engine/db/library.hpp
index 9d1602d..817836b 100644
--- a/src/engine/db/library.hpp
+++ b/src/engine/db/library.hpp
@@ -162,7 +162,7 @@ public:
 		void getMetaData(library_id_t file_id, const LibMetadata::Ptr & );
     /** set the metadata block (XMP) */
     bool setMetaData(library_id_t file_id, const LibMetadata::Ptr & );
-    bool setMetaData(library_id_t file_id, int meta, const boost::any & value);
+    bool setMetaData(library_id_t file_id, fwk::PropertyIndex meta, const fwk::PropertyValue & value);
 
 		void getAllLabels(const eng::Label::ListPtr & l);
     library_id_t addLabel(const std::string & name, const std::string & color);
diff --git a/src/engine/db/properties-def.hpp b/src/engine/db/properties-def.hpp
index 004b91e..30f346c 100644
--- a/src/engine/db/properties-def.hpp
+++ b/src/engine/db/properties-def.hpp
@@ -26,28 +26,29 @@
 // - the value of the id
 // - XMP NS - NULL if none
 // - XMP property - NULL if none
+// - type
 
-DEFINE_PROPERTY(NpXmpRatingProp, MAKE_METADATA_IDX(META_NS_XMPCORE, META_XMPCORE_RATING), NS_XAP, "Rating" )
-DEFINE_PROPERTY(NpXmpLabelProp,  MAKE_METADATA_IDX(META_NS_XMPCORE, META_XMPCORE_LABEL), NS_XAP, "Label" )
+DEFINE_PROPERTY(NpXmpRatingProp, MAKE_METADATA_IDX(META_NS_XMPCORE, META_XMPCORE_RATING), NS_XAP, "Rating", int32_t )
+DEFINE_PROPERTY(NpXmpLabelProp,  MAKE_METADATA_IDX(META_NS_XMPCORE, META_XMPCORE_LABEL), NS_XAP, "Label", int32_t )
 
-DEFINE_PROPERTY(NpTiffOrientationProp, MAKE_METADATA_IDX(META_NS_TIFF, META_TIFF_ORIENTATION), NS_TIFF, "Orientation" )
-DEFINE_PROPERTY(NpTiffMakeProp, MAKE_METADATA_IDX(META_NS_TIFF, META_TIFF_MAKE), NS_TIFF, "Make" )
-DEFINE_PROPERTY(NpTiffModelProp, MAKE_METADATA_IDX(META_NS_TIFF, META_TIFF_MODEL), NS_TIFF, "Model" )
+DEFINE_PROPERTY(NpTiffOrientationProp, MAKE_METADATA_IDX(META_NS_TIFF, META_TIFF_ORIENTATION), NS_TIFF, "Orientation", int32_t )
+DEFINE_PROPERTY(NpTiffMakeProp, MAKE_METADATA_IDX(META_NS_TIFF, META_TIFF_MAKE), NS_TIFF, "Make", std::string )
+DEFINE_PROPERTY(NpTiffModelProp, MAKE_METADATA_IDX(META_NS_TIFF, META_TIFF_MODEL), NS_TIFF, "Model", std::string )
 
-DEFINE_PROPERTY(NpExifAuxLensProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_AUX_LENS), NS_EXIF_AUX, "Lens" )
-DEFINE_PROPERTY(NpExifExposureProgramProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_EXPOSUREPROGRAM), NS_EXIF, "ExposureProgram")
-DEFINE_PROPERTY(NpExifExposureTimeProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_EXPOSURETIME), NS_EXIF, "ExposureTime")
-DEFINE_PROPERTY(NpExifFNumberPropProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_FNUMBER), NS_EXIF, "FNumber")
-DEFINE_PROPERTY(NpExifIsoSpeedRatingsProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_ISOSPEEDRATINGS), NS_EXIF, "ISOSpeedRatings")
-DEFINE_PROPERTY(NpExifExposureBiasProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_EXPOSUREBIAS), NS_EXIF, "ExposureBiasValue")
-DEFINE_PROPERTY(NpExifFlashFiredProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_FLASHFIRED), NS_EXIF, "Flash/exif:Fired")
-DEFINE_PROPERTY(NpExifAuxFlashCompensationProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_AUX_FLASHCOMPENSATION), NS_EXIF_AUX, "FlashCompensation")
-DEFINE_PROPERTY(NpExifWbProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_WB), NS_EXIF, "WhiteBalance")
-DEFINE_PROPERTY(NpExifDateTimeOriginalProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_DATETIMEORIGINAL), NS_EXIF, "DateTimeOriginal")
-DEFINE_PROPERTY(NpExifFocalLengthProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_FOCALLENGTH), NS_EXIF, "FocalLength")
+DEFINE_PROPERTY(NpExifAuxLensProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_AUX_LENS), NS_EXIF_AUX, "Lens", std::string )
+DEFINE_PROPERTY(NpExifExposureProgramProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_EXPOSUREPROGRAM), NS_EXIF, "ExposureProgram", int32_t)
+DEFINE_PROPERTY(NpExifExposureTimeProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_EXPOSURETIME), NS_EXIF, "ExposureTime", int32_t)
+DEFINE_PROPERTY(NpExifFNumberPropProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_FNUMBER), NS_EXIF, "FNumber", int32_t)
+DEFINE_PROPERTY(NpExifIsoSpeedRatingsProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_ISOSPEEDRATINGS), NS_EXIF, "ISOSpeedRatings", int32_t)
+DEFINE_PROPERTY(NpExifExposureBiasProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_EXPOSUREBIAS), NS_EXIF, "ExposureBiasValue", int32_t)
+DEFINE_PROPERTY(NpExifFlashFiredProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_FLASHFIRED), NS_EXIF, "Flash/exif:Fired", int32_t)
+DEFINE_PROPERTY(NpExifAuxFlashCompensationProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_AUX_FLASHCOMPENSATION), NS_EXIF_AUX, "FlashCompensation", int32_t)
+DEFINE_PROPERTY(NpExifWbProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_WB), NS_EXIF, "WhiteBalance", int32_t)
+DEFINE_PROPERTY(NpExifDateTimeOriginalProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_DATETIMEORIGINAL), NS_EXIF, "DateTimeOriginal", int32_t)
+DEFINE_PROPERTY(NpExifFocalLengthProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_FOCALLENGTH), NS_EXIF, "FocalLength", int32_t)
 
-DEFINE_PROPERTY(NpIptcHeadlineProp, MAKE_METADATA_IDX(META_NS_IPTC, META_IPTC_HEADLINE), NS_PHOTOSHOP, "Headline")
-DEFINE_PROPERTY(NpIptcDescriptionProp, MAKE_METADATA_IDX(META_NS_IPTC, META_IPTC_DESCRIPTION), NS_DC, "description")
-DEFINE_PROPERTY(NpIptcKeywordsProp, MAKE_METADATA_IDX(META_NS_IPTC, META_IPTC_KEYWORDS), NS_DC, "subject")
+DEFINE_PROPERTY(NpIptcHeadlineProp, MAKE_METADATA_IDX(META_NS_IPTC, META_IPTC_HEADLINE), NS_PHOTOSHOP, "Headline", std::string)
+DEFINE_PROPERTY(NpIptcDescriptionProp, MAKE_METADATA_IDX(META_NS_IPTC, META_IPTC_DESCRIPTION), NS_DC, "description", std::string)
+DEFINE_PROPERTY(NpIptcKeywordsProp, MAKE_METADATA_IDX(META_NS_IPTC, META_IPTC_KEYWORDS), NS_DC, "subject", std::string)
 
-DEFINE_PROPERTY(NpNiepceFlagProp, MAKE_METADATA_IDX(META_NS_NIEPCE, META_NIEPCE_FLAG), xmp::NIEPCE_XMP_NAMESPACE, "Flag")
+DEFINE_PROPERTY(NpNiepceFlagProp, MAKE_METADATA_IDX(META_NS_NIEPCE, META_NIEPCE_FLAG), xmp::NIEPCE_XMP_NAMESPACE, "Flag", int32_t)
diff --git a/src/engine/db/properties.cpp b/src/engine/db/properties.cpp
index ccdc4d0..c140067 100644
--- a/src/engine/db/properties.cpp
+++ b/src/engine/db/properties.cpp
@@ -22,20 +22,59 @@
 
 namespace eng {
 
-#define DEFINE_PROPERTY(a,b,c,d)			\
-    { a, #a },
+#define DEFINE_PROPERTY(a,b,c,d,e)               \
+    { a, #a, typeid(e) },
 
-const property_desc_t properties_names[] = {
+static const property_desc_t properties_names[] = {
 
     #include "engine/db/properties-def.hpp"
 
-    { 0, NULL }
+    { 0, NULL, typeid(NULL) }
 };
 
 #undef DEFINE_PROPERTY
 
+const char * _propertyName(fwk::PropertyIndex idx)
+{
+    const PropDescMap & propmap = property_desc_map();
+    PropDescMap::const_iterator iter = propmap.find(idx);
+    if(iter != propmap.end()) {
+        if(iter->second->name) {
+            return iter->second->name;
+        }
+    }
+    return "UNKNOWN";
 }
 
+const PropDescMap & property_desc_map()
+{
+    static PropDescMap s_map;
+    if(s_map.empty()) {
+        const eng::property_desc_t * current = eng::properties_names;
+        while(current->prop != 0) {
+            if(current->name) {
+                s_map.insert(std::make_pair(current->prop, current));
+            }
+            ++current;
+        }
+    }
+    return s_map;
+}
+
+bool check_property_type(fwk::PropertyIndex idx, const std::type_info & ti)
+{
+    const PropDescMap & propmap = property_desc_map();
+    PropDescMap::const_iterator iter = propmap.find(idx);
+    if(iter != propmap.end()) {
+        return iter->second->type == ti;
+    }
+    return false;
+}
+
+
+}
+
+
 /*
   Local Variables:
   mode:c++
diff --git a/src/engine/db/properties.hpp b/src/engine/db/properties.hpp
index 3df1b21..da032c5 100644
--- a/src/engine/db/properties.hpp
+++ b/src/engine/db/properties.hpp
@@ -21,6 +21,8 @@
 #ifndef __ENG_PROPERTIES_HPP__
 #define __ENG_PROPERTIES_HPP__
 
+#include <typeinfo>
+
 #include "fwk/base/propertybag.hpp"
 #include "engine/db/metadata.hpp"
 
@@ -28,7 +30,7 @@ namespace eng {
 
   // prefix Np is for Niepce Property
 
-#define DEFINE_PROPERTY(a,b,c,d)                 \
+#define DEFINE_PROPERTY(a,b,c,d,e)               \
     a = b,
 
 enum {
@@ -43,9 +45,19 @@ enum {
 struct property_desc_t {
     fwk::PropertyIndex prop;
     const char * name;
+    const std::type_info & type;
 };
 
-extern const property_desc_t properties_names[];
+typedef std::map<fwk::PropertyIndex, const property_desc_t*> PropDescMap;
+
+/** get the properties description */
+const PropDescMap & property_desc_map();
+/** return true of the property is of the type ti */
+bool check_property_type(fwk::PropertyIndex idx, const std::type_info & ti);
+
+
+/** internal property name */
+const char * _propertyName(fwk::PropertyIndex idx);
 
 }
 
diff --git a/src/engine/db/xmpproperties.cpp b/src/engine/db/xmpproperties.cpp
index f08eb55..dbd27bc 100644
--- a/src/engine/db/xmpproperties.cpp
+++ b/src/engine/db/xmpproperties.cpp
@@ -35,7 +35,7 @@ const PropsToXmpMap & props_to_xmp_map()
     static PropsToXmpMap s_props_map;
     if(s_props_map.empty()) {
 
-#define DEFINE_PROPERTY(a,b,c,d) \
+#define DEFINE_PROPERTY(a,b,c,d,e)                                       \
         s_props_map.insert(std::make_pair(b, std::make_pair(c,d)));
 #include "engine/db/properties-def.hpp"
 #undef DEFINE_PROPERTY
@@ -71,6 +71,23 @@ bool get_prop_from_xmp(const fwk::XmpMeta * meta, fwk::PropertyIndex p,
     return false;
 }
 
+bool property_index_to_xmp(fwk::PropertyIndex index, const char * & ns, const char * & property)
+{
+    const PropsToXmpMap & propmap = props_to_xmp_map();
+     PropsToXmpMap::const_iterator iter = propmap.find(index);
+    if(iter == propmap.end()) {
+        // not found
+        return false;
+    }
+    if(iter->second.first == NULL || iter->second.second == NULL) {
+        // no XMP equivalent
+        return false;
+    }
+    ns = iter->second.first;
+    property = iter->second.second;
+    return true;
+}
+
 void convert_xmp_to_properties(const fwk::XmpMeta * meta, const fwk::PropertySet & propset,
                                fwk::PropertyBag & properties)
 {
@@ -121,22 +138,6 @@ void convert_xmp_to_properties(const fwk::XmpMeta * meta, const fwk::PropertySet
     }
 }
 
-#if 0
-
-if(current->type == META_DT_STRING_ARRAY) {
-    xmp::ScopedPtr<XmpIteratorPtr> 
-        iter(xmp_iterator_new(xmp->xmp(), current->ns,
-                              current->property, XMP_ITER_JUSTLEAFNODES));
-    std::vector<std::string> vec;
-    while(xmp_iterator_next(iter, NULL, NULL, value, NULL)) {
-        vec.push_back(xmp_string_cstr(value));
-    }
-    std::string v = fwk::join(vec, ", ");
-    add_data(current, v.c_str());
-}
-
-#endif
-
 }
 
 /*
diff --git a/src/engine/db/xmpproperties.hpp b/src/engine/db/xmpproperties.hpp
index 4929f93..e2fbbbf 100644
--- a/src/engine/db/xmpproperties.hpp
+++ b/src/engine/db/xmpproperties.hpp
@@ -37,6 +37,8 @@ typedef std::map<fwk::PropertyIndex, std::pair<const char*, const char *> > Prop
 /** get the mapping of properties to XMP */
 const PropsToXmpMap & props_to_xmp_map();
 
+bool property_index_to_xmp(fwk::PropertyIndex index, const char * & ns, const char * & property);
+
 /** convert XMP to a set of properties 
  * @param meta the XmpMeta source
  * @param propset the property set requested
diff --git a/src/engine/library/clienttypes.hpp b/src/engine/library/clienttypes.hpp
index d7598ff..2f5b2a5 100644
--- a/src/engine/library/clienttypes.hpp
+++ b/src/engine/library/clienttypes.hpp
@@ -20,17 +20,18 @@
 #ifndef _LIBRARY_CLIENTTYPES_H_
 #define _LIBRARY_CLIENTTYPES_H_
 
+#include "fwk/base/propertybag.hpp"
 #include "engine/db/librarytypes.hpp"
 
 namespace eng {
 
-	typedef int tid_t; /**< transaction ID */
+  typedef int tid_t; /**< transaction ID */
 
-	struct metadata_desc_t {
-		library_id_t id;
-		int          meta;
-		int          value;
-	};
+  struct metadata_desc_t {
+    library_id_t id;
+    fwk::PropertyIndex          meta;
+    fwk::PropertyValue          value;
+  };
 }
 
 
diff --git a/src/engine/library/commands.cpp b/src/engine/library/commands.cpp
index c603387..87fc89e 100644
--- a/src/engine/library/commands.cpp
+++ b/src/engine/library/commands.cpp
@@ -115,7 +115,8 @@ void Commands::cmdRequestMetadata(const Library::Ptr & lib,
 }
 
 void Commands::cmdSetMetadata(const Library::Ptr & lib,
-                              library_id_t file_id, int meta, int value)
+                              library_id_t file_id, fwk::PropertyIndex meta, 
+                              const fwk::PropertyValue & value)
 {
 	metadata_desc_t m;
 	m.id = file_id;
diff --git a/src/engine/library/commands.hpp b/src/engine/library/commands.hpp
index 83648ff..e621668 100644
--- a/src/engine/library/commands.hpp
+++ b/src/engine/library/commands.hpp
@@ -52,7 +52,8 @@ public:
 		static void cmdRequestMetadata(const Library::Ptr & lib,
                                    library_id_t file_id);
     static void cmdSetMetadata(const Library::Ptr & lib,
-                               library_id_t file_id, int meta, int value);
+                               library_id_t file_id, fwk::PropertyIndex meta, 
+                               const fwk::PropertyValue & value);
     static void cmdListAllLabels(const Library::Ptr & lib);
     static void cmdCreateLabel(const Library::Ptr & lib, const std::string & s, 
                                const std::string & color);
diff --git a/src/fwk/toolkit/metadatawidget.cpp b/src/fwk/toolkit/metadatawidget.cpp
index 904a95f..a9e8671 100644
--- a/src/fwk/toolkit/metadatawidget.cpp
+++ b/src/fwk/toolkit/metadatawidget.cpp
@@ -92,10 +92,9 @@ void MetaDataWidget::set_data_source(const fwk::PropertyBag & properties)
     }
 
     const MetaDataFormat * current = m_fmt->formats;
-    xmp::ScopedPtr<XmpStringPtr> value(xmp_string_new());
     while(current && current->label) {
         PropertyValue v;
-        if(properties.get_value_for_property(current->id, v)) {
+        if(properties.get_value_for_property(current->id, v) || !current->readonly) {
             add_data(current, v);
         }
         else {
@@ -147,7 +146,7 @@ void MetaDataWidget::add_data(const MetaDataFormat * current,
             }
             else {
                 Gtk::Entry * e = Gtk::manage(new Gtk::Entry());
-                e->signal_changed().connect(
+                e->signal_focus_out_event().connect(
                     sigc::bind(
                         sigc::mem_fun(*this, 
                                       &MetaDataWidget::on_str_changed),
@@ -210,14 +209,15 @@ void MetaDataWidget::add_data(const MetaDataFormat * current,
     m_table.show_all();
 }
 
-void MetaDataWidget::on_str_changed(Gtk::Entry *e, fwk::PropertyIndex prop)
+bool MetaDataWidget::on_str_changed(GdkEventFocus*, Gtk::Entry *e, fwk::PropertyIndex prop)
 {
     if(m_update) {
-        return;
+        return true;
     }
     fwk::PropertyBag props;
     props.set_value_for_property(prop, fwk::PropertyValue(e->get_text()));
     signal_metadata_changed.emit(props);
+    return true;
 }
 
 void MetaDataWidget::on_int_changed(int value, fwk::PropertyIndex prop)
diff --git a/src/fwk/toolkit/metadatawidget.hpp b/src/fwk/toolkit/metadatawidget.hpp
index 5db4120..9064f96 100644
--- a/src/fwk/toolkit/metadatawidget.hpp
+++ b/src/fwk/toolkit/metadatawidget.hpp
@@ -74,7 +74,7 @@ public:
     
     sigc::signal<void, const fwk::PropertyBag &> signal_metadata_changed;
 protected:
-    void on_str_changed(Gtk::Entry *, fwk::PropertyIndex prop);
+    bool on_str_changed(GdkEventFocus*, Gtk::Entry *, fwk::PropertyIndex prop);
     void on_int_changed(int, fwk::PropertyIndex prop);
 private:
     void clear_widget(std::pair<const PropertyIndex, Gtk::Widget *> & p);
diff --git a/src/libraryclient/clientimpl.cpp b/src/libraryclient/clientimpl.cpp
index a009c26..7ff16dc 100644
--- a/src/libraryclient/clientimpl.cpp
+++ b/src/libraryclient/clientimpl.cpp
@@ -111,7 +111,7 @@ tid_t ClientImpl::requestMetadata(eng::library_id_t file_id)
 }
 
 
-tid_t ClientImpl::setMetadata(eng::library_id_t file_id, int meta, int value)
+tid_t ClientImpl::setMetadata(eng::library_id_t file_id, int meta, const fwk::PropertyValue & value)
 {
     tid_t id = LibraryClient::newTid();
     Op::Ptr op(new Op(id, boost::bind(&Commands::cmdSetMetadata, _1,
diff --git a/src/libraryclient/clientimpl.hpp b/src/libraryclient/clientimpl.hpp
index 0230fa9..385615a 100644
--- a/src/libraryclient/clientimpl.hpp
+++ b/src/libraryclient/clientimpl.hpp
@@ -46,7 +46,7 @@ public:
 		eng::tid_t queryFolderContent(eng::library_id_t id);
 	eng::tid_t countFolder(eng::library_id_t id);
 	eng::tid_t requestMetadata(eng::library_id_t id);
-    eng::tid_t setMetadata(eng::library_id_t id, int meta, int value);
+    eng::tid_t setMetadata(eng::library_id_t id, int meta, const fwk::PropertyValue & value);
 
     eng::tid_t getAllLabels();
     eng::tid_t createLabel(const std::string & s, const std::string & color);
diff --git a/src/libraryclient/libraryclient.cpp b/src/libraryclient/libraryclient.cpp
index 09615f0..c550b77 100644
--- a/src/libraryclient/libraryclient.cpp
+++ b/src/libraryclient/libraryclient.cpp
@@ -87,8 +87,7 @@ eng::tid_t LibraryClient::requestMetadata(eng::library_id_t id)
 /** set the metadata */
 eng::tid_t LibraryClient::setMetadata(library_id_t id, fwk::PropertyIndex meta, const fwk::PropertyValue & value)
 {
-    // FIXME we should pass the value directly
-    return m_pImpl->setMetadata(id, meta, boost::get<int>(value));
+    return m_pImpl->setMetadata(id, meta, value);
 }
 
 eng::tid_t LibraryClient::getAllLabels()
diff --git a/src/niepce/ui/imageliststore.cpp b/src/niepce/ui/imageliststore.cpp
index 2fba801..05efa1b 100644
--- a/src/niepce/ui/imageliststore.cpp
+++ b/src/niepce/ui/imageliststore.cpp
@@ -20,6 +20,7 @@
 #include <gtkmm/icontheme.h>
 
 #include "imageliststore.hpp"
+#include "engine/db/properties.hpp"
 #include "fwk/base/debug.hpp"
 #include "fwk/toolkit/application.hpp"
 #include "fwk/toolkit/gdkutils.hpp"
@@ -102,16 +103,19 @@ void ImageListStore::on_lib_notification(const eng::LibNotification &ln)
     }
     case eng::Library::NOTIFY_METADATA_CHANGED:
     {
-		eng::metadata_desc_t m = boost::any_cast<eng::metadata_desc_t>(ln.param);
-        DBG_OUT("metadata changed");
-        Gtk::TreeRow row;
-        std::map<eng::library_id_t, Gtk::TreeIter>::const_iterator iter = m_idmap.find(m.id);
-        if(iter != m_idmap.end()) {
-            row = *(iter->second);
-            //
-            eng::LibFile::Ptr file = row[m_columns.m_libfile];
-            file->setProperty(m.meta, m.value);
-            row[m_columns.m_libfile] = file;
+        eng::metadata_desc_t m = boost::any_cast<eng::metadata_desc_t>(ln.param);
+        fwk::PropertyIndex prop = m.meta;
+        DBG_OUT("metadata changed %s", eng::_propertyName(prop));
+        // only interested in a few props
+        if(is_property_interesting(prop)) {
+            std::map<eng::library_id_t, Gtk::TreeIter>::const_iterator iter = m_idmap.find(m.id);
+            if(iter != m_idmap.end()) {
+                Gtk::TreeRow row = *(iter->second);
+                //
+                eng::LibFile::Ptr file = row[m_columns.m_libfile];
+                file->setProperty(prop, boost::get<int>(m.value));
+                row[m_columns.m_libfile] = file;
+            }
         }
         break;
     }
@@ -147,6 +151,13 @@ libraryclient::LibraryClient::Ptr ImageListStore::getLibraryClient()
     return	shell->getLibraryClient();
 }
 
+
+bool ImageListStore::is_property_interesting(fwk::PropertyIndex idx)
+{
+    return (idx == eng::NpXmpRatingProp) || (idx == eng::NpXmpLabelProp)
+        || (idx == eng::NpTiffOrientationProp) || (idx == eng::NpNiepceFlagProp);
+}
+
 }
 
 
diff --git a/src/niepce/ui/imageliststore.hpp b/src/niepce/ui/imageliststore.hpp
index 8220a31..34a84eb 100644
--- a/src/niepce/ui/imageliststore.hpp
+++ b/src/niepce/ui/imageliststore.hpp
@@ -75,6 +75,7 @@ protected:
     ImageListStore(const Columns& columns);
 private:
     libraryclient::LibraryClient::Ptr getLibraryClient();
+    static bool is_property_interesting(fwk::PropertyIndex idx);
 
     const Columns           & m_columns;
     std::map<eng::library_id_t, Gtk::TreeIter> m_idmap;



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