add bindings for QGraphicsSceneDragDropEvent
[qtscriptgenerator.git] / generator / docgenerator.cpp
blobbbac1d503cc30114ac739846865a94856d8edb10
1 /****************************************************************************
2 **
3 ** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
4 **
5 ** This file is part of the Qt Script Generator project on Trolltech Labs.
6 **
7 ** This file may be used under the terms of the GNU General Public
8 ** License version 2.0 as published by the Free Software Foundation
9 ** and appearing in the file LICENSE.GPL included in the packaging of
10 ** this file. Please review the following information to ensure GNU
11 ** General Public Licensing requirements will be met:
12 ** http://www.trolltech.com/products/qt/opensource.html
14 ** If you are unsure which license is appropriate for your use, please
15 ** review the following information:
16 ** http://www.trolltech.com/products/qt/licensing.html or contact the
17 ** sales department at sales@trolltech.com.
19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 ****************************************************************************/
24 #include "docgenerator.h"
25 #include "fileout.h"
27 DocGenerator::DocGenerator()
31 QString DocGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const
33 return QString::fromLatin1("%0.html").arg(meta_class->name().toLower());
36 QString DocGenerator::subDirectoryForClass(const AbstractMetaClass *) const
38 return QString::fromLatin1("doc");
41 static void writeDocumentHeader(QTextStream &s, const QString &title)
43 s << "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>" << endl
44 << "<!DOCTYPE html" << endl
45 << " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">" << endl
46 << "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">" << endl
47 << "<head>" << endl
48 << " <title>" << title << "</title>" << endl
49 << " <link href=\"classic.css\" rel=\"stylesheet\" type=\"text/css\" />" << endl
50 << "</head>" << endl
51 << "<body>" << endl;
54 static void writeDocumentFooter(QTextStream &s)
56 s << "</body>" << endl
57 << "</html>" << endl;
60 static bool classLessThan(const AbstractMetaClass *c1, const AbstractMetaClass *c2)
62 return c1->name() < c2->name();
65 bool DocGenerator::shouldGenerate(const AbstractMetaClass *meta_class) const
67 uint cg = meta_class->typeEntry()->codeGeneration();
68 return (cg & TypeEntry::GenerateCode) != 0;
71 void DocGenerator::generate()
73 Generator::generate();
75 QHash<QString, QList<const AbstractMetaClass*> > packHash;
76 for (int i = 0; i < m_classes.size(); ++i) {
77 const AbstractMetaClass *cls = m_classes.at(i);
78 packHash[cls->package()].append(cls);
81 // package pages
82 QHash<QString, QList<const AbstractMetaClass*> >::const_iterator it;
83 for (it = packHash.constBegin(); it != packHash.constEnd(); ++it) {
84 QString package = it.key();
85 QList<const AbstractMetaClass*> classesInPackage = it.value();
86 qSort(classesInPackage.begin(), classesInPackage.end(), classLessThan);
88 FileOut file(m_out_dir + "/doc/" + package.split(".").join("_") + ".html");
90 writeDocumentHeader(file.stream, package + " Package");
92 file.stream << "<h1 align=\"center\">" << package << " Package</h1>" << endl;
94 file.stream << "<h2>Classes</h2>" << endl
95 << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">" << endl;
97 for (int i = 0; i < classesInPackage.size(); ++i) {
98 const AbstractMetaClass *cls = classesInPackage.at(i);
99 if (cls->name() == "Global")
100 continue; /// ### fixme
101 file.stream << "<tr valign=\"top\" class=\"";
102 if (i & 1)
103 file.stream << "odd";
104 else
105 file.stream << "even";
106 file.stream << "\"><th><a href=\"" << fileNameForClass(cls) << "\">" << cls->name()
107 << "</a></th></tr>" << endl;
110 file.stream << "</table></p>" << endl;
112 writeDocumentFooter(file.stream);
115 // all classes page
117 FileOut file(m_out_dir + "/doc/classes.html");
119 writeDocumentHeader(file.stream, "Classes");
121 file.stream << "<h1 align=\"center\">Classes</h1>" << endl
122 << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">" << endl;
124 AbstractMetaClassList sortedClasses = m_classes;
125 qSort(sortedClasses.begin(), sortedClasses.end(), classLessThan);
127 for (int i = 0; i < sortedClasses.size(); ++i) {
128 const AbstractMetaClass *cls = sortedClasses.at(i);
129 if (cls->name() == "Global")
130 continue; /// ### fixme
131 file.stream << "<tr valign=\"top\" class=\"";
132 if (i & 1)
133 file.stream << "odd";
134 else
135 file.stream << "even";
136 file.stream << "\"><th><a href=\"" << fileNameForClass(cls) << "\">" << cls->name()
137 << "</a></th></tr>" << endl;
140 file.stream << "</table></p>" << endl;
142 writeDocumentFooter(file.stream);
145 // index.html
147 FileOut file(m_out_dir + "/doc/index.html");
149 writeDocumentHeader(file.stream, "Qt Bindings Reference Documentation");
151 file.stream << "<h1 align=\"center\">Qt Script Qt Bindings Reference Documentation</h1>" << endl;
153 file.stream << "<h3>Packages</h3>" << endl;
154 file.stream << "<ul>" << endl;
155 QStringList sortedPackages = packHash.keys();
156 qSort(sortedPackages.begin(), sortedPackages.end());
157 for (int i = 0; i < sortedPackages.size(); ++i) {
158 QString pkg = sortedPackages.at(i);
159 file.stream << "<li><b><a href=\"" << pkg.split(".").join("_") << ".html\">"
160 << pkg << "</a></b></li>" << endl;
162 file.stream << "</ul>" << endl;
164 file.stream << "<h3><a href=\"classes.html\">All Classes</a></h3>" << endl;
166 file.stream << "<h3><a href=\"../examples\">Examples</a></h3>" << endl;
168 file.stream << "<h3>Getting Started</h3>" << endl
169 << "<p>Using the Qt API in Qt Script is very similar to C++." << endl
170 << "<pre>var f = new QFile(\"foo.txt\");</pre>" << endl
171 << "C++ enum values are mapped to properties of the script constructor function; e.g. " << endl
172 << "QIODevice::ReadOnly becomes QIODevice.ReadOnly.</p>" << endl
173 << "<pre>f.open(new QIODevice.OpenMode(QIODevice.ReadOnly));</pre>" << endl
174 << "<p>Each C++ flag type is mapped to a property of the script constructor function; e.g. " << endl
175 << "QIODevice::OpenMode becomes QIODevice.OpenMode. Such a property is a constructor function " << endl
176 << "that takes one or more enum values and constructs a flags instance by OR'ing the arguments " << endl
177 << "together.</p>" << endl
178 << "<pre>var ts = new QTextStream(f);" << endl
179 << "ts.writeString(\"Boo\");</pre>" << endl
180 << "<p>C++ streaming operators are normally mapped to readT() and writeT() functions.</p>" << endl
181 << "<pre>f.close();</pre>" << endl
182 << "<p>In Qt Script, all objects are allocated on the heap; objects that are no longer " << endl
183 << "referenced are garbage collected sometime in the future; therefore, make sure to " << endl
184 << "explicitly free up resources if you can. (Without the call to close(), the underlying " << endl
185 << "file would remain open until the file object is garbage collected.)</p>" << endl
188 file.stream << "<h3><a href=\"http://doc.trolltech.com/latest\">Qt Reference Documentation</a></h3>" << endl;
190 writeDocumentFooter(file.stream);
194 static bool shouldIgnoreEnum(const AbstractMetaEnum *enom)
196 return !enom->wasPublic() || (enom->name() == "enum_1");
199 // in classgenerator.cpp
200 void findPrototypeAndStaticFunctions(
201 const AbstractMetaClass *meta_class,
202 QMap<QString, AbstractMetaFunctionList> &nameToPrototypeFunctions,
203 QMap<QString, AbstractMetaFunctionList> &nameToStaticFunctions);
204 QList<int> uniqueEnumValueIndexes(const AbstractMetaEnumValueList &values);
206 static void writeFunction(QTextStream &s, const AbstractMetaFunction *fun)
208 s << "<li><div class=\"fn\"/><b>" << fun->targetLangSignature() << "</b></li>" << endl;
211 void DocGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
213 QString title = meta_class->name();
214 title.append(" ");
215 if (meta_class->isNamespace())
216 title.append("Namespace");
217 else
218 title.append("Class");
219 title.append(" Reference");
220 writeDocumentHeader(s, title);
222 s << "<h1 align=\"center\">" << title << "</h1>" << endl;
224 s << "<h3 align=\"center\">[<a href=\"";
225 s << meta_class->package().split(".").join("_") << ".html";
226 s << "\">";
227 s << meta_class->package();
228 s << "</a> package]</h3>" << endl;
230 if (meta_class->baseClass()) {
231 s << "<p>Inherits <a href=\"" << fileNameForClass(meta_class->baseClass()) << "\">"
232 << meta_class->baseClass()->name() << "</a>.</p>" << endl;
233 } else if (!meta_class->interfaces().isEmpty()) {
234 AbstractMetaClass *iface = meta_class->interfaces().first();
235 AbstractMetaClass *impl = iface->primaryInterfaceImplementor();
236 if (impl != meta_class) {
237 s << "<p>Inherits <a href=\"" << fileNameForClass(impl) << "\">"
238 << impl->name() << "</a>.</p>" << endl;
242 AbstractMetaFunctionList ctors;
243 ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
244 | AbstractMetaClass::WasPublic
245 | AbstractMetaClass::NotRemovedFromTargetLang);
246 QMap<QString, AbstractMetaFunctionList> nameToPrototypeFunctions;
247 QMap<QString, AbstractMetaFunctionList> nameToStaticFunctions;
248 findPrototypeAndStaticFunctions(meta_class, nameToPrototypeFunctions, nameToStaticFunctions);
250 s << "<h3>Constructor</h3>" << endl;
251 if (!ctors.isEmpty()) {
252 s << "<ul>" << endl;
253 for (int i = 0; i < ctors.size(); ++i) {
254 writeFunction(s, ctors.at(i));
256 s << "</ul>" << endl;
257 } else {
258 s << "<p>This class has no public constructors. Calling the constructor function will cause a TypeError.</p>";
261 s << "<h3>Constructor Properties</h3>" << endl;
262 s << "<ul>" << endl;
263 s << "<li><b>prototype</b>: The " << meta_class->name() << " prototype object</li>" << endl;
264 if (!nameToStaticFunctions.isEmpty()) {
265 QMap<QString, AbstractMetaFunctionList>::const_iterator it;
266 for (it = nameToStaticFunctions.constBegin(); it != nameToStaticFunctions.constEnd(); ++it) {
267 writeFunction(s, it.value().first());
271 AbstractMetaEnumList enums = meta_class->enums();
272 for (int i = 0; i < enums.size(); ++i) {
273 const AbstractMetaEnum *enom = enums.at(i);
274 if (shouldIgnoreEnum(enom))
275 continue;
276 AbstractMetaEnumValueList values = enom->values();
277 QList<int> indexes = uniqueEnumValueIndexes(values);
278 for (int j = 0; j < indexes.size(); ++j) {
279 AbstractMetaEnumValue *val = values.at(indexes.at(j));
280 s << "<li><b>" << val->name();
281 if (!val->stringValue().isEmpty())
282 s << " = " << val->stringValue();
283 s << "</b></li>" << endl;
285 s << "<li><b>" << enom->name() << "( value )</b></li>" << endl;
286 FlagsTypeEntry *flags = enom->typeEntry()->flags();
287 if (flags)
288 s << "<li><b>" << flags->flagsName() << "( value1, value2, ... )</b></li>" << endl;
291 s << "</ul>" << endl;
293 if (!nameToPrototypeFunctions.isEmpty()) {
294 s << "<h3>Prototype Object Properties</h3>" << endl;
295 if (meta_class->baseClass()) {
296 s << "<p>The " << meta_class->name() << " prototype object inherits properties from the "
297 << "<a href=\"" << fileNameForClass(meta_class->baseClass()) << "\">"
298 << meta_class->baseClass()->name() << "</a> prototype object and "
299 << "also has the following properties.</p>" << endl;
301 s << "<ul>" << endl;
302 QMap<QString, AbstractMetaFunctionList>::const_iterator it;
303 for (it = nameToPrototypeFunctions.constBegin(); it != nameToPrototypeFunctions.constEnd(); ++it) {
304 writeFunction(s, it.value().first());
306 s << "</ul>" << endl;
309 if (!meta_class->isNamespace()) {
310 s << "<h3>Instance Properties</h3>" << endl;
312 QList<QPropertySpec *> props = meta_class->propertySpecs();
313 if (!props.isEmpty()) {
314 s << "<p>" << meta_class->name() << " objects inherit properties from the "
315 << meta_class->name() << " prototype object and also have the following properties.</p>" << endl;
316 s << "<ul>" << endl;
317 for (int i = 0; i < props.size(); ++i) {
318 s << "<li><div class=\"fn\"/><b>" << props.at(i)->name() << "</b></li>" << endl;
320 s << "</ul>" << endl;
321 } else {
322 s << "<p>" << meta_class->name() << " objects have no special properties beyond those "
323 << "inherited from the " << meta_class->name() << " prototype object.</p>" << endl;
328 writeDocumentFooter(s);