1use super::proxy_cpp_bridge::{QListModelProxyCpp, ffi};
5use crate::{RustObjAccess, call_rust_trait_impl, call_cpp_impl};
6use qtbridge_runtime::qrustproxy::{QRustProxy, ConstructionMode};
7use qtbridge_runtime::{DispatchMetaCall, QObjectHolder};
8use qtbridge_runtime::QModelItem;
9use qtbridge_type_lib::{QByteArray, QHash, QMetaObject, QMetaType, QModelIndex, QVariant};
10use std::cell::RefCell;
11use std::rc::Rc;
12
13#[doc(hidden)]
14pub trait QListModelAdapter: DispatchMetaCall {
15 fn index(&self, row: i32, column: i32, parent: &QModelIndex) -> QModelIndex;
16 fn row_count(&self, parent: &QModelIndex) -> i32;
17 fn data(&self, index: &QModelIndex, role: i32) -> QVariant;
18 fn role_names(&self) -> QHash<i32, QByteArray>;
19 fn set_data(&mut self, index: &QModelIndex, value: &QVariant, role: i32) -> bool;
20 fn remove_rows(&mut self, first: i32, count: i32, parent: &QModelIndex) -> bool;
21 fn sibling(&self, row: i32, column: i32, idx: &QModelIndex) -> QModelIndex;
22}
23
24impl<T> QListModelAdapter for T
25where
26 T: QListModel + QObjectHolder<ProxyRust = QListModelProxyRust> {
27 fn index(&self, row: i32, column: i32, parent: &QModelIndex) -> QModelIndex {
28 let proxy = <Self as QObjectHolder>::get_rust_proxy(self);
29 proxy.base_index(row, column, parent)
30 }
31 fn row_count(&self, _parent: &QModelIndex) -> i32 {
32 return self.len() as i32;
33 }
34 fn data(&self, index: &QModelIndex, role: i32) -> QVariant {
35 let Some(item) = self.get(index.row() as usize)
36 else {
37 return QVariant::default();
38 };
39 item.get_role(role)
40 }
41 fn role_names(&self) -> QHash<i32, QByteArray> {
42 let names = T::Item::role_names();
43 let mut result = QHash::default();
44 names.iter()
45 .for_each(|(k, v)| result.insert(k, &QByteArray::from(v)));
46 result
47 }
48 fn set_data(&mut self, index: &QModelIndex, value: &QVariant, role: i32) -> bool {
49 if !index.is_valid() {
50 return false;
51 }
52 let Some(mut item) = self.get(index.row() as usize)
53 .cloned()
54 else {
55 return false;
56 };
57 let updated = item.set_role(role, value);
58 if updated {
59 self.set_unnotified(index.row() as usize, item);
60 self.get_rust_proxy_mut().base_data_changed(index, index);
61 }
62 updated
63 }
64 fn remove_rows(&mut self, first: i32, count: i32, parent: &QModelIndex) -> bool {
65 let first = first as usize;
66 let last = first + count as usize;
67 if last > self.len() {
68 return false;
69 }
70 self.get_rust_proxy_mut().base_begin_remove_rows(parent, first as i32, (last - 1) as i32);
71 for index in (first..last).rev() {
72 self.remove_unnotified(index);
73 }
74 self.get_rust_proxy_mut().base_end_remove_rows();
75 true
76 }
77 fn sibling(&self, row: i32, column: i32, idx: &QModelIndex) -> QModelIndex {
78 let proxy = self.get_rust_proxy();
79 proxy.base_sibling(row, column, idx)
80 }
81}
82
83pub trait QListModel {
154 type Item: QModelItem + Default + Clone;
161
162 fn len(&self) -> usize;
164
165 fn get(&self, index: usize) -> Option<&Self::Item>;
168
169 fn set_unnotified(&mut self, _index: usize, _value: Self::Item) -> bool {
178 false
179 }
180
181 fn push_unnotified(&mut self, value: Self::Item) {
191 self.insert_unnotified(self.len(), value);
192 }
193
194 fn insert_unnotified(&mut self, _index: usize, _value: Self::Item) {
204 panic!("In order to use insert, implement insert_unnotified")
205 }
206
207 fn pop_unnotified(&mut self) -> Option<Self::Item> {
217 (self.len() > 0)
218 .then(|| self.remove_unnotified(self.len() - 1))
219 }
220
221 fn remove_unnotified(&mut self, _index: usize) -> Self::Item {
231 panic!("In order to use remove, implement remove_unnotified")
232 }
233
234 fn reset_unnotified(&mut self) {
244 panic!("In order to use reset, implement reset_unnotified")
245 }
246
247}
248
249pub trait QListModelBase : QListModel + QObjectHolder<ProxyRust = QListModelProxyRust> {
277 fn set(&mut self, index: usize, value: <Self as QListModel>::Item) -> bool {
286 if self.set_unnotified(index, value) {
287 let model_index = self.get_rust_proxy().base_index(index as i32, 0 , &QModelIndex::default());
288 self.get_rust_proxy_mut().base_data_changed(&model_index, &model_index);
289 true
290 } else {
291 false
292 }
293 }
294
295 fn push(&mut self, value: Self::Item) {
300 self.get_rust_proxy_mut().base_begin_insert_rows(&QModelIndex::default(), self.len() as i32, self.len() as i32);
301 self.push_unnotified(value);
302 self.get_rust_proxy_mut().base_end_insert_rows();
303 }
304
305 fn insert(&mut self, index: usize, value: Self::Item) {
310 self.get_rust_proxy_mut().base_begin_insert_rows(&QModelIndex::default(), index as i32, index as i32);
311 self.insert_unnotified(index, value);
312 self.get_rust_proxy_mut().base_end_insert_rows();
313 }
314
315 fn pop(&mut self) -> Option<Self::Item> {
323 if self.len() == 0 {
324 return None;
325 }
326 self.get_rust_proxy_mut().base_begin_remove_rows(&QModelIndex::default(), self.len() as i32 - 1, self.len() as i32 - 1);
327 let value = self.pop_unnotified();
328 self.get_rust_proxy_mut().base_end_remove_rows();
329 value
330 }
331
332 fn remove(&mut self, index: usize) -> Self::Item {
337 self.get_rust_proxy_mut().base_begin_remove_rows(&QModelIndex::default(), index as i32, index as i32);
338 let value = self.remove_unnotified(index);
339 self.get_rust_proxy_mut().base_end_remove_rows();
340 value
341 }
342 fn reset(&mut self) {
346 self.get_rust_proxy_mut().base_begin_reset_model();
347 self.reset_unnotified();
348 self.get_rust_proxy_mut().base_end_reset_model();
349 }
350}
351
352impl<T> QListModelBase for T
353where T: QListModel + QObjectHolder<ProxyRust = QListModelProxyRust> { }
354
355pub struct QListModelProxyRust {
356 cpp_proxy: *mut QListModelProxyCpp,
357 #[allow(dead_code)]
358 rust_obj: RustObjAccess<dyn QListModelAdapter>,
359 on_drop: Box<dyn FnOnce()>,
360}
361
362impl QRustProxy for QListModelProxyRust {
363
364 type ProxyCppType = QListModelProxyCpp;
365 type AdapterType = dyn QListModelAdapter;
366
367 fn new<OnDropFn: FnOnce() + 'static>(rust_obj: &Rc<RefCell<dyn QListModelAdapter>>, construct: ConstructionMode, on_drop: OnDropFn) -> *mut Self {
368 let boxed_self = Box::new(Self {
369 cpp_proxy: std::ptr::null_mut(),
370 rust_obj: match construct {
371 ConstructionMode::Strong | ConstructionMode::AtAddress(_) => RustObjAccess::new_strong(rust_obj.clone()),
372 ConstructionMode::Weak => RustObjAccess::new_weak(Rc::downgrade(rust_obj)),
373 },
374 on_drop: Box::new(on_drop),
375 });
376 let raw_self = Box::into_raw(boxed_self);
377
378 unsafe{ (*raw_self).cpp_proxy = match construct {
379 ConstructionMode::AtAddress(addr) => {
380 ffi::create_qlist_model_proxy_cpp_at( addr, raw_self)
381 }
382 ConstructionMode::Strong | ConstructionMode::Weak => {
383 ffi::create_qlist_model_proxy_cpp(raw_self)
384 }
385 }};
386 raw_self
387 }
388 fn get_static_meta_object() -> &'static QMetaObject {
389 ffi::static_qmeta_object_of_qlist_model_proxy_cpp()
390 }
391 fn get_size_of_cpp_proxy() -> usize {
392 ffi::size_of_qlist_model_proxy_cpp()
393 }
394 fn get_align_of_cpp_proxy() -> usize {
395 ffi::align_of_qlist_model_proxy_cpp()
396 }
397 fn get_qmetatype_list_of_cpp_proxy() -> QMetaType {
398 ffi::qmetatype_list_of_qlist_model_proxy_cpp()
399 }
400 fn get_cpp_proxy(&self) -> *const QListModelProxyCpp {
401 self.cpp_proxy as *const _
402 }
403 fn get_cpp_proxy_mut(&self) -> *mut QListModelProxyCpp {
404 self.cpp_proxy
405 }
406}
407
408impl QListModelProxyRust {
409 pub fn drop_self(self_ptr: *mut Self) {
410 let boxed_self = unsafe { Box::from_raw(self_ptr) };
411 (boxed_self.on_drop)();
412 }
413 pub fn invoke_slot(&self, slot_id: u32, inputs: &[*const u8], outputs: &[*mut u8]) {
414 call_rust_trait_impl!(self, invoke_slot(slot_id, inputs, outputs))
415 }
416 pub fn invoke_slot_mut(&mut self, slot_id: u32, inputs: &[*const u8], outputs: &[*mut u8]) {
417 call_rust_trait_impl!(mut self, invoke_slot_mut(slot_id, inputs, outputs))
418 }
419 pub fn read_property(&self, prop_id: u32) -> QVariant {
420 call_rust_trait_impl!(self, read_property(prop_id))
421 }
422 pub fn write_property(&mut self, prop_id: u32, value: &QVariant) {
423 call_rust_trait_impl!(mut self, write_property(prop_id, value))
424 }
425 pub fn index(&self, row: i32, column: i32, parent: &QModelIndex) -> QModelIndex {
426 call_rust_trait_impl!(self, index(row, column, parent))
427 }
428 pub fn row_count(&self, parent: &QModelIndex) -> i32 {
429 call_rust_trait_impl!(self, row_count(parent))
430 }
431 pub fn data(&self, index: &QModelIndex, role: i32) -> QVariant {
432 call_rust_trait_impl!(self, data(index, role))
433 }
434 pub fn role_names(&self) -> QHash<i32, QByteArray> {
435 call_rust_trait_impl!(self, role_names())
436 }
437 pub fn set_data(&mut self, index: &QModelIndex, value: &QVariant, role: i32) -> bool {
438 call_rust_trait_impl!(mut self, set_data(index, value, role))
439 }
440 pub fn remove_rows(&mut self, first: i32, count: i32, parent: &QModelIndex) -> bool {
441 call_rust_trait_impl!(mut self, remove_rows(first, count, parent))
442 }
443 pub fn sibling(&self, row: i32, column: i32, idx: &QModelIndex) -> QModelIndex {
444 call_rust_trait_impl!(self, sibling(row, column, idx))
445 }
446 pub fn base_index(&self, row: i32, column: i32, parent: &QModelIndex) -> QModelIndex {
447 call_cpp_impl!(self, base_index(row, column, parent))
448 }
449 pub fn base_role_names(&self) -> QHash<i32, QByteArray> {
450 call_cpp_impl!(self, base_role_names())
451 }
452 pub fn base_set_data(&mut self, index: &QModelIndex, value: &QVariant, role: i32) -> bool {
453 call_cpp_impl!(mut self, base_set_data(index, value, role))
454 }
455 pub fn base_remove_rows(&mut self, first: i32, count: i32, parent: &QModelIndex) -> bool {
456 call_cpp_impl!(mut self, base_remove_rows(first, count, parent))
457 }
458 pub fn base_sibling(&self, row: i32, column: i32, idx: &QModelIndex) -> QModelIndex {
459 call_cpp_impl!(self, base_sibling(row, column, idx))
460 }
461 pub fn base_data_changed(&mut self, top_left: &QModelIndex, bottom_right: &QModelIndex) {
462 call_cpp_impl!(mut self, base_data_changed(top_left, bottom_right))
463 }
464 pub fn base_begin_insert_rows(&mut self, parent: &QModelIndex, first: i32, last: i32) {
465 call_cpp_impl!(mut self, base_begin_insert_rows(parent, first, last))
466 }
467 pub fn base_end_insert_rows(&mut self) {
468 call_cpp_impl!(mut self, base_end_insert_rows())
469 }
470 pub fn base_begin_move_rows(&mut self, source_parent: &QModelIndex, source_first: i32, source_last: i32, destination_parent: &QModelIndex, destination_child: i32) {
471 call_cpp_impl!(mut self, base_begin_move_rows(source_parent, source_first, source_last, destination_parent, destination_child))
472 }
473 pub fn base_end_move_rows(&mut self) {
474 call_cpp_impl!(mut self, base_end_move_rows())
475 }
476 pub fn base_begin_remove_rows(&mut self, parent: &QModelIndex, first: i32, last: i32) {
477 call_cpp_impl!(mut self, base_begin_remove_rows(parent, first, last))
478 }
479 pub fn base_end_remove_rows(&mut self) {
480 call_cpp_impl!(mut self, base_end_remove_rows())
481 }
482 pub fn base_begin_reset_model(&mut self) {
483 call_cpp_impl!(mut self, base_begin_reset_model())
484 }
485 pub fn base_end_reset_model(&mut self) {
486 call_cpp_impl!(mut self, base_end_reset_model())
487 }
488}