1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtDBus module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qdbusmessage.h" |
41 | #include "qdbusconnection.h" |
42 | #include "qdbusabstractadaptor.h" |
43 | |
44 | #include "qdbuscontext.h" |
45 | #include "qdbuscontext_p.h" |
46 | |
47 | #ifndef QT_NO_DBUS |
48 | |
49 | QT_BEGIN_NAMESPACE |
50 | |
51 | QDBusContextPrivate *QDBusContextPrivate::set(QObject *obj, QDBusContextPrivate *newContext) |
52 | { |
53 | // determine if this is an adaptor or not |
54 | if (qobject_cast<QDBusAbstractAdaptor *>(obj)) |
55 | obj = obj->parent(); |
56 | |
57 | Q_ASSERT(obj); |
58 | |
59 | void *ptr = obj->qt_metacast("QDBusContext" ); |
60 | QDBusContext *q_ptr = reinterpret_cast<QDBusContext *>(ptr); |
61 | if (q_ptr) { |
62 | QDBusContextPrivate *old = q_ptr->d_ptr; |
63 | q_ptr->d_ptr = newContext; |
64 | return old; |
65 | } |
66 | |
67 | return nullptr; |
68 | } |
69 | |
70 | /*! |
71 | \since 4.3 |
72 | \class QDBusContext |
73 | \inmodule QtDBus |
74 | |
75 | \brief The QDBusContext class allows slots to determine the D-Bus context of the calls. |
76 | |
77 | When a slot is called in an object due to a signal delivery or due |
78 | to a remote method call, it is sometimes necessary to know the |
79 | context in which that happened. In particular, if the slot |
80 | determines that it wants to send the reply at a later opportunity |
81 | or if it wants to reply with an error, the context is needed. |
82 | |
83 | The QDBusContext class is an alternative to accessing the context |
84 | that doesn't involve modifying the code generated by the \l |
85 | {Qt D-Bus XML compiler (qdbusxml2cpp)}. |
86 | |
87 | QDBusContext is used by subclassing it from the objects being |
88 | exported using QDBusConnection::registerObject(). The following |
89 | example illustrates the usage: |
90 | |
91 | \snippet code/src_qdbus_qdbuscontext.cpp 0 |
92 | |
93 | The example illustrates the two typical uses, that of sending |
94 | error replies and that of delayed replies. |
95 | |
96 | Note: do not subclass QDBusContext and QDBusAbstractAdaptor at the |
97 | same time. QDBusContext should appear in the real object, not the |
98 | adaptor. If it's necessary from the adaptor code to determine the |
99 | context, use a public inheritance and access the functions via |
100 | QObject::parent(). |
101 | */ |
102 | |
103 | /*! |
104 | Constructs an empty QDBusContext. |
105 | */ |
106 | QDBusContext::QDBusContext() |
107 | : d_ptr(nullptr) |
108 | { |
109 | } |
110 | |
111 | /*! |
112 | An empty destructor. |
113 | */ |
114 | QDBusContext::~QDBusContext() |
115 | { |
116 | } |
117 | |
118 | /*! |
119 | Returns \c true if we are processing a D-Bus call. If this function |
120 | returns \c true, the rest of the functions in this class are |
121 | available. |
122 | |
123 | Accessing those functions when this function returns \c false is |
124 | undefined and may lead to crashes. |
125 | */ |
126 | bool QDBusContext::calledFromDBus() const |
127 | { |
128 | return d_ptr; |
129 | } |
130 | |
131 | /*! |
132 | Returns the connection from which this call was received. |
133 | */ |
134 | QDBusConnection QDBusContext::connection() const |
135 | { |
136 | return d_ptr->connection; |
137 | } |
138 | |
139 | /*! |
140 | Returns the message that generated this call. |
141 | */ |
142 | const QDBusMessage &QDBusContext::message() const |
143 | { |
144 | return d_ptr->message; |
145 | } |
146 | |
147 | /*! |
148 | Returns \c true if this call will have a delayed reply. |
149 | |
150 | \sa setDelayedReply() |
151 | */ |
152 | bool QDBusContext::isDelayedReply() const |
153 | { |
154 | return message().isDelayedReply(); |
155 | } |
156 | |
157 | /*! |
158 | Sets whether this call will have a delayed reply or not. |
159 | |
160 | If \a enable is false, Qt D-Bus will automatically generate a reply |
161 | back to the caller, if needed, as soon as the called slot returns. |
162 | |
163 | If \a enable is true, Qt D-Bus will not generate automatic |
164 | replies. It will also ignore the return value from the slot and |
165 | any output parameters. Instead, the called object is responsible |
166 | for storing the incoming message and send a reply or error at a |
167 | later time. |
168 | |
169 | Failing to send a reply will result in an automatic timeout error |
170 | being generated by D-Bus. |
171 | */ |
172 | void QDBusContext::setDelayedReply(bool enable) const |
173 | { |
174 | message().setDelayedReply(enable); |
175 | } |
176 | |
177 | /*! |
178 | Sends an error \a name as a reply to the caller. The optional \a |
179 | msg parameter is a human-readable text explaining the failure. |
180 | |
181 | If an error is sent, the return value and any output parameters |
182 | from the called slot will be ignored by Qt D-Bus. |
183 | */ |
184 | void QDBusContext::sendErrorReply(const QString &name, const QString &msg) const |
185 | { |
186 | setDelayedReply(true); |
187 | connection().send(message().createErrorReply(name, msg)); |
188 | } |
189 | |
190 | /*! |
191 | \overload |
192 | Sends an error \a type as a reply to the caller. The optional \a |
193 | msg parameter is a human-readable text explaining the failure. |
194 | |
195 | If an error is sent, the return value and any output parameters |
196 | from the called slot will be ignored by Qt D-Bus. |
197 | */ |
198 | void QDBusContext::sendErrorReply(QDBusError::ErrorType type, const QString &msg) const |
199 | { |
200 | setDelayedReply(true); |
201 | connection().send(message().createErrorReply(type, msg)); |
202 | } |
203 | |
204 | QT_END_NAMESPACE |
205 | |
206 | #endif // QT_NO_DBUS |
207 | |