[niepce] Implement a generic properties system for editing. Move away from XMP. Implement the infrastructure
- From: Hubert FiguiÃre <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce] Implement a generic properties system for editing. Move away from XMP. Implement the infrastructure
- Date: Sat, 12 Nov 2011 06:17:46 +0000 (UTC)
commit 89952409eef1cfa3fcb14a628fb73b0d9afce51d
Author: Hub Figuiere <hub figuiere net>
Date: Fri Nov 11 15:19:30 2011 -0800
Implement a generic properties system for editing.
Move away from XMP.
Implement the infrastructure for editing metadata in the UI.
src/engine/db/Makefile.am | 5 +-
src/engine/db/metadata.hpp | 39 ++++++-
src/engine/db/properties-def.hpp | 53 +++++++++
src/engine/db/properties.cpp | 47 ++++++++
src/engine/db/properties.hpp | 61 ++++++++++
src/engine/db/xmpproperties.cpp | 150 ++++++++++++++++++++++++
src/engine/db/xmpproperties.hpp | 59 +++++++++
src/fwk/Makefile.am | 1 +
src/fwk/base/propertybag.cpp | 68 +++++++++++
src/fwk/base/propertybag.hpp | 76 ++++++++++++
src/fwk/toolkit/metadatawidget.cpp | 130 +++++++++++++--------
src/fwk/toolkit/metadatawidget.hpp | 50 ++++++--
src/fwk/toolkit/widgets/ratinglabel.cpp | 4 +-
src/fwk/toolkit/widgets/ratinglabel.hpp | 2 +-
src/fwk/utils/exempi.hpp | 24 ----
src/niepce/ui/gridviewmodule.cpp | 12 ++
src/niepce/ui/gridviewmodule.hpp | 2 +
src/niepce/ui/metadatapanecontroller.cpp | 188 ++++++++++++++++++------------
src/niepce/ui/metadatapanecontroller.hpp | 14 ++-
src/niepce/ui/selectioncontroller.cpp | 24 ++++
src/niepce/ui/selectioncontroller.hpp | 3 +
21 files changed, 839 insertions(+), 173 deletions(-)
---
diff --git a/src/engine/db/Makefile.am b/src/engine/db/Makefile.am
index 084d1fb..3c5d776 100644
--- a/src/engine/db/Makefile.am
+++ b/src/engine/db/Makefile.am
@@ -36,4 +36,7 @@ libniepcedb_a_SOURCES = library.hpp library.cpp \
storage.hpp storage.cpp \
fsfile.hpp fsfile.cpp \
filebundle.hpp filebundle.cpp \
- metadata.hpp
+ metadata.hpp \
+ properties.hpp properties.cpp \
+ xmpproperties.hpp xmpproperties.cpp \
+ properties-def.hpp
diff --git a/src/engine/db/metadata.hpp b/src/engine/db/metadata.hpp
index 51b403e..08e4598 100644
--- a/src/engine/db/metadata.hpp
+++ b/src/engine/db/metadata.hpp
@@ -1,7 +1,7 @@
/*
* niepce - eng/db/metadata.hpp
*
- * Copyright (C) 2008 Hubert Figuiere
+ * Copyright (C) 2008,2011 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,22 +28,53 @@ enum {
META_NS_XMPCORE = 0,
META_NS_TIFF,
META_NS_EXIF,
+ META_NS_IPTC,
META_NS_NIEPCE
};
/** Metadata for xmpcore. Combine with %META_NS_XMPCORE */
enum {
- META_XMPCORE_RATING = 0,
- META_XMPCORE_LABEL = 1,
+ _META_XMPCORE_NONE_ = 0,
+ META_XMPCORE_RATING = 1, // NS_XAP, "Rating"
+ META_XMPCORE_LABEL, // NS_XAP, "Label"
_META_XMPCORE_LAST_
};
/** Metadata for tiff. Combine with %META_NS_TIFF */
enum {
- META_TIFF_ORIENTATION = 0
+ META_TIFF_ORIENTATION = 0,
+ META_TIFF_MAKE, // NS_TIFF, "Make"
+ META_TIFF_MODEL, // NS_TIFF, "Model"
+
+ _META_TIFF_LAST_
+};
+
+enum {
+ META_EXIF_AUX_LENS = 0, // NS_EXIF_AUX, "Lens"
+ META_EXIF_EXPOSUREPROGRAM, // NS_EXIF, "ExposureProgram"
+ META_EXIF_EXPOSURETIME, // NS_EXIF, "ExposureTime"
+ META_EXIF_FNUMBER, // NS_EXIF, "FNumber"
+ META_EXIF_ISOSPEEDRATINGS, // NS_EXIF, "ISOSpeedRatings"
+ META_EXIF_EXPOSUREBIAS, // NS_EXIF, "ExposureBiasValue"
+ META_EXIF_FLASHFIRED, // NS_EXIF, "Flash/exif:Fired"
+ META_EXIF_AUX_FLASHCOMPENSATION, // NS_EXIF_AUX, "FlashCompensation"
+ META_EXIF_WB, // NS_EXIF, "WhiteBalance"
+ META_EXIF_DATETIMEORIGINAL, // NS_EXIF, "DateTimeOriginal"
+ META_EXIF_FOCALLENGTH, // NS_EXIF, "FocalLength"
+
+ _META_EXIF_LAST_
+};
+
+enum {
+ META_IPTC_HEADLINE = 0, // NS_PHOTOSHOP, "Headline"
+ META_IPTC_DESCRIPTION = 1, // NS_DC, "description"
+ META_IPTC_KEYWORDS = 2, // NS_DC, "subject"
+
+ _META_IPTC_LAST_
};
+/** Metadata for Niepce. Combine with %META_NS_NIEPCE */
enum {
META_NIEPCE_FLAG = 0
};
diff --git a/src/engine/db/properties-def.hpp b/src/engine/db/properties-def.hpp
new file mode 100644
index 0000000..004b91e
--- /dev/null
+++ b/src/engine/db/properties-def.hpp
@@ -0,0 +1,53 @@
+/*
+ * niepce - eng/db/proeprties-def.hpp
+ *
+ * Copyright (C) 2011 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 DEFINE_PROPERTY
+#error DEFINE_PROPERTY must be defined
+#endif
+
+// format is
+// - const
+// - the value of the id
+// - XMP NS - NULL if none
+// - XMP property - NULL if none
+
+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(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(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(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(NpNiepceFlagProp, MAKE_METADATA_IDX(META_NS_NIEPCE, META_NIEPCE_FLAG), xmp::NIEPCE_XMP_NAMESPACE, "Flag")
diff --git a/src/engine/db/properties.cpp b/src/engine/db/properties.cpp
new file mode 100644
index 0000000..ccdc4d0
--- /dev/null
+++ b/src/engine/db/properties.cpp
@@ -0,0 +1,47 @@
+/*
+ * niepce - eng/db/properties.cpp
+ *
+ * Copyright (C) 2011 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 "properties.hpp"
+
+
+namespace eng {
+
+#define DEFINE_PROPERTY(a,b,c,d) \
+ { a, #a },
+
+const property_desc_t properties_names[] = {
+
+ #include "engine/db/properties-def.hpp"
+
+ { 0, NULL }
+};
+
+#undef DEFINE_PROPERTY
+
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0))
+ indent-tabs-mode:nil
+ fill-column:80
+ End:
+*/
diff --git a/src/engine/db/properties.hpp b/src/engine/db/properties.hpp
new file mode 100644
index 0000000..3df1b21
--- /dev/null
+++ b/src/engine/db/properties.hpp
@@ -0,0 +1,61 @@
+/*
+ * niepce - eng/db/properties.hpp
+ *
+ * Copyright (C) 2011 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 __ENG_PROPERTIES_HPP__
+#define __ENG_PROPERTIES_HPP__
+
+#include "fwk/base/propertybag.hpp"
+#include "engine/db/metadata.hpp"
+
+namespace eng {
+
+ // prefix Np is for Niepce Property
+
+#define DEFINE_PROPERTY(a,b,c,d) \
+ a = b,
+
+enum {
+
+ #include "engine/db/properties-def.hpp"
+
+ _NpLastProp
+};
+
+#undef DEFINE_PROPERTY
+
+struct property_desc_t {
+ fwk::PropertyIndex prop;
+ const char * name;
+};
+
+extern const property_desc_t properties_names[];
+
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0))
+ indent-tabs-mode:nil
+ fill-column:80
+ End:
+*/
+#endif
diff --git a/src/engine/db/xmpproperties.cpp b/src/engine/db/xmpproperties.cpp
new file mode 100644
index 0000000..f08eb55
--- /dev/null
+++ b/src/engine/db/xmpproperties.cpp
@@ -0,0 +1,150 @@
+/*
+ * niepce - eng/db/xmpproperties.hpp
+ *
+ * Copyright (C) 2011 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 <exempi/xmpconsts.h>
+
+#include "fwk/base/debug.hpp"
+#include "fwk/base/propertybag.hpp"
+#include "fwk/utils/stringutils.hpp"
+#include "fwk/utils/exempi.hpp"
+
+#include "properties.hpp"
+#include "xmpproperties.hpp"
+
+
+namespace eng {
+
+const PropsToXmpMap & props_to_xmp_map()
+{
+ static PropsToXmpMap s_props_map;
+ if(s_props_map.empty()) {
+
+#define DEFINE_PROPERTY(a,b,c,d) \
+ s_props_map.insert(std::make_pair(b, std::make_pair(c,d)));
+#include "engine/db/properties-def.hpp"
+#undef DEFINE_PROPERTY
+
+ }
+ return s_props_map;
+}
+
+bool get_prop_from_xmp(const fwk::XmpMeta * meta, fwk::PropertyIndex p,
+ fwk::PropertyValue & value)
+{
+ const PropsToXmpMap & propmap = props_to_xmp_map();
+ PropsToXmpMap::const_iterator iter = propmap.find(p);
+ if(iter == propmap.end()) {
+ // not found
+ return false;
+ }
+ if(iter->second.first == NULL || iter->second.second == NULL) {
+ // no XMP equivalent
+ return false;
+ }
+ xmp::ScopedPtr<XmpStringPtr> xmp_value(xmp_string_new());
+ if(xmp_get_property(meta->xmp(), iter->second.first,
+ iter->second.second, xmp_value, NULL)) {
+ const char * v = NULL;
+ v = xmp_string_cstr(xmp_value);
+ if(v) {
+ value = fwk::PropertyValue(v);
+ return true;
+ }
+ }
+ // not found in XMP
+ return false;
+}
+
+void convert_xmp_to_properties(const fwk::XmpMeta * meta, const fwk::PropertySet & propset,
+ fwk::PropertyBag & properties)
+{
+ if(meta == NULL) {
+ ERR_OUT("invalid passing NULL meta");
+ return;
+ }
+ fwk::PropertySet::const_iterator iter;
+ xmp::ScopedPtr<XmpStringPtr> value(xmp_string_new());
+ fwk::PropertyValue propval;
+ for(iter = propset.begin(); iter != propset.end(); ++iter) {
+ switch(*iter) {
+ case NpXmpRatingProp:
+ properties.set_value_for_property(NpXmpRatingProp,
+ fwk::PropertyValue(meta->rating()));
+ break;
+ case NpXmpLabelProp:
+ properties.set_value_for_property(NpXmpLabelProp,
+ fwk::PropertyValue(meta->label()));
+ break;
+ case NpTiffOrientationProp:
+ properties.set_value_for_property(NpTiffOrientationProp,
+ fwk::PropertyValue(meta->orientation()));
+ break;
+ case NpIptcKeywordsProp:
+ {
+ xmp::ScopedPtr<XmpIteratorPtr>
+ iter(xmp_iterator_new(meta->xmp(), NS_DC,
+ "subject", 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, ", ");
+ properties.set_value_for_property(NpIptcKeywordsProp,
+ fwk::PropertyValue(v));
+ break;
+ }
+ default:
+ if(get_prop_from_xmp(meta, *iter, propval)) {
+ properties.set_value_for_property(*iter, propval);
+ }
+ else {
+ DBG_OUT("unknown prop %u", *iter);
+ }
+ break;
+ }
+ }
+}
+
+#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
+
+}
+
+/*
+ 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/xmpproperties.hpp b/src/engine/db/xmpproperties.hpp
new file mode 100644
index 0000000..4929f93
--- /dev/null
+++ b/src/engine/db/xmpproperties.hpp
@@ -0,0 +1,59 @@
+/*
+ * niepce - eng/db/xmpproperties.hpp
+ *
+ * Copyright (C) 2011 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 __ENG_XMPPROPERTIES_HPP__
+#define __ENG_XMPPROPERTIES_HPP__
+
+#include <map>
+#include "fwk/base/propertybag.hpp"
+
+namespace fwk {
+class XmpMeta;
+}
+
+namespace eng {
+
+typedef std::map<fwk::PropertyIndex, std::pair<const char*, const char *> > PropsToXmpMap;
+
+/** get the mapping of properties to XMP */
+const PropsToXmpMap & props_to_xmp_map();
+
+/** convert XMP to a set of properties
+ * @param meta the XmpMeta source
+ * @param propset the property set requested
+ * @param props the output properties
+ */
+void convert_xmp_to_properties(const fwk::XmpMeta * meta,
+ const fwk::PropertySet & propset, fwk::PropertyBag & props);
+
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+#endif
diff --git a/src/fwk/Makefile.am b/src/fwk/Makefile.am
index 615b380..1013211 100644
--- a/src/fwk/Makefile.am
+++ b/src/fwk/Makefile.am
@@ -29,4 +29,5 @@ libfwk_a_SOURCES = base/color.hpp base/color.cpp \
base/geometry.hpp base/geometry.cpp \
base/singleton.hpp \
base/map.hpp \
+ base/propertybag.hpp base/propertybag.cpp \
$(NULL)
diff --git a/src/fwk/base/propertybag.cpp b/src/fwk/base/propertybag.cpp
new file mode 100644
index 0000000..2d6adb6
--- /dev/null
+++ b/src/fwk/base/propertybag.cpp
@@ -0,0 +1,68 @@
+/*
+ * niepce - fwk/base/propertybag.cpp
+ *
+ * Copyright (C) 2011 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 "propertybag.hpp"
+
+namespace fwk {
+
+bool PropertyBag::set_value_for_property(PropertyIndex idx, const PropertyValue & value)
+{
+ bool removed = (m_bag.erase(idx) == 1);
+ m_bag.insert(std::make_pair(idx, value));
+ return removed;
+}
+
+/** return true if a property is found */
+bool PropertyBag::get_value_for_property(PropertyIndex idx, PropertyValue & value) const
+{
+ _Map::const_iterator iter = m_bag.find(idx);
+ if(iter == m_bag.end()) {
+ return false;
+ }
+ value = iter->second;
+ return true;
+}
+
+
+bool PropertyBag::has_value_for_property(PropertyIndex idx) const
+{
+ return m_bag.find(idx) != m_bag.end();
+}
+
+
+bool PropertyBag::remove_value_for_property(PropertyIndex idx)
+{
+ _Map::size_type sz = m_bag.erase(idx);
+ return sz == 1;
+}
+
+
+
+}
+/*
+ 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/fwk/base/propertybag.hpp b/src/fwk/base/propertybag.hpp
new file mode 100644
index 0000000..4200ac5
--- /dev/null
+++ b/src/fwk/base/propertybag.hpp
@@ -0,0 +1,76 @@
+/*
+ * niepce - fwk/base/propertybag.cpp
+ *
+ * Copyright (C) 2011 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 __FWK_PROPERTYBAG_HPP_
+#define __FWK_PROPERTYBAG_HPP_
+
+#include <map>
+#include <set>
+#include <tr1/memory>
+#include <boost/variant.hpp>
+
+namespace fwk {
+
+typedef uint32_t PropertyIndex;
+typedef boost::variant<int, std::string> PropertyValue;
+
+typedef std::set<PropertyIndex> PropertySet;
+
+/** a property bag
+ * It is important that the values for PropertyIndex be properly name spaced
+ * by the caller.
+ */
+class PropertyBag
+{
+public:
+ typedef std::tr1::shared_ptr<PropertyBag> Ptr;
+
+ bool empty() const
+ {
+ return m_bag.empty();
+ }
+
+ /** return true if a property was removed prior to insertion */
+ bool set_value_for_property(PropertyIndex idx, const PropertyValue & value);
+ /** return true if a property is found */
+ bool get_value_for_property(PropertyIndex idx, PropertyValue & value) const;
+ /** return true if property exist */
+ bool has_value_for_property(PropertyIndex idx) const;
+ /** return true if the property was removed */
+ bool remove_value_for_property(PropertyIndex idx);
+private:
+ typedef std::map<PropertyIndex, PropertyValue> _Map;
+ _Map m_bag;
+};
+
+
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+#endif
diff --git a/src/fwk/toolkit/metadatawidget.cpp b/src/fwk/toolkit/metadatawidget.cpp
index 4f92484..35e0c61 100644
--- a/src/fwk/toolkit/metadatawidget.cpp
+++ b/src/fwk/toolkit/metadatawidget.cpp
@@ -24,6 +24,7 @@
#include <boost/bind.hpp>
#include <glibmm/i18n.h>
#include <gtkmm/label.h>
+#include <gtkmm/entry.h>
#include "fwk/base/debug.hpp"
#include "fwk/base/fractions.hpp"
@@ -31,6 +32,9 @@
#include "fwk/utils/stringutils.hpp"
#include "fwk/toolkit/widgets/ratinglabel.hpp"
+// remove
+#include "engine/db/properties.hpp"
+
#include "metadatawidget.hpp"
@@ -45,20 +49,25 @@ MetaDataWidget::MetaDataWidget(const Glib::ustring & title)
add(m_table);
}
-void MetaDataWidget::set_data_format(const xmp::MetaDataSectionFormat * fmt)
+void MetaDataWidget::set_data_format(const MetaDataSectionFormat * fmt)
{
m_fmt = fmt;
}
namespace {
static
-void clear_widget(std::pair<const std::string, Gtk::Widget *> & p)
+void clear_widget(std::pair<const PropertyIndex, Gtk::Widget *> & p)
{
Gtk::Label * l = dynamic_cast<Gtk::Label*>(p.second);
if(l) {
l->set_text("");
return;
}
+ Gtk::Entry * e = dynamic_cast<Gtk::Entry*>(p.second);
+ if(e) {
+ e->set_text("");
+ return;
+ }
fwk::RatingLabel * rl = dynamic_cast<fwk::RatingLabel*>(p.second);
if(rl) {
rl->set_rating(0);
@@ -67,14 +76,14 @@ void clear_widget(std::pair<const std::string, Gtk::Widget *> & p)
}
}
-void MetaDataWidget::set_data_source(const fwk::XmpMeta * xmp)
+void MetaDataWidget::set_data_source(const fwk::PropertyBag & properties)
{
DBG_OUT("set data source");
if(!m_data_map.empty()) {
std::for_each(m_data_map.begin(), m_data_map.end(),
boost::bind(&clear_widget, _1));
}
- if(!xmp) {
+ if(properties.empty()) {
return;
}
if(!m_fmt) {
@@ -82,71 +91,71 @@ void MetaDataWidget::set_data_source(const fwk::XmpMeta * xmp)
return;
}
- const xmp::MetaDataFormat * current = m_fmt->formats;
+ const MetaDataFormat * current = m_fmt->formats;
xmp::ScopedPtr<XmpStringPtr> value(xmp_string_new());
while(current && current->label) {
- std::string id(current->property);
- id += "-";
- id += current->ns;
- if(current->type == xmp::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(id, current->label, v.c_str(), current->type);
+ PropertyValue v;
+ if(properties.get_value_for_property(current->id, v)) {
+ add_data(current, v);
}
else {
- const char * v = "";
- if(xmp_get_property(xmp->xmp(), current->ns,
- current->property, value, NULL)) {
- v = xmp_string_cstr(value);
- }
- else {
- DBG_OUT("get_property failed id = %s, ns = %s, prop = %s,"
- "label = %s",
- id.c_str(), current->ns, current->property,
- current->label);
- }
- add_data(id, current->label, v, current->type);
+ DBG_OUT("get_property failed id = %d, label = %s",
+ current->id, current->label);
}
current++;
}
}
-void MetaDataWidget::add_data(const std::string & id,
- const std::string & label,
- const char * value,
- xmp::MetaDataType type)
+void MetaDataWidget::add_data(const MetaDataFormat * current,
+ const PropertyValue & value)
{
Gtk::Widget *w = NULL;
int n_row;
- std::map<std::string, Gtk::Widget *>::iterator iter
+ std::map<PropertyIndex, Gtk::Widget *>::iterator iter
= m_data_map.end();
if(m_data_map.empty()) {
n_row = 0;
}
else {
- iter = m_data_map.find(id);
+ iter = m_data_map.find(current->id);
n_row = m_table.property_n_rows();
}
if(iter == m_data_map.end()) {
Gtk::Label *labelw = Gtk::manage(new Gtk::Label(
Glib::ustring("<b>")
- + label + "</b>"));
+ + current->label + "</b>"));
labelw->set_alignment(0.0f, 0.5f);
labelw->set_use_markup(true);
- if(type == xmp::META_DT_STAR_RATING) {
- w = Gtk::manage(new fwk::RatingLabel());
+ if(current->type == META_DT_STAR_RATING) {
+ fwk::RatingLabel * r = Gtk::manage(new fwk::RatingLabel(0, !current->readonly));
+ if(!current->readonly) {
+ r->signal_changed.connect(
+ sigc::bind(
+ sigc::mem_fun(*this,
+ &MetaDataWidget::on_int_changed),
+ current->id));
+ }
+ w = r;
}
else {
- w = Gtk::manage(new Gtk::Label());
- static_cast<Gtk::Label*>(w)->set_alignment(0.0f, 0.5f);
+ // TODO make it editable
+
+ if(current->readonly) {
+ Gtk::Label * l = Gtk::manage(new Gtk::Label());
+ l->set_alignment(0.0f, 0.5f);
+ w = l;
+ }
+ else {
+ Gtk::Entry * e = Gtk::manage(new Gtk::Entry());
+ e->signal_changed().connect(
+ sigc::bind(
+ sigc::mem_fun(*this,
+ &MetaDataWidget::on_str_changed),
+ e, current->id));
+ w = e;
+ }
}
m_table.resize(n_row + 1, 2);
@@ -154,42 +163,61 @@ void MetaDataWidget::add_data(const std::string & id,
Gtk::FILL, Gtk::SHRINK, 4, 0);
m_table.attach(*w, 1, 2, n_row, n_row+1,
Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 4, 0);
- m_data_map.insert(std::make_pair(id, w));
+ m_data_map.insert(std::make_pair(current->id, w));
}
else {
w = static_cast<Gtk::Label*>(iter->second);
}
- switch(type) {
- case xmp::META_DT_FRAC:
+ switch(current->type) {
+ case META_DT_FRAC:
{
try {
- double decimal = fwk::fraction_to_decimal(value);
+ double decimal = fwk::fraction_to_decimal(boost::get<std::string>(value));
std::string frac = boost::lexical_cast<std::string>(decimal);
static_cast<Gtk::Label*>(w)->set_text(frac);
}
catch(...) {
- DBG_OUT("conversion of '%s' to frac failed", value);
+ DBG_OUT("conversion of '%u' to frac failed", current->id);
}
break;
}
- case xmp::META_DT_STAR_RATING:
+ case META_DT_STAR_RATING:
{
try {
- int rating = boost::lexical_cast<int>(value);
+ int rating = boost::get<int>(value);
static_cast<fwk::RatingLabel*>(w)->set_rating(rating);
}
catch(...) {
- DBG_OUT("conversion of '%s' to int failed", value);
+ DBG_OUT("conversion of '%u' to int failed", current->id);
}
break;
}
- default:
- static_cast<Gtk::Label*>(w)->set_text(value);
+ default:
+ if(current->readonly) {
+ static_cast<Gtk::Label*>(w)->set_text(boost::get<std::string>(value));
+ }
+ else {
+ static_cast<Gtk::Entry*>(w)->set_text(boost::get<std::string>(value));
+ }
break;
}
m_table.show_all();
}
+void MetaDataWidget::on_str_changed(Gtk::Entry *e, fwk::PropertyIndex prop)
+{
+ fwk::PropertyBag props;
+ props.set_value_for_property(prop, fwk::PropertyValue(e->get_text()));
+ signal_metadata_changed.emit(props);
+}
+
+void MetaDataWidget::on_int_changed(int value, fwk::PropertyIndex prop)
+{
+ fwk::PropertyBag props;
+ props.set_value_for_property(prop, fwk::PropertyValue(value));
+ signal_metadata_changed.emit(props);
+}
+
}
/*
diff --git a/src/fwk/toolkit/metadatawidget.hpp b/src/fwk/toolkit/metadatawidget.hpp
index cd163d6..f7997cd 100644
--- a/src/fwk/toolkit/metadatawidget.hpp
+++ b/src/fwk/toolkit/metadatawidget.hpp
@@ -26,32 +26,60 @@
#include <gtkmm/table.h>
+#include "fwk/base/propertybag.hpp"
#include "fwk/toolkit/widgets/toolboxitemwidget.hpp"
namespace xmp {
- struct MetaDataSectionFormat;
+struct MetaDataSectionFormat;
+struct MetaDataFormat;
}
namespace fwk {
-class XmpMeta;
+enum MetaDataType {
+ META_DT_NONE = 0,
+ META_DT_STRING,
+ META_DT_STRING_ARRAY,
+ META_DT_TEXT,
+ META_DT_DATE,
+ META_DT_FRAC,
+ META_DT_STAR_RATING
+};
+struct MetaDataFormat {
+ const char * label;
+ uint32_t id;
+ MetaDataType type;
+ bool readonly;
+};
+
+struct MetaDataSectionFormat {
+ const char * section;
+ const MetaDataFormat * formats;
+};
+
+
+class XmpMeta;
class MetaDataWidget
: public fwk::ToolboxItemWidget
{
public:
- MetaDataWidget(const Glib::ustring & title);
-
- void add_data(const std::string & id, const std::string & label,
- const char * value, xmp::MetaDataType type);
- void set_data_format(const xmp::MetaDataSectionFormat * fmt);
- void set_data_source(const fwk::XmpMeta * xmp);
+ MetaDataWidget(const Glib::ustring & title);
+
+ void add_data(const MetaDataFormat * current,
+ const PropertyValue & value);
+ void set_data_format(const MetaDataSectionFormat * fmt);
+ void set_data_source(const fwk::PropertyBag & properties);
+
+ sigc::signal<void, const fwk::PropertyBag &> signal_metadata_changed;
protected:
+ void on_str_changed(Gtk::Entry *, fwk::PropertyIndex prop);
+ void on_int_changed(int, fwk::PropertyIndex prop);
private:
- Gtk::Table m_table;
- std::map<std::string, Gtk::Widget *> m_data_map;
- const xmp::MetaDataSectionFormat * m_fmt;
+ Gtk::Table m_table;
+ std::map<const PropertyIndex, Gtk::Widget *> m_data_map;
+ const MetaDataSectionFormat * m_fmt;
};
}
diff --git a/src/fwk/toolkit/widgets/ratinglabel.cpp b/src/fwk/toolkit/widgets/ratinglabel.cpp
index c4489c7..252277c 100644
--- a/src/fwk/toolkit/widgets/ratinglabel.cpp
+++ b/src/fwk/toolkit/widgets/ratinglabel.cpp
@@ -93,10 +93,10 @@ int RatingLabel::rating_value_from_hit_x(double x)
return round(x / width);
}
-RatingLabel::RatingLabel(int rating)
+ RatingLabel::RatingLabel(int rating, bool editable)
: Gtk::DrawingArea()
, m_rating(rating)
- , m_is_editable(false)
+ , m_is_editable(editable)
{
DBG_OUT("ctor");
}
diff --git a/src/fwk/toolkit/widgets/ratinglabel.hpp b/src/fwk/toolkit/widgets/ratinglabel.hpp
index 0f7e628..51f8445 100644
--- a/src/fwk/toolkit/widgets/ratinglabel.hpp
+++ b/src/fwk/toolkit/widgets/ratinglabel.hpp
@@ -29,7 +29,7 @@ class RatingLabel
: public Gtk::DrawingArea
{
public:
- RatingLabel(int rating = 0);
+ RatingLabel(int rating = 0, bool editable = true);
virtual ~RatingLabel();
bool is_editable() const
diff --git a/src/fwk/utils/exempi.hpp b/src/fwk/utils/exempi.hpp
index d4de3c8..df63f4c 100644
--- a/src/fwk/utils/exempi.hpp
+++ b/src/fwk/utils/exempi.hpp
@@ -75,30 +75,6 @@ private:
T _p;
};
-
-enum MetaDataType {
- META_DT_NONE = 0,
- META_DT_STRING,
- META_DT_STRING_ARRAY,
- META_DT_DATE,
- META_DT_FRAC,
- META_DT_STAR_RATING
-};
-
-
-struct MetaDataFormat {
- const char * label;
- const char * ns;
- const char * property;
- MetaDataType type;
- bool readonly;
-};
-
-struct MetaDataSectionFormat {
- const char * section;
- const MetaDataFormat * formats;
-};
-
extern const char * NIEPCE_XMP_NAMESPACE;
extern const char * NIEPCE_XMP_NS_PREFIX;
extern const char * UFRAW_INTEROP_NAMESPACE;
diff --git a/src/niepce/ui/gridviewmodule.cpp b/src/niepce/ui/gridviewmodule.cpp
index d473a77..ae28307 100644
--- a/src/niepce/ui/gridviewmodule.cpp
+++ b/src/niepce/ui/gridviewmodule.cpp
@@ -22,6 +22,8 @@
#include <gtkmm/treestore.h>
#include <gtkmm/treeselection.h>
+#include <exempi/xmpconsts.h>
+
#include "fwk/base/debug.hpp"
#include "fwk/toolkit/application.hpp"
#include "fwk/toolkit/configdatabinder.hpp"
@@ -111,6 +113,8 @@ Gtk::Widget * GridViewModule::buildWidget(const Glib::RefPtr<Gtk::UIManager> & m
m_lib_splitview.pack1(m_scrollview);
m_dock = new fwk::Dock();
m_metapanecontroller = MetaDataPaneController::Ptr(new MetaDataPaneController);
+ m_metapanecontroller->signal_metadata_changed.connect(
+ sigc::mem_fun(*this, &GridViewModule::on_metadata_changed));
add(m_metapanecontroller);
m_lib_splitview.pack2(*m_dock);
m_dock->vbox().pack_start(*m_metapanecontroller->buildWidget(manager));
@@ -171,6 +175,14 @@ void GridViewModule::select_image(eng::library_id_t id)
}
}
+
+void GridViewModule::on_metadata_changed(const fwk::PropertyBag & props)
+{
+ // TODO this MUST be more generic
+ DBG_OUT("on_metadata_changed()");
+ m_shell.get_selection_controller()->set_properties(props);
+}
+
void GridViewModule::on_rating_changed(int /*id*/, int rating)
{
m_shell.get_selection_controller()->set_rating(rating);
diff --git a/src/niepce/ui/gridviewmodule.hpp b/src/niepce/ui/gridviewmodule.hpp
index 665c57b..b95e5c7 100644
--- a/src/niepce/ui/gridviewmodule.hpp
+++ b/src/niepce/ui/gridviewmodule.hpp
@@ -28,6 +28,7 @@
#include <gtkmm/liststore.h>
#include <gtkmm/treestore.h>
+#include "fwk/base/propertybag.hpp"
#include "engine/db/library.hpp"
#include "niepce/ui/ilibrarymodule.hpp"
#include "niepce/ui/imoduleshell.hpp"
@@ -74,6 +75,7 @@ protected:
private:
+ void on_metadata_changed(const fwk::PropertyBag &);
void on_rating_changed(int id, int rating);
const IModuleShell & m_shell;
diff --git a/src/niepce/ui/metadatapanecontroller.cpp b/src/niepce/ui/metadatapanecontroller.cpp
index f4bef64..b721fa5 100644
--- a/src/niepce/ui/metadatapanecontroller.cpp
+++ b/src/niepce/ui/metadatapanecontroller.cpp
@@ -24,109 +24,149 @@
#include <gtkmm/entry.h>
#include <gtkmm/stock.h>
-#include <exempi/xmpconsts.h>
-
#include "fwk/base/debug.hpp"
-#include "fwk/utils/exempi.hpp"
#include "fwk/toolkit/metadatawidget.hpp"
+#include "engine/db/properties.hpp"
+#include "engine/db/xmpproperties.hpp"
#include "metadatapanecontroller.hpp"
-using namespace xmp;
-
namespace ui {
-
- const MetaDataSectionFormat *
- MetaDataPaneController::get_format()
- {
- static const MetaDataFormat s_camerainfo_format[] = {
- { _("Make:"), NS_TIFF, "Make", META_DT_STRING, true },
- { _("Model:"), NS_TIFF, "Model", META_DT_STRING, true },
- { _("Lens:"), NS_EXIF_AUX, "Lens", META_DT_STRING, true },
- { NULL, NULL, NULL, META_DT_NONE, true }
+const fwk::MetaDataSectionFormat *
+MetaDataPaneController::get_format()
+{
+ static const fwk::MetaDataFormat s_camerainfo_format[] = {
+ { _("Make:"), eng::NpTiffMakeProp, fwk::META_DT_STRING, true },
+ { _("Model:"), eng::NpTiffModelProp, fwk::META_DT_STRING, true },
+ { _("Lens:"), eng::NpExifAuxLensProp, fwk::META_DT_STRING, true },
+ { NULL, 0, fwk::META_DT_NONE, true }
};
- static const MetaDataFormat s_shootinginfo_format[] = {
- { _("Exposure Program:"), NS_EXIF, "ExposureProgram", META_DT_STRING, true },
- { _("Speed:"), NS_EXIF, "ExposureTime", META_DT_STRING, true },
- { _("Aperture:"), NS_EXIF, "FNumber", META_DT_FRAC, true },
- { _("ISO:"), NS_EXIF, "ISOSpeedRatings", META_DT_STRING_ARRAY, true },
- { _("Exposure Bias:"), NS_EXIF, "ExposureBiasValue", META_DT_FRAC, true },
- // this one is fishy as it hardcode the prefix.
- { _("Flash:"), NS_EXIF, "Flash/exif:Fired", META_DT_STRING, true },
- { _("Flash compensation:"), NS_EXIF_AUX, "FlashCompensation", META_DT_STRING, true },
- { _("Focal length:"), NS_EXIF, "FocalLength", META_DT_FRAC, true },
- { _("White balance:"), NS_EXIF, "WhiteBalance", META_DT_STRING, true },
- { _("Date:"), NS_EXIF, "DateTimeOriginal", META_DT_DATE, false },
- { NULL, NULL, NULL, META_DT_NONE, true }
+ static const fwk::MetaDataFormat s_shootinginfo_format[] = {
+ { _("Exposure Program:"), eng::NpExifExposureProgramProp, fwk::META_DT_STRING, true },
+ { _("Speed:"), eng::NpExifExposureTimeProp, fwk::META_DT_STRING, true },
+ { _("Aperture:"), eng::NpExifFNumberPropProp, fwk::META_DT_FRAC, true },
+ { _("ISO:"), eng::NpExifIsoSpeedRatingsProp, fwk::META_DT_STRING_ARRAY, true },
+ { _("Exposure Bias:"), eng::NpExifExposureBiasProp, fwk::META_DT_FRAC, true },
+ { _("Flash:"), eng::NpExifFlashFiredProp, fwk::META_DT_STRING, true },
+ { _("Flash compensation:"), eng::NpExifAuxFlashCompensationProp, fwk::META_DT_STRING, true },
+ { _("Focal length:"), eng::NpExifFocalLengthProp, fwk::META_DT_FRAC, true },
+ { _("White balance:"), eng::NpExifWbProp, fwk::META_DT_STRING, true },
+ { _("Date:"), eng::NpExifDateTimeOriginalProp, fwk::META_DT_DATE, false },
+ { NULL, 0, fwk::META_DT_NONE, true }
};
- static const MetaDataFormat s_iptc_format[] = {
- { _("Rating:"), NS_XAP, "Rating", META_DT_STAR_RATING, false },
- { _("Label:"), NS_XAP, "Label", META_DT_STRING, false },
- { _("Keywords:"), NS_DC, "subject", META_DT_STRING_ARRAY, false },
- { NULL, NULL, NULL, META_DT_NONE, true }
+ static const fwk::MetaDataFormat s_iptc_format[] = {
+ { _("Headline:"), eng::NpIptcHeadlineProp, fwk::META_DT_STRING, false },
+ { _("Caption:"), eng::NpIptcDescriptionProp, fwk::META_DT_TEXT, false },
+ { _("Rating:"), eng::NpXmpRatingProp, fwk::META_DT_STAR_RATING, false },
+ { _("Label:"), eng::NpXmpLabelProp, fwk::META_DT_STRING, false },
+ { _("Keywords:"), eng::NpIptcKeywordsProp, fwk::META_DT_STRING_ARRAY, false },
+ { NULL, 0, fwk::META_DT_NONE, true }
};
- static const MetaDataSectionFormat s_format[] = {
- { _("Camera Information"),
- s_camerainfo_format
- },
- { _("Shooting Information"),
- s_shootinginfo_format
- },
- { _("IPTC"),
- s_iptc_format
- },
- { _("Rights"),
- NULL
- },
- { NULL, NULL
- }
+ static const fwk::MetaDataSectionFormat s_format[] = {
+ { _("Camera Information"),
+ s_camerainfo_format
+ },
+ { _("Shooting Information"),
+ s_shootinginfo_format
+ },
+ { _("IPTC"),
+ s_iptc_format
+ },
+ { _("Rights"),
+ NULL
+ },
+ { NULL, NULL
+ }
};
return s_format;
- }
+}
+
+const fwk::PropertySet & MetaDataPaneController::get_property_set()
+{
+ static fwk::PropertySet propset;
+ if(propset.empty()) {
+ const fwk::MetaDataSectionFormat * formats = get_format();
+
+ const fwk::MetaDataSectionFormat * current = formats;
+ while(current->section) {
+ const fwk::MetaDataFormat * format = current->formats;
+ while(format && format->label) {
+ propset.insert(format->id);
+ format++;
+ }
+ current++;
+ }
+ }
+ return propset;
+}
+
- MetaDataPaneController::MetaDataPaneController()
+MetaDataPaneController::MetaDataPaneController()
: Dockable("Metadata", _("Image Properties"),
Gtk::Stock::PROPERTIES.id /*, DockItem::DOCKED_STATE*/),
m_fileid(0)
- {
- }
-
- MetaDataPaneController::~MetaDataPaneController()
- {
- }
-
- Gtk::Widget *
- MetaDataPaneController::buildWidget(const Glib::RefPtr<Gtk::UIManager> & )
- {
+{
+}
+
+MetaDataPaneController::~MetaDataPaneController()
+{
+}
+
+Gtk::Widget *
+MetaDataPaneController::buildWidget(const Glib::RefPtr<Gtk::UIManager> & )
+{
if(m_widget) {
- return m_widget;
+ return m_widget;
}
Gtk::VBox *vbox = build_vbox();
m_widget = vbox;
DBG_ASSERT(vbox, "dockable vbox not found");
-
- const MetaDataSectionFormat * formats = get_format();
- const MetaDataSectionFormat * current = formats;
+ const fwk::MetaDataSectionFormat * formats = get_format();
+
+ const fwk::MetaDataSectionFormat * current = formats;
while(current->section) {
- fwk::MetaDataWidget *w = Gtk::manage(new fwk::MetaDataWidget(current->section));
- vbox->pack_start(*w, Gtk::PACK_SHRINK, 0);
- w->set_data_format(current);
- m_widgets.push_back(w);
- current++;
+ fwk::MetaDataWidget *w = Gtk::manage(new fwk::MetaDataWidget(current->section));
+ vbox->pack_start(*w, Gtk::PACK_SHRINK, 0);
+ w->set_data_format(current);
+ m_widgets.push_back(w);
+ w->signal_metadata_changed.connect(
+ sigc::mem_fun(*this,
+ &MetaDataPaneController::on_metadata_changed));
+ current++;
}
return m_widget;
- }
-
+}
- void MetaDataPaneController::display(eng::library_id_t file_id, const fwk::XmpMeta * meta)
- {
+void MetaDataPaneController::on_metadata_changed(const fwk::PropertyBag & props)
+{
+ signal_metadata_changed.emit(props);
+}
+
+
+void MetaDataPaneController::display(eng::library_id_t file_id, const fwk::XmpMeta * meta)
+{
m_fileid = file_id;
DBG_OUT("displaying metadata");
+ fwk::PropertyBag properties;
+ if(meta) {
+ const fwk::PropertySet & propset = get_property_set();
+ eng::convert_xmp_to_properties(meta, propset, properties);
+ }
std::for_each(m_widgets.begin(), m_widgets.end(),
boost::bind(&fwk::MetaDataWidget::set_data_source,
- _1, meta));
- }
+ _1, properties));
+}
}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0))
+ indent-tabs-mode:nil
+ fill-column:80
+ End:
+*/
diff --git a/src/niepce/ui/metadatapanecontroller.hpp b/src/niepce/ui/metadatapanecontroller.hpp
index bdc539b..8f20291 100644
--- a/src/niepce/ui/metadatapanecontroller.hpp
+++ b/src/niepce/ui/metadatapanecontroller.hpp
@@ -26,12 +26,11 @@
#include "fwk/utils/exempi.hpp"
#include "fwk/toolkit/dockable.hpp"
-namespace xmp {
-struct MetaDataSectionFormat;
-}
namespace fwk {
+struct MetaDataSectionFormat;
class MetaDataWidget;
class Dock;
+class PropertyBag;
}
namespace ui {
@@ -47,12 +46,17 @@ public:
void display(eng::library_id_t file_id, const fwk::XmpMeta * meta);
eng::library_id_t displayed_file() const
{ return m_fileid; }
+
+ sigc::signal<void, const fwk::PropertyBag &> signal_metadata_changed;
private:
+ void on_metadata_changed(const fwk::PropertyBag &);
+
std::vector<fwk::MetaDataWidget *> m_widgets;
- static const xmp::MetaDataSectionFormat * get_format();
+ static const fwk::MetaDataSectionFormat * get_format();
+ static const fwk::PropertySet & get_property_set();
- eng::library_id_t m_fileid;
+ eng::library_id_t m_fileid;
};
}
diff --git a/src/niepce/ui/selectioncontroller.cpp b/src/niepce/ui/selectioncontroller.cpp
index 38fd780..0282194 100644
--- a/src/niepce/ui/selectioncontroller.cpp
+++ b/src/niepce/ui/selectioncontroller.cpp
@@ -243,13 +243,37 @@ void SelectionController::set_flag(int flag)
_set_metadata(_("Set Flag"), file,
MAKE_METADATA_IDX(eng::META_NS_NIEPCE, eng::META_NIEPCE_FLAG),
old_value, flag);
+ // we need to set the flag here so that undo/redo works
+ // consistently.
+ file->setFlag(flag);
+ }
+ }
+}
+
+
+void SelectionController::set_properties(const fwk::PropertyBag & /*props*/)
+{
+ eng::library_id_t selection = get_selection();
+ if(selection >= 0) {
+ Gtk::TreeIter iter = m_imageliststore->get_iter_from_id(selection);
+ if(iter) {
+#if 0
+ eng::LibFile::Ptr file = (*iter)[m_imageliststore->columns().m_libfile];
+ DBG_OUT("old flag is %d", file->flag());
+ int old_value = file->flag();
+ _set_metadata(_("Set Properties"), file,
+ // FIXME
+ MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_RATING),
+ old_value, flag);
// we need to set the rating here so that undo/redo works
// consistently.
file->setFlag(flag);
+#endif
}
}
}
+
}
/*
diff --git a/src/niepce/ui/selectioncontroller.hpp b/src/niepce/ui/selectioncontroller.hpp
index bbaeb25..cf04770 100644
--- a/src/niepce/ui/selectioncontroller.hpp
+++ b/src/niepce/ui/selectioncontroller.hpp
@@ -25,6 +25,7 @@
#include <sigc++/signal.h>
+#include "fwk/base/propertybag.hpp"
#include "fwk/toolkit/controller.hpp"
#include "engine/db/librarytypes.hpp";
#include "ui/imageliststore.hpp"
@@ -90,6 +91,8 @@ public:
/** set flag */
void set_flag(int flag);
+ void set_properties(const fwk::PropertyBag & props);
+
/** get the current selection
* todo: change it to support multiple
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]