[niepce] Date property
- From: Hubert FiguiÃre <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce] Date property
- Date: Thu, 23 Feb 2012 06:39:31 +0000 (UTC)
commit d470ccf9db5fe72b2bd28c0a89cc6fa47c889580
Author: Hub Figuiere <hub figuiere net>
Date: Wed Feb 1 17:02:46 2012 -0800
Date property
.gitignore | 1 +
src/engine/db/libmetadata.cpp | 38 +++--
src/engine/db/library.cpp | 8 +-
src/engine/db/properties-def.hpp | 2 +-
src/fwk/base/Makefile.am | 13 +-
src/fwk/base/date.cpp | 106 ++++++++++
src/fwk/base/date.hpp | 66 +++++++
src/fwk/base/propertybag.hpp | 8 +-
src/fwk/base/t/testdate.cpp | 50 +++++
src/fwk/base/t/testfractions.cpp | 2 +-
src/fwk/toolkit/metadatawidget.cpp | 296 ++++++++++++++++++-----------
src/fwk/toolkit/metadatawidget.hpp | 20 ++-
src/fwk/utils/exempi.cpp | 23 +--
src/fwk/utils/exempi.hpp | 6 +-
src/niepce/modules/interfaces/Makefile.am | 1 +
15 files changed, 486 insertions(+), 154 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 47f495a..ed19e7b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,6 +36,7 @@ po/Makefile.in.in
src/fwk/base/testmoniker
src/fwk/base/testgeometry
src/fwk/base/testfractions
+src/fwk/base/testdate
src/fwk/utils/test_db
src/fwk/utils/test_db2
src/fwk/utils/test_db3
diff --git a/src/engine/db/libmetadata.cpp b/src/engine/db/libmetadata.cpp
index 6d79641..918d0ba 100644
--- a/src/engine/db/libmetadata.cpp
+++ b/src/engine/db/libmetadata.cpp
@@ -54,7 +54,7 @@ LibMetadata::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);
+ PropsToXmpMap::const_iterator iter = propmap.find(index);
if(iter == propmap.end()) {
// not found
return false;
@@ -104,14 +104,21 @@ bool LibMetadata::setMetaData(fwk::PropertyIndex meta,
else if(value.type() == typeid(fwk::StringArray)) {
fwk::StringArray v = boost::get<fwk::StringArray>(value);
// TODO see if we can get that without deleting the whole property
- /*result = */xmp_delete_property(xmp(), ns, property);
+ result = xmp_delete_property(xmp(), ns, property);
for(fwk::StringArray::const_iterator iter = v.begin();
iter != v.end(); ++iter) {
- /*result = */xmp_append_array_item(xmp(), ns, property,
- XMP_PROP_VALUE_IS_ARRAY,
- iter->c_str(), 0);
+ result = xmp_append_array_item(xmp(), ns, property,
+ XMP_PROP_VALUE_IS_ARRAY,
+ iter->c_str(), 0);
}
}
+ else if(value.type() == typeid(fwk::Date)) {
+ fwk::Date d = boost::get<fwk::Date>(value);
+
+ result = xmp_set_property_date(xmp(), ns, property,
+ &d.xmp_date(), 0);
+
+ }
if(!result) {
ERR_OUT("error setting property %s:%s %d", ns, property,
xmp_get_error());
@@ -165,19 +172,24 @@ void LibMetadata::to_properties(const fwk::PropertySet & propset,
xmp::ScopedPtr<XmpStringPtr> value(xmp_string_new());
fwk::PropertyValue propval;
for(iter = propset.begin(); iter != propset.end(); ++iter) {
- switch(*iter) {
+ fwk::PropertySet::key_type prop_id = *iter;
+ switch(prop_id) {
case NpXmpRatingProp:
- properties.set_value_for_property(NpXmpRatingProp,
+ properties.set_value_for_property(prop_id,
fwk::PropertyValue(rating()));
break;
case NpXmpLabelProp:
- properties.set_value_for_property(NpXmpLabelProp,
+ properties.set_value_for_property(prop_id,
fwk::PropertyValue(label()));
break;
case NpTiffOrientationProp:
- properties.set_value_for_property(NpTiffOrientationProp,
+ properties.set_value_for_property(prop_id,
fwk::PropertyValue(orientation()));
break;
+ case NpExifDateTimeOriginalProp:
+ properties.set_value_for_property(prop_id,
+ fwk::PropertyValue(creation_date()));
+ break;
case NpIptcKeywordsProp:
{
xmp::ScopedPtr<XmpIteratorPtr>
@@ -187,16 +199,16 @@ void LibMetadata::to_properties(const fwk::PropertySet & propset,
while(xmp_iterator_next(iter, NULL, NULL, value, NULL)) {
vec.push_back(xmp_string_cstr(value));
}
- properties.set_value_for_property(NpIptcKeywordsProp,
+ properties.set_value_for_property(prop_id,
fwk::PropertyValue(vec));
break;
}
default:
- if(getMetaData(*iter, propval)) {
- properties.set_value_for_property(*iter, propval);
+ if(getMetaData(prop_id, propval)) {
+ properties.set_value_for_property(prop_id, propval);
}
else {
- DBG_OUT("unknown prop %u", *iter);
+ DBG_OUT("unknown prop %u", prop_id);
}
break;
}
diff --git a/src/engine/db/library.cpp b/src/engine/db/library.cpp
index 5de502d..bdf4cfc 100644
--- a/src/engine/db/library.cpp
+++ b/src/engine/db/library.cpp
@@ -284,7 +284,7 @@ library_id_t Library::addFile(library_id_t folder_id, const std::string & file,
rating = meta.rating();
label = meta.label();
flag = meta.flag();
- time_t creation_date = meta.creation_date();
+ time_t creation_date = fwk::make_time_value(meta.creation_date());
if(creation_date == -1) {
creation_date = 0;
}
@@ -896,6 +896,9 @@ bool Library::getXmpIdsInQueue(std::vector<library_id_t> & ids)
bool Library::rewriteXmpForId(library_id_t id)
{
+ /// DISABLED
+#if 0
+
SQLStatement del(boost::format("DELETE FROM xmp_update_queue "
" WHERE id='%1%';") % id);
SQLStatement getxmp(boost::format("SELECT xmp, main_file, xmp_file FROM files "
@@ -952,7 +955,8 @@ bool Library::rewriteXmpForId(library_id_t id)
{
DBG_OUT("db exception %s", e.what());
return false;
- }
+ }
+#endif
return true;
}
diff --git a/src/engine/db/properties-def.hpp b/src/engine/db/properties-def.hpp
index de8f8b2..2e8d16c 100644
--- a/src/engine/db/properties-def.hpp
+++ b/src/engine/db/properties-def.hpp
@@ -44,7 +44,7 @@ DEFINE_PROPERTY(NpExifExposureBiasProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXI
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(NpExifDateTimeOriginalProp, MAKE_METADATA_IDX(META_NS_EXIF, META_EXIF_DATETIMEORIGINAL), NS_EXIF, "DateTimeOriginal", fwk::Date)
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", std::string)
diff --git a/src/fwk/base/Makefile.am b/src/fwk/base/Makefile.am
index a2b90c2..d5105df 100644
--- a/src/fwk/base/Makefile.am
+++ b/src/fwk/base/Makefile.am
@@ -1,14 +1,19 @@
INCLUDES = -I$(top_srcdir)/src \
@BOOST_CPPFLAGS@ \
+ @EXEMPI_CFLAGS@ \
$(NULL)
noinst_LIBRARIES = libfwkbase.a
-TESTS = testmoniker testgeometry
+TESTS = testmoniker testgeometry testfractions testdate
-check_PROGRAMS = testmoniker testgeometry
+check_PROGRAMS = testmoniker testgeometry testfractions testdate
+
+testdate_SOURCES = t/testdate.cpp
+testdate_LDADD = libfwkbase.a \
+ @LIBGLIBMM_LIBS@
testmoniker_SOURCES = t/testmoniker.cpp
testmoniker_LDADD = libfwkbase.a \
@@ -18,10 +23,14 @@ testgeometry_SOURCES = t/testgeometry.cpp
testgeometry_LDADD = libfwkbase.a \
@LIBGLIBMM_LIBS@
+testfractions_SOURCES = t/testfractions.cpp
+testfractions_LDADD = libfwkbase.a \
+ @LIBGLIBMM_LIBS@
libfwkbase_a_SOURCES = color.hpp color.cpp \
autoflag.hpp \
+ date.hpp date.cpp \
debug.hpp debug.cpp \
fractions.hpp fractions.cpp \
moniker.hpp moniker.cpp \
diff --git a/src/fwk/base/date.cpp b/src/fwk/base/date.cpp
new file mode 100644
index 0000000..b8fbac4
--- /dev/null
+++ b/src/fwk/base/date.cpp
@@ -0,0 +1,106 @@
+/*
+ * niepce - fwk/base/date.hpp
+ *
+ * Copyright (C) 2012 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 <stdio.h>
+#include <time.h>
+
+#include "date.hpp"
+#include "debug.hpp"
+
+namespace fwk {
+
+time_t make_time_value(const Date & d)
+{
+ time_t date = 0;
+
+ const XmpDateTime & value = d.xmp_date();
+ struct tm dt;
+ dt.tm_sec = value.second;
+ dt.tm_min = value.minute;
+ dt.tm_hour = value.hour;
+ dt.tm_mday = value.day;
+ dt.tm_mon = value.month;
+ dt.tm_year = value.year - 1900;
+ dt.tm_isdst = -1;
+ // this field is supposed to be a glibc extension. oh joy.
+ dt.tm_gmtoff = value.tzSign * ((value.tzHour * 3600) +
+ (value.tzMinute * 60));
+ date = mktime(&dt);
+ DBG_ASSERT(date != -1, "date is -1");
+
+ return date;
+}
+
+XmpDateTime& make_xmp_date_time(time_t t, XmpDateTime& xmp_dt)
+{
+ // FIXME find a better way. This should work.
+ struct tm gmt;
+ struct tm* pgmt = gmtime_r(&t, &gmt);
+ DBG_ASSERT(pgmt == &gmt, "gmtime failed");
+
+ xmp_dt.year = gmt.tm_year + 1900;
+ xmp_dt.month = gmt.tm_mon + 1;
+ xmp_dt.day = gmt.tm_mday;
+ xmp_dt.hour = gmt.tm_hour;
+ xmp_dt.minute = gmt.tm_min;
+ xmp_dt.second = gmt.tm_sec;
+ xmp_dt.tzSign = 0;
+ xmp_dt.tzHour = 0;
+ xmp_dt.tzMinute = 0;
+ xmp_dt.nanoSecond = 0;
+ return xmp_dt;
+}
+
+Date::Date(const XmpDateTime& dt, const Timezone* tz)
+ : m_datetime(dt)
+ , m_tz(tz)
+{
+}
+
+Date::Date(const time_t dt, const Timezone* tz)
+ : m_tz(tz)
+{
+ make_xmp_date_time(dt, m_datetime);
+}
+
+std::string Date::to_string() const
+{
+ char buffer[256];
+
+ snprintf(buffer, 256, "%u:%u:%d %u:%u:%u %c%u%u",
+ m_datetime.year, m_datetime.month,
+ m_datetime.day, m_datetime.hour,
+ m_datetime.minute, m_datetime.second,
+ m_datetime.tzSign >= 0 ? '+' : '-',
+ m_datetime.tzHour, m_datetime.tzMinute);
+
+ return buffer;
+}
+
+}
+
+/*
+ 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/date.hpp b/src/fwk/base/date.hpp
new file mode 100644
index 0000000..add14f0
--- /dev/null
+++ b/src/fwk/base/date.hpp
@@ -0,0 +1,66 @@
+/*
+ * niepce - fwk/base/date.hpp
+ *
+ * Copyright (C) 2012 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_BASE_DATE_HPP
+#define __FWK_BASE_DATE_HPP
+
+#include <string>
+
+#include <exempi/xmp.h>
+
+namespace fwk {
+
+class Timezone;
+
+XmpDateTime& make_xmp_date_time(time_t t, XmpDateTime& xmp_dt);
+
+/**
+ * Class to deal with ISO8601 string dates as used by XMP.
+ * Bonus: with a timezone.
+ */
+class Date
+{
+public:
+ Date(const XmpDateTime& dt, const Timezone* tz = NULL);
+ Date(const time_t dt, const Timezone* tz = NULL);
+
+ std::string to_string() const;
+ const XmpDateTime& xmp_date() const
+ { return m_datetime; }
+
+private:
+ XmpDateTime m_datetime;
+ // weak pointer.
+ const Timezone* m_tz;
+};
+
+time_t make_time_value(const Date &);
+
+}
+
+/*
+ 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/base/propertybag.hpp b/src/fwk/base/propertybag.hpp
index 15b0856..358fa69 100644
--- a/src/fwk/base/propertybag.hpp
+++ b/src/fwk/base/propertybag.hpp
@@ -1,7 +1,7 @@
/*
* niepce - fwk/base/propertybag.cpp
*
- * Copyright (C) 2011 Hubert Figuiere
+ * Copyright (C) 2011-2012 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
@@ -17,8 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
-
#ifndef __FWK_PROPERTYBAG_HPP_
#define __FWK_PROPERTYBAG_HPP_
@@ -30,11 +28,13 @@
#include <tr1/memory>
#include <boost/variant.hpp>
+#include "fwk/base/date.hpp"
+
namespace fwk {
typedef uint32_t PropertyIndex;
typedef std::vector<std::string> StringArray;
-typedef boost::variant<int, std::string, StringArray> PropertyValue;
+typedef boost::variant<int, std::string, StringArray, Date> PropertyValue;
typedef std::set<PropertyIndex> PropertySet;
diff --git a/src/fwk/base/t/testdate.cpp b/src/fwk/base/t/testdate.cpp
new file mode 100644
index 0000000..ac9865e
--- /dev/null
+++ b/src/fwk/base/t/testdate.cpp
@@ -0,0 +1,50 @@
+/*
+ * niepce - base/t/testdate.cpp
+ *
+ * Copyright (C) 2012 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/>.
+ */
+/** @brief unit test for date */
+
+#include <boost/test/minimal.hpp>
+
+#include <stdlib.h>
+#include <vector>
+#include <boost/rational.hpp>
+
+#include "fwk/base/date.hpp"
+
+int test_main( int, char *[] ) // note the name!
+{
+ fwk::Date d(0);
+
+ XmpDateTime xmp_dt = d.xmp_date();
+ BOOST_CHECK(xmp_dt.year == 1970);
+ BOOST_CHECK(xmp_dt.month == 1);
+ BOOST_CHECK(xmp_dt.day == 1);
+
+ printf("%s\n", d.to_string().c_str());
+
+ return 0;
+}
+/*
+ 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/t/testfractions.cpp b/src/fwk/base/t/testfractions.cpp
index caee8c2..9cc78fe 100644
--- a/src/fwk/base/t/testfractions.cpp
+++ b/src/fwk/base/t/testfractions.cpp
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** @brief unit test for files */
+/** @brief unit test for fractions */
#include <boost/test/minimal.hpp>
diff --git a/src/fwk/toolkit/metadatawidget.cpp b/src/fwk/toolkit/metadatawidget.cpp
index f6dbe78..c8a2c3e 100644
--- a/src/fwk/toolkit/metadatawidget.cpp
+++ b/src/fwk/toolkit/metadatawidget.cpp
@@ -37,7 +37,7 @@
#include "fwk/toolkit/widgets/tokentextview.hpp"
// remove
-#include "engine/db/properties.hpp"
+//#include "engine/db/properties.hpp"
#include "metadatawidget.hpp"
@@ -60,10 +60,85 @@ void MetaDataWidget::set_data_format(const MetaDataSectionFormat * fmt)
create_widgets_for_format(fmt);
}
-void MetaDataWidget::create_widgets_for_format(const MetaDataSectionFormat * fmt)
+Gtk::Widget*
+MetaDataWidget::create_star_rating_widget(bool readonly, uint32_t id)
+{
+ fwk::RatingLabel* r = Gtk::manage(new fwk::RatingLabel(0, !readonly));
+ if(!readonly) {
+ r->signal_changed.connect(
+ sigc::bind(
+ sigc::mem_fun(*this,
+ &MetaDataWidget::on_int_changed),
+ id));
+ }
+ return r;
+}
+
+Gtk::Widget*
+MetaDataWidget::create_string_array_widget(bool readonly, uint32_t id)
+{
+ fwk::TokenTextView * ttv = Gtk::manage(new fwk::TokenTextView());
+ if(!readonly) {
+ ttv->signal_focus_out_event().connect(
+ sigc::bind(
+ sigc::mem_fun(*this,
+ &MetaDataWidget::on_string_array_changed),
+ ttv, id));
+ }
+ return ttv;
+}
+
+Gtk::Widget*
+MetaDataWidget::create_text_widget(bool readonly, uint32_t id)
+{
+ if(readonly) {
+ Gtk::Label * l = Gtk::manage(new Gtk::Label());
+ l->set_alignment(0.0f, 0.5f);
+ return l;
+ }
+
+ Gtk::TextView * e = Gtk::manage(new NoTabTextView());
+ e->set_editable(true);
+ e->set_wrap_mode(Gtk::WRAP_WORD);
+ e->signal_focus_out_event().connect(
+ sigc::bind(
+ sigc::mem_fun(*this,
+ &MetaDataWidget::on_text_changed),
+ e->get_buffer(), id));
+ return e;
+}
+
+Gtk::Widget*
+MetaDataWidget::create_string_widget(bool readonly, uint32_t id)
+{
+ if(readonly) {
+ Gtk::Label * l = Gtk::manage(new Gtk::Label());
+ l->set_alignment(0.0f, 0.5f);
+ return l;
+ }
+
+ Gtk::Entry * e = Gtk::manage(new Gtk::Entry());
+ e->set_has_frame(false); // TODO make that a custom widget
+ e->signal_focus_out_event().connect(
+ sigc::bind(
+ sigc::mem_fun(*this,
+ &MetaDataWidget::on_str_changed),
+ e, id));
+ return e;
+}
+
+Gtk::Widget*
+MetaDataWidget::create_date_widget(bool /*readonly*/, uint32_t id)
+{
+ // for now a date widget is just like a string. Read only
+ return create_string_widget(true, id);
+}
+
+void
+MetaDataWidget::create_widgets_for_format(const MetaDataSectionFormat * fmt)
{
Gtk::Widget *w = NULL;
- const MetaDataFormat * current = m_fmt->formats;
+ const MetaDataFormat * current = fmt->formats;
int n_row = 0;
while(current && current->label) {
@@ -73,68 +148,21 @@ void MetaDataWidget::create_widgets_for_format(const MetaDataSectionFormat * fmt
labelw->set_alignment(0.0f, 0.5f);
labelw->set_use_markup(true);
- switch(current->type)
- {
+ switch(current->type) {
case 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;
+ w = create_star_rating_widget(current->readonly, current->id);
break;
- }
case META_DT_STRING_ARRAY:
- {
- fwk::TokenTextView * ttv = Gtk::manage(new fwk::TokenTextView());
- if(!current->readonly) {
- ttv->signal_focus_out_event().connect(
- sigc::bind(
- sigc::mem_fun(*this,
- &MetaDataWidget::on_string_array_changed),
- ttv, current->id));
- }
- w = ttv;
+ w = create_string_array_widget(current->readonly, current->id);
break;
- }
case META_DT_TEXT:
- if(current->readonly) {
- Gtk::Label * l = Gtk::manage(new Gtk::Label());
- l->set_alignment(0.0f, 0.5f);
- w = l;
- }
- else {
- Gtk::TextView * e = Gtk::manage(new NoTabTextView());
- e->set_editable(true);
- e->set_wrap_mode(Gtk::WRAP_WORD);
- e->signal_focus_out_event().connect(
- sigc::bind(
- sigc::mem_fun(*this,
- &MetaDataWidget::on_text_changed),
- e->get_buffer(), current->id));
- w = e;
- }
+ w = create_text_widget(current->readonly, current->id);
+ break;
+ case META_DT_DATE:
+ w = create_date_widget(current->readonly, current->id);
break;
default:
- 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->set_has_frame(false); // TODO make that a custom widget
- e->signal_focus_out_event().connect(
- sigc::bind(
- sigc::mem_fun(*this,
- &MetaDataWidget::on_str_changed),
- e, current->id));
- w = e;
- }
+ w = create_string_widget(current->readonly, current->id);
break;
}
@@ -211,6 +239,99 @@ void MetaDataWidget::set_data_source(const fwk::PropertyBag & properties)
}
}
+bool MetaDataWidget::set_fraction_data(Gtk::Widget* w, const PropertyValue & value)
+{
+ try {
+ const std::string& str_value = boost::get<std::string>(value);
+ DBG_OUT("set fraction %s", str_value.c_str());
+ double decimal = fwk::fraction_to_decimal(str_value);
+ std::string frac = boost::lexical_cast<std::string>(decimal);
+ AutoFlag flag(m_update);
+ static_cast<Gtk::Label*>(w)->set_text(frac);
+ }
+ catch(...) {
+ return false;
+ }
+ return true;
+}
+
+bool MetaDataWidget::set_star_rating_data(Gtk::Widget* w, const PropertyValue & value)
+{
+ try {
+ int rating = boost::get<int>(value);
+ AutoFlag flag(m_update);
+ static_cast<fwk::RatingLabel*>(w)->set_rating(rating);
+ }
+ catch(...) {
+ return false;
+ }
+ return true;
+}
+
+bool MetaDataWidget::set_string_array_data(Gtk::Widget* w, const PropertyValue & value)
+{
+ try {
+ AutoFlag flag(m_update);
+ fwk::StringArray tokens = boost::get<fwk::StringArray>(value);
+
+ static_cast<fwk::TokenTextView*>(w)->set_tokens(tokens);
+ }
+ catch(...) {
+ return false;
+ }
+ return true;
+}
+
+bool MetaDataWidget::set_text_data(Gtk::Widget* w, bool readonly,
+ const PropertyValue & value)
+{
+ try {
+ AutoFlag flag(m_update);
+ if(readonly) {
+ static_cast<Gtk::Label*>(w)->set_text(boost::get<std::string>(value));
+ }
+ else {
+ static_cast<Gtk::TextView*>(w)->get_buffer()->set_text(boost::get<std::string>(value));
+ }
+ }
+ catch(...) {
+ return false;
+ }
+ return true;
+}
+
+bool MetaDataWidget::set_string_data(Gtk::Widget* w, bool readonly,
+ const PropertyValue & value)
+{
+ try {
+ AutoFlag flag(m_update);
+ if(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));
+ }
+ }
+ catch(...) {
+ return false;
+ }
+ return true;
+}
+
+bool MetaDataWidget::set_date_data(Gtk::Widget* w, const PropertyValue & value)
+{
+ try {
+ AutoFlag flag(m_update);
+ fwk::Date date = boost::get<fwk::Date>(value);
+ static_cast<Gtk::Label*>(w)->set_text(date.to_string());
+
+ DBG_OUT("setting date data %s\n", date.to_string().c_str());
+ }
+ catch(...) {
+ return false;
+ }
+ return true;
+}
void MetaDataWidget::add_data(const MetaDataFormat * current,
const PropertyValue & value)
@@ -227,65 +348,22 @@ void MetaDataWidget::add_data(const MetaDataFormat * current,
switch(current->type) {
case META_DT_FRAC:
- try {
- double decimal = fwk::fraction_to_decimal(boost::get<std::string>(value));
- std::string frac = boost::lexical_cast<std::string>(decimal);
- AutoFlag flag(m_update);
- static_cast<Gtk::Label*>(w)->set_text(frac);
- }
- catch(...) {
- DBG_OUT("conversion of '%u' to frac failed", current->id);
- }
+ set_fraction_data(w, value);
break;
case META_DT_STAR_RATING:
- try {
- int rating = boost::get<int>(value);
- AutoFlag flag(m_update);
- static_cast<fwk::RatingLabel*>(w)->set_rating(rating);
- }
- catch(...) {
- DBG_OUT("conversion of '%u' to int failed", current->id);
- }
+ set_star_rating_data(w, value);
break;
case META_DT_STRING_ARRAY:
- try {
- AutoFlag flag(m_update);
- fwk::StringArray tokens = boost::get<fwk::StringArray>(value);
-
- static_cast<fwk::TokenTextView*>(w)->set_tokens(tokens);
- }
- catch(...) {
- DBG_OUT("conversion of '%u' from %s to StringArray failed", current->id,
- value.type().name());
- }
+ set_string_array_data(w, value);
break;
case META_DT_TEXT:
- try {
- AutoFlag flag(m_update);
- if(current->readonly) {
- static_cast<Gtk::Label*>(w)->set_text(boost::get<std::string>(value));
- }
- else {
- static_cast<Gtk::TextView*>(w)->get_buffer()->set_text(boost::get<std::string>(value));
- }
- }
- catch(...) {
- DBG_OUT("conversion of '%u' to int failed", current->id);
- }
+ set_text_data(w, current->readonly, value);
+ break;
+ case META_DT_DATE:
+ set_date_data(w, value);
break;
default:
- try {
- AutoFlag flag(m_update);
- 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));
- }
- }
- catch(...) {
- DBG_OUT("conversion of '%u' to string failed", current->id);
- }
+ set_string_data(w, current->readonly, value);
break;
}
}
diff --git a/src/fwk/toolkit/metadatawidget.hpp b/src/fwk/toolkit/metadatawidget.hpp
index fde9299..9792acb 100644
--- a/src/fwk/toolkit/metadatawidget.hpp
+++ b/src/fwk/toolkit/metadatawidget.hpp
@@ -20,7 +20,6 @@
#ifndef __NIEPCE_FRAMEWORK_META_DATA_WIDGET_H__
#define __NIEPCE_FRAMEWORK_META_DATA_WIDGET_H__
-
#include <map>
#include <string>
@@ -59,7 +58,6 @@ struct MetaDataSectionFormat {
const MetaDataFormat * formats;
};
-
class XmpMeta;
class TokenTextView;
@@ -84,6 +82,24 @@ protected:
private:
void clear_widget(std::pair<const PropertyIndex, Gtk::Widget *> & p);
void create_widgets_for_format(const MetaDataSectionFormat * fmt);
+
+ // the widget factory
+ Gtk::Widget* create_star_rating_widget(bool readonly, uint32_t id);
+ Gtk::Widget* create_string_array_widget(bool readonly, uint32_t id);
+ Gtk::Widget* create_text_widget(bool readonly, uint32_t id);
+ Gtk::Widget* create_string_widget(bool readonly, uint32_t id);
+ Gtk::Widget* create_date_widget(bool readonly, uint32_t id);
+
+ // set data
+ bool set_fraction_data(Gtk::Widget* w, const PropertyValue & value);
+ bool set_star_rating_data(Gtk::Widget* w, const PropertyValue & value);
+ bool set_string_array_data(Gtk::Widget* w, const PropertyValue & value);
+ bool set_text_data(Gtk::Widget* w, bool readonly,
+ const PropertyValue & value);
+ bool set_string_data(Gtk::Widget* w, bool readonly,
+ const PropertyValue & value);
+ bool set_date_data(Gtk::Widget* w, const PropertyValue & value);
+
void emit_metadata_changed(fwk::PropertyIndex prop, const fwk::PropertyValue & value);
Gtk::Table m_table;
diff --git a/src/fwk/utils/exempi.cpp b/src/fwk/utils/exempi.cpp
index 6b32371..0fcc847 100644
--- a/src/fwk/utils/exempi.cpp
+++ b/src/fwk/utils/exempi.cpp
@@ -1,7 +1,7 @@
/*
* niepce - utils/exempi.cpp
*
- * Copyright (C) 2007-2008 Hubert Figuiere
+ * Copyright (C) 2007-2008,2012 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
@@ -30,6 +30,7 @@
#include <exempi/xmpconsts.h>
#include "fwk/base/debug.hpp"
+#include "fwk/base/date.hpp"
#include "exempi.hpp"
#include "pathutils.hpp"
@@ -205,31 +206,17 @@ int32_t XmpMeta::flag() const
return _flag;
}
-
-time_t XmpMeta::creation_date() const
+fwk::Date XmpMeta::creation_date() const
{
- time_t date = 0;
XmpDateTime value;
if(xmp_get_property_date(m_xmp, NS_EXIF, "DateTimeOriginal",
&value, NULL)) {
- struct tm dt;
- dt.tm_sec = value.second;
- dt.tm_min = value.minute;
- dt.tm_hour = value.hour;
- dt.tm_mday = value.day;
- dt.tm_mon = value.month;
- dt.tm_year = value.year - 1900;
- dt.tm_isdst = -1;
- // this field is supposed to be a glibc extension. oh joy.
- dt.tm_gmtoff = value.tzSign * ((value.tzHour * 3600) +
- (value.tzMinute * 60));
- date = mktime(&dt);
- DBG_ASSERT(date != -1, "date is -1");
+ return fwk::Date(value);
}
else {
ERR_OUT("get \"DateTimeOriginal\" property failed: %d", xmp_get_error());
}
- return date;
+ return Date(0);
}
std::string XmpMeta::creation_date_str() const
diff --git a/src/fwk/utils/exempi.hpp b/src/fwk/utils/exempi.hpp
index df63f4c..278f38e 100644
--- a/src/fwk/utils/exempi.hpp
+++ b/src/fwk/utils/exempi.hpp
@@ -4,7 +4,7 @@
/*
* niepce - utils/exempi.h
*
- * Copyright (C) 2007-2008 Hubert Figuiere
+ * Copyright (C) 2007-2008,2012 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
@@ -85,6 +85,8 @@ extern const char * UFRAW_INTEROP_NS_PREFIX;
namespace fwk {
+class Date;
+
class ExempiManager
: public boost::noncopyable
{
@@ -124,7 +126,7 @@ public:
/** return the rating, -1 is not found (not set) */
int32_t rating() const;
int32_t flag() const;
- time_t creation_date() const;
+ fwk::Date creation_date() const;
std::string creation_date_str() const;
const std::vector< std::string > & keywords() const;
private:
diff --git a/src/niepce/modules/interfaces/Makefile.am b/src/niepce/modules/interfaces/Makefile.am
index e9bdfae..36476f7 100644
--- a/src/niepce/modules/interfaces/Makefile.am
+++ b/src/niepce/modules/interfaces/Makefile.am
@@ -1,6 +1,7 @@
INCLUDES = -I$(top_srcdir)/src/ \
+ @EXEMPI_CFLAGS@ \
@LIBGLIBMM_CFLAGS@ \
@LIBGTKMM_CFLAGS@
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]