1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qdbusmessage.h" |
5 | #include "qdbusconnection.h" |
6 | #include "qdbusabstractadaptor.h" |
7 | |
8 | #include "qdbuscontext.h" |
9 | #include "qdbuscontext_p.h" |
10 | |
11 | #ifndef QT_NO_DBUS |
12 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | QDBusContextPrivate *QDBusContextPrivate::set(QObject *obj, QDBusContextPrivate *newContext) |
16 | { |
17 | // determine if this is an adaptor or not |
18 | if (qobject_cast<QDBusAbstractAdaptor *>(object: obj)) |
19 | obj = obj->parent(); |
20 | |
21 | Q_ASSERT(obj); |
22 | |
23 | void *ptr = obj->qt_metacast("QDBusContext" ); |
24 | QDBusContext *q_ptr = reinterpret_cast<QDBusContext *>(ptr); |
25 | if (q_ptr) { |
26 | QDBusContextPrivate *old = q_ptr->d_ptr; |
27 | q_ptr->d_ptr = newContext; |
28 | return old; |
29 | } |
30 | |
31 | return nullptr; |
32 | } |
33 | |
34 | /*! |
35 | \since 4.3 |
36 | \class QDBusContext |
37 | \inmodule QtDBus |
38 | |
39 | \brief The QDBusContext class allows slots to determine the D-Bus context of the calls. |
40 | |
41 | When a slot is called in an object due to a signal delivery or due |
42 | to a remote method call, it is sometimes necessary to know the |
43 | context in which that happened. In particular, if the slot |
44 | determines that it wants to send the reply at a later opportunity |
45 | or if it wants to reply with an error, the context is needed. |
46 | |
47 | The QDBusContext class is an alternative to accessing the context |
48 | that doesn't involve modifying the code generated by the \l |
49 | {Qt D-Bus XML compiler (qdbusxml2cpp)}. |
50 | |
51 | QDBusContext is used by subclassing it from the objects being |
52 | exported using QDBusConnection::registerObject(). The following |
53 | example illustrates the usage: |
54 | |
55 | \snippet code/src_qdbus_qdbuscontext.cpp 0 |
56 | |
57 | The example illustrates the two typical uses, that of sending |
58 | error replies and that of delayed replies. |
59 | |
60 | Note: do not subclass QDBusContext and QDBusAbstractAdaptor at the |
61 | same time. QDBusContext should appear in the real object, not the |
62 | adaptor. If it's necessary from the adaptor code to determine the |
63 | context, use a public inheritance and access the functions via |
64 | QObject::parent(). |
65 | */ |
66 | |
67 | /*! |
68 | Constructs an empty QDBusContext. |
69 | */ |
70 | QDBusContext::QDBusContext() |
71 | : d_ptr(nullptr) |
72 | { |
73 | } |
74 | |
75 | /*! |
76 | An empty destructor. |
77 | */ |
78 | QDBusContext::~QDBusContext() |
79 | { |
80 | } |
81 | |
82 | /*! |
83 | Returns \c true if we are processing a D-Bus call. If this function |
84 | returns \c true, the rest of the functions in this class are |
85 | available. |
86 | |
87 | Accessing those functions when this function returns \c false is |
88 | undefined and may lead to crashes. |
89 | */ |
90 | bool QDBusContext::calledFromDBus() const |
91 | { |
92 | return d_ptr; |
93 | } |
94 | |
95 | /*! |
96 | Returns the connection from which this call was received. |
97 | */ |
98 | QDBusConnection QDBusContext::connection() const |
99 | { |
100 | return d_ptr->connection; |
101 | } |
102 | |
103 | /*! |
104 | Returns the message that generated this call. |
105 | */ |
106 | const QDBusMessage &QDBusContext::message() const |
107 | { |
108 | return d_ptr->message; |
109 | } |
110 | |
111 | /*! |
112 | Returns \c true if this call will have a delayed reply. |
113 | |
114 | \sa setDelayedReply() |
115 | */ |
116 | bool QDBusContext::isDelayedReply() const |
117 | { |
118 | return message().isDelayedReply(); |
119 | } |
120 | |
121 | /*! |
122 | Sets whether this call will have a delayed reply or not. |
123 | |
124 | If \a enable is false, Qt D-Bus will automatically generate a reply |
125 | back to the caller, if needed, as soon as the called slot returns. |
126 | |
127 | If \a enable is true, Qt D-Bus will not generate automatic |
128 | replies. It will also ignore the return value from the slot and |
129 | any output parameters. Instead, the called object is responsible |
130 | for storing the incoming message and send a reply or error at a |
131 | later time. |
132 | |
133 | Failing to send a reply will result in an automatic timeout error |
134 | being generated by D-Bus. |
135 | */ |
136 | void QDBusContext::setDelayedReply(bool enable) const |
137 | { |
138 | message().setDelayedReply(enable); |
139 | } |
140 | |
141 | /*! |
142 | Sends an error \a name as a reply to the caller. The optional \a |
143 | msg parameter is a human-readable text explaining the failure. |
144 | |
145 | If an error is sent, the return value and any output parameters |
146 | from the called slot will be ignored by Qt D-Bus. |
147 | */ |
148 | void QDBusContext::sendErrorReply(const QString &name, const QString &msg) const |
149 | { |
150 | setDelayedReply(true); |
151 | connection().send(message: message().createErrorReply(name, msg)); |
152 | } |
153 | |
154 | /*! |
155 | \overload |
156 | Sends an error \a type as a reply to the caller. The optional \a |
157 | msg parameter is a human-readable text explaining the failure. |
158 | |
159 | If an error is sent, the return value and any output parameters |
160 | from the called slot will be ignored by Qt D-Bus. |
161 | */ |
162 | void QDBusContext::sendErrorReply(QDBusError::ErrorType type, const QString &msg) const |
163 | { |
164 | setDelayedReply(true); |
165 | connection().send(message: message().createErrorReply(type, msg)); |
166 | } |
167 | |
168 | QT_END_NAMESPACE |
169 | |
170 | #endif // QT_NO_DBUS |
171 | |