Define roles per column

master
Jos van den Oever 2017-08-13 12:49:53 +02:00
parent b78cf46a70
commit 4781e9147b
5 changed files with 152 additions and 69 deletions

View File

@ -33,22 +33,38 @@
"type": "QString",
"write": true
}],
"roles": [{
"name": "FileIcon",
"value": "Qt::DecorationRole",
"type": "QByteArray"
}, {
"name": "FilePath",
"value": "Qt::UserRole + 1",
"type": "QString"
}, {
"name": "FileName",
"value": "Qt::UserRole + 2",
"type": "QString"
}, {
"name": "FilePermissions",
"value": "Qt::UserRole + 3",
"type": "int"
}]
"roles": [
[{
"name": "FileName",
"value": "Qt::DisplayRole",
"type": "QString"
}, {
"name": "FileIcon",
"value": "Qt::DecorationRole",
"type": "QByteArray"
}, {
"name": "FilePath",
"value": "Qt::UserRole + 1",
"type": "QString"
}, {
"name": "FileName",
"value": "Qt::UserRole + 2",
"type": "QString"
}, {
"name": "FilePermissions",
"value": "Qt::UserRole + 3",
"type": "int"
}],
[{
"name": "FilePath",
"value": "Qt::DisplayRole",
"type": "QString"
}],
[{
"name": "FilePermissions",
"value": "Qt::DisplayRole",
"type": "int"
}]
]
}]
}

View File

