source: trunk/tools/activeqt/dumpcpp/main.cpp@ 890

Last change on this file since 890 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 59.3 KB
RevLine 
[2]1/****************************************************************************
2**
[846]3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
[561]4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
[2]6**
7** This file is part of the tools applications of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
[561]24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
[2]27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
[561]36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
[2]38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QAxObject>
43#include <QFile>
44#include <QMetaObject>
45#include <QMetaEnum>
46#include <QTextStream>
47#include <QSettings>
48#include <QStringList>
49#include <QUuid>
50#include <QWidget>
51#include <qt_windows.h>
52#include <ocidl.h>
53
54QT_BEGIN_NAMESPACE
55
56static ITypeInfo *currentTypeInfo = 0;
57
58enum ObjectCategory
59{
60 DefaultObject = 0x00,
61 SubObject = 0x001,
62 ActiveX = 0x002,
63 NoMetaObject = 0x004,
64 NoImplementation = 0x008,
65 NoDeclaration = 0x010,
66 NoInlines = 0x020,
67 OnlyInlines = 0x040,
68 DoNothing = 0x080,
69 Licensed = 0x100,
70 TypeLibID = 0x101
71};
72
73// this comes from moc/qmetaobject.cpp
74enum ProperyFlags {
75 Invalid = 0x00000000,
76 Readable = 0x00000001,
77 Writable = 0x00000002,
78 Resetable = 0x00000004,
79 EnumOrFlag = 0x00000008,
80 StdCppSet = 0x00000100,
81 Override = 0x00000200,
82 Designable = 0x00001000,
83 ResolveDesignable = 0x00002000,
84 Scriptable = 0x00004000,
85 ResolveScriptable = 0x00008000,
86 Stored = 0x00010000,
87 ResolveStored = 0x00020000,
88 Editable = 0x00040000,
89 ResolveEditable = 0x00080000
90};
91
92enum MemberFlags {
93 AccessPrivate = 0x00,
94 AccessProtected = 0x01,
95 AccessPublic = 0x02,
96 MemberMethod = 0x00,
97 MemberSignal = 0x04,
98 MemberSlot = 0x08,
99 MemberCompatibility = 0x10,
100 MemberCloned = 0x20,
101 MemberScriptable = 0x40,
102};
103
104extern QMetaObject *qax_readEnumInfo(ITypeLib *typeLib, const QMetaObject *parentObject);
105extern QMetaObject *qax_readClassInfo(ITypeLib *typeLib, ITypeInfo *typeInfo, const QMetaObject *parentObject);
106extern QMetaObject *qax_readInterfaceInfo(ITypeLib *typeLib, ITypeInfo *typeInfo, const QMetaObject *parentObject);
107extern QList<QByteArray> qax_qualified_usertypes;
108extern QString qax_docuFromName(ITypeInfo *typeInfo, const QString &name);
109extern bool qax_dispatchEqualsIDispatch;
110
111QByteArray nameSpace;
112QMap<QByteArray, QByteArray> namespaceForType;
113
114void writeEnums(QTextStream &out, const QMetaObject *mo)
115{
116 // enums
117 for (int ienum = mo->enumeratorOffset(); ienum < mo->enumeratorCount(); ++ienum) {
118 QMetaEnum metaEnum = mo->enumerator(ienum);
119 out << " enum " << metaEnum.name() << " {" << endl;
120 for (int k = 0; k < metaEnum.keyCount(); ++k) {
121 QByteArray key(metaEnum.key(k));
122 out << " " << key.leftJustified(24) << "= " << metaEnum.value(k);
123 if (k < metaEnum.keyCount() - 1)
124 out << ",";
125 out << endl;
126 }
127 out << " };" << endl;
128 out << endl;
129 }
130}
131
132void writeHeader(QTextStream &out, const QByteArray &nameSpace)
133{
134 out << "#ifndef QAX_DUMPCPP_" << nameSpace.toUpper() << "_H" << endl;
135 out << "#define QAX_DUMPCPP_" << nameSpace.toUpper() << "_H" << endl;
136 out << endl;
137 out << "// Define this symbol to __declspec(dllexport) or __declspec(dllimport)" << endl;
138 out << "#ifndef " << nameSpace.toUpper() << "_EXPORT" << endl;
139 out << "#define " << nameSpace.toUpper() << "_EXPORT" << endl;
140 out << "#endif" << endl;
141 out << endl;
142 out << "#include <qaxobject.h>" << endl;
143 out << "#include <qaxwidget.h>" << endl;
144 out << "#include <qdatetime.h>" << endl;
145 out << "#include <qpixmap.h>" << endl;
146 out << endl;
147 out << "struct IDispatch;" << endl;
148 out << endl;
149}
150
151void generateNameSpace(QTextStream &out, const QMetaObject *mo, const QByteArray &nameSpace)
152{
153 out << "namespace " << nameSpace << " {" << endl;
154 out << endl;
155 writeEnums(out, mo);
156
157 // don't close on purpose
158}
159
160static QByteArray joinParameterNames(const QList<QByteArray> &parameterNames)
161{
162 QByteArray slotParameters;
163 for (int p = 0; p < parameterNames.count(); ++p) {
164 slotParameters += parameterNames.at(p);
165 if (p < parameterNames.count() - 1)
166 slotParameters += ',';
167 }
168
169 return slotParameters;
170}
171
172QByteArray constRefify(const QByteArray &type)
173{
174 QByteArray ctype(type);
175 if (type == "QString" || type == "QPixmap"
176 || type == "QVariant" || type == "QDateTime"
177 || type == "QColor" || type == "QFont"
178 || type == "QByteArray" || type == "QValueList<QVariant>"
179 || type == "QStringList")
180 ctype = "const " + ctype + "&";
181
182 return ctype;
183}
184
185void generateClassDecl(QTextStream &out, const QString &controlID, const QMetaObject *mo, const QByteArray &className, const QByteArray &nameSpace, ObjectCategory category)
186{
187 QList<QByteArray> functions;
188
189 QByteArray indent;
190 if (!(category & OnlyInlines))
191 indent = " ";
192
193 if (!(category & OnlyInlines)) {
194 // constructors
195 out << "class " << nameSpace.toUpper() << "_EXPORT " << className << " : public ";
196 if (category & ActiveX)
197 out << "QAxWidget";
198 else
199 out << "QAxObject";
200 out << endl;
201
202 out << "{" << endl;
203 out << "public:" << endl;
204 out << " " << className << "(";
205 if (category & Licensed)
206 out << "const QString &licenseKey = QString(), ";
207 if (category & ActiveX)
208 out << "QWidget *parent = 0, Qt::WindowFlags f";
209 else if (category & SubObject)
210 out << "IDispatch *subobject = 0, QAxObject *parent";
211 else
212 out << "QObject *parent";
213 out << " = 0)" << endl;
214 out << " : ";
215 if (category & ActiveX)
216 out << "QAxWidget(parent, f";
217 else if (category & SubObject)
218 out << "QAxObject((IUnknown*)subobject, parent";
219 else
220 out << "QAxObject(parent";
221 out << ")" << endl;
222 out << " {" << endl;
223 if (category & SubObject)
224 out << " internalRelease();" << endl;
225 else if (category & Licensed) {
226 out << " if (licenseKey.isEmpty())" << endl;
227 out << " setControl(\"" << controlID << "\");" << endl;
228 out << " else" << endl;
229 out << " setControl(\"" << controlID << ":\" + licenseKey);" << endl;
230 } else {
231 out << " setControl(\"" << controlID << "\");" << endl;
232 }
233 out << " }" << endl;
234 out << endl;
235
236 for (int ci = mo->classInfoOffset(); ci < mo->classInfoCount(); ++ci) {
237 QMetaClassInfo info = mo->classInfo(ci);
238 QByteArray iface_name = info.name();
239 if (iface_name.startsWith("Event "))
240 continue;
241
242 QByteArray iface_class = info.value();
243
244 out << " " << className << "(" << iface_class << " *iface)" << endl;
245
246 if (category & ActiveX)
247 out << " : QAxWidget()" << endl;
248 else
249 out << " : QAxObject()" << endl;
250 out << " {" << endl;
251 out << " initializeFrom(iface);" << endl;
252 out << " delete iface;" << endl;
253 out << " }" << endl;
254 out << endl;
255 }
256 }
257
258 functions << className;
259
260 // enums
261 if (nameSpace.isEmpty() && !(category & OnlyInlines)) {
262 for (int ienum = mo->enumeratorOffset(); ienum < mo->enumeratorCount(); ++ienum) {
263 QMetaEnum metaEnum = mo->enumerator(ienum);
264 out << " enum " << metaEnum.name() << " {" << endl;
265 for (int k = 0; k < metaEnum.keyCount(); ++k) {
266 QByteArray key(metaEnum.key(k));
267 out << " " << key.leftJustified(24) << "= " << metaEnum.value(k);
268 if (k < metaEnum.keyCount() - 1)
269 out << ",";
270 out << endl;
271 }
272 out << " };" << endl;
273 out << endl;
274 }
275 }
276 // QAxBase public virtual functions.
277 QList<QByteArray> axBase_vfuncs;
278 axBase_vfuncs.append("metaObject");
279 axBase_vfuncs.append("qObject");
280 axBase_vfuncs.append("className");
281 axBase_vfuncs.append("propertyWritable");
282 axBase_vfuncs.append("setPropertyWritable");
283
284 // properties
285 for (int iprop = mo->propertyOffset(); iprop < mo->propertyCount(); ++iprop) {
286 QMetaProperty property = mo->property(iprop);
287 if (!property.isReadable())
288 continue;
289
290 QByteArray propertyName(property.name());
291 if (propertyName == "control" || propertyName == className)
292 continue;
293
294 if (!(category & OnlyInlines)) {
295 out << indent << "/*" << endl << indent << "Property " << propertyName << endl;
296 QString documentation = qax_docuFromName(currentTypeInfo, QString::fromLatin1(propertyName.constData()));
297 if (!documentation.isEmpty()) {
298 out << endl;
299 out << indent << documentation << endl;
300 }
301 out << indent << "*/" << endl;
302 }
303
304 // Check whether the new function conflicts with any of QAxBase public virtual functions.
305 // If so, prepend the function name with '<classname>_'. Since all internal metaobject magic
306 // remains the same, we have to use the original name when used with QObject::connect or QMetaObject