| 1 | /* Copyright (C) 2018 Olivier Goffart <ogoffart@woboq.com> |
| 2 | |
| 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
| 4 | associated documentation files (the "Software"), to deal in the Software without restriction, |
| 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 6 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, |
| 7 | subject to the following conditions: |
| 8 | |
| 9 | The above copyright notice and this permission notice shall be included in all copies or substantial |
| 10 | portions of the Software. |
| 11 | |
| 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
| 13 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 14 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES |
| 15 | OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 16 | CONNECTION 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 `qmake6` or `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 | |
| 123 | use std::collections::HashMap; |
| 124 | use std::convert::From; |
| 125 | use std::fmt; |
| 126 | use std::hash::Hash; |
| 127 | use std::iter::FromIterator; |
| 128 | use std::ops::{Index, IndexMut}; |
| 129 | |
| 130 | #[cfg (feature = "chrono" )] |
| 131 | use chrono::prelude::*; |
| 132 | |
| 133 | #[cfg (no_qt)] |
| 134 | pub(crate) mod no_qt { |
| 135 | pub fn panic<T>() -> T { |
| 136 | panic!("Qt was not found during build" ) |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | pub(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 | } |
| 167 | use internal_prelude::*; |
| 168 | |
| 169 | mod qtcore; |
| 170 | pub use crate::qtcore::{ |
| 171 | qreal, NormalizationForm, QByteArray, QListIterator, QSettings, QString, QStringList, QUrl, |
| 172 | QVariant, QVariantList, UnicodeVersion, |
| 173 | }; |
| 174 | |
| 175 | mod qtgui; |
| 176 | pub use crate::qtgui::{QColor, QColorNameFormat, QColorSpec, QRgb, QRgba64}; |
| 177 | |
| 178 | cpp! {{ |
| 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 | |
| 193 | cpp_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 | ); |
| 200 | impl 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" )] |
| 241 | impl 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" )] |
| 247 | impl 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 ] |
| 255 | fn test_qdate() { |
| 256 | let date = QDate::from_y_m_d(2019, 10, 22); |
| 257 | assert_eq!((2019, 10, 22), date.get_y_m_d()); |
| 258 | } |
| 259 | |
| 260 | #[test ] |
| 261 | fn test_qdate_is_valid() { |
| 262 | let valid_qdate = QDate::from_y_m_d(2019, 10, 26); |
| 263 | assert!(valid_qdate.is_valid()); |
| 264 | |
| 265 | let invalid_qdate = QDate::from_y_m_d(-1, -1, -1); |
| 266 | assert!(!invalid_qdate.is_valid()); |
| 267 | } |
| 268 | |
| 269 | #[cfg (feature = "chrono" )] |
| 270 | #[test ] |
| 271 | fn 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 | |
| 281 | cpp_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 | ); |
| 288 | impl 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" )] |
| 357 | impl 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" )] |
| 369 | impl 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 ] |
| 377 | fn test_qtime() { |
| 378 | let qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(300)); |
| 379 | assert_eq!((10, 30, 40, 300), qtime.get_h_m_s_ms()); |
| 380 | } |
| 381 | |
| 382 | #[cfg (feature = "chrono" )] |
| 383 | #[test ] |
| 384 | fn 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 ] |
| 395 | fn test_qtime_is_valid() { |
| 396 | let valid_qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(300)); |
| 397 | assert!(valid_qtime.is_valid()); |
| 398 | |
| 399 | let invalid_qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(9999)); |
| 400 | assert!(!invalid_qtime.is_valid()); |
| 401 | } |
| 402 | |
| 403 | cpp_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 | ); |
| 410 | impl 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 ] |
| 471 | fn test_qdatetime_from_date() { |
| 472 | let qdate = QDate::from_y_m_d(2019, 10, 22); |
| 473 | let qdatetime = QDateTime::from_date(qdate); |
| 474 | let actual_qdate = qdatetime.get_date(); |
| 475 | |
| 476 | assert_eq!((2019, 10, 22), actual_qdate.get_y_m_d()); |
| 477 | } |
| 478 | |
| 479 | #[test ] |
| 480 | fn test_qdatetime_from_date_time_local_timezone() { |
| 481 | let qdate = QDate::from_y_m_d(2019, 10, 22); |
| 482 | let qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(300)); |
| 483 | let qdatetime = QDateTime::from_date_time_local_timezone(qdate, qtime); |
| 484 | let (actual_qdate, actual_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 ] |
| 496 | fn 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 | |
| 525 | cpp_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 | |
| 533 | impl 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 | |
| 616 | impl 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 | } |
| 634 | impl 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 | |
| 647 | impl 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 | |
| 653 | cpp_class!(unsafe struct QVariantMapIteratorInternal as "QVariantMap::iterator" ); |
| 654 | |
| 655 | /// Internal class used to iterate over a [`QVariantMap`] |
| 656 | pub struct QVariantMapIterator<'a> { |
| 657 | map: &'a QVariantMap, |
| 658 | iterator: QVariantMapIteratorInternal, |
| 659 | } |
| 660 | |
| 661 | impl<'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 | |
| 692 | impl<'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: &'a QString), Some(v: &'a QVariant)) => Some((k, v)), |
| 707 | _ => None, |
| 708 | } |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | impl<'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 | |
| 724 | impl<K, V> FromIterator<(K, V)> for QVariantMap |
| 725 | where |
| 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 | |
| 739 | impl<K, V> From<HashMap<K, V>> for QVariantMap |
| 740 | where |
| 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 | |
| 749 | impl<K, V, const N: usize> From<[(K, V); N]> for QVariantMap |
| 750 | where |
| 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.into(), element:val.into()); |
| 758 | } |
| 759 | temp |
| 760 | } |
| 761 | } |
| 762 | |
| 763 | impl<K, V> From<QVariantMap> for HashMap<K, V> |
| 764 | where |
| 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)] |
| 776 | mod 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 | |
| 845 | cpp_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 | ); |
| 852 | impl 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)] |
| 887 | pub struct QRectF { |
| 888 | pub x: qreal, |
| 889 | pub y: qreal, |
| 890 | pub width: qreal, |
| 891 | pub height: qreal, |
| 892 | } |
| 893 | impl 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)] |
| 923 | pub struct QPointF { |
| 924 | pub x: qreal, |
| 925 | pub y: qreal, |
| 926 | } |
| 927 | impl 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 | } |
| 936 | impl 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)] |
| 950 | pub struct QSizeF { |
| 951 | pub width: qreal, |
| 952 | pub height: qreal, |
| 953 | } |
| 954 | |
| 955 | #[test ] |
| 956 | fn test_qpointf_qrectf() { |
| 957 | let rect = QRectF { x: 200., y: 150., width: 60., height: 75. }; |
| 958 | let pt = 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)] |
| 968 | pub 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)] |
| 978 | pub 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)] |
| 988 | pub 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)] |
| 1001 | pub 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 | } |
| 1033 | cpp_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 | ); |
| 1040 | impl 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 | |
| 1099 | cpp_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 | |
| 1106 | impl 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 | |
| 1115 | impl 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 | |
| 1121 | impl 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)] |
| 1133 | pub enum PenStyle { |
| 1134 | NoPen = 0, |
| 1135 | SolidLine = 1, |
| 1136 | DashLine = 2, |
| 1137 | DotLine = 3, |
| 1138 | DashDotLine = 4, |
| 1139 | DashDotDotLine = 5, |
| 1140 | CustomDashLine = 6, |
| 1141 | } |
| 1142 | cpp_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 | |
| 1150 | impl 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)] |
| 1198 | pub 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)] |
| 1226 | pub 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 | } |
| 1247 | cpp_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 | ); |
| 1254 | impl 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)] |
| 1274 | pub struct QLineF { |
| 1275 | pub pt1: QPointF, |
| 1276 | pub pt2: QPointF, |
| 1277 | } |
| 1278 | |
| 1279 | cpp_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 | ); |
| 1285 | impl 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)] |
| 1520 | pub 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 | |
| 1530 | cpp! {{ |
| 1531 | #include <QtCore/QJsonDocument> |
| 1532 | #include <QtCore/QJsonValue> |
| 1533 | #include <QtCore/QJsonObject> |
| 1534 | #include <QtCore/QJsonArray> |
| 1535 | }} |
| 1536 | cpp_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 | |
| 1544 | impl Into<QVariant> for QJsonValue { |
| 1545 | fn into(self) -> QVariant { |
| 1546 | cpp!(unsafe [self as "QJsonValue" ] -> QVariant as "QVariant" { return self.toVariant(); }) |
| 1547 | } |
| 1548 | } |
| 1549 | impl 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 | |
| 1555 | impl Into<QJsonObject> for QJsonValue { |
| 1556 | fn into(self) -> QJsonObject { |
| 1557 | cpp!(unsafe [self as "QJsonValue" ] -> QJsonObject as "QJsonObject" { return self.toObject(); }) |
| 1558 | } |
| 1559 | } |
| 1560 | impl From<QJsonObject> for QJsonValue { |
| 1561 | fn from(v: QJsonObject) -> QJsonValue { |
| 1562 | cpp!(unsafe [v as "QJsonObject" ] -> QJsonValue as "QJsonValue" { return QJsonValue(v); }) |
| 1563 | } |
| 1564 | } |
| 1565 | impl Into<QJsonArray> for QJsonValue { |
| 1566 | fn into(self) -> QJsonArray { |
| 1567 | cpp!(unsafe [self as "QJsonValue" ] -> QJsonArray as "QJsonArray" { return self.toArray(); }) |
| 1568 | } |
| 1569 | } |
| 1570 | impl 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 | |
| 1576 | impl Into<QString> for QJsonValue { |
| 1577 | fn into(self) -> QString { |
| 1578 | cpp!(unsafe [self as "QJsonValue" ] -> QString as "QString" { return self.toString(); }) |
| 1579 | } |
| 1580 | } |
| 1581 | impl 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 | |
| 1587 | impl Into<bool> for QJsonValue { |
| 1588 | fn into(self) -> bool { |
| 1589 | cpp!(unsafe [self as "QJsonValue" ] -> bool as "bool" { return self.toBool(); }) |
| 1590 | } |
| 1591 | } |
| 1592 | impl 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 | |
| 1598 | impl Into<f64> for QJsonValue { |
| 1599 | fn into(self) -> f64 { |
| 1600 | cpp!(unsafe [self as "QJsonValue" ] -> f64 as "double" { return self.toDouble(); }) |
| 1601 | } |
| 1602 | } |
| 1603 | impl 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 ] |
| 1610 | fn 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 | |
| 1639 | cpp_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 | |
| 1647 | impl 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 | |
| 1698 | impl 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 | } |
| 1714 | impl 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 | |
| 1731 | cpp! {{ #include <QtCore/QDebug> }} |
| 1732 | |
| 1733 | #[test ] |
| 1734 | fn 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 ] |
| 1774 | fn test_qjsonobject_utf8() { |
| 1775 | let emoji = String::from("🦀" ); |
| 1776 | let expected = String::from("{ \"🦀 \":1}" ); |
| 1777 | |
| 1778 | let mut qmap: QJsonObject = QJsonObject::default(); |
| 1779 | qmap.insert(&emoji, QVariant::from(1).into()); |
| 1780 | |
| 1781 | let actual = qmap.to_json(); |
| 1782 | let actual = actual.to_str().unwrap(); |
| 1783 | |
| 1784 | assert_eq!(actual, expected); |
| 1785 | } |
| 1786 | |
| 1787 | cpp_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 | |
| 1795 | impl 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 | |
| 1825 | impl 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 ] |
| 1840 | fn test_qjsonarray() { |
| 1841 | let mut array = 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::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 | |