@ -77,15 +77,15 @@ impl DirectoryTrait for Directory {
fn row_count(&self) -> c_int {
10
}
fn file_name(&self, row: c_int) -> String {
String::new()
}
fn file_icon(&self, row: c_int) -> Vec<u8> {
Vec::new()
}
fn file_path(&self, row: c_int) -> String {
String::new()
}
fn file_name(&self, row: c_int) -> String {
String::new()
}
fn file_permissions(&self, row: c_int) -> c_int {
0
}

View File

@ -181,9 +181,9 @@ pub trait DirectoryTrait {
fn row_count(&self) -> c_int;
fn can_fetch_more(&self) -> bool { false }
fn fetch_more(&self) {}
fn file_name(&self, row: c_int) -> String;
fn file_icon(&self, row: c_int) -> Vec<u8>;
fn file_path(&self, row: c_int) -> String;
fn file_name(&self, row: c_int) -> String;
fn file_permissions(&self, row: c_int) -> c_int;
}
@ -245,6 +245,15 @@ pub unsafe extern "C" fn directory_fetch_more(ptr: *mut Directory) {
(&mut *ptr).fetch_more()
}
#[no_mangle]
pub unsafe extern "C" fn directory_data_file_name(ptr: *const Directory,
row: c_int,
d: *mut c_void,
set: fn(*mut c_void, QString)) {
let data = (&*ptr).file_name(row);
set(d, QString::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn directory_data_file_icon(ptr: *const Directory,
row: c_int,
@ -263,15 +272,6 @@ pub unsafe extern "C" fn directory_data_file_path(ptr: *const Directory,
set(d, QString::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn directory_data_file_name(ptr: *const Directory,
row: c_int,
d: *mut c_void,
set: fn(*mut c_void, QString)) {
let data = (&*ptr).file_name(row);
set(d, QString::from(&data));
}
#[no_mangle]
pub unsafe extern "C" fn directory_data_file_permissions(ptr: *const Directory, row: c_int) -> c_int {
(&*ptr).file_permissions(row)

View File

@ -128,16 +128,16 @@ void Directory::setPath(const QString& v) {
directory_path_set(d, v);
}
enum DirectoryRole {
DirectoryRoleFileName = Qt::DisplayRole,
DirectoryRoleFileIcon = Qt::DecorationRole,
DirectoryRoleFilePath = Qt::UserRole + 1,
DirectoryRoleFileName = Qt::UserRole + 2,
DirectoryRoleFilePermissions = Qt::UserRole + 3,
};
extern "C" {
void directory_data_file_name(DirectoryInterface*, int, QString*, qstring_set);
void directory_data_file_icon(DirectoryInterface*, int, QByteArray*, qbytearray_set);
void directory_data_file_path(DirectoryInterface*, int, QString*, qstring_set);
void directory_data_file_name(DirectoryInterface*, int, QString*, qstring_set);
int directory_data_file_permissions(DirectoryInterface*, int);
int directory_row_count(DirectoryInterface*);
@ -184,30 +184,53 @@ QVariant Directory::data(const QModelIndex &index, int role) const
QVariant v;
QString s;
QByteArray b;
switch ((DirectoryRole)role) {
case DirectoryRoleFileIcon:
directory_data_file_icon(d, index.row(), &b, set_qbytearray);
v.setValue<QByteArray>(b);
switch (index.column()) {
case 0:
switch (role) {
case Qt::DisplayRole:
directory_data_file_name(d, index.row(), &s, set_qstring);
v.setValue<QString>(s);
break;
case Qt::DecorationRole:
directory_data_file_icon(d, index.row(), &b, set_qbytearray);
v.setValue<QByteArray>(b);
break;
case Qt::UserRole + 1:
directory_data_file_path(d, index.row(), &s, set_qstring);
v.setValue<QString>(s);
break;
case Qt::UserRole + 2:
directory_data_file_name(d, index.row(), &s, set_qstring);
v.setValue<QString>(s);
break;
case Qt::UserRole + 3:
v.setValue<int>(directory_data_file_permissions(d, index.row()));
break;
}
break;
case DirectoryRoleFilePath:
directory_data_file_path(d, index.row(), &s, set_qstring);
v.setValue<QString>(s);
case 1:
switch (role) {
case Qt::DisplayRole:
directory_data_file_path(d, index.row(), &s, set_qstring);
v.setValue<QString>(s);
break;
}
break;
case DirectoryRoleFileName:
directory_data_file_name(d, index.row(), &s, set_qstring);
v.setValue<QString>(s);
break;
case DirectoryRoleFilePermissions:
v.setValue<int>(directory_data_file_permissions(d, index.row()));
case 2:
switch (role) {
case Qt::DisplayRole:
v.setValue<int>(directory_data_file_permissions(d, index.row()));
break;
}
break;
}
return v;
}
QHash<int, QByteArray> Directory::roleNames() const {
QHash<int, QByteArray> names;
names.insert(Qt::DisplayRole, "FileName");
names.insert(Qt::DecorationRole, "FileIcon");
names.insert(Qt::UserRole + 1, "FilePath");
names.insert(Qt::UserRole + 2, "FileName");
names.insert(Qt::UserRole + 3, "FilePermissions");
return names;
}

View File

@ -99,7 +99,8 @@ struct Object {
QString name;
ObjectType type;
QList<Property> properties;
QList<Role> roles;
QList<QList<Role>> columnRoles;
QList<Role> allRoles;
};
struct Configuration {
@ -145,6 +146,31 @@ parseRole(const QJsonObject& json) {
return r;
}
QList<Role> parseRoles(const QJsonArray& roles, QList<Role>& all) {
QList<Role> r;
for (const QJsonValue& val: roles) {
const Role role = parseRole(val.toObject());
r.append(role);
bool found = false;
for (auto ar: all) {
if (ar.name == role.name) {
found = true;
if (ar.type.name != role.type.name) {
err << QCoreApplication::translate("main",
"Role %1 has two different types: %2 and %3.\n")
.arg(ar.name, ar.type.name, role.type.name);
err.flush();
exit(1);
}
}
}
if (!found) {
all.append(role);
}
}
return r;
}
Object
parseObject(const QJsonObject& json) {
Object o;
@ -158,8 +184,19 @@ parseObject(const QJsonObject& json) {
for (const QJsonValue& val: json.value("properties").toArray()) {
o.properties.append(parseProperty(val.toObject()));
}
for (const QJsonValue& val: json.value("roles").toArray()) {
o.roles.append(parseRole(val.toObject()));
QJsonArray roles = json.value("roles").toArray();
if (o.type != ObjectTypeObject && roles.size() == 0) {
err << QCoreApplication::translate("main",
"No roles are defined for %1.\n").arg(o.name);
err.flush();
exit(1);
}
if (roles.at(0).isArray()) {
for (const QJsonValue& val: roles) {
o.columnRoles.append(parseRoles(val.toArray(), o.allRoles));
}
} else {
o.columnRoles.append(parseRoles(roles, o.allRoles));
}
return o;
}
@ -241,13 +278,13 @@ void writeCppListModel(QTextStream& cpp, const Object& o) {
const QString lcname(snakeCase(o.name));
cpp << "enum " << o.name << "Role {\n";
for (auto role: o.roles) {
for (auto role: o.allRoles) {
cpp << " " << o.name << "Role" << role.name << " = " << role.value << ",\n";
}
cpp << "};\n\n";
cpp << "extern \"C\" {\n";
for (auto role: o.roles) {
for (auto role: o.allRoles) {
if (role.type.isComplex()) {
cpp << QString(" void %2_data_%3(%1Interface*, int, %4);\n")
.arg(o.name, lcname, snakeCase(role.name), cGetType(role.type));
@ -301,29 +338,36 @@ QVariant %1::data(const QModelIndex &index, int role) const
QVariant v;
QString s;
QByteArray b;
switch ((%1Role)role) {
switch (index.column()) {
)").arg(o.name, lcname);
for (auto role: o.roles) {
cpp << QString(" case %1Role%2:\n").arg(o.name, role.name);
if (role.type.name == "QString") {
cpp << QString(" %1_data_%2(d, index.row(), &s, set_%3);\n")
.arg(lcname, snakeCase(role.name), role.type.name.toLower());
cpp << " v.setValue<QString>(s);\n";
} else if (role.type.name == "QByteArray") {
cpp << QString(" %1_data_%2(d, index.row(), &b, set_%3);\n")
.arg(lcname, snakeCase(role.name), role.type.name.toLower());
cpp << " v.setValue<QByteArray>(b);\n";
} else {
cpp << QString(" v.setValue<%3>(%1_data_%2(d, index.row()));\n")
.arg(lcname, snakeCase(role.name), role.type.name);
for (int col = 0; col < o.columnRoles.size(); ++col) {
auto roles = o.columnRoles[col];
cpp << QString(" case %1:\n").arg(col);
cpp << QString(" switch (role) {\n");
for (auto role: roles) {
cpp << QString(" case %1:\n").arg(role.value);
if (role.type.name == "QString") {
cpp << QString(" %1_data_%2(d, index.row(), &s, set_%3);\n")
.arg(lcname, snakeCase(role.name), role.type.name.toLower());
cpp << " v.setValue<QString>(s);\n";
} else if (role.type.name == "QByteArray") {
cpp << QString(" %1_data_%2(d, index.row(), &b, set_%3);\n")
.arg(lcname, snakeCase(role.name), role.type.name.toLower());
cpp << " v.setValue<QByteArray>(b);\n";
} else {
cpp << QString(" v.setValue<%3>(%1_data_%2(d, index.row()));\n")
.arg(lcname, snakeCase(role.name), role.type.name);
}
cpp << " break;\n";
}
cpp << " }\n";
cpp << " break;\n";
}
cpp << " }\n return v;\n}\n";
cpp << "QHash<int, QByteArray> " << o.name << "::roleNames() const {\n";
cpp << " QHash<int, QByteArray> names;\n";
for (auto role: o.roles) {
for (auto role: o.allRoles) {
cpp << " names.insert(" << role.value << ", \"" << role.name << "\");\n";
}
cpp << " return names;\n";
@ -642,7 +686,7 @@ pub trait %1Trait {
r << " fn row_count(&self) -> c_int;\n";
r << " fn can_fetch_more(&self) -> bool { false }\n";
r << " fn fetch_more(&self) {}\n";
for (auto role: o.roles) {
for (auto role: o.allRoles) {
r << QString(" fn %1(&self, row: c_int) -> %2;\n")
.arg(snakeCase(role.name), role.type.rustType);
}
@ -751,7 +795,7 @@ pub unsafe extern "C" fn %2_fetch_more(ptr: *mut %1) {
(&mut *ptr).fetch_more()
}
)").arg(o.name, lcname);
for (auto role: o.roles) {
for (auto role: o.allRoles) {
if (role.type.isComplex()) {
r << QString(R"(
#[no_mangle]
@ -851,7 +895,7 @@ void writeRustImplementationObject(QTextStream& r, const Object& o) {
}
if (o.type == ObjectTypeList) {
r << " fn row_count(&self) -> c_int {\n 10\n }\n";
for (auto role: o.roles) {
for (auto role: o.allRoles) {
r << QString(" fn %1(&self, row: c_int) -> %2 {\n")
.arg(snakeCase(role.name), role.type.rustType);
r << " " << role.type.rustTypeInit << "\n";