Skip to content

Commit f5c2664

Browse files
Add access to internalPointer to QModelIndex
Unfortunately this currently requires the use of our own c_void type. See: dtolnay/cxx#1049 Closes #719
1 parent acb4339 commit f5c2664

File tree

5 files changed

+88
-1
lines changed

5 files changed

+88
-1
lines changed

crates/cxx-qt-lib-headers/include/common.h

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
namespace rust {
1515
namespace cxxqtlib1 {
1616

17+
using c_void = void;
18+
1719
template<typename T, typename... Args>
1820
T
1921
construct(Args... args)

crates/cxx-qt-lib/src/core/mod.rs

+30
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,33 @@ pub use qvariant::{QVariant, QVariantValue};
9595

9696
mod qvector;
9797
pub use qvector::{QVector, QVectorElement};
98+
99+
#[cxx::bridge]
100+
mod ffi {
101+
#[namespace = "rust::cxxqtlib1"]
102+
unsafe extern "C++" {
103+
include!("cxx-qt-lib/common.h");
104+
type c_void;
105+
}
106+
}
107+
108+
/// This is a workaround for CXX missing support for `*mut c_void`/`*const c_void` types.
109+
///
110+
/// To use this type add this to your bridge:
111+
/// ```rust
112+
/// # #[cxx::bridge]
113+
/// # mod ffi {
114+
/// #
115+
/// #[namespace = "rust::cxxqtlib1"]
116+
/// unsafe extern "C++" {
117+
/// include!("cxx-qt-lib/common.h");
118+
/// type c_void = cxx_qt_lib::c_void;
119+
/// }
120+
/// #
121+
/// # }
122+
/// #
123+
/// # fn main() {}
124+
/// ```
125+
///
126+
/// See: <https://github.com/dtolnay/cxx/issues/1049>
127+
pub use ffi::c_void;

crates/cxx-qt-lib/src/core/qmodelindex.rs

+5
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,16 @@ mod ffi {
3434
/// Returns the sibling at row for the current column. If there is no sibling at this position, an invalid QModelIndex is returned.
3535
#[rust_name = "sibling_at_row"]
3636
fn siblingAtRow(self: &QModelIndex, row: i32) -> QModelIndex;
37+
38+
/// Returns a `*mut c_void` pointer used by the model to associate the index with the internal data structure.
39+
#[rust_name = "internal_pointer_mut"]
40+
fn internalPointer(self: &QModelIndex) -> *mut c_void;
3741
}
3842

3943
#[namespace = "rust::cxxqtlib1"]
4044
unsafe extern "C++" {
4145
include!("cxx-qt-lib/common.h");
46+
type c_void = crate::c_void;
4247

4348
#[doc(hidden)]
4449
#[rust_name = "qmodelindex_init_default"]

tests/qt_types_standalone/cpp/qmodelindex.h

+35-1
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,31 @@
66
// SPDX-License-Identifier: MIT OR Apache-2.0
77
#pragma once
88

9+
#include <QtCore/QAbstractListModel>
910
#include <QtCore/QModelIndex>
1011
#include <QtCore/QStringListModel>
1112
#include <QtTest/QTest>
1213

1314
#include "cxx-qt-gen/qmodelindex_cxx.cxx.h"
1415

15-
class QModelIndexTest : public QObject
16+
// We subclass from QAbstractListModel to have a valid model to use for
17+
// access to createIndex();
18+
class QModelIndexTest : public QAbstractListModel
1619
{
1720
Q_OBJECT
1821

22+
public:
23+
int rowCount(const QModelIndex& parent = QModelIndex()) const override
24+
{
25+
return 0;
26+
}
27+
28+
QVariant data(const QModelIndex& index,
29+
int role = Qt::DisplayRole) const override
30+
{
31+
return QVariant();
32+
}
33+
1934
private Q_SLOTS:
2035
void construct()
2136
{
@@ -38,4 +53,23 @@ private Q_SLOTS:
3853
QCOMPARE(c.isValid(), true);
3954
QCOMPARE(c.row(), 0);
4055
}
56+
57+
void internalPointer()
58+
{
59+
const auto index = createIndex(0, 0, (void*)&my_data);
60+
61+
auto pointer = internal_pointer_qmodelindex(index);
62+
QCOMPARE((int*)pointer, &my_data);
63+
}
64+
65+
void internalId()
66+
{
67+
const auto index = createIndex(0, 0, (quintptr)1234);
68+
69+
auto id = internal_id_qmodelindex(index);
70+
QCOMPARE(id, 1234);
71+
}
72+
73+
private:
74+
int my_data = 42;
4175
};

tests/qt_types_standalone/rust/src/qmodelindex.rs

+16
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,18 @@ mod qmodelindex_cxx {
1212
type QModelIndex = cxx_qt_lib::QModelIndex;
1313
}
1414

15+
#[namespace = "rust::cxxqtlib1"]
16+
unsafe extern "C++" {
17+
include!("cxx-qt-lib/common.h");
18+
type c_void = cxx_qt_lib::c_void;
19+
}
20+
1521
extern "Rust" {
1622
fn construct_qmodelindex() -> QModelIndex;
1723
fn read_qmodelindex(i: &QModelIndex) -> bool;
1824
fn clone_qmodelindex(i: &QModelIndex) -> QModelIndex;
25+
fn internal_pointer_qmodelindex(i: &QModelIndex) -> *mut c_void;
26+
fn internal_id_qmodelindex(i: &QModelIndex) -> usize;
1927
}
2028
}
2129

@@ -30,3 +38,11 @@ fn read_qmodelindex(i: &QModelIndex) -> bool {
3038
fn clone_qmodelindex(i: &QModelIndex) -> QModelIndex {
3139
i.clone()
3240
}
41+
42+
fn internal_pointer_qmodelindex(i: &QModelIndex) -> *mut qmodelindex_cxx::c_void {
43+
i.internal_pointer_mut()
44+
}
45+
46+
fn internal_id_qmodelindex(i: &QModelIndex) -> usize {
47+
i.internal_id()
48+
}

0 commit comments

Comments
 (0)