cxx_qt_lib/core/
qcoreapplication.rs

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