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