Any QAbstractItemModel value can now be optional

master
Jos van den Oever 2017-08-18 17:21:02 +02:00
parent 0fe433f701
commit b94d65a217
15 changed files with 247 additions and 36 deletions

View File

@ -198,5 +198,5 @@ pub unsafe extern "C" fn fibonacci_list_sort(ptr: *mut FibonacciList, column: c_
#[no_mangle]
pub unsafe extern "C" fn fibonacci_list_data_result(ptr: *const FibonacciList, row: c_int) -> u64 {
(&*ptr).result(row)
(&*ptr).result(row).into()
}

View File

@ -3,6 +3,28 @@
use std::slice;
use libc::{c_int, uint8_t, uint16_t};
#[repr(C)]
pub struct COption<T> {
data: T,
some: bool,
}
impl<T> From<Option<T>> for COption<T> where T: Default {
fn from(t: Option<T>) -> COption <T> {
if let Some(v) = t {
COption {
data: v,
some: true
}
} else {
COption {
data: T::default(),
some: false
}
}
}
}
#[repr(C)]
pub struct QString {
data: *const uint8_t,

View File

@ -37,8 +37,8 @@ impl Item for DirEntry {
fn file_type(&self) -> c_int {
0
}
fn file_size(&self) -> u64 {
self.metadata.as_ref().map_or(0, |m|m.len())
fn file_size(&self) -> Option<u64> {
self.metadata.as_ref().map(|m|m.len())
}
fn retrieve(id: usize, parents: Vec<&DirEntry>,
q: Incoming<Self>,
@ -81,7 +81,7 @@ pub trait Item: Default {
fn file_name(&self) -> String;
fn file_permissions(&self) -> c_int;
fn file_type(&self) -> c_int;
fn file_size(&self) -> u64;
fn file_size(&self) -> Option<u64>;
}
pub type Tree = RGeneralItemModel<DirEntry>;
@ -274,9 +274,9 @@ impl<T: Item> TreeTrait for RGeneralItemModel<T> where T: Sync + Send {
.map(|entry| entry.data.file_type())
.unwrap_or_default()
}
fn file_size(&self, row: c_int, parent: usize) -> u64 {
fn file_size(&self, row: c_int, parent: usize) -> Option<u64> {
self.get(row, parent)
.map(|entry| entry.data.file_size())
.unwrap_or_default()
.unwrap_or(None)
}
}

View File

@ -83,7 +83,7 @@ pub trait TreeTrait {
fn file_path(&self, row: c_int, parent: usize) -> Option<String>;
fn file_permissions(&self, row: c_int, parent: usize) -> i32;
fn file_type(&self, row: c_int, parent: usize) -> i32;
fn file_size(&self, row: c_int, parent: usize) -> u64;
fn file_size(&self, row: c_int, parent: usize) -> Option<u64>;
fn index(&self, row: c_int, parent: usize) -> usize;
fn parent(&self, parent: usize) -> QModelIndex;
}
@ -193,17 +193,17 @@ pub unsafe extern "C" fn tree_data_file_path(ptr: *const Tree,
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_permissions(ptr: *const Tree, row: c_int, parent: usize) -> i32 {
(&*ptr).file_permissions(row, parent)
(&*ptr).file_permissions(row, parent).into()
}
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_type(ptr: *const Tree, row: c_int, parent: usize) -> i32 {
(&*ptr).file_type(row, parent)
(&*ptr).file_type(row, parent).into()
}
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_size(ptr: *const Tree, row: c_int, parent: usize) -> u64 {
(&*ptr).file_size(row, parent)
pub unsafe extern "C" fn tree_data_file_size(ptr: *const Tree, row: c_int, parent: usize) -> COption<u64> {
(&*ptr).file_size(row, parent).into()
}
#[no_mangle]

View File

@ -3,6 +3,28 @@
use std::slice;
use libc::{c_int, uint8_t, uint16_t};
#[repr(C)]
pub struct COption<T> {
data: T,
some: bool,
}
impl<T> From<Option<T>> for COption<T> where T: Default {
fn from(t: Option<T>) -> COption <T> {
if let Some(v) = t {
COption {
data: v,
some: true
}
} else {
COption {
data: T::default(),
some: false
}
}
}
}
#[repr(C)]
pub struct QString {
data: *const uint8_t,

View File

@ -2,6 +2,19 @@
#include "Fibonacci.h"
namespace {
template <typename T>
struct option {
private:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);
}
return QVariant();
}
};
struct qbytearray_t {
private:
const char* data;
@ -177,7 +190,7 @@ QVariant FibonacciList::data(const QModelIndex &index, int role) const
case 0:
switch (role) {
case Qt::DisplayRole:
v.setValue<quint64>(fibonacci_list_data_result(d, index.row()));
v = fibonacci_list_data_result(d, index.row());
break;
}
break;
@ -189,4 +202,7 @@ QHash<int, QByteArray> FibonacciList::roleNames() const {
names.insert(Qt::DisplayRole, "result");
return names;
}
bool FibonacciList::setData(const QModelIndex &index, const QVariant &value, int role)
{
return false;
}

View File

@ -41,6 +41,7 @@ public:
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;

View File

@ -2,6 +2,19 @@
#include "Tree.h"
namespace {
template <typename T>
struct option {
private:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);
}
return QVariant();
}
};
struct qbytearray_t {
private:
const char* data;
@ -110,7 +123,7 @@ extern "C" {
void tree_data_file_path(const Tree::Private*, int, quintptr, QString*, qstring_set);
qint32 tree_data_file_permissions(const Tree::Private*, int, quintptr);
qint32 tree_data_file_type(const Tree::Private*, int, quintptr);
quint64 tree_data_file_size(const Tree::Private*, int, quintptr);
option<quint64> tree_data_file_size(const Tree::Private*, int, quintptr);
void tree_sort(Tree::Private*, int column, Qt::SortOrder order = Qt::AscendingOrder);
int tree_row_count(const Tree::Private*, int, quintptr);
@ -189,28 +202,28 @@ QVariant Tree::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DisplayRole:
tree_data_file_name(d, index.row(), index.internalId(), &s, set_qstring);
v.setValue<QString>(s);
if (!s.isNull()) v.setValue<QString>(s);
break;
case Qt::DecorationRole:
tree_data_file_icon(d, index.row(), index.internalId(), &b, set_qbytearray);
v.setValue<QByteArray>(b);
if (!b.isNull()) v.setValue<QByteArray>(b);
break;
case Qt::UserRole + 1:
tree_data_file_path(d, index.row(), index.internalId(), &s, set_qstring);
v.setValue<QString>(s);
if (!s.isNull()) v.setValue<QString>(s);
break;
case Qt::UserRole + 2:
tree_data_file_name(d, index.row(), index.internalId(), &s, set_qstring);
v.setValue<QString>(s);
if (!s.isNull()) v.setValue<QString>(s);
break;
case Qt::UserRole + 3:
v.setValue<qint32>(tree_data_file_permissions(d, index.row(), index.internalId()));
v = tree_data_file_permissions(d, index.row(), index.internalId());
break;
case Qt::UserRole + 4:
v.setValue<qint32>(tree_data_file_type(d, index.row(), index.internalId()));
v = tree_data_file_type(d, index.row(), index.internalId());
break;
case Qt::UserRole + 5:
v.setValue<quint64>(tree_data_file_size(d, index.row(), index.internalId()));
v = tree_data_file_size(d, index.row(), index.internalId());
break;
}
break;
@ -218,28 +231,28 @@ QVariant Tree::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DisplayRole:
tree_data_file_path(d, index.row(), index.internalId(), &s, set_qstring);
v.setValue<QString>(s);
if (!s.isNull()) v.setValue<QString>(s);
break;
}
break;
case 2:
switch (role) {
case Qt::DisplayRole:
v.setValue<qint32>(tree_data_file_permissions(d, index.row(), index.internalId()));
v = tree_data_file_permissions(d, index.row(), index.internalId());
break;
}
break;
case 3:
switch (role) {
case Qt::DisplayRole:
v.setValue<qint32>(tree_data_file_type(d, index.row(), index.internalId()));
v = tree_data_file_type(d, index.row(), index.internalId());
break;
}
break;
case 4:
switch (role) {
case Qt::DisplayRole:
v.setValue<quint64>(tree_data_file_size(d, index.row(), index.internalId()));
v = tree_data_file_size(d, index.row(), index.internalId());
break;
}
break;
@ -256,4 +269,7 @@ QHash<int, QByteArray> Tree::roleNames() const {
names.insert(Qt::UserRole + 5, "fileSize");
return names;
}
bool Tree::setData(const QModelIndex &index, const QVariant &value, int role)
{
return false;
}

View File

@ -21,6 +21,7 @@ public:
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;

View File

@ -44,7 +44,8 @@
}, {
"name": "fileSize",
"value": "Qt::UserRole + 5",
"type": "quint64"
"type": "quint64",
"optional": true
}],
[{
"name": "filePath",
@ -65,7 +66,8 @@
[{
"name": "fileSize",
"value": "Qt::DisplayRole",
"type": "quint64"
"type": "quint64",
"optional": true
}]
]
}]

View File

@ -103,6 +103,7 @@ struct Role {
QString name;
QString value;
BindingTypeProperties type;
bool write;
bool optional;
};
@ -142,6 +143,15 @@ BindingTypeProperties parseBindingType(const QString& value) {
exit(1);
}
template <typename T>
QString cppSetType(const T& p)
{
if (p.optional) {
return "option<" + p.type.cppSetType + ">";
}
return p.type.cppSetType;
}
template <typename T>
QString rustType(const T& p)
{
@ -151,6 +161,15 @@ QString rustType(const T& p)
return p.type.rustType;
}
template <typename T>
QString rustCType(const T& p)
{
if (p.optional) {
return "COption<" + p.type.rustType + ">";
}
return p.type.rustType;
}
template <typename T>
QString rustTypeInit(const T& p)
{
@ -176,6 +195,7 @@ parseRole(const QJsonObject& json) {
r.name = json.value("name").toString();
r.value = json.value("value").toString();
r.type = parseBindingType(json.value("type").toString());
r.write = json.value("write").toBool();
r.optional = json.value("optional").toBool();
return r;
}
@ -299,6 +319,7 @@ void writeHeaderItemModel(QTextStream& h) {
h << QString(R"(
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
@ -330,7 +351,7 @@ void writeCppModel(QTextStream& cpp, const Object& o) {
.arg(o.name, lcname, snakeCase(role.name), cGetType(role.type), indexDecl);
} else {
cpp << QString(" %4 %2_data_%3(const %1::Private*%5);\n")
.arg(o.name, lcname, snakeCase(role.name), role.type.cppSetType, indexDecl);
.arg(o.name, lcname, snakeCase(role.name), cppSetType(role), indexDecl);
}
}
cpp << QString(" void %2_sort(%1::Private*, int column, Qt::SortOrder order = Qt::AscendingOrder);\n").arg(o.name, lcname);
@ -468,14 +489,14 @@ QVariant %1::data(const QModelIndex &index, int role) const
if (role.type.name == "QString") {
cpp << QString(" %1_data_%2(d%4, &s, set_%3);\n")
.arg(lcname, snakeCase(role.name), role.type.name.toLower(), index);
cpp << " v.setValue<QString>(s);\n";
cpp << " if (!s.isNull()) v.setValue<QString>(s);\n";
} else if (role.type.name == "QByteArray") {
cpp << QString(" %1_data_%2(d%4, &b, set_%3);\n")
.arg(lcname, snakeCase(role.name), role.type.name.toLower(), index);
cpp << " v.setValue<QByteArray>(b);\n";
cpp << " if (!b.isNull()) v.setValue<QByteArray>(b);\n";
} else {
cpp << QString(" v.setValue<%3>(%1_data_%2(d%5));\n")
.arg(lcname, snakeCase(role.name), role.type.cppSetType, index);
cpp << QString(" v = %1_data_%2(d%3);\n")
.arg(lcname, snakeCase(role.name), index);
}
cpp << " break;\n";
}
@ -489,7 +510,12 @@ QVariant %1::data(const QModelIndex &index, int role) const
cpp << " names.insert(" << role.value << ", \"" << role.name << "\");\n";
}
cpp << " return names;\n";
cpp << "}\n\n";
cpp << QString(R"(}
bool %1::setData(const QModelIndex &index, const QVariant &value, int role)
{
return false;
}
)").arg(o.name);
}
void writeHeaderObject(QTextStream& h, const Object& o) {
@ -751,6 +777,19 @@ void writeCpp(const Configuration& conf) {
#include "%1"
namespace {
template <typename T>
struct option {
private:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);
}
return QVariant();
}
};
struct qbytearray_t {
private:
const char* data;
@ -1135,9 +1174,9 @@ pub unsafe extern "C" fn %2_data_%3(ptr: *const %1,
r << QString(R"(
#[no_mangle]
pub unsafe extern "C" fn %2_data_%3(ptr: *const %1, row: c_int%5) -> %4 {
(&*ptr).%3(row%6)
(&*ptr).%3(row%6).into()
}
)").arg(o.name, lcname, snakeCase(role.name), rustType(role), indexDecl, index);
)").arg(o.name, lcname, snakeCase(role.name), rustCType(role), indexDecl, index);
}
}
}
@ -1288,6 +1327,28 @@ void writeRustTypes(const Configuration& conf) {
use std::slice;
use libc::{c_int, uint8_t, uint16_t};
#[repr(C)]
pub struct COption<T> {
data: T,
some: bool,
}
impl<T> From<Option<T>> for COption<T> where T: Default {
fn from(t: Option<T>) -> COption <T> {
if let Some(v) = t {
COption {
data: v,
some: true
}
} else {
COption {
data: T::default(),
some: false
}
}
}
}
#[repr(C)]
pub struct QString {
data: *const uint8_t,

View File

@ -3,6 +3,28 @@
use std::slice;
use libc::{c_int, uint8_t, uint16_t};
#[repr(C)]
pub struct COption<T> {
data: T,
some: bool,
}
impl<T> From<Option<T>> for COption<T> where T: Default {
fn from(t: Option<T>) -> COption <T> {
if let Some(v) = t {
COption {
data: v,
some: true
}
} else {
COption {
data: T::default(),
some: false
}
}
}
}
#[repr(C)]
pub struct QString {
data: *const uint8_t,

View File

@ -3,6 +3,28 @@
use std::slice;
use libc::{c_int, uint8_t, uint16_t};
#[repr(C)]
pub struct COption<T> {
data: T,
some: bool,
}
impl<T> From<Option<T>> for COption<T> where T: Default {
fn from(t: Option<T>) -> COption <T> {
if let Some(v) = t {
COption {
data: v,
some: true
}
} else {
COption {
data: T::default(),
some: false
}
}
}
}
#[repr(C)]
pub struct QString {
data: *const uint8_t,

View File

@ -2,6 +2,19 @@
#include "test_object_rust.h"
namespace {
template <typename T>
struct option {
private:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);
}
return QVariant();
}
};
struct qbytearray_t {
private:
const char* data;

View File

@ -2,6 +2,19 @@
#include "test_object_types_rust.h"
namespace {
template <typename T>
struct option {
private:
T value;
bool some;
public:
operator QVariant() const {
if (some) {
return QVariant(value);
}
return QVariant();
}
};
struct qbytearray_t {
private:
const char* data;