1/* Copyright (C) 2018 Olivier Goffart <ogoffart@woboq.com>
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
4associated documentation files (the "Software"), to deal in the Software without restriction,
5including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
6and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
7subject to the following conditions:
8
9The above copyright notice and this permission notice shall be included in all copies or substantial
10portions of the Software.
11
12THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
13NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
15OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17*/
18//! This crate contains manually generated bindings to Qt basic value types.
19//! It is meant to be used by other crates, such as the `qmetaobject` crate which re-expose them.
20//!
21//! The Qt types are basically exposed using the [`mod@cpp`] crate. They have manually writen rust idiomatic
22//! API which expose the C++ API.
23//! These types are the direct equivalent of the Qt types and are exposed on the stack.
24//!
25//! In addition, the build script of this crate expose some metadata to downstream crate that also
26//! want to use Qt's C++ API.
27//! Build scripts of crates that depends directly from this crate will have the following
28//! environment variables set when the build script is run:
29//! - `DEP_QT_VERSION`: The Qt version as given by qmake.
30//! - `DEP_QT_INCLUDE_PATH`: The include directory to give to the `cpp_build` crate to locate the Qt headers.
31//! - `DEP_QT_LIBRARY_PATH`: The path containing the Qt libraries.
32//! - `DEP_QT_COMPILE_FLAGS`: A list of flags separated by `;`
33//! - `DEP_QT_FOUND`: Set to 1 when qt was found, or 0 if qt was not found and the `required` feature is not set.
34//! - `DEP_QT_ERROR_MESSAGE`: when `DEP_QT_FOUND` is 0, contains the error that caused the build to fail
35//!
36//! ## Finding Qt
37//!
38//! This is the algorithm used to find Qt.
39//!
40//! - You can set the environment variable `QT_INCLUDE_PATH` and `QT_LIBRARY_PATH` to be a single
41//! directory where the Qt headers and Qt libraries are installed.
42//! - Otherwise you can specify a `QMAKE` environment variable with the absolute path of the
43//! `qmake` executable which will be used to query these paths.
44//! - If none of these environment variable is set, the `qmake` executable found in `$PATH`.
45//!
46//! ## Philosophy
47//!
48//! The goal of this crate is to expose a idiomatic Qt API for the core value type classes.
49//! The API is manually generated to expose required feature in the most rust-like API, while
50//! still keeping the similarities with the Qt API itself.
51//!
52//! It is not meant to expose all of the Qt API exhaustively, but only the part which is
53//! relevant for the usage in other crate.
54//! If you see a feature missing, feel free to write a issue or a pull request.
55//!
56//! Note that this crate concentrate on the value types, not the widgets or the
57//! the `QObject`. For that, there is the `qmetaobject` crate.
58//!
59//! ## Usage with the `cpp` crate
60//!
61//! Here is an example that make use of the types exposed by this crate in combination
62//! with the [`mod@cpp`] crate to call native API:
63//!
64//! In `Cargo.toml`
65//! ```toml
66//! #...
67//! [dependencies]
68//! qttype = "0.1"
69//! cpp = "0.5"
70//! #...
71//! [build-dependencies]
72//! cpp_build = "0.5"
73//! ```
74//!
75//! Note: It is important to depend directly on `qttype`, it is not enough to rely on the
76//! dependency coming transitively from another dependencies, otherwise the `DEP_QT_*`
77//! environment variables won't be defined.
78//!
79//! Then in the `build.rs` file:
80//! ```rust,no_run
81//! fn main() {
82//! let mut config = cpp_build::Config::new();
83//! config.include(std::env::var("DEP_QT_INCLUDE_PATH").unwrap());
84//! for f in std::env::var("DEP_QT_COMPILE_FLAGS").unwrap().split_terminator(";") {
85//! config.flag(f);
86//! }
87//! config.build("src/main.rs");
88//! }
89//! ```
90//!
91//! With that, you can now use the types inside your .rs files:
92//!
93//! ```ignore
94//! let byte_array = qttypes::QByteArray::from("Hello World!");
95//! cpp::cpp!([byte_array as "QByteArray"] { qDebug() << byte_array; });
96//! ```
97//!
98//! You will find a small but working example in the
99//! [qmetaobject-rs repository](https://github.com/woboq/qmetaobject-rs/tree/master/examples/graph).
100//!
101//! ## Cargo Features
102//!
103//! - **`required`**: When this feature is enabled (the default), the build script will panic with an error
104//! if Qt is not found. Otherwise, when not enabled, the build will continue, but any use of the classes will
105//! panic at runtime.
106//! - **`chrono`**: enable the conversion between [`QDateTime`] related types and the types from the `chrono` crate.
107//!
108//! Link against these Qt modules using cargo features:
109//!
110//! | Cargo feature | Qt module |
111//! | ------------------------- | --------------------- |
112//! | **`qtmultimedia`** | Qt Multimedia |
113//! | **`qtmultimediawidgets`** | Qt Multimedia Widgets |
114//! | **`qtquick`** | Qt Quick |
115//! | **`qtquickcontrols2`** | Qt Quick Controls |
116//! | **`qtsql`** | Qt SQL |
117//! | **`qttest`** | Qt Test |
118//! | **`qtwebengine`** | Qt WebEngine |
119//!
120
121#![cfg_attr(no_qt, allow(unused))]
122
123use std::collections::HashMap;
124use std::convert::From;
125use std::fmt;
126use std::hash::Hash;
127use std::iter::FromIterator;
128use std::ops::{Index, IndexMut};
129
130#[cfg(feature = "chrono")]
131use chrono::prelude::*;
132
133#[cfg(no_qt)]
134pub(crate) mod no_qt {
135 pub fn panic<T>() -> T {
136 panic!("Qt was not found during build")
137 }
138}
139
140pub(crate) mod internal_prelude {
141 #[cfg(not(no_qt))]
142 pub(crate) use cpp::{cpp, cpp_class};
143 #[cfg(no_qt)]
144 macro_rules! cpp {
145 {{ $($t:tt)* }} => {};
146 {$(unsafe)? [$($a:tt)*] -> $ret:ty as $b:tt { $($t:tt)* } } => {
147 crate::no_qt::panic::<$ret>()
148 };
149 { $($t:tt)* } => {
150 crate::no_qt::panic::<()>()
151 };
152 }
153
154 #[cfg(no_qt)]
155 macro_rules! cpp_class {
156 ($(#[$($attrs:tt)*])* $vis:vis unsafe struct $name:ident as $type:expr) => {
157 #[derive(Default, Ord, Eq, PartialEq, PartialOrd, Clone, Copy)]
158 #[repr(C)]
159 $vis struct $name;
160 };
161 }
162 #[cfg(no_qt)]
163 pub(crate) use cpp;
164 #[cfg(no_qt)]
165 pub(crate) use cpp_class;
166}
167use internal_prelude::*;
168
169mod qtcore;
170pub use crate::qtcore::{
171 qreal, NormalizationForm, QByteArray, QListIterator, QSettings, QString, QStringList, QUrl,
172 QVariant, QVariantList, UnicodeVersion,
173};
174
175mod qtgui;
176pub use crate::qtgui::{QColor, QColorNameFormat, QColorSpec, QRgb, QRgba64};
177
178cpp! {{
179 #include <QtCore/QByteArray>
180 #include <QtCore/QDateTime>
181 #include <QtCore/QModelIndex>
182 #include <QtCore/QString>
183 #include <QtCore/QUrl>
184 #include <QtCore/QVariant>
185
186 #include <QtGui/QImage>
187 #include <QtGui/QPixmap>
188 #include <QtGui/QPainter>
189 #include <QtGui/QPen>
190 #include <QtGui/QBrush>
191}}
192
193cpp_class!(
194 /// Wrapper around [`QDate`][class] class.
195 ///
196 /// [class]: https://doc.qt.io/qt-5/qdate.html
197 #[derive(PartialEq, PartialOrd, Eq, Ord)]
198 pub unsafe struct QDate as "QDate"
199);
200impl QDate {
201 /// Wrapper around [`QDate(int y, int m, int d)`][ctor] constructor.
202 ///
203 /// [ctor]: https://doc.qt.io/qt-5/qdate.html#QDate-2
204 pub fn from_y_m_d(y: i32, m: i32, d: i32) -> Self {
205 cpp!(unsafe [y as "int", m as "int", d as "int"] -> QDate as "QDate" {
206 return QDate(y, m, d);
207 })
208 }
209
210 /// Wrapper around [`QDate::getDate(int *year, int *month, int *day)`][method] method.
211 ///
212 /// # Wrapper-specific
213 ///
214 /// Returns the year, month and day components as a tuple, instead of mutable references.
215 ///
216 /// [method]: https://doc.qt.io/qt-5/qdate.html#getDate
217 pub fn get_y_m_d(&self) -> (i32, i32, i32) {
218 let mut res = (0, 0, 0);
219 let (ref mut y, ref mut m, ref mut d) = res;
220
221 // In version prior to Qt 5.7, this method was marked non-const.
222 // A #[cfg(qt_5_7)] attribute does not solve that issue, because the cpp_build crate is not
223 // smart enough not to compile the non-qualifying closure.
224 cpp!(unsafe [self as "QDate*", y as "int*", m as "int*", d as "int*"] {
225 return self->getDate(y, m, d);
226 });
227
228 res
229 }
230
231 /// Wrapper around [`QDate::isValid()`][method] method.
232 ///
233 /// [method]: https://doc.qt.io/qt-5/qdate.html#isValid
234 pub fn is_valid(&self) -> bool {
235 cpp!(unsafe [self as "const QDate*"] -> bool as "bool" {
236 return self->isValid();
237 })
238 }
239}
240#[cfg(feature = "chrono")]
241impl From<NaiveDate> for QDate {
242 fn from(a: NaiveDate) -> QDate {
243 QDate::from_y_m_d(a.year() as i32, a.month() as i32, a.day() as i32)
244 }
245}
246#[cfg(feature = "chrono")]
247impl Into<NaiveDate> for QDate {
248 fn into(self) -> NaiveDate {
249 let (y, m, d) = self.get_y_m_d();
250 NaiveDate::from_ymd(y, m as u32, d as u32)
251 }
252}
253
254#[test]
255fn test_qdate() {
256 let date: QDate = QDate::from_y_m_d(y:2019, m:10, d:22);
257 assert_eq!((2019, 10, 22), date.get_y_m_d());
258}
259
260#[test]
261fn test_qdate_is_valid() {
262 let valid_qdate: QDate = QDate::from_y_m_d(y:2019, m:10, d:26);
263 assert!(valid_qdate.is_valid());
264
265 let invalid_qdate: QDate = QDate::from_y_m_d(y:-1, m:-1, d:-1);
266 assert!(!invalid_qdate.is_valid());
267}
268
269#[cfg(feature = "chrono")]
270#[test]
271fn test_qdate_chrono() {
272 let chrono_date = NaiveDate::from_ymd(2019, 10, 22);
273 let qdate: QDate = chrono_date.into();
274 let actual_chrono_date: NaiveDate = qdate.into();
275
276 // Ensure that conversion works for both the Into trait and get_y_m_d() function
277 assert_eq!((2019, 10, 22), qdate.get_y_m_d());
278 assert_eq!(chrono_date, actual_chrono_date);
279}
280
281cpp_class!(
282 /// Wrapper around [`QTime`][class] class.
283 ///
284 /// [class]: https://doc.qt.io/qt-5/qtime.html
285 #[derive(PartialEq, PartialOrd, Eq, Ord)]
286 pub unsafe struct QTime as "QTime"
287);
288impl QTime {
289 /// Wrapper around [`QTime(int h, int m, int s = 0, int ms = 0)`][ctor] constructor.
290 ///
291 /// # Wrapper-specific
292 ///
293 /// Default arguments converted to `Option`s.
294 ///
295 /// [ctor]: https://doc.qt.io/qt-5/qtime.html#QTime-2
296 pub fn from_h_m_s_ms(h: i32, m: i32, s: Option<i32>, ms: Option<i32>) -> Self {
297 let s = s.unwrap_or(0);
298 let ms = ms.unwrap_or(0);
299
300 cpp!(unsafe [h as "int", m as "int", s as "int", ms as "int"] -> QTime as "QTime" {
301 return QTime(h, m, s, ms);
302 })
303 }
304
305 /// Wrapper around [`QTime::hour()`][method] method.
306 ///
307 /// [method]: https://doc.qt.io/qt-5/qtime.html#hour
308 pub fn get_hour(&self) -> i32 {
309 cpp!(unsafe [self as "const QTime*"] -> i32 as "int" {
310 return self->hour();
311 })
312 }
313
314 /// Wrapper around [`QTime::minute()`][method] method.
315 ///
316 /// [method]: https://doc.qt.io/qt-5/qtime.html#minute
317 pub fn get_minute(&self) -> i32 {
318 cpp!(unsafe [self as "const QTime*"] -> i32 as "int" {
319 return self->minute();
320 })
321 }
322
323 /// Wrapper around [`QTime::second()`][method] method.
324 ///
325 /// [method]: https://doc.qt.io/qt-5/qtime.html#second
326 pub fn get_second(&self) -> i32 {
327 cpp!(unsafe [self as "const QTime*"] -> i32 as "int" {
328 return self->second();
329 })
330 }
331
332 /// Wrapper around [`QTime::msec()`][method] method.
333 ///
334 /// [method]: https://doc.qt.io/qt-5/qtime.html#msec
335 pub fn get_msec(&self) -> i32 {
336 cpp!(unsafe [self as "const QTime*"] -> i32 as "int" {
337 return self->msec();
338 })
339 }
340
341 /// Convenience function for obtaining the hour, minute, second and millisecond components.
342 pub fn get_h_m_s_ms(&self) -> (i32, i32, i32, i32) {
343 (self.get_hour(), self.get_minute(), self.get_second(), self.get_msec())
344 }
345
346 /// Wrapper around [`QTime::isValid()`][method] method.
347 ///
348 /// [method]: https://doc.qt.io/qt-5/qtime.html#isValid
349 pub fn is_valid(&self) -> bool {
350 cpp!(unsafe [self as "const QTime*"] -> bool as "bool" {
351 return self->isValid();
352 })
353 }
354}
355
356#[cfg(feature = "chrono")]
357impl From<NaiveTime> for QTime {
358 fn from(a: NaiveTime) -> QTime {
359 QTime::from_h_m_s_ms(
360 a.hour() as i32,
361 a.minute() as i32,
362 Some(a.second() as i32),
363 Some(a.nanosecond() as i32 / 1_000_000),
364 )
365 }
366}
367
368#[cfg(feature = "chrono")]
369impl Into<NaiveTime> for QTime {
370 fn into(self) -> NaiveTime {
371 let (h, m, s, ms) = self.get_h_m_s_ms();
372 NaiveTime::from_hms_milli(h as u32, m as u32, s as u32, ms as u32)
373 }
374}
375
376#[test]
377fn test_qtime() {
378 let qtime: QTime = QTime::from_h_m_s_ms(h:10, m:30, s:Some(40), ms:Some(300));
379 assert_eq!((10, 30, 40, 300), qtime.get_h_m_s_ms());
380}
381
382#[cfg(feature = "chrono")]
383#[test]
384fn test_qtime_chrono() {
385 let chrono_time = NaiveTime::from_hms(10, 30, 50);
386 let qtime: QTime = chrono_time.into();
387 let actual_chrono_time: NaiveTime = qtime.into();
388
389 // Ensure that conversion works for both the Into trait and get_h_m_s_ms() function
390 assert_eq!((10, 30, 50, 0), qtime.get_h_m_s_ms());
391 assert_eq!(chrono_time, actual_chrono_time);
392}
393
394#[test]
395fn test_qtime_is_valid() {
396 let valid_qtime: QTime = QTime::from_h_m_s_ms(h:10, m:30, s:Some(40), ms:Some(300));
397 assert!(valid_qtime.is_valid());
398
399 let invalid_qtime: QTime = QTime::from_h_m_s_ms(h:10, m:30, s:Some(40), ms:Some(9999));
400 assert!(!invalid_qtime.is_valid());
401}
402
403cpp_class!(
404 /// Wrapper around [`QDateTime`][class] class.
405 ///
406 /// [class]: https://doc.qt.io/qt-5/qdatetime.html
407 #[derive(PartialEq, PartialOrd, Eq, Ord)]
408 pub unsafe struct QDateTime as "QDateTime"
409);
410impl QDateTime {
411 /// Wrapper around [`QDateTime(const QDateTime &other)`][ctor] constructor.
412 ///
413 /// [ctor]: https://doc.qt.io/qt-5/qdatetime.html#QDateTime-1
414 pub fn from_date(date: QDate) -> Self {
415 cpp!(unsafe [date as "QDate"] -> QDateTime as "QDateTime" {
416 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
417 return date.startOfDay();
418 #else
419 return QDateTime(date);
420 #endif
421 })
422 }
423
424 /// Wrapper around [`QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec = Qt::LocalTime)`][ctor] constructor.
425 ///
426 /// # Wrapper-specific
427 ///
428 /// `spec` is left as it is, thus it is always `Qt::LocalTime`.
429 ///
430 /// [ctor]: https://doc.qt.io/qt-5/qdatetime.html#QDateTime-2
431 pub fn from_date_time_local_timezone(date: QDate, time: QTime) -> Self {
432 cpp!(unsafe [date as "QDate", time as "QTime"] -> QDateTime as "QDateTime" {
433 return QDateTime(date, time);
434 })
435 }
436
437 /// Wrapper around [`QDateTime::date()`][method] method.
438 ///
439 /// [method]: https://doc.qt.io/qt-5/qdatetime.html#date
440 pub fn get_date(&self) -> QDate {
441 cpp!(unsafe [self as "const QDateTime*"] -> QDate as "QDate" {
442 return self->date();
443 })
444 }
445
446 /// Wrapper around [`QDateTime::time()`][method] method.
447 ///
448 /// [method]: https://doc.qt.io/qt-5/qdatetime.html#time
449 pub fn get_time(&self) -> QTime {
450 cpp!(unsafe [self as "const QDateTime*"] -> QTime as "QTime" {
451 return self->time();
452 })
453 }
454
455 /// Convenience function for obtaining both date and time components.
456 pub fn get_date_time(&self) -> (QDate, QTime) {
457 (self.get_date(), self.get_time())
458 }
459
460 /// Wrapper around [`QDateTime::isValid()`][method] method.
461 ///
462 /// [method]: https://doc.qt.io/qt-5/qdatetime.html#isValid
463 pub fn is_valid(&self) -> bool {
464 cpp!(unsafe [self as "const QDateTime*"] -> bool as "bool" {
465 return self->isValid();
466 })
467 }
468}
469
470#[test]
471fn test_qdatetime_from_date() {
472 let qdate: QDate = QDate::from_y_m_d(y:2019, m:10, d:22);
473 let qdatetime: QDateTime = QDateTime::from_date(qdate);
474 let actual_qdate: QDate = qdatetime.get_date();
475
476 assert_eq!((2019, 10, 22), actual_qdate.get_y_m_d());
477}
478
479#[test]
480fn test_qdatetime_from_date_time_local_timezone() {
481 let qdate: QDate = QDate::from_y_m_d(y:2019, m:10, d:22);
482 let qtime: QTime = QTime::from_h_m_s_ms(h:10, m:30, s:Some(40), ms:Some(300));
483 let qdatetime: QDateTime = QDateTime::from_date_time_local_timezone(date:qdate, time:qtime);
484 let (actual_qdate: QDate, actual_qtime: QTime) = qdatetime.get_date_time();
485
486 assert_eq!((2019, 10, 22), actual_qdate.get_y_m_d());
487 assert_eq!((10, 30, 40, 300), actual_qtime.get_h_m_s_ms());
488
489 assert_eq!(10, actual_qtime.get_hour());
490 assert_eq!(30, actual_qtime.get_minute());
491 assert_eq!(40, actual_qtime.get_second());
492 assert_eq!(300, actual_qtime.get_msec());
493}
494
495#[test]
496fn test_qdatetime_is_valid() {
497 let valid_qdate = QDate::from_y_m_d(2019, 10, 26);
498 let invalid_qdate = QDate::from_y_m_d(-1, -1, -1);
499
500 let valid_qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(300));
501 let invalid_qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(9999));
502
503 let valid_qdatetime_from_date = QDateTime::from_date(valid_qdate);
504 assert!(valid_qdatetime_from_date.is_valid());
505
506 let valid_qdatetime_from_valid_date_valid_time =
507 QDateTime::from_date_time_local_timezone(valid_qdate, valid_qtime);
508 assert!(valid_qdatetime_from_valid_date_valid_time.is_valid());
509
510 // Refer to the documentation for QDateTime's constructors using QDate, QTime.
511 // If the date is valid, but the time is not, the time will be set to midnight
512 let valid_qdatetime_from_valid_date_invalid_time =
513 QDateTime::from_date_time_local_timezone(valid_qdate, invalid_qtime);
514 assert!(valid_qdatetime_from_valid_date_invalid_time.is_valid());
515
516 let invalid_qdatetime_from_invalid_date_valid_time =
517 QDateTime::from_date_time_local_timezone(invalid_qdate, valid_qtime);
518 assert!(!invalid_qdatetime_from_invalid_date_valid_time.is_valid());
519
520 let invalid_qdatetime_from_invalid_date_invalid_time =
521 QDateTime::from_date_time_local_timezone(invalid_qdate, invalid_qtime);
522 assert!(!invalid_qdatetime_from_invalid_date_invalid_time.is_valid());
523}
524
525cpp_class!(
526 /// Wrapper around [`QVariantMap`][type] typedef.
527 ///
528 /// [type]: https://doc.qt.io/qt-5/qvariant.html#QVariantMap-typedef
529 #[derive(Default, PartialEq, Eq)]
530 pub unsafe struct QVariantMap as "QVariantMap"
531);
532
533impl QVariantMap {
534 /// Wrapper around [`insert(int, const QString &, const QVariant &)`][method] method.
535 ///
536 /// [method]: https://doc.qt.io/qt-5/qlist.html#insert
537 pub fn insert(&mut self, key: QString, element: QVariant) {
538 cpp!(unsafe [self as "QVariantMap*", key as "QString", element as "QVariant"] {
539 self->insert(key, std::move(element));
540 })
541 }
542
543 /// Wrapper around [`remove(const QString &)`][method] method.
544 ///
545 /// [method]: https://doc.qt.io/qt-5/qmap.html#remove
546 pub fn remove(&mut self, key: QString) -> usize {
547 cpp!(unsafe [self as "QVariantMap*", key as "QString"] -> usize as "size_t" {
548 return self->remove(key);
549 })
550 }
551
552 /// Wrapper around [`take(const QString &)`][method] method.
553 ///
554 /// [method]: https://doc.qt.io/qt-5/qmap.html#take
555 pub fn take(&mut self, key: QString) -> QVariant {
556 cpp!(unsafe [self as "QVariantMap*", key as "QString"] -> QVariant as "QVariant" {
557 return self->take(key);
558 })
559 }
560
561 /// Wrapper around [`size()`][method] method.
562 ///
563 /// [method]: https://doc.qt.io/qt-5/qmap.html#size
564 pub fn len(&self) -> usize {
565 cpp!(unsafe [self as "const QVariantMap*"] -> usize as "size_t" {
566 return self->size();
567 })
568 }
569
570 /// Wrapper around [`isEmpty()`][method] method.
571 ///
572 /// [method]: https://doc.qt.io/qt-5/qmap.html#isEmpty
573 pub fn is_empty(&self) -> bool {
574 cpp!(unsafe [self as "const QVariantMap*"] -> bool as "bool" {
575 return self->isEmpty();
576 })
577 }
578
579 /// Wrapper around [`contains(const QString &)`][method] method.
580 ///
581 /// [method]: https://doc.qt.io/qt-5/qmap.html#contains
582 pub fn contains(&self, key: QString) -> bool {
583 cpp!(unsafe [self as "const QVariantMap*", key as "QString"] -> bool as "bool" {
584 return self->contains(key);
585 })
586 }
587
588 /// Wrapper around [`clear()`][method] method.
589 ///
590 /// [method]: https://doc.qt.io/qt-5/qmap.html#clear
591 pub fn clear(&mut self) {
592 cpp!(unsafe [self as "QVariantMap*"] {
593 self->clear();
594 })
595 }
596
597 /// Wrapper around [`value(const QString &, const QVariant &)`][method] method.
598 ///
599 /// [method]: https://doc.qt.io/qt-5/qmap.html#value
600 pub fn value(&self, key: QString, default_value: QVariant) -> QVariant {
601 cpp!(unsafe [self as "const QVariantMap*", key as "QString", default_value as "QVariant"] -> QVariant as "QVariant" {
602 return self->value(key, default_value);
603 })
604 }
605
606 /// Wrapper around [`key(const QVariant &, const QString &)`][method] method.
607 ///
608 /// [method]: https://doc.qt.io/qt-5/qmap.html#key
609 pub fn key(&self, value: QVariant, default_key: QString) -> QString {
610 cpp!(unsafe [self as "const QVariantMap*", default_key as "QString", value as "QVariant"] -> QString as "QString" {
611 return self->key(value, default_key);
612 })
613 }
614}
615
616impl Index<QString> for QVariantMap {
617 type Output = QVariant;
618
619 /// Wrapper around [`at(int)`][method] method.
620 ///
621 /// [method]: https://doc.qt.io/qt-5/qlist.html#at
622 #[track_caller]
623 fn index(&self, key: QString) -> &Self::Output {
624 cpp!(unsafe [self as "const QVariantMap*", key as "QString"] -> Option<&QVariant> as "const QVariant*" {
625 auto x = self->constFind(key);
626 if (x == self->constEnd()) {
627 return NULL;
628 } else {
629 return &x.value();
630 }
631 }).expect(msg:"key not in the QVariant")
632 }
633}
634impl IndexMut<QString> for QVariantMap {
635 /// Wrapper around [`operator[](int)`][method] operator method.
636 ///
637 /// [method]: https://doc.qt.io/qt-5/qlist.html#operator-5b-5d
638 fn index_mut(&mut self, key: QString) -> &mut Self::Output {
639 unsafe {
640 &mut *cpp!([self as "QVariantMap*", key as "QString"] -> *mut QVariant as "QVariant*" {
641 return &(*self)[key];
642 })
643 }
644 }
645}
646
647impl fmt::Debug for QVariantMap {
648 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
649 f.debug_map().entries(self.into_iter()).finish()
650 }
651}
652
653cpp_class!(unsafe struct QVariantMapIteratorInternal as "QVariantMap::iterator");
654
655/// Internal class used to iterate over a [`QVariantMap`]
656pub struct QVariantMapIterator<'a> {
657 map: &'a QVariantMap,
658 iterator: QVariantMapIteratorInternal,
659}
660
661impl<'a> QVariantMapIterator<'a> {
662 fn key(&self) -> Option<&'a QString> {
663 let iterator = &self.iterator;
664 cpp!(unsafe [iterator as "const QVariantMap::iterator*"] -> Option<&QString> as "const QString*" {
665 return &iterator->key();
666 })
667 }
668
669 fn value(&self) -> Option<&'a QVariant> {
670 let iterator = &self.iterator;
671 cpp!(unsafe [iterator as "const QVariantMap::iterator*"] -> Option<&QVariant> as "QVariant*" {
672 return &iterator->value();
673 })
674 }
675
676 fn check_end(&self) -> bool {
677 let map = self.map;
678 let iterator = &self.iterator;
679 cpp!(unsafe [iterator as "const QVariantMap::iterator*", map as "const QVariantMap*"] -> bool as "bool" {
680 return (*iterator == map->end());
681 })
682 }
683
684 fn increment(&mut self) {
685 let iterator = &self.iterator;
686 cpp!(unsafe [iterator as "QVariantMap::iterator*"] {
687 ++(*iterator);
688 })
689 }
690}
691
692impl<'a> Iterator for QVariantMapIterator<'a> {
693 type Item = (&'a QString, &'a QVariant);
694
695 fn next(&mut self) -> Option<Self::Item> {
696 if self.check_end() {
697 return None;
698 }
699
700 let key: Option<&QString> = self.key();
701 let value: Option<&QVariant> = self.value();
702
703 self.increment();
704
705 match (key, value) {
706 (Some(k: &QString), Some(v: &QVariant)) => Some((k, v)),
707 _ => None,
708 }
709 }
710}
711
712impl<'a> IntoIterator for &'a QVariantMap {
713 type Item = (&'a QString, &'a QVariant);
714 type IntoIter = QVariantMapIterator<'a>;
715
716 fn into_iter(self) -> Self::IntoIter {
717 let iter: QVariantMapIteratorInternal = cpp!(unsafe [self as "QVariantMap*"] -> QVariantMapIteratorInternal as "QVariantMap::iterator" {
718 return self->begin();
719 });
720 Self::IntoIter { map: self, iterator: iter }
721 }
722}
723
724impl<K, V> FromIterator<(K, V)> for QVariantMap
725where
726 K: Into<QString>,
727 V: Into<QVariant>,
728{
729 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
730 let mut m: QVariantMap = QVariantMap::default();
731 for i: (K, V) in iter {
732 let (k: K, v: V) = i;
733 m.insert(key:k.into(), element:v.into());
734 }
735 m
736 }
737}
738
739impl<K, V> From<HashMap<K, V>> for QVariantMap
740where
741 K: Into<QString>,
742 V: Into<QVariant>,
743{
744 fn from(m: HashMap<K, V>) -> Self {
745 m.into_iter().collect()
746 }
747}
748
749impl<K, V, const N: usize> From<[(K, V); N]> for QVariantMap
750where
751 K: Into<QString>,
752 V: Into<QVariant>,
753{
754 fn from(m: [(K, V); N]) -> Self {
755 let mut temp: QVariantMap = QVariantMap::default();
756 for (key: K, val: V) in m {
757 temp.insert(key:key.into(), element:val.into());
758 }
759 temp
760 }
761}
762
763impl<K, V> From<QVariantMap> for HashMap<K, V>
764where
765 K: Hash + Eq,
766 V: Eq,
767 QString: Into<K>,
768 QVariant: Into<V>,
769{
770 fn from(m: QVariantMap) -> Self {
771 m.into_iter().map(|(k: &QString, v: &QVariant)| (k.clone().into(), v.clone().into())).collect()
772 }
773}
774
775#[cfg(test)]
776mod qvariantmap_tests {
777 use super::*;
778
779 #[test]
780 fn test_qvariantmap() {
781 let mut map = QVariantMap::default();
782
783 let key1 = QString::from("a");
784 let val1 = QString::from("abc");
785
786 assert!(map.is_empty());
787 map.insert(key1.clone(), val1.clone().into());
788 assert_eq!(map.len(), 1);
789 assert_eq!(map[key1.clone()].to_qbytearray().to_string(), val1.to_string());
790
791 assert_eq!(map.take(key1.clone()).to_qbytearray().to_string(), val1.to_string());
792 assert!(map.is_empty());
793
794 map[key1.clone()] = val1.clone().into();
795
796 let default_value = QVariant::from(10);
797
798 assert_eq!(map[key1.clone()].to_qbytearray().to_string(), val1.to_string());
799 assert_eq!(map.value(key1.clone(), default_value.clone()), val1.clone().into());
800 assert_eq!(map.value(val1.clone(), default_value.clone()), default_value.clone());
801
802 assert_eq!(map.key(val1.clone().into(), val1.clone()), key1.clone());
803 assert_eq!(map.key(key1.clone().into(), val1.clone()), val1.clone());
804 }
805
806 #[test]
807 #[should_panic(expected = "key not in the QVariant")]
808 fn test_index_panic() {
809 let map = QVariantMap::default();
810
811 map[QString::from("t")].to_qbytearray().to_string();
812 }
813
814 #[test]
815 fn test_iter() {
816 let hashmap =
817 HashMap::from([("Mercury", 0.4), ("Venus", 0.7), ("Earth", 1.0), ("Mars", 1.5)]);
818 let map: QVariantMap = hashmap.clone().into();
819
820 assert_eq!(map.len(), hashmap.len());
821
822 for (k, v) in map.into_iter() {
823 assert_eq!(hashmap[k.to_string().as_str()].to_string(), v.to_qbytearray().to_string());
824 }
825 }
826
827 #[test]
828 fn test_from() {
829 let hashmap1 = HashMap::from([
830 ("A".to_string(), QVariant::from(QString::from("abc"))),
831 ("B".to_string(), QVariant::from(QString::from("def"))),
832 ]);
833 let qvariantmap1: QVariantMap = hashmap1.clone().into();
834 let hashmap2 = qvariantmap1.clone().into();
835 assert_eq!(hashmap1, hashmap2);
836
837 let qvariantmap2 = QVariantMap::from([
838 ("A".to_string(), QVariant::from(QString::from("abc"))),
839 ("B".to_string(), QVariant::from(QString::from("def"))),
840 ]);
841 assert_eq!(qvariantmap1, qvariantmap2);
842 }
843}
844
845cpp_class!(
846 /// Wrapper around [`QModelIndex`][class] class.
847 ///
848 /// [class]: https://doc.qt.io/qt-5/qmodelindex.html
849 #[derive(PartialEq, Eq)]
850 pub unsafe struct QModelIndex as "QModelIndex"
851);
852impl QModelIndex {
853 /// Wrapper around [`internalId()`][method] method.
854 ///
855 /// [method]: https://doc.qt.io/qt-5/qmodelindex.html#internalId
856 pub fn id(&self) -> usize {
857 cpp!(unsafe [self as "const QModelIndex*"] -> usize as "uintptr_t" { return self->internalId(); })
858 }
859
860 /// Wrapper around [`column()`][method] method.
861 ///
862 /// [method]: https://doc.qt.io/qt-5/qmodelindex.html#column
863 pub fn column(&self) -> i32 {
864 cpp!(unsafe [self as "const QModelIndex*"] -> i32 as "int" { return self->column(); })
865 }
866
867 /// Wrapper around [`row()`][method] method.
868 ///
869 /// [method]: https://doc.qt.io/qt-5/qmodelindex.html#row
870 pub fn row(&self) -> i32 {
871 cpp!(unsafe [self as "const QModelIndex*"] -> i32 as "int" { return self->row(); })
872 }
873
874 /// Wrapper around [`isValid()`][method] method.
875 ///
876 /// [method]: https://doc.qt.io/qt-5/qmodelindex.html#isValid
877 pub fn is_valid(&self) -> bool {
878 cpp!(unsafe [self as "const QModelIndex*"] -> bool as "bool" { return self->isValid(); })
879 }
880}
881
882/// Bindings for [`QRectF`][class] class.
883///
884/// [class]: https://doc.qt.io/qt-5/qrectf.html
885#[repr(C)]
886#[derive(Default, Clone, Copy, PartialEq, Debug)]
887pub struct QRectF {
888 pub x: qreal,
889 pub y: qreal,
890 pub width: qreal,
891 pub height: qreal,
892}
893impl QRectF {
894 /// Wrapper around [`contains(const QPointF &)`][method] method.
895 ///
896 /// [method]: https://doc.qt.io/qt-5/qrectf.html#contains
897 pub fn contains(&self, pos: QPointF) -> bool {
898 cpp!(unsafe [self as "const QRectF*", pos as "QPointF"] -> bool as "bool" {
899 return self->contains(pos);
900 })
901 }
902
903 /// Same as the [`topLeft`][method] method.
904 ///
905 /// [method]: https://doc.qt.io/qt-5/qrectf.html#topLeft
906 pub fn top_left(&self) -> QPointF {
907 QPointF { x: self.x, y: self.y }
908 }
909
910 /// Same as the [`isValid`][method] method.
911 ///
912 /// [method]: https://doc.qt.io/qt-5/qrectf.html#isValid
913 pub fn is_valid(&self) -> bool {
914 self.width > 0. && self.height > 0.
915 }
916}
917
918/// Bindings for [`QPointF`][class] class.
919///
920/// [class]: https://doc.qt.io/qt-5/qpointf.html
921#[repr(C)]
922#[derive(Default, Clone, Copy, PartialEq, Debug)]
923pub struct QPointF {
924 pub x: qreal,
925 pub y: qreal,
926}
927impl std::ops::Add for QPointF {
928 type Output = QPointF;
929 /// Wrapper around [`operator+(const QPointF &, const QPointF &)`][func] function.
930 ///
931 /// [func]: https://doc.qt.io/qt-5/qpointf.html#operator-2b
932 fn add(self, other: QPointF) -> QPointF {
933 QPointF { x: self.x + other.x, y: self.y + other.y }
934 }
935}
936impl std::ops::AddAssign for QPointF {
937 /// Wrapper around [`operator+=(const QPointF &`][method] method.
938 ///
939 /// [method]: https://doc.qt.io/qt-5/qpointf.html#operator-2b-eq
940 fn add_assign(&mut self, other: QPointF) {
941 *self = QPointF { x: self.x + other.x, y: self.y + other.y };
942 }
943}
944
945/// Bindings for [`QSizeF`][class] class.
946///
947/// [class]: https://doc.qt.io/qt-5/qsizef.html
948#[repr(C)]
949#[derive(Default, Clone, Copy, PartialEq, Debug)]
950pub struct QSizeF {
951 pub width: qreal,
952 pub height: qreal,
953}
954
955#[test]
956fn test_qpointf_qrectf() {
957 let rect: QRectF = QRectF { x: 200., y: 150., width: 60., height: 75. };
958 let pt: QPointF = QPointF { x: 12., y: 5.5 };
959 assert!(!rect.contains(pt));
960 assert!(rect.contains(pt + rect.top_left()));
961}
962
963/// Bindings for [`QSize`][class] class.
964///
965/// [class]: https://doc.qt.io/qt-5/qsize.html
966#[repr(C)]
967#[derive(Default, Clone, Copy, PartialEq, Debug)]
968pub struct QSize {
969 pub width: u32,
970 pub height: u32,
971}
972
973/// Bindings for [`QPoint`][class] class.
974///
975/// [class]: https://doc.qt.io/qt-5/qpoint.html
976#[repr(C)]
977#[derive(Default, Clone, Copy, PartialEq, Debug)]
978pub struct QPoint {
979 pub x: i32,
980 pub y: i32,
981}
982
983/// Bindings for [`QMargins`][class] class.
984///
985/// [class]: https://doc.qt.io/qt-5/qmargins.html
986#[repr(C)]
987#[derive(Default, Clone, Copy, PartialEq, Debug)]
988pub struct QMargins {
989 pub left: i32,
990 pub top: i32,
991 pub right: i32,
992 pub bottom: i32,
993}
994
995/// Bindings for [`QImage::Format`][class] enum class.
996///
997/// [class]: https://doc.qt.io/qt-5/qimage.html#Format-enum
998#[repr(C)]
999#[derive(Clone, Copy, PartialEq, Debug)]
1000#[allow(non_camel_case_types)]
1001pub enum ImageFormat {
1002 Invalid = 0,
1003 Mono = 1,
1004 MonoLSB = 2,
1005 Indexed8 = 3,
1006 RGB32 = 4,
1007 ARGB32 = 5,
1008 ARGB32_Premultiplied = 6,
1009 RGB16 = 7,
1010 ARGB8565_Premultiplied = 8,
1011 RGB666 = 9,
1012 ARGB6666_Premultiplied = 10,
1013 RGB555 = 11,
1014 ARGB8555_Premultiplied = 12,
1015 RGB888 = 13,
1016 RGB444 = 14,
1017 ARGB4444_Premultiplied = 15,
1018 RGBX8888 = 16,
1019 RGBA8888 = 17,
1020 RGBA8888_Premultiplied = 18,
1021 BGR30 = 19,
1022 A2BGR30_Premultiplied = 20,
1023 RGB30 = 21,
1024 A2RGB30_Premultiplied = 22,
1025 Alpha8 = 23,
1026 Grayscale8 = 24,
1027 Grayscale16 = 28,
1028 RGBX64 = 25,
1029 RGBA64 = 26,
1030 RGBA64_Premultiplied = 27,
1031 BGR888 = 29,
1032}
1033cpp_class!(
1034 /// Wrapper around [`QImage`][class] class.
1035 ///
1036 /// [class]: https://doc.qt.io/qt-5/qimage.html
1037 #[derive(Default, Clone, PartialEq)]
1038 pub unsafe struct QImage as "QImage"
1039);
1040impl QImage {
1041 /// Wrapper around [`QImage(const QString &fileName, const char *format = nullptr)`][ctor] constructor.
1042 ///
1043 /// [ctor]: https://doc.qt.io/qt-5/qimage.html#QImage-8
1044 pub fn load_from_file(filename: QString) -> Self {
1045 cpp!(unsafe [filename as "QString"] -> QImage as "QImage" {
1046 return QImage(filename);
1047 })
1048 }
1049
1050 /// Wrapper around [`QImage(const QSize &, QImage::Format)`][ctor] constructor.
1051 ///
1052 /// [ctor]: https://doc.qt.io/qt-5/qimage.html#QImage-1
1053 pub fn new(size: QSize, format: ImageFormat) -> Self {
1054 cpp!(unsafe [size as "QSize", format as "QImage::Format" ] -> QImage as "QImage" {
1055 return QImage(size, format);
1056 })
1057 }
1058
1059 /// Wrapper around [`size()`][method] method.
1060 ///
1061 /// [method]: https://doc.qt.io/qt-5/qimage.html#size
1062 pub fn size(&self) -> QSize {
1063 cpp!(unsafe [self as "const QImage*"] -> QSize as "QSize" { return self->size(); })
1064 }
1065
1066 /// Wrapper around [`format()`][method] method.
1067 ///
1068 /// [method]: https://doc.qt.io/qt-5/qimage.html#format
1069 pub fn format(&self) -> ImageFormat {
1070 cpp!(unsafe [self as "const QImage*"] -> ImageFormat as "QImage::Format" { return self->format(); })
1071 }
1072
1073 /// Wrapper around [`fill(const QColor &)`][method] method.
1074 ///
1075 /// [method]: https://doc.qt.io/qt-5/qimage.html#fill-1
1076 pub fn fill(&mut self, color: QColor) {
1077 cpp!(unsafe [self as "QImage*", color as "QColor"] { self->fill(color); })
1078 }
1079
1080 /// Wrapper around [`setPixelColor(const QPoint &, const QColor &)`][method] method.
1081 ///
1082 /// [method]: https://doc.qt.io/qt-5/qimage.html#setPixelColor
1083 pub fn set_pixel_color(&mut self, x: u32, y: u32, color: QColor) {
1084 cpp!(unsafe [self as "QImage*", x as "int", y as "int", color as "QColor"] {
1085 self->setPixelColor(x, y, color);
1086 })
1087 }
1088
1089 /// Wrapper around [`pixelColor(const QPoint &)`][method] method.
1090 ///
1091 /// [method]: https://doc.qt.io/qt-5/qimage.html#pixelColor
1092 pub fn get_pixel_color(&self, x: u32, y: u32) -> QColor {
1093 cpp!(unsafe [self as "const QImage*", x as "int", y as "int"] -> QColor as "QColor" {
1094 return self->pixelColor(x, y);
1095 })
1096 }
1097}
1098
1099cpp_class!(
1100 /// Wrapper around [`QPixmap`][class] class.
1101 ///
1102 /// [class]: https://doc.qt.io/qt-5/qpixmap.html
1103 pub unsafe struct QPixmap as "QPixmap"
1104);
1105
1106impl QPixmap {
1107 /// Wrapper around [`size()`][method] method.
1108 ///
1109 /// [method]: https://doc.qt.io/qt-5/qpixmap.html#size
1110 pub fn size(&self) -> QSize {
1111 cpp!(unsafe [self as "const QPixmap*"] -> QSize as "QSize" { return self->size(); })
1112 }
1113}
1114
1115impl From<QPixmap> for QImage {
1116 fn from(pixmap: QPixmap) -> Self {
1117 cpp!(unsafe [pixmap as "QPixmap"] -> QImage as "QImage" { return pixmap.toImage(); })
1118 }
1119}
1120
1121impl From<QImage> for QPixmap {
1122 fn from(image: QImage) -> Self {
1123 cpp!(unsafe [image as "QImage"] -> QPixmap as "QPixmap" { return QPixmap::fromImage(image); })
1124 }
1125}
1126
1127/// Bindings for [`Qt::PenStyle`][enum] enum.
1128///
1129/// [enum]: https://doc.qt.io/qt-5/qt.html#PenStyle-enum
1130#[repr(C)]
1131#[derive(Clone, Copy, PartialEq, Debug)]
1132#[allow(non_camel_case_types)]
1133pub enum PenStyle {
1134 NoPen = 0,
1135 SolidLine = 1,
1136 DashLine = 2,
1137 DotLine = 3,
1138 DashDotLine = 4,
1139 DashDotDotLine = 5,
1140 CustomDashLine = 6,
1141}
1142cpp_class!(
1143 /// Wrapper around [`QPen`][class] class.
1144 ///
1145 /// [class]: https://doc.qt.io/qt-5/qpen.html
1146 #[derive(Default)]
1147 pub unsafe struct QPen as "QPen"
1148);
1149
1150impl QPen {
1151 pub fn from_color(color: QColor) -> Self {
1152 cpp!(unsafe [color as "QColor"] -> QPen as "QPen" { return QPen(color); })
1153 }
1154 pub fn from_style(style: PenStyle) -> Self {
1155 cpp!(unsafe [style as "Qt::PenStyle"] -> QPen as "QPen" { return QPen(style); })
1156 }
1157 pub fn set_color(&mut self, color: QColor) {
1158 cpp!(unsafe [self as "QPen*", color as "QColor"] { return self->setColor(color); });
1159 }
1160 pub fn set_style(&mut self, style: PenStyle) {
1161 cpp!(unsafe [self as "QPen*", style as "Qt::PenStyle"] { return self->setStyle(style); });
1162 }
1163 pub fn set_width(&mut self, width: i32) {
1164 cpp!(unsafe [self as "QPen*", width as "int"] { return self->setWidth(width); });
1165 }
1166 pub fn set_width_f(&mut self, width: qreal) {
1167 cpp!(unsafe [self as "QPen*", width as "qreal"] { return self->setWidthF(width); });
1168 }
1169
1170 // QBrush brush() const
1171 // Qt::PenCapStyle capStyle() const
1172 // QColor color() const
1173 // qreal dashOffset() const
1174 // QVector<qreal> dashPattern() const
1175 // bool isCosmetic() const
1176 // bool isSolid() const
1177 // Qt::PenJoinStyle joinStyle() const
1178 // qreal miterLimit() const
1179 // void setBrush(const QBrush &brush)
1180 // void setCapStyle(Qt::PenCapStyle style)
1181 // void setCosmetic(bool cosmetic)
1182 // void setDashOffset(qreal offset)
1183 // void setDashPattern(const QVector<qreal> &pattern)
1184 // void setJoinStyle(Qt::PenJoinStyle style)
1185 // void setMiterLimit(qreal limit)
1186 // Qt::PenStyle style() const
1187 // void swap(QPen &other)
1188 // int width() const
1189 // qreal widthF() const
1190}
1191
1192/// Bindings for [`QStandardPaths::StandardLocation`][enum] enum.
1193///
1194/// [enum]: https://doc.qt.io/qt-5/qstandardpaths.html#StandardLocation-enum
1195#[repr(C)]
1196#[derive(Clone, Copy, PartialEq, Debug)]
1197#[allow(non_camel_case_types)]
1198pub enum QStandardPathLocation {
1199 DesktopLocation = 0,
1200 DocumentsLocation = 1,
1201 FontsLocation = 2,
1202 ApplicationsLocation = 3,
1203 MusicLocation = 4,
1204 MoviesLocation = 5,
1205 PicturesLocation = 6,
1206 TempLocation = 7,
1207 HomeLocation = 8,
1208 AppLocalDataLocation = 9,
1209 CacheLocation = 10,
1210 GenericDataLocation = 11,
1211 RuntimeLocation = 12,
1212 ConfigLocation = 13,
1213 DownloadLocation = 14,
1214 GenericCacheLocation = 15,
1215 GenericConfigLocation = 16,
1216 AppDataLocation = 17,
1217 AppConfigLocation = 18,
1218}
1219
1220/// Bindings for [`Qt::BrushStyle`][enum] enum.
1221///
1222/// [enum]: https://doc.qt.io/qt-5/qt.html#BrushStyle-enum
1223#[repr(C)]
1224#[derive(Clone, Copy, PartialEq, Debug)]
1225#[allow(non_camel_case_types)]
1226pub enum BrushStyle {
1227 NoBrush = 0,
1228 SolidPattern = 1,
1229 Dense1Pattern = 2,
1230 Dense2Pattern = 3,
1231 Dense3Pattern = 4,
1232 Dense4Pattern = 5,
1233 Dense5Pattern = 6,
1234 Dense6Pattern = 7,
1235 Dense7Pattern = 8,
1236 HorPattern = 9,
1237 VerPattern = 10,
1238 CrossPattern = 11,
1239 BDiagPattern = 12,
1240 FDiagPattern = 13,
1241 DiagCrossPattern = 14,
1242 LinearGradientPattern = 15,
1243 ConicalGradientPattern = 17,
1244 RadialGradientPattern = 16,
1245 TexturePattern = 24,
1246}
1247cpp_class!(
1248 /// Wrapper around [`QBrush`][class] class.
1249 ///
1250 /// [class]: https://doc.qt.io/qt-5/qbrush.html
1251 #[derive(Default)]
1252 pub unsafe struct QBrush as "QBrush "
1253);
1254impl QBrush {
1255 pub fn from_color(color: QColor) -> Self {
1256 cpp!(unsafe [color as "QColor"] -> QBrush as "QBrush" { return QBrush(color); })
1257 }
1258 pub fn from_style(style: BrushStyle) -> Self {
1259 cpp!(unsafe [style as "Qt::BrushStyle"] -> QBrush as "QBrush" { return QBrush(style); })
1260 }
1261 pub fn set_color(&mut self, color: QColor) {
1262 cpp!(unsafe [self as "QBrush*", color as "QColor"] { return self->setColor(color); });
1263 }
1264 pub fn set_style(&mut self, style: BrushStyle) {
1265 cpp!(unsafe [self as "QBrush*", style as "Qt::BrushStyle"] { return self->setStyle(style); });
1266 }
1267}
1268
1269/// Bindings for [`QLineF`][class] class.
1270///
1271/// [class]: https://doc.qt.io/qt-5/qlinef.html
1272#[repr(C)]
1273#[derive(Default, Clone, Copy, PartialEq, Debug)]
1274pub struct QLineF {
1275 pub pt1: QPointF,
1276 pub pt2: QPointF,
1277}
1278
1279cpp_class!(
1280 /// Wrapper around [`QPainter`][class] class.
1281 ///
1282 /// [class]: https://doc.qt.io/qt-5/qpainter.html
1283 pub unsafe struct QPainter as "QPainter "
1284);
1285impl QPainter {
1286 pub fn draw_arc(&mut self, rectangle: QRectF, start_angle: i32, span_angle: i32) {
1287 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", start_angle as "int", span_angle as "int"] {
1288 self->drawArc(rectangle, start_angle, span_angle);
1289 });
1290 }
1291 pub fn draw_chord(&mut self, rectangle: QRectF, start_angle: i32, span_angle: i32) {
1292 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", start_angle as "int", span_angle as "int"] {
1293 self->drawChord(rectangle, start_angle, span_angle);
1294 });
1295 }
1296
1297 pub fn draw_convex_polygon(&mut self, points: &[QPointF]) {
1298 let points_ptr = points.as_ptr();
1299 let points_count = points.len() as u64;
1300 cpp!(unsafe [self as "QPainter *", points_ptr as "QPointF*", points_count as "uint64_t"] {
1301 self->drawConvexPolygon(points_ptr, points_count);
1302 });
1303 }
1304
1305 pub fn draw_ellipse(&mut self, rectangle: QRectF) {
1306 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF"] {
1307 self->drawEllipse(rectangle);
1308 });
1309 }
1310 pub fn draw_ellipse_with_center(&mut self, center: QPointF, rx: qreal, ry: qreal) {
1311 cpp!(unsafe [self as "QPainter *", center as "QPointF", rx as "qreal", ry as "qreal"] {
1312 self->drawEllipse(center, rx, ry);
1313 });
1314 }
1315
1316 pub fn draw_image_fit_rect(&mut self, rectangle: QRectF, image: QImage) {
1317 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", image as "QImage"] {
1318 self->drawImage(rectangle, image);
1319 });
1320 }
1321 pub fn draw_image_at_point(&mut self, point: QPointF, image: QImage) {
1322 cpp!(unsafe [self as "QPainter *", point as "QPointF", image as "QImage"] {
1323 self->drawImage(point, image);
1324 });
1325 }
1326 pub fn draw_image_fit_rect_with_source(
1327 &mut self,
1328 rectangle: QRectF,
1329 image: QImage,
1330 source_rect: QRectF,
1331 ) {
1332 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", image as "QImage", source_rect as "QRectF"] {
1333 self->drawImage(rectangle, image, source_rect);
1334 });
1335 }
1336 pub fn draw_image_at_point_with_source(
1337 &mut self,
1338 point: QPointF,
1339 image: QImage,
1340 source_rect: QRectF,
1341 ) {
1342 cpp!(unsafe [self as "QPainter *", point as "QPointF", image as "QImage", source_rect as "QRectF"] {
1343 self->drawImage(point, image, source_rect);
1344 });
1345 }
1346
1347 pub fn draw_line(&mut self, line: QLineF) {
1348 cpp!(unsafe [self as "QPainter *", line as "QLineF"] {
1349 self->drawLine(line);
1350 });
1351 }
1352 pub fn draw_lines(&mut self, lines: &[QLineF]) {
1353 let lines_ptr = lines.as_ptr();
1354 let lines_count = lines.len() as u64;
1355 cpp!(unsafe [self as "QPainter *", lines_ptr as "QLineF*", lines_count as "uint64_t"] {
1356 self->drawLines(lines_ptr, lines_count);
1357 });
1358 }
1359 pub fn draw_lines_from_points(&mut self, point_pairs: &[QPointF]) {
1360 let point_pairs_ptr = point_pairs.as_ptr();
1361 let point_pairs_count = point_pairs.len() as u64;
1362 cpp!(unsafe [self as "QPainter *", point_pairs_ptr as "QLineF*", point_pairs_count as "uint64_t"] {
1363 self->drawLines(point_pairs_ptr, point_pairs_count);
1364 });
1365 }
1366
1367 pub fn draw_pie(&mut self, rectangle: QRectF, start_angle: i32, span_angle: i32) {
1368 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", start_angle as "int", span_angle as "int"] {
1369 self->drawPie(rectangle, start_angle, span_angle);
1370 });
1371 }
1372
1373 pub fn draw_point(&mut self, point: QPointF) {
1374 cpp!(unsafe [self as "QPainter *", point as "QPointF"] {
1375 self->drawPoint(point);
1376 });
1377 }
1378 pub fn draw_points(&mut self, points: &[QPointF]) {
1379 let points_ptr = points.as_ptr();
1380 let points_count = points.len() as u64;
1381 cpp!(unsafe [self as "QPainter *", points_ptr as "QPointF*", points_count as "uint64_t"] {
1382 self->drawPoints(points_ptr, points_count);
1383 });
1384 }
1385
1386 pub fn draw_polygon(&mut self, points: &[QPointF]) {
1387 let points_ptr = points.as_ptr();
1388 let points_count = points.len() as u64;
1389 cpp!(unsafe [self as "QPainter *", points_ptr as "QPointF*", points_count as "uint64_t"] {
1390 self->drawPolygon(points_ptr, points_count);
1391 });
1392 }
1393 pub fn draw_polyline(&mut self, points: &[QPointF]) {
1394 let points_ptr = points.as_ptr();
1395 let points_count = points.len() as u64;
1396 cpp!(unsafe [self as "QPainter *", points_ptr as "QPointF*", points_count as "uint64_t"] {
1397 self->drawPolyline(points_ptr, points_count);
1398 });
1399 }
1400
1401 pub fn draw_rect(&mut self, rectangle: QRectF) {
1402 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF"] {
1403 self->drawRect(rectangle);
1404 });
1405 }
1406 pub fn draw_rects(&mut self, rects: &[QRectF]) {
1407 let rects_ptr = rects.as_ptr();
1408 let rects_count = rects.len() as u64;
1409 cpp!(unsafe [self as "QPainter *", rects_ptr as "QRectF*", rects_count as "uint64_t"] {
1410 self->drawRects(rects_ptr, rects_count);
1411 });
1412 }
1413 pub fn draw_rounded_rect(&mut self, rect: QRectF, x_radius: qreal, y_radius: qreal) {
1414 cpp!(unsafe [self as "QPainter *", rect as "QRectF", x_radius as "qreal", y_radius as "qreal"] {
1415 self->drawRoundedRect(rect, x_radius, y_radius);
1416 });
1417 }
1418
1419 pub fn draw_text(&mut self, position: QPointF, text: QString) {
1420 cpp!(unsafe [self as "QPainter *", position as "QPointF", text as "QString"] {
1421 self->drawText(position, text);
1422 });
1423 }
1424 pub fn draw_text_in_rect(&mut self, rectangle: QRectF, flags: u32, text: QString) -> QRectF {
1425 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", flags as "uint32_t", text as "QString"] -> QRectF as "QRectF" {
1426 QRectF boundingRect;
1427 self->drawText(rectangle, flags, text, &boundingRect);
1428 return boundingRect;
1429 })
1430 }
1431
1432 pub fn erase_rect(&mut self, rectangle: QRectF) {
1433 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF"] {
1434 self->eraseRect(rectangle);
1435 });
1436 }
1437
1438 pub fn fill_rect(&mut self, rectangle: QRectF, brush: QBrush) {
1439 cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", brush as "QBrush"] {
1440 self->fillRect(rectangle, brush);
1441 });
1442 }
1443
1444 pub fn reset_transform(&mut self) {
1445 cpp!(unsafe [self as "QPainter *"] {
1446 self->resetTransform();
1447 });
1448 }
1449
1450 pub fn restore(&mut self) {
1451 cpp!(unsafe [self as "QPainter *"] {
1452 self->restore();
1453 });
1454 }
1455
1456 pub fn rotate(&mut self, angle: qreal) {
1457 cpp!(unsafe [self as "QPainter *", angle as "qreal"] {
1458 self->rotate(angle);
1459 });
1460 }
1461
1462 pub fn save(&mut self) {
1463 cpp!(unsafe [self as "QPainter *"] {
1464 self->save();
1465 });
1466 }
1467
1468 pub fn scale(&mut self, sx: qreal, sy: qreal) {
1469 cpp!(unsafe [self as "QPainter *", sx as "qreal", sy as "qreal"] {
1470 self->scale(sx, sy);
1471 });
1472 }
1473
1474 pub fn set_background(&mut self, brush: QBrush) {
1475 cpp!(unsafe [self as "QPainter *", brush as "QBrush"] {
1476 self->setBackground(brush);
1477 });
1478 }
1479
1480 pub fn set_brush(&mut self, brush: QBrush) {
1481 cpp!(unsafe [self as "QPainter *", brush as "QBrush"] {
1482 self->setBrush(brush);
1483 });
1484 }
1485
1486 pub fn set_opacity(&mut self, opacity: qreal) {
1487 cpp!(unsafe [self as "QPainter *", opacity as "qreal"] {
1488 self->setOpacity(opacity);
1489 });
1490 }
1491
1492 pub fn set_pen(&mut self, pen: QPen) {
1493 cpp!(unsafe [self as "QPainter *", pen as "QPen"] {
1494 self->setPen(pen);
1495 });
1496 }
1497
1498 pub fn translate(&mut self, offset: QPointF) {
1499 cpp!(unsafe [self as "QPainter *", offset as "QPointF"] {
1500 self->translate(offset);
1501 });
1502 }
1503 pub fn set_render_hint(&mut self, hint: QPainterRenderHint, on: bool) {
1504 cpp!(unsafe [self as "QPainter *", hint as "QPainter::RenderHint", on as "bool"] {
1505 self->setRenderHint(hint, on);
1506 });
1507 }
1508
1509 // void setBackgroundMode(Qt::BGMode mode)
1510 // void setCompositionMode(QPainter::CompositionMode mode)
1511 // void setFont(const QFont &font)
1512}
1513
1514/// Bindings for [`QPainter::RenderHint`][enum] enum.
1515///
1516/// [enum]: https://doc.qt.io/qt-5/qpainter.html#RenderHint-enum
1517#[repr(C)]
1518#[derive(Clone, Copy, PartialEq, Debug)]
1519#[allow(non_camel_case_types)]
1520pub enum QPainterRenderHint {
1521 Antialiasing = 0x01,
1522 TextAntialiasing = 0x02,
1523 SmoothPixmapTransform = 0x04,
1524 HighQualityAntialiasing = 0x08,
1525 NonCosmeticDefaultPen = 0x10,
1526 Qt4CompatiblePainting = 0x20,
1527 LosslessImageRendering = 0x40,
1528}
1529
1530cpp! {{
1531 #include <QtCore/QJsonDocument>
1532 #include <QtCore/QJsonValue>
1533 #include <QtCore/QJsonObject>
1534 #include <QtCore/QJsonArray>
1535}}
1536cpp_class!(
1537 /// Wrapper around [`QJsonValue`][class] class.
1538 ///
1539 /// [class]: https://doc.qt.io/qt-5/qjsonvalue.html
1540 #[derive(Default, PartialEq, Eq, Clone)]
1541 pub unsafe struct QJsonValue as "QJsonValue"
1542);
1543
1544impl Into<QVariant> for QJsonValue {
1545 fn into(self) -> QVariant {
1546 cpp!(unsafe [self as "QJsonValue"] -> QVariant as "QVariant" { return self.toVariant(); })
1547 }
1548}
1549impl From<QVariant> for QJsonValue {
1550 fn from(v: QVariant) -> QJsonValue {
1551 cpp!(unsafe [v as "QVariant"] -> QJsonValue as "QJsonValue" { return QJsonValue::fromVariant(v); })
1552 }
1553}
1554
1555impl Into<QJsonObject> for QJsonValue {
1556 fn into(self) -> QJsonObject {
1557 cpp!(unsafe [self as "QJsonValue"] -> QJsonObject as "QJsonObject" { return self.toObject(); })
1558 }
1559}
1560impl From<QJsonObject> for QJsonValue {
1561 fn from(v: QJsonObject) -> QJsonValue {
1562 cpp!(unsafe [v as "QJsonObject"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1563 }
1564}
1565impl Into<QJsonArray> for QJsonValue {
1566 fn into(self) -> QJsonArray {
1567 cpp!(unsafe [self as "QJsonValue"] -> QJsonArray as "QJsonArray" { return self.toArray(); })
1568 }
1569}
1570impl From<QJsonArray> for QJsonValue {
1571 fn from(v: QJsonArray) -> QJsonValue {
1572 cpp!(unsafe [v as "QJsonArray"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1573 }
1574}
1575
1576impl Into<QString> for QJsonValue {
1577 fn into(self) -> QString {
1578 cpp!(unsafe [self as "QJsonValue"] -> QString as "QString" { return self.toString(); })
1579 }
1580}
1581impl From<QString> for QJsonValue {
1582 fn from(v: QString) -> QJsonValue {
1583 cpp!(unsafe [v as "QString"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1584 }
1585}
1586
1587impl Into<bool> for QJsonValue {
1588 fn into(self) -> bool {
1589 cpp!(unsafe [self as "QJsonValue"] -> bool as "bool" { return self.toBool(); })
1590 }
1591}
1592impl From<bool> for QJsonValue {
1593 fn from(v: bool) -> QJsonValue {
1594 cpp!(unsafe [v as "bool"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1595 }
1596}
1597
1598impl Into<f64> for QJsonValue {
1599 fn into(self) -> f64 {
1600 cpp!(unsafe [self as "QJsonValue"] -> f64 as "double" { return self.toDouble(); })
1601 }
1602}
1603impl From<f64> for QJsonValue {
1604 fn from(v: f64) -> QJsonValue {
1605 cpp!(unsafe [v as "double"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1606 }
1607}
1608
1609#[test]
1610fn test_qjsonvalue() {
1611 let test_str = QJsonValue::from(QVariant::from(QString::from("test")));
1612 let test_str2 = QJsonValue::from(QString::from("test"));
1613 assert!(test_str == test_str2);
1614 assert_eq!(<QJsonValue as Into<QString>>::into(test_str), QString::from("test"));
1615
1616 let test_bool = QJsonValue::from(true);
1617 let test_bool_variant: QVariant = QJsonValue::from(true).into();
1618 let test_bool_variant2 = QVariant::from(true);
1619 assert!(test_bool_variant == test_bool_variant2);
1620 assert_eq!(<QJsonValue as Into<bool>>::into(test_bool), true);
1621
1622 let test_f64 = QJsonValue::from(1.2345);
1623 let test_f64_variant: QVariant = QJsonValue::from(1.2345).into();
1624 let test_f64_variant2 = QVariant::from(1.2345);
1625 assert!(test_f64_variant == test_f64_variant2);
1626 assert_eq!(<QJsonValue as Into<f64>>::into(test_f64), 1.2345);
1627
1628 let values = QJsonArray::from(vec![
1629 QJsonValue::from(QString::from("test")),
1630 QJsonValue::from(true),
1631 QJsonValue::from(false),
1632 QJsonValue::from(1.2345),
1633 QJsonValue::from(456.0),
1634 ]);
1635
1636 assert_eq!(values.to_json().to_string(), "[\"test\",true,false,1.2345,456]");
1637}
1638
1639cpp_class!(
1640 /// Wrapper around [`QJsonObject`][class] class.
1641 ///
1642 /// [class]: https://doc.qt.io/qt-5/qjsonobject.html
1643 #[derive(Default, PartialEq, Eq, Clone)]
1644 pub unsafe struct QJsonObject as "QJsonObject"
1645);
1646
1647impl QJsonObject {
1648 pub fn to_json(&self) -> QByteArray {
1649 cpp!(unsafe [self as "QJsonObject*"] -> QByteArray as "QByteArray" { return QJsonDocument(*self).toJson(QJsonDocument::Compact); })
1650 }
1651 pub fn to_json_pretty(&self) -> QByteArray {
1652 cpp!(unsafe [self as "QJsonObject*"] -> QByteArray as "QByteArray" { return QJsonDocument(*self).toJson(QJsonDocument::Indented); })
1653 }
1654 pub fn insert(&mut self, key: &str, value: QJsonValue) {
1655 let len = key.len();
1656 let ptr = key.as_ptr();
1657 cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*", value as "QJsonValue"] { self->insert(QString::fromUtf8(ptr, len), std::move(value)); })
1658 }
1659 pub fn value(&self, key: &str) -> QJsonValue {
1660 let len = key.len();
1661 let ptr = key.as_ptr();
1662 cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*"] -> QJsonValue as "QJsonValue" { return self->value(QString::fromUtf8(ptr, len)); })
1663 }
1664 pub fn take(&mut self, key: &str) -> QJsonValue {
1665 let len = key.len();
1666 let ptr = key.as_ptr();
1667 cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*"] -> QJsonValue as "QJsonValue" { return self->take(QString::fromUtf8(ptr, len)); })
1668 }
1669 pub fn remove(&mut self, key: &str) {
1670 let len = key.len();
1671 let ptr = key.as_ptr();
1672 cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*"] { return self->remove(QString::fromUtf8(ptr, len)); })
1673 }
1674 pub fn len(&self) -> usize {
1675 cpp!(unsafe [self as "QJsonObject*"] -> usize as "size_t" { return self->size(); })
1676 }
1677 pub fn is_empty(&self) -> bool {
1678 cpp!(unsafe [self as "QJsonObject*"] -> bool as "bool" { return self->isEmpty(); })
1679 }
1680 pub fn contains(&self, key: &str) -> bool {
1681 let len = key.len();
1682 let ptr = key.as_ptr();
1683 cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*"] -> bool as "bool" { return self->contains(QString::fromUtf8(ptr, len)); })
1684 }
1685 pub fn keys(&self) -> Vec<String> {
1686 let len = self.len();
1687 let mut vec = Vec::with_capacity(len);
1688
1689 let keys = cpp!(unsafe [self as "QJsonObject*"] -> QStringList as "QStringList" { return self->keys(); });
1690
1691 for i in 0..len {
1692 vec.push(keys[i].to_string());
1693 }
1694 vec
1695 }
1696}
1697
1698impl From<HashMap<String, String>> for QJsonObject {
1699 fn from(v: HashMap<String, String>) -> QJsonObject {
1700 let keys: Vec<QString> = v.keys().cloned().map(QString::from).collect();
1701 let values: Vec<QString> = v.values().cloned().map(QString::from).collect();
1702 let keys_ptr: *const QString = keys.as_ptr();
1703 let values_ptr: *const QString = values.as_ptr();
1704 let len: usize = keys.len();
1705 cpp!(unsafe [keys_ptr as "const QString*", values_ptr as "const QString*", len as "size_t"] -> QJsonObject as "QJsonObject" {
1706 QJsonObject obj;
1707 for (size_t i = 0; i < len; ++i) {
1708 obj.insert(keys_ptr[i], values_ptr[i]);
1709 }
1710 return obj;
1711 })
1712 }
1713}
1714impl From<HashMap<String, QJsonValue>> for QJsonObject {
1715 fn from(v: HashMap<String, QJsonValue>) -> QJsonObject {
1716 let keys: Vec<QString> = v.keys().cloned().map(QString::from).collect();
1717 let values: Vec<QJsonValue> = v.values().cloned().collect();
1718 let keys_ptr: *const QString = keys.as_ptr();
1719 let values_ptr: *const QJsonValue = values.as_ptr();
1720 let len: usize = keys.len();
1721 cpp!(unsafe [keys_ptr as "const QString*", values_ptr as "const QJsonValue*", len as "size_t"] -> QJsonObject as "QJsonObject" {
1722 QJsonObject obj;
1723 for (size_t i = 0; i < len; ++i) {
1724 obj.insert(keys_ptr[i], values_ptr[i]);
1725 }
1726 return obj;
1727 })
1728 }
1729}
1730
1731cpp! {{ #include <QtCore/QDebug> }}
1732
1733#[test]
1734fn test_qjsonobject() {
1735 let mut hashmap = HashMap::new();
1736 hashmap.insert("key".to_owned(), "value".to_owned());
1737 hashmap.insert("test".to_owned(), "hello".to_owned());
1738 let object = QJsonObject::from(hashmap);
1739 assert_eq!(object.to_json().to_string(), "{\"key\":\"value\",\"test\":\"hello\"}");
1740
1741 let array = QJsonArray::from(vec![
1742 QJsonValue::from(QString::from("test")),
1743 QJsonValue::from(true),
1744 QJsonValue::from(false),
1745 QJsonValue::from(1.2345),
1746 QJsonValue::from(456.0),
1747 ]);
1748
1749 let mut valuemap = HashMap::new();
1750 valuemap.insert("1_string".to_owned(), QJsonValue::from(QString::from("test")));
1751 valuemap.insert("2_bool".to_owned(), QJsonValue::from(true));
1752 valuemap.insert("3_f64".to_owned(), QJsonValue::from(1.2345));
1753 valuemap.insert("4_int".to_owned(), QJsonValue::from(456.0));
1754 valuemap.insert("5_array".to_owned(), QJsonValue::from(array));
1755 valuemap.insert("6_object".to_owned(), QJsonValue::from(object));
1756 let object = QJsonObject::from(valuemap);
1757 assert_eq!(object.to_json().to_string(), "{\"1_string\":\"test\",\"2_bool\":true,\"3_f64\":1.2345,\"4_int\":456,\"5_array\":[\"test\",true,false,1.2345,456],\"6_object\":{\"key\":\"value\",\"test\":\"hello\"}}");
1758
1759 let at_f64: f64 = object.value("3_f64").into();
1760 assert_eq!(at_f64, 1.2345);
1761
1762 let at_string = object.value("1_string");
1763 assert_eq!(<QJsonValue as Into<QString>>::into(at_string).to_string(), "test");
1764
1765 let mut object = QJsonObject::default();
1766 object.insert("key", QJsonValue::from(QString::from("value")));
1767 object.insert("test", QJsonValue::from(QString::from("hello")));
1768 assert_eq!(object.to_json().to_string(), "{\"key\":\"value\",\"test\":\"hello\"}");
1769
1770 assert_eq!(object.keys(), vec!["key".to_owned(), "test".to_owned()]);
1771}
1772
1773#[test]
1774fn test_qjsonobject_utf8() {
1775 let emoji: String = String::from("🦀");
1776 let expected: String = String::from("{\"🦀\":1}");
1777
1778 let mut qmap: QJsonObject = QJsonObject::default();
1779 qmap.insert(&emoji, value:QVariant::from(1).into());
1780
1781 let actual: QByteArray = qmap.to_json();
1782 let actual: &str = actual.to_str().unwrap();
1783
1784 assert_eq!(actual, expected);
1785}
1786
1787cpp_class!(
1788 /// Wrapper around [`QJsonArray`][class] class.
1789 ///
1790 /// [class]: https://doc.qt.io/qt-5/qjsonarray.html
1791 #[derive(Default, PartialEq, Eq, Clone)]
1792 pub unsafe struct QJsonArray as "QJsonArray"
1793);
1794
1795impl QJsonArray {
1796 pub fn to_json(&self) -> QByteArray {
1797 cpp!(unsafe [self as "QJsonArray*"] -> QByteArray as "QByteArray" { return QJsonDocument(*self).toJson(QJsonDocument::Compact); })
1798 }
1799 pub fn to_json_pretty(&self) -> QByteArray {
1800 cpp!(unsafe [self as "QJsonArray*"] -> QByteArray as "QByteArray" { return QJsonDocument(*self).toJson(QJsonDocument::Indented); })
1801 }
1802 pub fn push(&mut self, value: QJsonValue) {
1803 cpp!(unsafe [self as "QJsonArray*", value as "QJsonValue"] { self->append(std::move(value)); })
1804 }
1805 pub fn insert(&mut self, index: usize, element: QJsonValue) {
1806 cpp!(unsafe [self as "QJsonArray*", index as "size_t", element as "QJsonValue"] { self->insert(index, std::move(element)); })
1807 }
1808 pub fn at(&self, index: usize) -> QJsonValue {
1809 cpp!(unsafe [self as "QJsonArray*", index as "size_t"] -> QJsonValue as "QJsonValue" { return self->at(index); })
1810 }
1811 pub fn take_at(&mut self, index: usize) -> QJsonValue {
1812 cpp!(unsafe [self as "QJsonArray*", index as "size_t"] -> QJsonValue as "QJsonValue" { return self->takeAt(index); })
1813 }
1814 pub fn remove_at(&mut self, index: usize) {
1815 cpp!(unsafe [self as "QJsonArray*", index as "size_t"] { return self->removeAt(index); })
1816 }
1817 pub fn len(&self) -> usize {
1818 cpp!(unsafe [self as "QJsonArray*"] -> usize as "size_t" { return self->size(); })
1819 }
1820 pub fn is_empty(&self) -> bool {
1821 cpp!(unsafe [self as "QJsonArray*"] -> bool as "bool" { return self->isEmpty(); })
1822 }
1823}
1824
1825impl From<Vec<QJsonValue>> for QJsonArray {
1826 fn from(v: Vec<QJsonValue>) -> QJsonArray {
1827 let ptr: *const QJsonValue = v.as_ptr();
1828 let len: usize = v.len();
1829 cpp!(unsafe [ptr as "const QJsonValue*", len as "size_t"] -> QJsonArray as "QJsonArray" {
1830 QJsonArray arr;
1831 for (size_t i = 0; i < len; ++i) {
1832 arr.append(ptr[i]);
1833 }
1834 return arr;
1835 })
1836 }
1837}
1838
1839#[test]
1840fn test_qjsonarray() {
1841 let mut array: QJsonArray = QJsonArray::default();
1842 array.push(QJsonValue::from(QString::from("test")));
1843 array.push(QJsonValue::from(true));
1844 array.push(QJsonValue::from(false));
1845 array.push(QJsonValue::from(1.2345));
1846 assert_eq!(array.to_json().to_string(), "[\"test\",true,false,1.2345]");
1847
1848 let mut vec: Vec = Vec::new();
1849 vec.push(QJsonValue::from(QString::from("test")));
1850 vec.push(QJsonValue::from(true));
1851 vec.push(QJsonValue::from(false));
1852 vec.push(QJsonValue::from(1.2345));
1853 assert!(QJsonArray::from(vec) == array);
1854
1855 assert_eq!(array.len(), 4);
1856
1857 assert_eq!(<QJsonValue as Into<QString>>::into(array.at(0)).to_string(), "test");
1858 assert!(array.at(3) == QJsonValue::from(1.2345));
1859}
1860