|
| 1 | +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]> |
| 2 | +// SPDX-FileContributor: Laurent Montel <[email protected]> |
| 3 | +// |
| 4 | +// SPDX-License-Identifier: MIT OR Apache-2.0 |
| 5 | + |
| 6 | +use crate::{QByteArray, QFont, QString, QStringList, QVector}; |
| 7 | +use core::pin::Pin; |
| 8 | + |
| 9 | +#[cxx::bridge] |
| 10 | +mod ffi { |
| 11 | + unsafe extern "C++" { |
| 12 | + include!("cxx-qt-lib/qbytearray.h"); |
| 13 | + type QByteArray = crate::QByteArray; |
| 14 | + include!("cxx-qt-lib/qstring.h"); |
| 15 | + type QString = crate::QString; |
| 16 | + include!("cxx-qt-lib/qstringlist.h"); |
| 17 | + type QStringList = crate::QStringList; |
| 18 | + include!("cxx-qt-lib/qvector.h"); |
| 19 | + type QVector_QByteArray = crate::QVector<QByteArray>; |
| 20 | + include!("cxx-qt-lib/qfont.h"); |
| 21 | + type QFont = crate::QFont; |
| 22 | + |
| 23 | + include!("cxx-qt-lib-extras/qapplication.h"); |
| 24 | + type QApplication; |
| 25 | + } |
| 26 | + |
| 27 | + #[namespace = "rust::cxxqtlib1"] |
| 28 | + unsafe extern "C++" { |
| 29 | + #[doc(hidden)] |
| 30 | + #[rust_name = "qpplication_new"] |
| 31 | + fn qapplicationNew(args: &QVector_QByteArray) -> UniquePtr<QApplication>; |
| 32 | + } |
| 33 | + |
| 34 | + // These are all static, so we need to create bindings until CXX supports statics |
| 35 | + #[namespace = "rust::cxxqtlib1"] |
| 36 | + unsafe extern "C++" { |
| 37 | + // Reuse the templated versions from QCoreApplication |
| 38 | + include!("cxx-qt-lib/qcoreapplication.h"); |
| 39 | + |
| 40 | + #[doc(hidden)] |
| 41 | + #[rust_name = "qapplication_add_library_path"] |
| 42 | + fn qapplicationAddLibraryPath(app: Pin<&mut QApplication>, path: &QString); |
| 43 | + #[doc(hidden)] |
| 44 | + #[rust_name = "qapplication_application_name"] |
| 45 | + fn qapplicationApplicationName(app: &QApplication) -> QString; |
| 46 | + #[doc(hidden)] |
| 47 | + #[rust_name = "qapplication_remove_library_path"] |
| 48 | + fn qapplicationRemoveLibraryPath(app: &QApplication, path: &QString); |
| 49 | + #[doc(hidden)] |
| 50 | + #[rust_name = "qapplication_application_version"] |
| 51 | + fn qapplicationApplicationVersion(app: &QApplication) -> QString; |
| 52 | + #[doc(hidden)] |
| 53 | + #[rust_name = "qapplication_exec"] |
| 54 | + fn qapplicationExec(app: Pin<&mut QApplication>) -> i32; |
| 55 | + #[doc(hidden)] |
| 56 | + #[rust_name = "qapplication_library_paths"] |
| 57 | + fn qapplicationLibraryPaths(app: &QApplication) -> QStringList; |
| 58 | + #[doc(hidden)] |
| 59 | + #[rust_name = "qapplication_organization_domain"] |
| 60 | + fn qapplicationOrganizationDomain(app: &QApplication) -> QString; |
| 61 | + #[doc(hidden)] |
| 62 | + #[rust_name = "qapplication_organization_name"] |
| 63 | + fn qapplicationOrganizationName(app: &QApplication) -> QString; |
| 64 | + #[doc(hidden)] |
| 65 | + #[rust_name = "qapplication_set_application_name"] |
| 66 | + fn qapplicationSetApplicationName(app: Pin<&mut QApplication>, name: &QString); |
| 67 | + #[doc(hidden)] |
| 68 | + #[rust_name = "qapplication_set_application_version"] |
| 69 | + fn qapplicationSetApplicationVersion(app: Pin<&mut QApplication>, version: &QString); |
| 70 | + #[doc(hidden)] |
| 71 | + #[rust_name = "qapplication_set_font"] |
| 72 | + fn qapplicationSetFont(app: Pin<&mut QApplication>, font: &QFont); |
| 73 | + #[doc(hidden)] |
| 74 | + #[rust_name = "qapplication_font"] |
| 75 | + fn qapplicationFont(app: &QApplication) -> QFont; |
| 76 | + #[doc(hidden)] |
| 77 | + #[rust_name = "qapplication_set_library_paths"] |
| 78 | + fn qapplicationSetLibraryPaths(app: Pin<&mut QApplication>, paths: &QStringList); |
| 79 | + #[doc(hidden)] |
| 80 | + #[rust_name = "qapplication_set_organization_domain"] |
| 81 | + fn qapplicationSetOrganizationDomain(app: Pin<&mut QApplication>, domain: &QString); |
| 82 | + #[doc(hidden)] |
| 83 | + #[rust_name = "qapplication_set_organization_name"] |
| 84 | + fn qapplicationSetOrganizationName(app: Pin<&mut QApplication>, name: &QString); |
| 85 | + } |
| 86 | + |
| 87 | + // QApplication is not a trivial to CXX and is not relocatable in Qt |
| 88 | + // as the following fails in C++. So we cannot mark it as a trivial type |
| 89 | + // and need to use references or pointers. |
| 90 | + // static_assert(QTypeInfo<QApplication>::isRelocatable); |
| 91 | + impl UniquePtr<QApplication> {} |
| 92 | +} |
| 93 | + |
| 94 | +pub use ffi::QApplication; |
| 95 | + |
| 96 | +impl QApplication { |
| 97 | + /// Prepends path to the beginning of the library path list, |
| 98 | + /// ensuring that it is searched for libraries first. |
| 99 | + /// If path is empty or already in the path list, the path list is not changed. |
| 100 | + pub fn add_library_path(self: Pin<&mut Self>, path: &QString) { |
| 101 | + ffi::qapplication_add_library_path(self, path); |
| 102 | + } |
| 103 | + |
| 104 | + /// The name of this application |
| 105 | + pub fn application_name(&self) -> QString { |
| 106 | + ffi::qapplication_application_name(self) |
| 107 | + } |
| 108 | + |
| 109 | + /// The version of this application |
| 110 | + pub fn application_version(&self) -> QString { |
| 111 | + ffi::qapplication_application_version(self) |
| 112 | + } |
| 113 | + |
| 114 | + /// Enters the main event loop and waits until exit() is called, |
| 115 | + /// and then returns the value that was set to exit() (which is 0 if exit() is called via quit()). |
| 116 | + pub fn exec(self: Pin<&mut Self>) -> i32 { |
| 117 | + ffi::qapplication_exec(self) |
| 118 | + } |
| 119 | + |
| 120 | + /// Returns the default application font. |
| 121 | + pub fn font(&self) -> QFont { |
| 122 | + ffi::qapplication_font(self) |
| 123 | + } |
| 124 | + |
| 125 | + /// Returns a list of paths that the application will search when dynamically loading libraries. |
| 126 | + pub fn library_paths(&self) -> QStringList { |
| 127 | + ffi::qapplication_library_paths(self) |
| 128 | + } |
| 129 | + |
| 130 | + /// Initializes the window system and constructs an application object. |
| 131 | + /// Standard [Qt command line arguments](https://doc.qt.io/qt-6/qapplication.html#supported-command-line-options) are handled automatically. |
| 132 | + pub fn new() -> cxx::UniquePtr<Self> { |
| 133 | + let mut vector = QVector::<QByteArray>::default(); |
| 134 | + |
| 135 | + // Construct an owned QVector of the args |
| 136 | + // as we need the args_os data to outlive this method |
| 137 | + // so we pass a QVector to C++ which is then stored |
| 138 | + for arg in std::env::args_os() { |
| 139 | + // Unix OsStrings can be directly converted to bytes. |
| 140 | + #[cfg(unix)] |
| 141 | + use std::os::unix::ffi::OsStrExt; |
| 142 | + |
| 143 | + // Windows OsStrings are WTF-8 encoded, so they need to be |
| 144 | + // converted to UTF-8 Strings before being converted to bytes. |
| 145 | + // https://simonsapin.github.io/wtf-8/ |
| 146 | + #[cfg(windows)] |
| 147 | + let arg = arg.to_string_lossy(); |
| 148 | + |
| 149 | + vector.append(QByteArray::from(arg.as_bytes())); |
| 150 | + } |
| 151 | + |
| 152 | + ffi::qapplication_new(&vector) |
| 153 | + } |
| 154 | + |
| 155 | + /// The Internet domain of the organization that wrote this application |
| 156 | + pub fn organization_domain(&self) -> QString { |
| 157 | + ffi::qapplication_organization_domain(self) |
| 158 | + } |
| 159 | + |
| 160 | + /// The name of the organization that wrote this application |
| 161 | + pub fn organization_name(&self) -> QString { |
| 162 | + ffi::qapplication_organization_name(self) |
| 163 | + } |
| 164 | + |
| 165 | + /// Set the name of this application |
| 166 | + pub fn set_application_name(self: Pin<&mut Self>, name: &QString) { |
| 167 | + ffi::qapplication_set_application_name(self, name); |
| 168 | + } |
| 169 | + |
| 170 | + /// Removes path from the library path list. If path is empty or not in the path list, the list is not changed. |
| 171 | + pub fn remove_library_path(&self, path: &QString) { |
| 172 | + ffi::qapplication_remove_library_path(self, path) |
| 173 | + } |
| 174 | + |
| 175 | + /// Set the version of this application |
| 176 | + pub fn set_application_version(self: Pin<&mut Self>, version: &QString) { |
| 177 | + ffi::qapplication_set_application_version(self, version); |
| 178 | + } |
| 179 | + |
| 180 | + /// Changes the default application font to font. |
| 181 | + pub fn set_application_font(self: Pin<&mut Self>, font: &QFont) { |
| 182 | + ffi::qapplication_set_font(self, font); |
| 183 | + } |
| 184 | + |
| 185 | + /// Sets the list of directories to search when loading plugins with QLibrary to paths. |
| 186 | + /// All existing paths will be deleted and the path list will consist of the paths given in paths and the path to the application. |
| 187 | + pub fn set_library_paths(self: Pin<&mut Self>, paths: &QStringList) { |
| 188 | + ffi::qapplication_set_library_paths(self, paths); |
| 189 | + } |
| 190 | + |
| 191 | + /// Sets the Internet domain of the organization that wrote this application |
| 192 | + pub fn set_organization_domain(self: Pin<&mut Self>, domain: &QString) { |
| 193 | + ffi::qapplication_set_organization_domain(self, domain); |
| 194 | + } |
| 195 | + |
| 196 | + /// Sets the name of the organization that wrote this application |
| 197 | + pub fn set_organization_name(self: Pin<&mut Self>, name: &QString) { |
| 198 | + ffi::qapplication_set_organization_name(self, name); |
| 199 | + } |
| 200 | +} |
0 commit comments