Implement setting of data via a model

master
Jos van den Oever 2017-08-19 13:58:40 +02:00
parent a5f22ad04b
commit d63cc3918c
6 changed files with 92 additions and 19 deletions

View File

@ -53,6 +53,9 @@ impl Item for DirEntry {
fn file_size(&self) -> Option<u64> {
self.metadata.as_ref().map(|m|m.len())
}
fn set_file_size(&mut self, file_size: Option<u64>) -> bool {
true
}
fn retrieve(id: usize, parents: Vec<&DirEntry>,
q: Incoming<Self>,
emit: TreeEmitter) {
@ -100,6 +103,7 @@ pub trait Item: Default {
fn file_type(&self) -> c_int;
fn file_size(&self) -> Option<u64>;
fn set_file_path(&mut self, file_path: Option<String>) -> bool;
fn set_file_size(&mut self, file_size: Option<u64>) -> bool;
}
pub type Tree = RGeneralItemModel<DirEntry>;
@ -298,6 +302,11 @@ impl<T: Item> TreeTrait for RGeneralItemModel<T> where T: Sync + Send {
.map(|entry| entry.data.file_path())
.unwrap_or_default()
}
fn set_file_path(&mut self, row: c_int, parent: usize, v: Option<String>) -> bool {
self.get_mut(row, parent)
.map(|mut entry| entry.data.set_file_path(v))
.unwrap_or(false)
}
fn file_type(&self, row: c_int, parent: usize) -> c_int {
self.get(row, parent)
.map(|entry| entry.data.file_type())
@ -308,9 +317,9 @@ impl<T: Item> TreeTrait for RGeneralItemModel<T> where T: Sync + Send {
.map(|entry| entry.data.file_size())
.unwrap_or(None)
}
fn set_file_path(&mut self, row: c_int, parent: usize, v: Option<String>) -> bool {
fn set_file_size(&mut self, row: c_int, parent: usize, v: Option<u64>) -> bool {
self.get_mut(row, parent)
.map(|mut entry| entry.data.set_file_path(v))
.map(|mut entry| entry.data.set_file_size(v))
.unwrap_or(false)
}
}

View File

@ -86,6 +86,7 @@ pub trait TreeTrait {
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) -> Option<u64>;
fn set_file_size(&mut self, row: c_int, parent: usize, Option<u64>) -> bool;
fn index(&self, row: c_int, parent: usize) -> usize;
fn parent(&self, parent: usize) -> QModelIndex;
}
@ -173,6 +174,11 @@ pub unsafe extern "C" fn tree_data_file_name(ptr: *const Tree,
set(d, QString::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn tree_set_data_file_name(ptr: *mut Tree, row: c_int, parent: usize, v: QStringIn) -> bool {
(&mut *ptr).set_file_name(row, parent, v.convert())
}
#[no_mangle]
pub unsafe extern "C" fn tree_data_file_icon(ptr: *const Tree,
row: c_int, parent: usize,
@ -193,6 +199,11 @@ pub unsafe extern "C" fn tree_data_file_path(ptr: *const Tree,
}
}
#[no_mangle]
pub unsafe extern "C" fn tree_set_data_file_path(ptr: *mut Tree, row: c_int, parent: usize, v: QStringIn) -> bool {
(&mut *ptr).set_file_path(row, parent, Some(v.convert()))
}
#[no_mangle]
pub unsafe extern "C" fn tree_set_data_file_path_none(ptr: *mut Tree, row: c_int, parent: usize) -> bool {
(&mut *ptr).set_file_path(row, parent, None)
@ -213,6 +224,16 @@ pub unsafe extern "C" fn tree_data_file_size(ptr: *const Tree, row: c_int, paren
(&*ptr).file_size(row, parent).into()
}
#[no_mangle]
pub unsafe extern "C" fn tree_set_data_file_size(ptr: *mut Tree, row: c_int, parent: usize, v: u64) -> bool {
(&mut *ptr).set_file_size(row, parent, Some(v))
}
#[no_mangle]
pub unsafe extern "C" fn tree_set_data_file_size_none(ptr: *mut Tree, row: c_int, parent: usize) -> bool {
(&mut *ptr).set_file_size(row, parent, None)
}
#[no_mangle]
pub unsafe extern "C" fn tree_index(ptr: *const Tree, row: c_int, parent: usize) -> usize {
(&*ptr).index(row, parent)

View File

@ -119,12 +119,16 @@ void Tree::setPath(const QString& v) {
}
extern "C" {
void tree_data_file_name(const Tree::Private*, int, quintptr, QString*, qstring_set);
bool tree_set_data_file_name(Tree::Private*, int, quintptr, qstring_t);
void tree_data_file_icon(const Tree::Private*, int, quintptr, QByteArray*, qbytearray_set);
void tree_data_file_path(const Tree::Private*, int, quintptr, QString*, qstring_set);
bool tree_set_data_file_path(Tree::Private*, int, quintptr, qstring_t);
bool tree_set_data_file_path_none(Tree::Private*, int, quintptr);
qint32 tree_data_file_permissions(const Tree::Private*, int, quintptr);
qint32 tree_data_file_type(const Tree::Private*, int, quintptr);
option<quint64> tree_data_file_size(const Tree::Private*, int, quintptr);
bool tree_set_data_file_size(Tree::Private*, int, quintptr, quint64);
bool tree_set_data_file_size_none(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);
@ -198,6 +202,9 @@ Qt::ItemFlags Tree::flags(const QModelIndex &i) const
if (i.column() == 1) {
flags |= Qt::ItemIsEditable;
}
if (i.column() == 4) {
flags |= Qt::ItemIsEditable;
}
return flags;
}
QVariant Tree::data(const QModelIndex &index, int role) const
@ -288,31 +295,44 @@ QHash<int, QByteArray> Tree::roleNames() const {
bool Tree::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.column() == 0) {
if (role == (Qt::DisplayRole)) {
return true;
if (role == Qt::DisplayRole) {
const QString val(value.value<QString>());
return tree_set_data_file_name(d, index.row(), index.internalId(), val);
}
if (role == (Qt::EditRole)) {
return true;
if (role == Qt::EditRole) {
const QString val(value.value<QString>());
return tree_set_data_file_name(d, index.row(), index.internalId(), val);
}
if (role == (Qt::UserRole + 1)) {
if (role == Qt::UserRole + 1) {
if (!value.isValid() || value.isNull()) {
return tree_set_data_file_path_none(d, index.row(), index.internalId());
}
return true;
const QString val(value.value<QString>());
return tree_set_data_file_path(d, index.row(), index.internalId(), val);
}
}
if (index.column() == 1) {
if (role == (Qt::DisplayRole)) {
if (role == Qt::DisplayRole) {
if (!value.isValid() || value.isNull()) {
return tree_set_data_file_path_none(d, index.row(), index.internalId());
}
return true;
const QString val(value.value<QString>());
return tree_set_data_file_path(d, index.row(), index.internalId(), val);
}
if (role == (Qt::EditRole)) {
if (role == Qt::EditRole) {
if (!value.isValid() || value.isNull()) {
return tree_set_data_file_path_none(d, index.row(), index.internalId());
}
return true;
const QString val(value.value<QString>());
return tree_set_data_file_path(d, index.row(), index.internalId(), val);
}
}
if (index.column() == 4) {
if (role == Qt::DisplayRole) {
if (!value.isValid()) {
return tree_set_data_file_size_none(d, index.row(), index.internalId());
}
return tree_set_data_file_size(d, index.row(), index.internalId(), value.value<quint64>());
}
}
return false;

View File

@ -69,11 +69,9 @@ int main (int argc, char *argv[])
view.sortByColumn(0, Qt::AscendingOrder);
view.show();
view.header()->setSectionResizeMode(QHeaderView::ResizeToContents);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("fsModel", &model);
engine.rootContext()->setContextProperty("sortedFsModel", &sortedModel);
engine.load(QUrl(QStringLiteral("qrc:///demo.qml")));
return app.exec();
}

View File

@ -81,6 +81,7 @@
"name": "fileSize",
"value": "Qt::DisplayRole",
"type": "quint64",
"write": true,
"optional": true
}]
]

View File

@ -206,9 +206,10 @@ QList<Role> parseRoles(const QJsonArray& roles, QList<Role>& all) {
const Role role = parseRole(val.toObject());
r.append(role);
bool found = false;
for (auto ar: all) {
for (Role& ar: all) {
if (ar.name == role.name) {
found = true;
ar.write |= role.write;
if (ar.type.name != role.type.name) {
err << QCoreApplication::translate("main",
"Role %1 has two different types: %2 and %3.\n")
@ -362,8 +363,8 @@ void writeCppModel(QTextStream& cpp, const Object& o) {
.arg(o.name, lcname, snakeCase(role.name), cppSetType(role), indexDecl);
}
if (role.write) {
// cpp << QString(" void %2_data_%3_set(%1::Private*, %3);")
// .arg(o.name, base, p.type.cSetType) << endl;
cpp << QString(" bool %2_set_data_%3(%1::Private*%5, %4);")
.arg(o.name, lcname, snakeCase(role.name), role.type.cSetType, indexDecl) << endl;
if (role.optional) {
cpp << QString(" bool %2_set_data_%3_none(%1::Private*%4);")
.arg(o.name, lcname, snakeCase(role.name), indexDecl) << endl;
@ -548,7 +549,7 @@ bool %1::setData(const QModelIndex &index, const QVariant &value, int role)
if (!role.write) {
continue;
}
cpp << " if (role == (" << role.value << ")) {\n";
cpp << " if (role == " << role.value << ") {\n";
if (role.optional) {
QString test = "!value.isValid()";
if (role.type.isComplex()) {
@ -559,7 +560,13 @@ bool %1::setData(const QModelIndex &index, const QVariant &value, int role)
.arg(lcname, snakeCase(role.name), index) << endl;
cpp << " }\n";
}
cpp << " return true;\n";
QString val = QString("value.value<%1>()").arg(role.type.name);
if (role.type.isComplex()) {
val = "val";
cpp << QString(" const %1 val(value.value<%1>());\n").arg(role.type.name);
}
cpp << QString(" return %1_set_data_%2(d%3, %4);")
.arg(lcname, snakeCase(role.name), index, val) << endl;
cpp << " }\n";
}
cpp << " }\n";
@ -1232,6 +1239,23 @@ pub unsafe extern "C" fn %2_data_%3(ptr: *const %1, row: c_int%5) -> %4 {
(&*ptr).%3(row%6).into()
}
)").arg(o.name, lcname, snakeCase(role.name), rustCType(role), indexDecl, index);
}
if (role.write) {
QString val = "v";
QString type = role.type.rustType;
if (role.type.isComplex()) {
val = val + ".convert()";
type = role.type.name == "QString" ? "QStringIn" : role.type.name;
}
if (role.optional) {
val = "Some(" + val + ")";
}
r << QString(R"(
#[no_mangle]
pub unsafe extern "C" fn %2_set_data_%3(ptr: *mut %1, row: c_int%4, v: %6) -> bool {
(&mut *ptr).set_%3(row%5, %7)
}
)").arg(o.name, lcname, snakeCase(role.name), indexDecl, index, type, val);
}
if (role.write && role.optional) {
r << QString(R"(