Skip to content

Commit

Permalink
Add access to internalPointer to QModelIndex
Browse files Browse the repository at this point in the history
Unfortunately this currently requires the use of our own c_void type.
See: dtolnay/cxx#1049

Closes KDAB#719
  • Loading branch information
LeonMatthesKDAB committed Dec 15, 2023
1 parent 5745154 commit 0dbba57
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Support for further types: `QLine`, `QLineF`, `QImage`
- `internal_pointer_mut()` function on `QModelIndex`
- `c_void` in CXX-Qt-lib for easy access to `void *`

## [0.6.0](https://github.com/KDAB/cxx-qt/compare/v0.5.3...v0.6.0) - 2023-11-17

Expand Down
2 changes: 2 additions & 0 deletions crates/cxx-qt-lib-headers/include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
namespace rust {
namespace cxxqtlib1 {

using c_void = void;

template<typename T, typename... Args>
T
construct(Args... args)
Expand Down
30 changes: 30 additions & 0 deletions crates/cxx-qt-lib/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,33 @@ pub use qvariant::{QVariant, QVariantValue};

mod qvector;
pub use qvector::{QVector, QVectorElement};

#[cxx::bridge]
mod ffi {
#[namespace = "rust::cxxqtlib1"]
unsafe extern "C++" {
include!("cxx-qt-lib/common.h");
type c_void;
}
}

/// This is a workaround for CXX missing support for `*mut c_void`/`*const c_void` types.
///
/// To use this type add this to your bridge:
/// ```rust
/// # #[cxx::bridge]
/// # mod ffi {
/// #
/// #[namespace = "rust::cxxqtlib1"]
/// unsafe extern "C++" {
/// include!("cxx-qt-lib/common.h");
/// type c_void = cxx_qt_lib::c_void;
/// }
/// #
/// # }
/// #
/// # fn main() {}
/// ```
///
/// See: <https://github.com/dtolnay/cxx/issues/1049>
pub use ffi::c_void;
5 changes: 5 additions & 0 deletions crates/cxx-qt-lib/src/core/qmodelindex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,16 @@ mod ffi {
/// Returns the sibling at row for the current column. If there is no sibling at this position, an invalid QModelIndex is returned.
#[rust_name = "sibling_at_row"]
fn siblingAtRow(self: &QModelIndex, row: i32) -> QModelIndex;

/// Returns a `*mut c_void` pointer used by the model to associate the index with the internal data structure.
#[rust_name = "internal_pointer_mut"]
fn internalPointer(self: &QModelIndex) -> *mut c_void;
}

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

#[doc(hidden)]
#[rust_name = "qmodelindex_init_default"]
Expand Down
36 changes: 35 additions & 1 deletion tests/qt_types_standalone/cpp/qmodelindex.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,31 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
#pragma once

#include <QtCore/QAbstractListModel>
#include <QtCore/QModelIndex>
#include <QtCore/QStringListModel>
#include <QtTest/QTest>

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

class QModelIndexTest : public QObject
// We subclass from QAbstractListModel to have a valid model to use for
// access to createIndex();
class QModelIndexTest : public QAbstractListModel
{
Q_OBJECT

public:
int rowCount(const QModelIndex& parent = QModelIndex()) const override
{
return 0;
}

QVariant data(const QModelIndex& index,
int role = Qt::DisplayRole) const override
{
return QVariant();
}

private Q_SLOTS:
void construct()
{
Expand All @@ -38,4 +53,23 @@ private Q_SLOTS:
QCOMPARE(c.isValid(), true);
QCOMPARE(c.row(), 0);
}

void internalPointer()
{
const auto index = createIndex(0, 0, (void*)&my_data);

auto pointer = internal_pointer_qmodelindex(index);
QCOMPARE((int*)pointer, &my_data);
}

void internalId()
{
const auto index = createIndex(0, 0, (quintptr)1234);

auto id = internal_id_qmodelindex(index);
QCOMPARE(id, 1234);
}

private:
int my_data = 42;
};
16 changes: 16 additions & 0 deletions tests/qt_types_standalone/rust/src/qmodelindex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ mod qmodelindex_cxx {
type QModelIndex = cxx_qt_lib::QModelIndex;
}

#[namespace = "rust::cxxqtlib1"]
unsafe extern "C++" {
include!("cxx-qt-lib/common.h");
type c_void = cxx_qt_lib::c_void;
}

extern "Rust" {
fn construct_qmodelindex() -> QModelIndex;
fn read_qmodelindex(i: &QModelIndex) -> bool;
fn clone_qmodelindex(i: &QModelIndex) -> QModelIndex;
fn internal_pointer_qmodelindex(i: &QModelIndex) -> *mut c_void;
fn internal_id_qmodelindex(i: &QModelIndex) -> usize;
}
}

Expand All @@ -30,3 +38,11 @@ fn read_qmodelindex(i: &QModelIndex) -> bool {
fn clone_qmodelindex(i: &QModelIndex) -> QModelIndex {
i.clone()
}

fn internal_pointer_qmodelindex(i: &QModelIndex) -> *mut qmodelindex_cxx::c_void {
i.internal_pointer_mut()
}

fn internal_id_qmodelindex(i: &QModelIndex) -> usize {
i.internal_id()
}

0 comments on commit 0dbba57

Please sign in to comment.