[niepce] npc-fwk: bind PropertyValue with cxx



commit dd33fb5d86b43a1ef70b159140a0350819b2a982
Author: Hubert Figuière <hub figuiere net>
Date:   Sat Oct 15 21:00:16 2022 -0400

    npc-fwk: bind PropertyValue with cxx

 crates/npc-engine/build.rs               |   1 +
 crates/npc-fwk/src/base/propertyvalue.rs | 152 +++++++++++--------------------
 crates/npc-fwk/src/lib.rs                |  28 ++++++
 niepce-main/build.rs                     |   1 +
 src/engine/db/properties.cpp             |   2 +-
 src/fwk/base/propertybag.cpp             |  52 ++---------
 src/fwk/base/propertybag.hpp             |  19 +---
 src/fwk/toolkit/metadatawidget.cpp       |  56 ++++++------
 src/fwk/toolkit/metadatawidget.hpp       |   3 +-
 src/niepce/modules/map/mapmodule.cpp     |  16 ++--
 src/niepce/ui/selectioncontroller.cpp    |  14 +--
 src/rust_bindings.hpp                    |   3 +-
 12 files changed, 148 insertions(+), 199 deletions(-)
---
diff --git a/crates/npc-engine/build.rs b/crates/npc-engine/build.rs
index cfa33519..b4627639 100644
--- a/crates/npc-engine/build.rs
+++ b/crates/npc-engine/build.rs
@@ -29,6 +29,7 @@ fn main() {
             .exclude_item("GtkToolbar")
             .exclude_item("GFileInfo")
             .exclude_item("RgbColour")
+            .exclude_item("PropertyValue")
             .exclude_item("Label")
             // Ensure these are opaque as generics are still a problem.
             .exclude_item("NiepcePropertySet")
diff --git a/crates/npc-fwk/src/base/propertyvalue.rs b/crates/npc-fwk/src/base/propertyvalue.rs
index 68eef699..ef8151b9 100644
--- a/crates/npc-fwk/src/base/propertyvalue.rs
+++ b/crates/npc-fwk/src/base/propertyvalue.rs
@@ -17,9 +17,6 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-use libc::c_char;
-use std::ffi::{CStr, CString};
-
 use super::date::Date;
 
 #[derive(Clone, Debug)]
@@ -33,118 +30,77 @@ pub enum PropertyValue {
 
 unsafe impl Send for PropertyValue {}
 
-/// Create a new String %PropertyValue from a C string
-///
-/// # Safety
-/// Dereference the pointer (C string)
-#[no_mangle]
-pub unsafe extern "C" fn fwk_property_value_new_str(v: *const c_char) -> *mut PropertyValue {
-    let cstr = CStr::from_ptr(v);
-    let value = Box::new(PropertyValue::String(cstr.to_string_lossy().into_owned()));
-    Box::into_raw(value)
-}
-
-#[no_mangle]
-pub extern "C" fn fwk_property_value_new_int(v: i32) -> *mut PropertyValue {
-    let value = Box::new(PropertyValue::Int(v));
-    Box::into_raw(value)
-}
-
-#[no_mangle]
-pub extern "C" fn fwk_property_value_new_date(v: &Date) -> *mut PropertyValue {
-    let value = Box::new(PropertyValue::Date(*v));
-    Box::into_raw(value)
-}
+impl PropertyValue {
+    pub fn is_empty(&self) -> bool {
+        matches!(*self, PropertyValue::Empty)
+    }
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_new_string_array() -> *mut PropertyValue {
-    let value = Box::new(PropertyValue::StringArray(vec![]));
-    Box::into_raw(value)
-}
+    pub fn is_integer(&self) -> bool {
+        matches!(*self, PropertyValue::Int(_))
+    }
 
-/// Delete the %PropertyValue object
-///
-/// # Safety
-/// Dereference the pointer.
-#[no_mangle]
-pub unsafe extern "C" fn fwk_property_value_delete(v: *mut PropertyValue) {
-    if !v.is_null() {
-        drop(Box::from_raw(v));
+    pub fn is_date(&self) -> bool {
+        matches!(*self, PropertyValue::Date(_))
     }
-}
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_is_empty(v: &PropertyValue) -> bool {
-    matches!(*v, PropertyValue::Empty)
-}
+    pub fn is_string(&self) -> bool {
+        matches!(*self, PropertyValue::String(_))
+    }
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_is_integer(v: &PropertyValue) -> bool {
-    matches!(*v, PropertyValue::Int(_))
-}
+    pub fn integer_unchecked(&self) -> i32 {
+        match *self {
+            PropertyValue::Int(i) => i,
+            _ => panic!("value is not Int"),
+        }
+    }
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_get_integer(v: &PropertyValue) -> i32 {
-    match *v {
-        PropertyValue::Int(i) => i,
-        _ => panic!("value is not Int"),
+    pub fn date_unchecked(&self) -> Box<Date> {
+        match *self {
+            PropertyValue::Date(ref d) => Box::new(*d),
+            _ => panic!("value is not Date"),
+        }
     }
-}
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_is_date(v: &PropertyValue) -> bool {
-    matches!(*v, PropertyValue::Date(_))
-}
+    pub fn string_unchecked(&self) -> &str {
+        match *self {
+            PropertyValue::String(ref s) => s,
+            _ => panic!("value is not a String"),
+        }
+    }
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_get_date(v: &PropertyValue) -> *mut Date {
-    match *v {
-        PropertyValue::Date(ref d) => Box::into_raw(Box::new(*d)),
-        _ => panic!("value is not Date"),
+    /// Add a string a StringArray %PropertyValue
+    ///
+    /// Will panic if the type is incorrect.
+    pub fn add_string_unchecked(&mut self, string: &str) {
+        match *self {
+            PropertyValue::StringArray(ref mut sa) => {
+                sa.push(string.to_string());
+            }
+            _ => panic!("value is not a StringArray"),
+        }
     }
-}
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_is_string(v: &PropertyValue) -> bool {
-    matches!(*v, PropertyValue::String(_))
+    pub fn string_array_unchecked(&self) -> &[String] {
+        match *self {
+            PropertyValue::StringArray(ref sa) => sa,
+            _ => panic!("value is not a StringArray"),
+        }
+    }
 }
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_get_string(v: &PropertyValue) -> *mut c_char {
-    match *v {
-        PropertyValue::String(ref s) => CString::new(s.as_bytes()).unwrap().into_raw(),
-        _ => panic!("value is not a String"),
-    }
+/// Create a new String %PropertyValue from a string
+pub fn property_value_new_str(v: &str) -> Box<PropertyValue> {
+    Box::new(PropertyValue::String(v.to_string()))
 }
 
-/// Add a string a StringArray %PropertyValue
-///
-/// Will panic if the type is incorrect.
-///
-/// # Safety
-/// Dereference the pointer (C string)
-#[no_mangle]
-pub unsafe extern "C" fn fwk_property_value_add_string(v: &mut PropertyValue, cstr: *const c_char) {
-    match *v {
-        PropertyValue::StringArray(ref mut sa) => {
-            sa.push(CStr::from_ptr(cstr).to_string_lossy().into_owned());
-        }
-        _ => panic!("value is not a StringArray"),
-    }
+pub fn property_value_new_int(v: i32) -> Box<PropertyValue> {
+    Box::new(PropertyValue::Int(v))
 }
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_count_string_array(v: &PropertyValue) -> usize {
-    match *v {
-        PropertyValue::StringArray(ref sa) => sa.len(),
-        _ => panic!("value is not a StringArray"),
-    }
+pub fn property_value_new_date(v: &Date) -> Box<PropertyValue> {
+    Box::new(PropertyValue::Date(*v))
 }
 
-#[no_mangle]
-pub extern "C" fn fwk_property_value_get_string_at(v: &PropertyValue, idx: usize) -> *mut c_char {
-    match *v {
-        PropertyValue::StringArray(ref sa) => CString::new(sa[idx].as_bytes()).unwrap().into_raw(),
-        _ => panic!("value is not a StringArray"),
-    }
+pub fn property_value_new_string_array() -> Box<PropertyValue> {
+    Box::new(PropertyValue::StringArray(vec![]))
 }
diff --git a/crates/npc-fwk/src/lib.rs b/crates/npc-fwk/src/lib.rs
index ee142a67..8d045bd6 100644
--- a/crates/npc-fwk/src/lib.rs
+++ b/crates/npc-fwk/src/lib.rs
@@ -53,6 +53,10 @@ use glib::translate::*;
 
 use self::base::rgbcolour::RgbColour;
 use crate::base::date::Date;
+use crate::base::propertyvalue::{
+    property_value_new_date, property_value_new_int, property_value_new_str,
+    property_value_new_string_array,
+};
 use crate::toolkit::thumbnail::Thumbnail;
 use crate::toolkit::Configuration;
 use crate::utils::files::FileList;
@@ -223,4 +227,28 @@ mod ffi {
         fn at(&self, idx: usize) -> String;
         fn push_back(&mut self, value: &str);
     }
+
+    extern "Rust" {
+        type PropertyValue;
+
+        fn property_value_new_str(v: &str) -> Box<PropertyValue>;
+        fn property_value_new_int(v: i32) -> Box<PropertyValue>;
+        fn property_value_new_date(v: &Date) -> Box<PropertyValue>;
+        fn property_value_new_string_array() -> Box<PropertyValue>;
+
+        fn is_empty(&self) -> bool;
+        fn is_integer(&self) -> bool;
+        fn is_date(&self) -> bool;
+        fn is_string(&self) -> bool;
+        #[cxx_name = "get_integer"]
+        fn integer_unchecked(&self) -> i32;
+        #[cxx_name = "get_date"]
+        fn date_unchecked(&self) -> Box<Date>;
+        #[cxx_name = "get_string"]
+        fn string_unchecked(&self) -> &str;
+        #[cxx_name = "add_string"]
+        fn add_string_unchecked(&mut self, string: &str);
+        #[cxx_name = "get_string_array"]
+        fn string_array_unchecked(&self) -> &[String];
+    }
 }
diff --git a/niepce-main/build.rs b/niepce-main/build.rs
index e6a303fd..9a7ad0e2 100644
--- a/niepce-main/build.rs
+++ b/niepce-main/build.rs
@@ -28,6 +28,7 @@ fn main() {
             .exclude_item("FileStatus")
             .exclude_item("FileList")
             .exclude_item("RgbColour")
+            .exclude_item("PropertyValue")
             .exclude_item("CUSTOM_START")
             .exclude_item("INTERNAL_START")
             .exclude_item("GdkPixbuf")
diff --git a/src/engine/db/properties.cpp b/src/engine/db/properties.cpp
index 9821641d..cff96b6b 100644
--- a/src/engine/db/properties.cpp
+++ b/src/engine/db/properties.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - eng/db/properties.cpp
  *
- * Copyright (C) 2011-2021 Hubert Figuiere
+ * Copyright (C) 2011-2022 Hubert Figuière
  *
  * 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
diff --git a/src/fwk/base/propertybag.cpp b/src/fwk/base/propertybag.cpp
index 88fb52e1..03f05735 100644
--- a/src/fwk/base/propertybag.cpp
+++ b/src/fwk/base/propertybag.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - fwk/base/propertybag.cpp
  *
- * Copyright (C) 2011-2021 Hubert Figuière
+ * Copyright (C) 2011-2022 Hubert Figuière
  *
  * 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,7 +17,6 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-
 #include "string.hpp"
 #include "debug.hpp"
 #include "propertybag.hpp"
@@ -34,45 +33,13 @@ PropertySetPtr property_set_new()
     return property_set_wrap(ffi::eng_property_set_new());
 }
 
-PropertyValuePtr property_value_wrap(PropertyValue* v)
-{
-    return PropertyValuePtr(v, &ffi::fwk_property_value_delete);
-}
-
-PropertyValuePtr property_value_new(const std::string& v)
-{
-    return property_value_wrap(ffi::fwk_property_value_new_str(v.c_str()));
-}
-
-PropertyValuePtr property_value_new(int v)
-{
-    return property_value_wrap(ffi::fwk_property_value_new_int(v));
-}
-
 PropertyValuePtr property_value_new(const std::vector<std::string>& sa)
 {
-    PropertyValue* value = ffi::fwk_property_value_new_string_array();
+    PropertyValuePtr value = fwk::property_value_new_string_array();
     for (auto s : sa) {
-        ffi::fwk_property_value_add_string(value, s.c_str());
-    }
-    return property_value_wrap(value);
-}
-
-std::string property_value_get_string(const PropertyValue &value)
-{
-    auto s = fwk::RustFfiString(ffi::fwk_property_value_get_string(&value));
-    return s.str();
-}
-
-std::vector<std::string> property_value_get_string_array(const PropertyValue &value)
-{
-    std::vector<std::string> v;
-    auto len = ffi::fwk_property_value_count_string_array(&value);
-    for (size_t i = 0; i < len; i++) {
-        auto s = fwk::RustFfiString(ffi::fwk_property_value_get_string_at(&value, i));
-        v.push_back(s.str());
+        value->add_string(s);
     }
-    return v;
+    return value;
 }
 
 PropertyBagPtr property_bag_wrap(PropertyBag* bag)
@@ -87,24 +54,23 @@ PropertyBagPtr property_bag_new()
 
 PropertyValuePtr property_bag_value(const PropertyBagPtr& bag, PropertyIndex idx)
 {
-    auto value = ffi::eng_property_bag_value(bag.get(), idx);
-    return property_value_wrap(value);
+    return PropertyValuePtr::from_raw(ffi::eng_property_bag_value(bag.get(), idx));
 }
 
 bool set_value_for_property(PropertyBag& bag, ffi::NiepcePropertyIdx idx,
-                            const PropertyValue & value)
+                            const PropertyValue& value)
 {
     return ffi::eng_property_bag_set_value(&bag, static_cast<uint32_t>(idx), &value);
 }
 
-fwk::Option<PropertyValuePtr> get_value_for_property(const PropertyBag& bag,
+std::optional<PropertyValuePtr> get_value_for_property(const PropertyBag& bag,
                                                      ffi::NiepcePropertyIdx idx)
 {
     auto value = ffi::eng_property_bag_value(&bag, static_cast<uint32_t>(idx));
     if (!value) {
-        return fwk::Option<PropertyValuePtr>();
+        return std::nullopt;
     }
-    return fwk::Option<PropertyValuePtr>(property_value_wrap(value));
+    return std::optional<PropertyValuePtr>(PropertyValuePtr::from_raw(value));
 }
 
 }
diff --git a/src/fwk/base/propertybag.hpp b/src/fwk/base/propertybag.hpp
index 5d41c27d..30918037 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-2013 Hubert Figuiere
+ * Copyright (C) 2011-2022 Hubert Figuière
  *
  * 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
@@ -22,10 +22,9 @@
 #include <stdint.h>
 #include <string>
 #include <vector>
-#include <set>
 #include <memory>
 
-#include "fwk/base/option.hpp"
+#include <optional>
 
 #include "rust_bindings.hpp"
 
@@ -33,15 +32,7 @@ namespace fwk {
 
 typedef uint32_t PropertyIndex;
 
-typedef std::shared_ptr<PropertyValue> PropertyValuePtr;
-
-PropertyValuePtr property_value_new(const std::string&);
-PropertyValuePtr property_value_new(int);
 PropertyValuePtr property_value_new(const std::vector<std::string>&);
-PropertyValuePtr property_value_new(const DatePtr&);
-
-std::string property_value_get_string(const PropertyValue &value);
-std::vector<std::string> property_value_get_string_array(const PropertyValue &value);
 
 typedef std::shared_ptr<PropertySet> PropertySetPtr;
 
@@ -58,12 +49,10 @@ PropertyBagPtr property_bag_wrap(PropertyBag*);
 
 PropertyValuePtr property_bag_value(const PropertyBagPtr& bag, PropertyIndex key);
 
-std::string property_value_get_string(const PropertyValue& v);
-
 /** return true if a property was removed prior to insertion */
-bool set_value_for_property(PropertyBag&, ffi::NiepcePropertyIdx idx, const PropertyValue & value);
+bool set_value_for_property(PropertyBag&, ffi::NiepcePropertyIdx idx, const PropertyValue& value);
 /** return property or an empty option */
-fwk::Option<PropertyValuePtr> get_value_for_property(const PropertyBag&, ffi::NiepcePropertyIdx idx);
+std::optional<PropertyValuePtr> get_value_for_property(const PropertyBag&, ffi::NiepcePropertyIdx idx);
 
 }
 
diff --git a/src/fwk/toolkit/metadatawidget.cpp b/src/fwk/toolkit/metadatawidget.cpp
index 9e17c313..01419312 100644
--- a/src/fwk/toolkit/metadatawidget.cpp
+++ b/src/fwk/toolkit/metadatawidget.cpp
@@ -254,7 +254,7 @@ void MetaDataWidget::set_data_source(const fwk::PropertyBagPtr& properties)
     auto current = m_fmt->formats.begin();
     while (current != m_fmt->formats.end()) {
         auto result = get_value_for_property(*properties, current->id);
-        if (!result.empty() || !current->readonly) {
+        if (result.has_value() || !current->readonly) {
             add_data(*current, std::move(result));
         }
         else {
@@ -268,12 +268,12 @@ void MetaDataWidget::set_data_source(const fwk::PropertyBagPtr& properties)
 bool MetaDataWidget::set_fraction_dec_data(Gtk::Widget* w,
                                            const PropertyValuePtr& value)
 {
-    if (!fwk_property_value_is_string(value.get())) {
+    if (!value->is_string()) {
         ERR_OUT("Data not string(fraction)");
         return false;
     }
     try {
-        const std::string str_value = fwk::property_value_get_string(*value);
+        const std::string str_value = std::string(value->get_string());
         DBG_OUT("set fraction dec %s", str_value.c_str());
         std::string frac = str(boost::format("%.1f")
                                % fwk::fraction_to_decimal(str_value));
@@ -289,12 +289,12 @@ bool MetaDataWidget::set_fraction_dec_data(Gtk::Widget* w,
 bool MetaDataWidget::set_fraction_data(Gtk::Widget* w,
                                        const PropertyValuePtr& value)
 {
-    if (!fwk_property_value_is_string(value.get())) {
+    if (!value->is_string()) {
         ERR_OUT("Data not string(fraction)");
         return false;
     }
     try {
-        const std::string str_value = fwk::property_value_get_string(*value);
+        const std::string str_value = std::string(value->get_string());
         DBG_OUT("set fraction %s", str_value.c_str());
         boost::rational<int> r
             = boost::lexical_cast<boost::rational<int>>(str_value);
@@ -313,12 +313,12 @@ bool MetaDataWidget::set_fraction_data(Gtk::Widget* w,
 bool MetaDataWidget::set_star_rating_data(Gtk::Widget* w,
                                           const PropertyValuePtr& value)
 {
-    if (!fwk_property_value_is_integer(value.get())) {
+    if (!value->is_integer()) {
         ERR_OUT("Data not integer");
         return false;
     }
     try {
-        int rating = fwk_property_value_get_integer(value.get());
+        int rating = value->get_integer();
         AutoFlag flag(m_update);
         ffi::fwk_rating_label_set_rating(static_cast<Gtk::Widget*>(w)->gobj(), rating);
     }
@@ -333,9 +333,13 @@ bool MetaDataWidget::set_string_array_data(Gtk::Widget* w, bool readonly,
 {
     try {
         AutoFlag flag(m_update);
-        std::vector<std::string> tokens = fwk::property_value_get_string_array(*value);
 
-        static_cast<fwk::TokenTextView*>(w)->set_tokens(tokens);
+        auto tokens = value->get_string_array();
+        std::vector<std::string> c_tokens;
+        for (auto token: tokens) {
+            c_tokens.push_back(std::string(token));
+        }
+        static_cast<fwk::TokenTextView*>(w)->set_tokens(c_tokens);
         static_cast<fwk::TokenTextView*>(w)->set_editable(!readonly);
     }
     catch(...) {
@@ -347,7 +351,7 @@ bool MetaDataWidget::set_string_array_data(Gtk::Widget* w, bool readonly,
 bool MetaDataWidget::set_text_data(Gtk::Widget* w, bool readonly,
                                    const PropertyValuePtr& value)
 {
-    if (!fwk_property_value_is_string(value.get())) {
+    if (!value->is_string()) {
         ERR_OUT("Data not string.");
         return false;
     }
@@ -355,10 +359,10 @@ bool MetaDataWidget::set_text_data(Gtk::Widget* w, bool readonly,
         AutoFlag flag(m_update);
         if(readonly) {
             static_cast<Gtk::Label*>(w)->set_text(
-                fwk::property_value_get_string(*value));
+                std::string(value->get_string()));
         } else {
             static_cast<Gtk::TextView*>(w)->get_buffer()->set_text(
-                fwk::property_value_get_string(*value));
+                std::string(value->get_string()));
         }
     }
     catch(...) {
@@ -370,7 +374,7 @@ bool MetaDataWidget::set_text_data(Gtk::Widget* w, bool readonly,
 bool MetaDataWidget::set_string_data(Gtk::Widget* w, bool readonly,
                                      const PropertyValuePtr& value)
 {
-    if (!fwk_property_value_is_string(value.get())) {
+    if (!value->is_string()) {
         ERR_OUT("Data not string.");
         return false;
     }
@@ -378,10 +382,10 @@ bool MetaDataWidget::set_string_data(Gtk::Widget* w, bool readonly,
         AutoFlag flag(m_update);
         if(readonly) {
             static_cast<Gtk::Label*>(w)->set_text(
-                fwk::property_value_get_string(*value));
+                std::string(value->get_string()));
         } else {
             static_cast<Gtk::Entry*>(w)->set_text(
-                fwk::property_value_get_string(*value));
+                std::string(value->get_string()));
         }
     }
     catch(...) {
@@ -392,12 +396,12 @@ bool MetaDataWidget::set_string_data(Gtk::Widget* w, bool readonly,
 
 bool MetaDataWidget::set_date_data(Gtk::Widget* w, const PropertyValuePtr& value)
 {
-    if (!fwk_property_value_is_date(value.get())) {
+    if (!value->is_date()) {
         return false;
     }
     try {
         AutoFlag flag(m_update);
-        fwk::DatePtr date = fwk::DatePtr::from_raw(fwk_property_value_get_date(value.get()));
+        fwk::DatePtr date = value->get_date();
         static_cast<Gtk::Label*>(w)->set_text(std::string(date->to_string()));
 
         DBG_OUT("setting date data %s", date->to_string().c_str());
@@ -409,13 +413,13 @@ bool MetaDataWidget::set_date_data(Gtk::Widget* w, const PropertyValuePtr& value
 }
 
 void MetaDataWidget::add_data(const MetaDataFormat& current,
-                              fwk::Option<PropertyValuePtr>&& optional_value)
+                              std::optional<PropertyValuePtr>&& optional_value)
 {
-    if (optional_value.empty()) {
+    if (!optional_value.has_value()) {
         return;
     }
-    auto value = optional_value.unwrap();
-    if (fwk_property_value_is_empty(value.get())) {
+    auto value = std::move(optional_value.value());
+    if (value->is_empty()) {
         return;
     }
 
@@ -461,7 +465,7 @@ bool MetaDataWidget::on_str_changed(Gtk::Entry *e,
     if(m_update) {
         return true;
     }
-    emit_metadata_changed(prop, fwk::property_value_new(e->get_text()));
+    emit_metadata_changed(prop, fwk::property_value_new_str(e->get_text().c_str()));
     return true;
 }
 
@@ -472,7 +476,7 @@ bool MetaDataWidget::on_text_changed(Glib::RefPtr<Gtk::TextBuffer> b,
         return true;
     }
     emit_metadata_changed(prop,
-                          fwk::property_value_new(b->get_text()));
+                          fwk::property_value_new_str(b->get_text().c_str()));
     return true;
 }
 
@@ -494,7 +498,7 @@ void MetaDataWidget::on_int_changed(int value, ffi::NiepcePropertyIdx prop)
     if(m_update) {
         return;
     }
-    emit_metadata_changed(prop, fwk::property_value_new(value));
+    emit_metadata_changed(prop, fwk::property_value_new_int(value));
 }
 
 void MetaDataWidget::emit_metadata_changed(ffi::NiepcePropertyIdx prop,
@@ -504,8 +508,8 @@ void MetaDataWidget::emit_metadata_changed(ffi::NiepcePropertyIdx prop,
     fwk::PropertyBagPtr old_props = fwk::property_bag_new();
     fwk::set_value_for_property(*props, prop, *value);
     auto result = fwk::get_value_for_property(*m_current_data, prop);
-    if (!result.empty()) {
-        fwk::set_value_for_property(*old_props, prop, *result.unwrap());
+    if (result.has_value()) {
+        fwk::set_value_for_property(*old_props, prop, *result.value());
     }
     signal_metadata_changed.emit(props, old_props);
 }
diff --git a/src/fwk/toolkit/metadatawidget.hpp b/src/fwk/toolkit/metadatawidget.hpp
index 7a63a9de..30183e02 100644
--- a/src/fwk/toolkit/metadatawidget.hpp
+++ b/src/fwk/toolkit/metadatawidget.hpp
@@ -21,6 +21,7 @@
 
 #include <map>
 #include <string>
+#include <optional>
 
 #include <gtkmm/grid.h>
 #include <gtkmm/textview.h>
@@ -69,7 +70,7 @@ public:
     MetaDataWidget(const Glib::ustring & title);
 
     void add_data(const MetaDataFormat& current,
-                  fwk::Option<PropertyValuePtr>&& value);
+                  std::optional<PropertyValuePtr>&& value);
     void set_data_format(const MetaDataSectionFormat* fmt);
     void set_data_source(const fwk::PropertyBagPtr& properties);
 
diff --git a/src/niepce/modules/map/mapmodule.cpp b/src/niepce/modules/map/mapmodule.cpp
index 7a32fab0..4cc6cd1e 100644
--- a/src/niepce/modules/map/mapmodule.cpp
+++ b/src/niepce/modules/map/mapmodule.cpp
@@ -88,19 +88,19 @@ MapModule::on_lib_notification(const eng::LibNotification &ln)
             double latitude, longitude;
             latitude = longitude = NAN;
             auto result = fwk::get_value_for_property(*properties, 
ffi::NiepcePropertyIdx::NpExifGpsLongProp);
-            if (!result.empty()) {
-                fwk::PropertyValuePtr val = result.unwrap();
+            if (result.has_value()) {
+                fwk::PropertyValuePtr val = std::move(result.value());
                 // it is a string
-                if (fwk_property_value_is_string(val.get())) {
-                    longitude = fwk::gps_coord_from_xmp(fwk::property_value_get_string(*val));
+                if (val->is_string()) {
+                    longitude = fwk::gps_coord_from_xmp(val->get_string());
                 }
             }
             result = fwk::get_value_for_property(*properties, ffi::NiepcePropertyIdx::NpExifGpsLatProp);
-            if (!result.empty()) {
-                fwk::PropertyValuePtr val = result.unwrap();
+            if (result.has_value()) {
+                fwk::PropertyValuePtr val = std::move(result.value());
                 // it is a string
-                if (fwk_property_value_is_string(val.get())) {
-                    latitude = fwk::gps_coord_from_xmp(fwk::property_value_get_string(*val));
+                if (val->is_string()) {
+                    latitude = fwk::gps_coord_from_xmp(val->get_string());
                 }
             }
 
diff --git a/src/niepce/ui/selectioncontroller.cpp b/src/niepce/ui/selectioncontroller.cpp
index ab90395b..57757ecc 100644
--- a/src/niepce/ui/selectioncontroller.cpp
+++ b/src/niepce/ui/selectioncontroller.cpp
@@ -194,11 +194,11 @@ bool SelectionController::_set_metadata(const std::string & undo_label,
     undo->new_command<void>(
         [libclient, file_id, meta, new_value] () {
             ffi::libraryclient_set_metadata(
-                libclient->client(), file_id, meta, fwk::property_value_new(new_value).get());
+                libclient->client(), file_id, meta, &*fwk::property_value_new_int(new_value));
         },
         [libclient, file_id, meta, old_value] () {
             ffi::libraryclient_set_metadata(
-                libclient->client(), file_id, meta, fwk::property_value_new(old_value).get());
+                libclient->client(), file_id, meta, &*fwk::property_value_new_int(old_value));
         });
     undo->execute();
     return true;
@@ -213,7 +213,9 @@ bool SelectionController::_set_metadata(const std::string & undo_label,
     auto len = eng_property_bag_len(props.get());
     for (size_t i = 0; i < len; i++) {
         auto key = eng_property_bag_key_by_index(props.get(), i);
-        fwk::PropertyValuePtr value = fwk::property_bag_value(old, key);
+        // This is a shared_ptr because it's the only way to pass it to the lambda
+        // as Box<> isn't copyable
+        auto value = std::make_shared<fwk::PropertyValuePtr>(fwk::property_bag_value(old, key));
         /*
         if (!result.empty()) {
             value = result.unwrap();
@@ -226,15 +228,15 @@ bool SelectionController::_set_metadata(const std::string & undo_label,
         */
 
         auto libclient = getLibraryClient();
-        auto new_value = fwk::property_bag_value(props, key);
+        auto new_value = std::make_shared<fwk::PropertyValuePtr>(fwk::property_bag_value(props, key));
         undo->new_command<void>(
             [libclient, file_id, key, new_value] () {
                 ffi::libraryclient_set_metadata(
-                    libclient->client(), file_id, static_cast<ffi::NiepcePropertyIdx>(key), new_value.get());
+                    libclient->client(), file_id, static_cast<ffi::NiepcePropertyIdx>(key), &**new_value);
             },
             [libclient, file_id, key, value] () {
                 ffi::libraryclient_set_metadata(
-                    libclient->client(), file_id, static_cast<ffi::NiepcePropertyIdx>(key), value.get());
+                    libclient->client(), file_id, static_cast<ffi::NiepcePropertyIdx>(key), &**value);
             });
     }
     undo->execute();
diff --git a/src/rust_bindings.hpp b/src/rust_bindings.hpp
index 7b1562ef..821cb9ef 100644
--- a/src/rust_bindings.hpp
+++ b/src/rust_bindings.hpp
@@ -34,6 +34,7 @@ struct DateTime;
 typedef fwk::Date Date;
 typedef rust_str str;
 typedef fwk::FileList FileList;
+typedef fwk::PropertyValue PropertyValue;
 typedef fwk::RgbColour RgbColour;
 typedef eng::Label Label;
 struct NiepcePropertyBag;
@@ -50,8 +51,8 @@ typedef rust::Box<fwk::Date> DatePtr;
 typedef rust::Box<Thumbnail> ThumbnailPtr;
 typedef rust::Box<FileList> FileListPtr;
 typedef rust::Box<RgbColour> RgbColourPtr;
+typedef rust::Box<PropertyValue> PropertyValuePtr;
 
-typedef ffi::PropertyValue PropertyValue;
 typedef ffi::NiepcePropertyBag PropertyBag;
 typedef ffi::NiepcePropertySet PropertySet;
 }


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