KJsEmbed

qobject_binding.h
1 /* This file is part of the KDE libraries
2  Copyright (C) 2005, 2006 Ian Reinhart Geiser <[email protected]>
3  Copyright (C) 2005, 2006 Matt Broadstone <[email protected]>
4  Copyright (C) 2005, 2006 Richard J. Moore <[email protected]>
5  Copyright (C) 2005, 2006 Erik L. Bunce <[email protected]>
6  Copyright (C) 2007, 2008 Sebastian Sauer <[email protected]>
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License as published by the Free Software Foundation; either
11  version 2 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Library General Public License for more details.
17 
18  You should have received a copy of the GNU Library General Public License
19  along with this library; see the file COPYING.LIB. If not, write to
20  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  Boston, MA 02110-1301, USA.
22 */
23 
24 #ifndef QOBJECT_BINDING_H
25 #define QOBJECT_BINDING_H
26 
27 #include <QObjectCleanupHandler>
28 #include <QDebug>
29 
30 #include <kjs/function.h>
31 
32 #include "binding_support.h"
33 #include "object_binding.h"
34 
35 /**
36 * A simple pointer style method.
37 * This will extract the pointer, cast it to the native type and place it in "value".
38 * Any data that should be returned from this method should be placed into "result";
39 *
40 */
41 #define START_QOBJECT_METHOD( METHODNAME, TYPE) \
42  KJS::JSValue *METHODNAME( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args ) \
43  { \
44  Q_UNUSED( args ); \
45  KJS::JSValue *result = KJS::jsNull(); \
46  KJSEmbed::QObjectBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::QObjectBinding>(exec, self ); \
47  if( imp ) \
48  { \
49  TYPE *object = imp->qobject<TYPE>(); \
50  if( object ) \
51  {
52 
53 /**
54 * End a variant method started by START_QOBJECT_METHOD
55 */
56 #define END_QOBJECT_METHOD \
57  } \
58  else \
59  KJS::throwError(exec, KJS::ReferenceError, QString("QO: The internal object died %1:%2.").arg(__FILE__).arg(__LINE__));\
60  } \
61  else \
62  KJS::throwError(exec, KJS::ReferenceError, QString("QObject died."));\
63  return result; \
64  }
65 
66 class QObject;
67 class QMetaMethod;
68 
69 namespace KJSEmbed
70 {
71 
72 KJS_BINDING(QObjectFactory)
73 
74 class EventProxy;
75 
76 class KJSEMBED_EXPORT QObjectBinding : public ObjectBinding
77 {
78 public:
79 
80  QObjectBinding(KJS::ExecState *exec, QObject *object);
81  ~QObjectBinding() override;
82 
83  static void publishQObject(KJS::ExecState *exec, KJS::JSObject *target, QObject *object);
84 
85  /**
86  * Enumeration of access-flags that could be OR-combined to define
87  * what parts of the QObject should be published.
88  * Default is AllSlots|AllSignals|AllProperties|AllObjects what
89  * means that everything got published, even e.g. private slots.
90  */
91  enum Access {
92  None = 0x00, ///< Don't publish anything.
93 
94  ScriptableSlots = 0x01, ///< Publish slots that have Q_SCRIPTABLE defined.
95  NonScriptableSlots = 0x02, ///< Publish slots that don't have Q_SCRIPTABLE defined.
96  PrivateSlots = 0x04, ///< Publish private slots.
97  ProtectedSlots = 0x08, ///< Publish protected slots.
98  PublicSlots = 0x10, ///< Publish public slots.
99  AllSlots = ScriptableSlots | NonScriptableSlots | PrivateSlots | ProtectedSlots | PublicSlots,
100 
101  ScriptableSignals = 0x100, ///< Publish signals that have Q_SCRIPTABLE defined.
102  NonScriptableSignals = 0x200, ///< Publish signals that don't have Q_SCRIPTABLE defined.
103  PrivateSignals = 0x400, ///< Publish private signals.
104  ProtectedSignals = 0x800, ///< Publish protected signals.
105  PublicSignals = 0x1000, ///< Publish public signals.
106  AllSignals = ScriptableSignals | NonScriptableSignals | PrivateSignals | ProtectedSignals | PublicSignals,
107 
108  ScriptableProperties = 0x10000, ///< Publish properties that have Q_SCRIPTABLE defined.
109  NonScriptableProperties = 0x20000, ///< Publish properties that don't have Q_SCRIPTABLE defined.
110  AllProperties = ScriptableProperties | NonScriptableProperties,
111 
112  GetParentObject = 0x100000, ///< Provide access to the parent QObject the QObject has.
113  SetParentObject = 0x200000, ///< Be able to set the parent QObject the QObject has.
114  ChildObjects = 0x400000, ///< Provide access to the child QObject's the QObject has.
115  AllObjects = GetParentObject | SetParentObject | ChildObjects
116  };
117 
118  Q_DECLARE_FLAGS(AccessFlags, Access)
119 
120  /**
121  * \return the defined \a Access flags.
122  */
123  AccessFlags access() const;
124 
125  /**
126  * Set the defined \a Access flags to \p access .
127  */
128  void setAccess(AccessFlags access);
129 
130  /**
131  * Set the value \p value of the property \p propertyName .
132  */
133  void put(KJS::ExecState *exec, const KJS::Identifier &propertyName, KJS::JSValue *value,
134  int attr = KJS::None) override;
135  using JSObject::put;
136 
137  /**
138  * \return true if the property \p propertyName can be changed else false is returned.
139  */
140  bool canPut(KJS::ExecState *exec, const KJS::Identifier &propertyName) const override;
141 
142  /**
143  * Called to ask if we have a callback for the named property.
144  * We return the callback in the property slot.
145  */
146  bool getOwnPropertySlot(KJS::ExecState *exec, const KJS::Identifier &propertyName,
147  KJS::PropertySlot &slot) override;
148  using JSObject::getOwnPropertySlot;
149 
150  /**
151  * Callback used to get properties.
152  */
153  static KJS::JSValue *propertyGetter(KJS::ExecState *exec, KJS::JSObject *, const KJS::Identifier &name, const KJS::PropertySlot &);
154 
155  /**
156  * \return a string-representation of the QObject. For example for a QWidget-instance that
157  * has the QObject::objectName "mywidget" the string "mywidget (QWidget)" is returned.
158  */
159  KJS::UString toString(KJS::ExecState *exec) const override;
160 
161  /**
162  * \return the QObject's classname. For example for a QWidget-instance the string "QWidget"
163  * is returned.
164  */
165  KJS::UString className() const override;
166 
167  /**
168  * Add the QObject \p object to the internal QObjectCleanupHandler to watch the
169  * lifetime of the QObject to know when the QObject got deleted.
170  */
171  void watchObject(QObject *object);
172 
173  /**
174  * \return the internal object as a pointer to type T to the
175  * internal object that is derived from QObject.
176  */
177  template <typename T>
178  T *qobject() const
179  {
180  QObject *object = QObjectBinding::object<QObject>();
181  if (object) {
182  return qobject_cast<T *>(object);
183  } else {
184  return nullptr;
185  }
186  }
187 
188 private:
189  EventProxy *m_evproxy;
190  QObjectCleanupHandler *m_cleanupHandler;
191  AccessFlags m_access;
192 };
193 
194 Q_DECLARE_OPERATORS_FOR_FLAGS(QObjectBinding::AccessFlags)
195 
196 class KJSEMBED_EXPORT SlotBinding : public KJS::InternalFunctionImp
197 {
198 public:
199  SlotBinding(KJS::ExecState *exec, const QMetaMethod &memberName);
200  KJS::JSValue *callAsFunction(KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args) override;
201  bool implementsCall() const override
202  {
203  return true;
204  }
205  bool implementsConstruct() const override
206  {
207  return false;
208  }
209 
210 protected:
211  QByteArray m_memberName;
212 };
213 
214 /**
215 * Returns a binding object for the specified QObject. This method walks
216 * up the meta objects in order to find the most specific binding it can.
217 * There should always be some kind of binding possible even if it is just
218 * the QObject binding.
219 *
220 * \param exec Represents the current state of script execution.
221 * \param value The QObject or from it inherited instance we should return
222 * a binding object for.
223 * \param owner Defines who's the owner of the QObject. This could be;
224 * \li CPPOwned what means, that the QObject's lifetime is handled
225 * within C++ code. So, we just provide access to it and don't
226 * take any future actions.
227 * \li QObjOwned means that the QObject got deleted if the parent QObject
228 * is destroyed. If the QObject has no parent QObject, it behaves like
229 * JSOwned.
230 * \li JSOwned means, that the returned KJS::JSObject takes care of
231 * deleting the QObject. This means, that the QObject got deleted
232 * as soon as the KJS::JSObject got destroyed what happens if the
233 * KJS::JSObject is not needed / in use any longer.
234 * \return the binding object instance that wraps the QObject instance or
235 * a JSObject with a prototype of jsNull (that is, the ECMAScript "null" value,
236 * not a null object pointer) if we failed to provide any binding for it.
237 */
238 KJSEMBED_EXPORT KJS::JSObject *createQObject(KJS::ExecState *exec, QObject *value, KJSEmbed::ObjectBinding::Ownership owner = KJSEmbed::ObjectBinding::JSOwned);
239 
240 }
241 #endif
242 
virtual QVariant callAsFunction(ScriptableExtension *callerPrincipal, quint64 objId, const ArgList &args)
virtual bool put(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName, const QVariant &value)
int access(const QString &path, int mode)
char * toString(const EngineQuery &query)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Dec 10 2023 03:59:19 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.