summaryrefslogtreecommitdiffstats
path: root/configure.in
Commit message (Expand)AuthorAgeFilesLines
* Check for existence of mremap()Andrew M. Kuchling2000-06-181-1/+2
* When building on Solaris and the compiler is GCC, use '$(CC) -G' toGreg Ward2000-05-261-1/+5
* Reduce opt level for BeOS - Donn Cave.Guido van Rossum2000-05-221-1/+1
* Fix the test for socklen_t so that it searches through sys/socket.h.Guido van Rossum2000-05-181-2/+10
* Add check for rint() in math library.Guido van Rossum2000-05-111-0/+6
* Andy Dustman: add GNU pth user-space thread support.Guido van Rossum2000-05-081-1/+5
* Added tests for socklen_tGuido van Rossum2000-04-241-0/+1
* Add Python version bump to configure script. (AMK)Guido van Rossum2000-03-311-1/+1
* Part of the Unicode checkin for Marc-Andre Lemburg.Guido van Rossum2000-03-101-2/+46
* Pat Knight:Guido van Rossum2000-02-251-4/+4
* According to Harri Pasanen, the Solaris+gcc test for LINKFORSHAREDGuido van Rossum2000-02-031-1/+1
* Changes to auto-detect the correct dynload_<platform>.c file.Guido van Rossum1999-12-201-0/+33
* Patch by Geoff Furnish to make compiling with C++ more gentle.Guido van Rossum1999-12-161-13/+47
* Remove test for getlogin_r(); the interface is not clearly defined, atFred Drake1999-12-141-2/+1
* Added detection of getlogin() and getlogin_r().Fred Drake1999-12-141-1/+2
* Added detection for getgroups(), fpathconf(), pathconf(),Fred Drake1999-12-131-5/+6
* Added support for ctermid, tempnam, tmpfile, tmpnam, and tmpnam_r.Fred Drake1999-12-091-2/+3
* Patch by Vladimir Marangozov, inspired by a bug report from GaryGuido van Rossum1999-11-161-0/+12
* Dynamic linking support for BSD/OS 4.x as suggested by Vivek KheraGuido van Rossum1999-10-051-0/+2
* Erik Lindvall contributed a BSD/OS 4 patch for LDSHARED.Guido van Rossum1999-09-171-0/+1
* Need to double the macro brackets in FreeBSD check.Guido van Rossum1999-04-271-2/+2
* FreeBSD/[34]* change, Dom Mitchell.Guido van Rossum1999-04-211-2/+2
* Quote a bunch of shell variables used in test, related to long-long.Guido van Rossum1999-04-101-4/+4
* For BeOS PowerPC. Chris Herborth.Guido van Rossum1999-04-061-1/+1
* Chris Herborth: the new compiler in R4.1 needs some new options to work...Guido van Rossum1999-03-241-1/+4
* Ack! It never defined HAVE_GETHOSTBYNAME_R so that code was never tested!Guido van Rossum1999-03-231-0/+4
* Add code to test for all sorts of gethostbyname_r variants,Guido van Rossum1999-03-221-1/+64
* Should test for gethost*by*name_r, not for gethostname_r (whichGuido van Rossum1999-03-151-1/+1
* Get rid of AC_CHECK_LIB(m, pow) since this is taken care of later withGuido van Rossum1999-02-231-1/+0
* Patches by William Lewis for Nextstep descendants.Guido van Rossum1999-01-271-18/+98
* Chris Herborth's first pass at making config and installGuido van Rossum1999-01-121-2/+34
* Ty Sarna writes:Guido van Rossum1999-01-071-3/+17
* Changes for long file support by Steve Clift.Guido van Rossum1999-01-061-0/+31
* Several tiny changes:Guido van Rossum1998-12-171-2/+4
* Add test for BSDI -- by Nigel Head and otto@mail.olympus.net.Guido van Rossum1998-10-071-0/+7
* Added tweak for SET_CCC (which I don't even know what it is!) for Linux.Guido van Rossum1998-10-021-2/+7
* Changes for BeOS, QNX and long long, by Chris Herborth.Guido van Rossum1998-08-041-4/+40
* Fix two unrelated problems in the same area:Guido van Rossum1998-07-071-16/+17
* Add timegm to list of functions tested, for Marc-Andre L.Guido van Rossum1998-06-111-1/+1
* support hpux pthreadsGuido van Rossum1998-05-071-1/+5
* Get rid of test for -lsun (very old IRIX); add test for -lm (needed onGuido van Rossum1998-05-071-4/+4
* Remove bogus CCSHARED for cc on IRIX 6.x.Guido van Rossum1998-04-201-1/+1
* Support for OpenBSD :-(Guido van Rossum1998-04-131-2/+2
* Get rid of the check for -linet -- recent Sequent Dynix systems don'tGuido van Rossum1998-03-261-7/+3
* Added mktime to checked functionsGuido van Rossum1998-03-061-1/+1
* Setting LINKFORSHARED for IRIX was a mistake.Guido van Rossum1998-03-051-4/+0
* Some changes because gcc on SGI doesn't support '-all'Guido van Rossum1998-03-051-7/+13
* Misc changes for AIX: install the python.exp file, and properly use $(srcdir).Guido van Rossum1998-03-031-1/+1
* Different way to suppores the DGUX ruleGuido van Rossum1998-02-191-2/+2
* Some shifting around of the DGUX hack so that it won't break on DEC UnixGuido van Rossum1998-01-131-1/+1
s='graph'>
-rw-r--r--util/install/win/pages/licenseagreementpage.ui202
-rw-r--r--util/install/win/pages/licensepage.ui264
-rw-r--r--util/install/win/pages/optionspage.ui503
-rw-r--r--util/install/win/pages/pages.cpp349
-rw-r--r--util/install/win/pages/pages.h226
-rw-r--r--util/install/win/pages/progresspage.ui78
-rw-r--r--util/install/win/pages/sidedecoration.ui108
-rw-r--r--util/install/win/pages/sidedecorationimpl.cpp205
-rw-r--r--util/install/win/pages/sidedecorationimpl.h70
-rw-r--r--util/install/win/pages/winintropage.ui39
-rw-r--r--util/install/win/qt.arq3
-rw-r--r--util/install/win/resource.cpp162
-rw-r--r--util/install/win/resource.h77
-rw-r--r--util/install/win/setupwizardimpl.cpp2571
-rw-r--r--util/install/win/setupwizardimpl.h276
-rw-r--r--util/install/win/setupwizardimpl_config.cpp1564
-rw-r--r--util/install/win/shell.cpp472
-rw-r--r--util/install/win/shell.h87
-rw-r--r--util/install/win/uninstaller/quninstall.pro7
-rw-r--r--util/install/win/uninstaller/uninstall.ui167
-rw-r--r--util/install/win/uninstaller/uninstaller.cpp142
-rw-r--r--util/install/win/uninstaller/uninstallimpl.cpp75
-rw-r--r--util/install/win/uninstaller/uninstallimpl.h54
-rw-r--r--util/install/win/win.pro136
-rw-r--r--util/lexgen/README16
-rw-r--r--util/lexgen/configfile.cpp99
-rw-r--r--util/lexgen/configfile.h81
-rw-r--r--util/lexgen/css2-simplified.lexgen93
-rw-r--r--util/lexgen/generator.cpp532
-rw-r--r--util/lexgen/generator.h221
-rw-r--r--util/lexgen/global.h113
-rw-r--r--util/lexgen/lexgen.lexgen24
-rw-r--r--util/lexgen/lexgen.pri3
-rw-r--r--util/lexgen/lexgen.pro6
-rw-r--r--util/lexgen/main.cpp323
-rw-r--r--util/lexgen/nfa.cpp508
-rw-r--r--util/lexgen/nfa.h127
-rw-r--r--util/lexgen/re2nfa.cpp547
-rw-r--r--util/lexgen/re2nfa.h116
-rw-r--r--util/lexgen/test.lexgen9
-rw-r--r--util/lexgen/tests/testdata/backtrack1/input1
-rw-r--r--util/lexgen/tests/testdata/backtrack1/output1
-rw-r--r--util/lexgen/tests/testdata/backtrack1/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/backtrack2/input1
-rw-r--r--util/lexgen/tests/testdata/backtrack2/output2
-rw-r--r--util/lexgen/tests/testdata/backtrack2/rules.lexgen4
-rw-r--r--util/lexgen/tests/testdata/casesensitivity/input1
-rw-r--r--util/lexgen/tests/testdata/casesensitivity/output14
-rw-r--r--util/lexgen/tests/testdata/casesensitivity/rules.lexgen7
-rw-r--r--util/lexgen/tests/testdata/comments/input1
-rw-r--r--util/lexgen/tests/testdata/comments/output2
-rw-r--r--util/lexgen/tests/testdata/comments/rules.lexgen2
-rw-r--r--util/lexgen/tests/testdata/dot/input1
-rw-r--r--util/lexgen/tests/testdata/dot/output2
-rw-r--r--util/lexgen/tests/testdata/dot/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/negation/input1
-rw-r--r--util/lexgen/tests/testdata/negation/output2
-rw-r--r--util/lexgen/tests/testdata/negation/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/quoteinset/input1
-rw-r--r--util/lexgen/tests/testdata/quoteinset/output1
-rw-r--r--util/lexgen/tests/testdata/quoteinset/rules.lexgen2
-rw-r--r--util/lexgen/tests/testdata/quotes/input1
-rw-r--r--util/lexgen/tests/testdata/quotes/output1
-rw-r--r--util/lexgen/tests/testdata/quotes/rules.lexgen2
-rw-r--r--util/lexgen/tests/testdata/simple/input1
-rw-r--r--util/lexgen/tests/testdata/simple/output2
-rw-r--r--util/lexgen/tests/testdata/simple/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/subsets1/input1
-rw-r--r--util/lexgen/tests/testdata/subsets1/output2
-rw-r--r--util/lexgen/tests/testdata/subsets1/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/subsets2/input1
-rw-r--r--util/lexgen/tests/testdata/subsets2/output3
-rw-r--r--util/lexgen/tests/testdata/subsets2/rules.lexgen4
-rw-r--r--util/lexgen/tests/tests.pro6
-rw-r--r--util/lexgen/tests/tst_lexgen.cpp285
-rw-r--r--util/lexgen/tokenizer.cpp237
-rw-r--r--util/local_database/README1
-rwxr-xr-xutil/local_database/cldr2qlocalexml.py459
-rw-r--r--util/local_database/enumdata.py428
-rw-r--r--util/local_database/formattags.txt23
-rw-r--r--util/local_database/locale.xml9217
-rwxr-xr-xutil/local_database/qlocalexml2cpp.py503
-rw-r--r--util/local_database/testlocales/localemodel.cpp462
-rw-r--r--util/local_database/testlocales/localemodel.h69
-rw-r--r--util/local_database/testlocales/localewidget.cpp89
-rw-r--r--util/local_database/testlocales/localewidget.h59
-rw-r--r--util/local_database/testlocales/main.cpp51
-rw-r--r--util/local_database/testlocales/testlocales.pro4
-rw-r--r--util/local_database/xpathlite.py107
-rw-r--r--util/normalize/README16
-rw-r--r--util/normalize/main.cpp197
-rw-r--r--util/normalize/normalize.pro9
-rw-r--r--util/plugintest/README3
-rw-r--r--util/plugintest/main.cpp66
-rw-r--r--util/plugintest/plugintest.pro4
-rw-r--r--util/qlalr/.gitignore1
-rw-r--r--util/qlalr/README1
-rw-r--r--util/qlalr/compress.cpp286
-rw-r--r--util/qlalr/compress.h60
-rw-r--r--util/qlalr/cppgenerator.cpp732
-rw-r--r--util/qlalr/cppgenerator.h99
-rw-r--r--util/qlalr/doc/qlalr.qdocconf65
-rw-r--r--util/qlalr/doc/src/classic.css97
-rw-r--r--util/qlalr/doc/src/images/qt-logo.pngbin0 -> 1422 bytes-rw-r--r--util/qlalr/doc/src/images/trolltech-logo.pngbin0 -> 1512 bytes-rw-r--r--util/qlalr/doc/src/qlalr.qdoc79
-rw-r--r--util/qlalr/dotgraph.cpp102
-rw-r--r--util/qlalr/dotgraph.h59
-rw-r--r--util/qlalr/examples/dummy-xml/dummy-xml.pro2
-rw-r--r--util/qlalr/examples/dummy-xml/ll/dummy-xml-ll.cpp83
-rw-r--r--util/qlalr/examples/dummy-xml/xml.g202
-rw-r--r--util/qlalr/examples/glsl/build.sh7
-rwxr-xr-xutil/qlalr/examples/glsl/glsl4
-rw-r--r--util/qlalr/examples/glsl/glsl-lex.l201
-rw-r--r--util/qlalr/examples/glsl/glsl.g621
-rw-r--r--util/qlalr/examples/glsl/glsl.pro4
-rw-r--r--util/qlalr/examples/lambda/COMPILE3
-rw-r--r--util/qlalr/examples/lambda/lambda.g41
-rw-r--r--util/qlalr/examples/lambda/lambda.pro3
-rw-r--r--util/qlalr/examples/lambda/main.cpp160
-rw-r--r--util/qlalr/examples/qparser/COMPILE3
-rw-r--r--util/qlalr/examples/qparser/calc.g93
-rw-r--r--util/qlalr/examples/qparser/calc.l20
-rw-r--r--util/qlalr/examples/qparser/qparser.cpp3
-rw-r--r--util/qlalr/examples/qparser/qparser.h111
-rw-r--r--util/qlalr/examples/qparser/qparser.pro4
-rw-r--r--util/qlalr/grammar.cpp123
-rw-r--r--util/qlalr/grammar_p.h119
-rw-r--r--util/qlalr/lalr.cpp783
-rw-r--r--util/qlalr/lalr.g803
-rw-r--r--util/qlalr/lalr.h502
-rw-r--r--util/qlalr/main.cpp185
-rw-r--r--util/qlalr/parsetable.cpp127
-rw-r--r--util/qlalr/parsetable.h59
-rw-r--r--util/qlalr/qlalr.pro21
-rw-r--r--util/qlalr/recognizer.cpp489
-rw-r--r--util/qlalr/recognizer.h111
-rw-r--r--util/qtscriptparser/make-parser.sh15
-rwxr-xr-xutil/scripts/make_qfeatures_dot_h118
-rwxr-xr-xutil/scripts/unix_to_dos16
-rw-r--r--util/unicode/README1
-rw-r--r--util/unicode/codecs/big5/BIG514079
-rw-r--r--util/unicode/codecs/big5/big5.pro6
-rw-r--r--util/unicode/codecs/big5/big5.qrc6
-rw-r--r--util/unicode/codecs/big5/main.cpp158
-rw-r--r--util/unicode/data/ArabicShaping.txt338
-rw-r--r--util/unicode/data/BidiMirroring.txt582
-rw-r--r--util/unicode/data/Blocks.txt185
-rw-r--r--util/unicode/data/CaseFolding.txt1093
-rw-r--r--util/unicode/data/CompositionExclusions.txt197
-rw-r--r--util/unicode/data/DerivedAge.txt867
-rw-r--r--util/unicode/data/GraphemeBreakProperty.txt1039
-rw-r--r--util/unicode/data/LineBreak.txt18542
-rw-r--r--util/unicode/data/NormalizationCorrections.txt48
-rw-r--r--util/unicode/data/Scripts.txt1538
-rw-r--r--util/unicode/data/ScriptsCorrections.txt0
-rw-r--r--util/unicode/data/ScriptsInitial.txt0
-rw-r--r--util/unicode/data/SentenceBreakProperty.txt1664
-rw-r--r--util/unicode/data/SpecialCasing.txt264
-rw-r--r--util/unicode/data/UnicodeData.txt17720
-rw-r--r--util/unicode/data/WordBreakProperty.txt677
-rw-r--r--util/unicode/main.cpp2524
-rw-r--r--util/unicode/unicode.pro2
-rwxr-xr-xutil/unicode/writingSystems.sh19
-rw-r--r--util/unicode/x11/encodings.in71
-rwxr-xr-xutil/unicode/x11/makeencodings135
-rwxr-xr-xutil/webkit/mkdist-webkit314
-rw-r--r--util/xkbdatagen/main.cpp478
-rw-r--r--util/xkbdatagen/xkbdatagen.pro3
214 files changed, 97599 insertions, 0 deletions
diff --git a/util/fixnonlatin1/fixnonlatin1.pro b/util/fixnonlatin1/fixnonlatin1.pro
new file mode 100644
index 0000000..bfc5e7d
--- /dev/null
+++ b/util/fixnonlatin1/fixnonlatin1.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET +=
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += main.cpp
+
+QT = core
diff --git a/util/fixnonlatin1/main.cpp b/util/fixnonlatin1/main.cpp
new file mode 100644
index 0000000..a089959
--- /dev/null
+++ b/util/fixnonlatin1/main.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCore/QtCore>
+
+// Scans files for characters >127 and replaces them with the \nnn octal representation
+
+int main(int argc, char *argv[])
+{
+ if (argc <= 1)
+ qFatal("Usage: %s FILES", argc ? argv[0] : "fixnonlatin1");
+ for (int i = 1; i < argc; ++i) {
+
+ QString fileName = QString::fromLocal8Bit(argv[i]);
+ if ( fileName.endsWith(".gif")
+ || fileName.endsWith(".jpg")
+ || fileName.endsWith(".tif")
+ || fileName.endsWith(".tiff")
+ || fileName.endsWith(".png")
+ || fileName.endsWith(".mng")
+ || fileName.endsWith(".ico")
+ || fileName.endsWith(".zip")
+ || fileName.endsWith(".gz")
+ || fileName.endsWith(".qpf")
+ || fileName.endsWith(".ttf")
+ || fileName.endsWith(".pfb")
+ || fileName.endsWith(".exe")
+ || fileName.endsWith(".nib")
+ || fileName.endsWith(".o")
+ )
+ continue;
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ qFatal("Cannot open '%s': %s", argv[i], qPrintable(file.errorString()));
+
+ QByteArray ba = file.readAll();
+ bool mod = false;
+ for (int j = 0; j < ba.count(); ++j) {
+ uchar c = ba.at(j);
+ if (c > 127) {
+ ba[j] = '\\';
+ ba.insert(j + 1, QByteArray::number(c, 8).rightJustified(3, '0', true));
+ j += 3;
+ mod = true;
+ }
+ }
+ file.close();
+
+ if (!mod)
+ continue;
+
+ qWarning("found non-latin1 characters in '%s'", argv[i]);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ qWarning("Cannot open '%s' for writing: %s", argv[i], qPrintable(file.errorString()));
+ continue;
+ }
+ if (file.write(ba) < 0)
+ qFatal("Error while writing into '%s': %s", argv[i], qPrintable(file.errorString()));
+ file.close();
+ }
+
+ return 0;
+}
+
diff --git a/util/gencmap/Makefile b/util/gencmap/Makefile
new file mode 100644
index 0000000..a338472
--- /dev/null
+++ b/util/gencmap/Makefile
@@ -0,0 +1,46 @@
+#############################################################################
+# Qt Makefile - gencmap
+#############################################################################
+
+####### Directories
+
+BASEDIR = $(QTDIR)
+INCDIR = $(BASEDIR)/include
+LIBDIR = $(BASEDIR)/lib
+
+####### Compiler
+
+CFLAGS = -O2
+LFLAGS = -L$(LIBDIR)
+CC = gcc
+
+####### Files
+
+SOURCES = gencmap.cpp
+OBJECTS = gencmap.o
+TARGET = gencmap
+
+####### Implicit rules
+
+.SUFFIXES:
+.SUFFIXES: .cpp $(SUFFIXES)
+
+.cpp.o:
+ $(CC) -c $(CFLAGS) -I$(INCDIR) $<
+
+####### Build rules
+
+all: $(TARGET)
+
+$(TARGET): $(OBJECTS)
+ $(CC) $(OBJECTS) -o $(TARGET) $(LFLAGS)
+
+depend:
+ @makedepend -I$(INCDIR) $(SOURCES) 2> /dev/null
+
+clean:
+ -rm -f *.o *.bak *~ *% #*
+ -rm -f $(TARGET)
+
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/util/gencmap/gencmap.cpp b/util/gencmap/gencmap.cpp
new file mode 100644
index 0000000..9d0d997
--- /dev/null
+++ b/util/gencmap/gencmap.cpp
@@ -0,0 +1,344 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcolor.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+
+#define APPLE_CMAP 1
+
+struct Col {
+ int r,g,b;
+};
+
+#if SPACE_SEARCH
+#define MAPSIZE 256
+#define ACCURACY 4 // Bits-per-channel
+#define SPACESIZE ((1<<ACCURACY)*(1<<ACCURACY)*(1<<ACCURACY))
+#define R(c) (((c>>(8-ACCURACY)*2)&((1<<ACCURACY)-1))<<ACCURACY)
+#define G(c) (((c>>(8-ACCURACY))&((1<<ACCURACY)-1))<<ACCURACY)
+#define B(c) (((c>>0)&((1<<ACCURACY)-1))<<ACCURACY)
+#define COL(c) (((c.r>>(8-ACCURACY))<<8)|((c.b>>(8-ACCURACY))<<4)|(c.g>>(8-ACCURACY)))
+#elif APPLE_CMAP
+#define SPACESIZE 216
+#define MAPSIZE 216
+#define R(c) ((apple_cmap[c]>>16)&0xff)
+#define G(c) ((apple_cmap[c]>>8)&0xff)
+#define B(c) ((apple_cmap[c]>>0)&0xff)
+#define COL(c) findapple(c)
+static int apple_cmap[216] = {
+0xffffff,
+0xffffcc,
+0xffff99,
+0xffff66,
+0xffff33,
+0xffff00,
+0xffccff,
+0xffcccc,
+0xffcc99,
+0xffcc66,
+0xffcc33,
+0xffcc00,
+0xff99ff,
+0xff99cc,
+0xff9999,
+0xff9966,
+0xff9933,
+0xff9900,
+0xff66ff,
+0xff66cc,
+0xff6699,
+0xff6666,
+0xff6633,
+0xff6600,
+0xff33ff,
+0xff33cc,
+0xff3399,
+0xff3366,
+0xff3333,
+0xff3300,
+0xff00ff,
+0xff00cc,
+0xff0099,
+0xff0066,
+0xff0033,
+0xff0000,
+0xccffff,
+0xccffcc,
+0xccff99,
+0xccff66,
+0xccff33,
+0xccff00,
+0xccccff,
+0xcccccc,
+0xcccc99,
+0xcccc66,
+0xcccc33,
+0xcccc00,
+0xcc99ff,
+0xcc99cc,
+0xcc9999,
+0xcc9966,
+0xcc9933,
+0xcc9900,
+0xcc66ff,
+0xcc66cc,
+0xcc6699,
+0xcc6666,
+0xcc6633,
+0xcc6600,
+0xcc33ff,
+0xcc33cc,
+0xcc3399,
+0xcc3366,
+0xcc3333,
+0xcc3300,
+0xcc00ff,
+0xcc00cc,
+0xcc0099,
+0xcc0066,
+0xcc0033,
+0xcc0000,
+0x99ffff,
+0x99ffcc,
+0x99ff99,
+0x99ff66,
+0x99ff33,
+0x99ff00,
+0x99ccff,
+0x99cccc,
+0x99cc99,
+0x99cc66,
+0x99cc33,
+0x99cc00,
+0x9999ff,
+0x9999cc,
+0x999999,
+0x999966,
+0x999933,
+0x999900,
+0x9966ff,
+0x9966cc,
+0x996699,
+0x996666,
+0x996633,
+0x996600,
+0x9933ff,
+0x9933cc,
+0x993399,
+0x993366,
+0x993333,
+0x993300,
+0x9900ff,
+0x9900cc,
+0x990099,
+0x990066,
+0x990033,
+0x990000,
+0x66ffff,
+0x66ffcc,
+0x66ff99,
+0x66ff66,
+0x66ff33,
+0x66ff00,
+0x66ccff,
+0x66cccc,
+0x66cc99,
+0x66cc66,
+0x66cc33,
+0x66cc00,
+0x6699ff,
+0x6699cc,
+0x669999,
+0x669966,
+0x669933,
+0x669900,
+0x6666ff,
+0x6666cc,
+0x666699,
+0x666666,
+0x666633,
+0x666600,
+0x6633ff,
+0x6633cc,
+0x663399,
+0x663366,
+0x663333,
+0x663300,
+0x6600ff,
+0x6600cc,
+0x660099,
+0x660066,
+0x660033,
+0x660000,
+0x33ffff,
+0x33ffcc,
+0x33ff99,
+0x33ff66,
+0x33ff33,
+0x33ff00,
+0x33ccff,
+0x33cccc,
+0x33cc99,
+0x33cc66,
+0x33cc33,
+0x33cc00,
+0x3399ff,
+0x3399cc,
+0x339999,
+0x339966,
+0x339933,
+0x339900,
+0x3366ff,
+0x3366cc,
+0x336699,
+0x336666,
+0x336633,
+0x336600,
+0x3333ff,
+0x3333cc,
+0x333399,
+0x333366,
+0x333333,
+0x333300,
+0x3300ff,
+0x3300cc,
+0x330099,
+0x330066,
+0x330033,
+0x330000,
+0x00ffff,
+0x00ffcc,
+0x00ff99,
+0x00ff66,
+0x00ff33,
+0x00ff00,
+0x00ccff,
+0x00cccc,
+0x00cc99,
+0x00cc66,
+0x00cc33,
+0x00cc00,
+0x0099ff,
+0x0099cc,
+0x009999,
+0x009966,
+0x009933,
+0x009900,
+0x0066ff,
+0x0066cc,
+0x006699,
+0x006666,
+0x006633,
+0x006600,
+0x0033ff,
+0x0033cc,
+0x003399,
+0x003366,
+0x003333,
+0x003300,
+0x0000ff,
+0x0000cc,
+0x000099,
+0x000066,
+0x000033,
+0x000000,
+};
+int findapple(Col c)
+{
+ for (int i=0; i<216; i++)
+ if (apple_cmap[i]==(c.r<<16)|(c.g<<8)|c.b) return i;
+ abort();
+}
+#endif
+
+#define SQ(x) ((x)*(x))
+#define D(c1,c2) (SQ(R(c1)-R(c2))+SQ(G(c1)-G(c2))+SQ(B(c1)-B(c2)))
+
+main()
+{
+ Col c[256] = {
+ { 0,0,0 },
+ { 255,255,255 },
+ { 255,0,0 }, { 0,255,0 }, { 0,0,255 },
+ { 255,255,0 }, { 0,255,255 }, { 255,0,255 },
+ #define PREALLOC 8
+ { 96,96,96 }, { 192,192,192 },
+ //#define PREALLOC 10
+ };
+ int done[SPACESIZE];
+ for (int a=0; a<SPACESIZE; a++) done[a]=0;
+ for (int a=0; a<PREALLOC; a++) done[COL(c[a])]=1;
+
+ for (int allocated=PREALLOC; allocated<MAPSIZE; allocated++) {
+ int mostdist;
+ int dist=0;
+ for (int a=0; a<SPACESIZE; a++) {
+ if (!done[a]) {
+ int closeness=INT_MAX;
+ for (int b=0; b<SPACESIZE; b++) {
+ if (done[b]) {
+ int d=D(a,b);
+ if (d < closeness) {
+ closeness=d;
+ }
+ }
+ }
+ if (closeness > dist) {
+ mostdist=a;
+ dist=closeness;
+ }
+ }
+ }
+ c[allocated].r=R(mostdist);
+ c[allocated].g=G(mostdist);
+ c[allocated].b=B(mostdist);
+ done[mostdist]=1;
+ fprintf(stderr,"Done %d of %d (%06x dist %d)\n",allocated+1,MAPSIZE,
+ qRgb(c[allocated].r, c[allocated].g, c[allocated].b), dist);
+ }
+
+ for (int i=0; i<256; i++) {
+ printf("0x%06x,%c", qRgb(c[i].r, c[i].g, c[i].b), i%4==3 ? '\n' : ' ');
+ }
+}
diff --git a/util/harfbuzz/update-harfbuzz b/util/harfbuzz/update-harfbuzz
new file mode 100755
index 0000000..29891b6
--- /dev/null
+++ b/util/harfbuzz/update-harfbuzz
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+set -e
+
+require_clean_work_tree() {
+ # test if working tree is dirty
+ git rev-parse --verify HEAD > /dev/null &&
+ git update-index --refresh &&
+ git diff-files --quiet &&
+ git diff-index --cached --quiet HEAD ||
+ die "Working tree is dirty"
+}
+
+branch=master
+
+if [ $# = 1 ]; then
+ repo=$1
+elif [ $# = 2 ]; then
+ repo=$1
+ branch=$2
+else
+ echo "usage: $0 <path to local harfbuzz repository> [branch]"
+ exit 1
+fi
+
+if [ ! -r $repo/.git ]; then
+ echo "The provided path $repo does not point to a git repository."
+ exit 2
+fi
+
+test -z "$(git rev-parse --show-cdup)" || {
+ exit=$?
+ echo >&2 "You need to run this command from the toplevel of the working tree."
+ exit $exit
+}
+
+require_clean_work_tree
+
+url=`git --git-dir=$repo/.git config remote.origin.url`
+
+git ls-files src/3rdparty/harfbuzz | git update-index --force-remove --stdin
+
+git fetch $repo $branch
+
+commit=`git rev-parse FETCH_HEAD`
+tree=`git cat-file commit FETCH_HEAD|grep "^tree" | awk '{print $2}'`
+
+git read-tree --prefix=src/3rdparty/harfbuzz $tree
+
+git checkout src/3rdparty/harfbuzz
+
+git status
+
+cat >commitlog.txt <<EOT
+Updated Harfbuzz from $url to $commit
+EOT
+
+echo
+echo "Wrote commitlog.txt. Use with"
+echo
+echo " git commit -e -F commitlog.txt"
+echo
+echo "to commit your changes"
diff --git a/util/install/archive/archive.pro b/util/install/archive/archive.pro
new file mode 100644
index 0000000..e313a4a
--- /dev/null
+++ b/util/install/archive/archive.pro
@@ -0,0 +1,9 @@
+TEMPLATE = lib
+CONFIG += staticlib
+CONFIG += qt x11
+CONFIG -= dll
+TARGET = arq
+
+SOURCES += qarchive.cpp ../keygen/keyinfo.cpp
+HEADERS += qarchive.h
+!zlib:unix:LIBS += -lz
diff --git a/util/install/archive/qarchive.cpp b/util/install/archive/qarchive.cpp
new file mode 100644
index 0000000..dd51c65
--- /dev/null
+++ b/util/install/archive/qarchive.cpp
@@ -0,0 +1,471 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qarchive.h"
+#include <qdatastream.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qapplication.h>
+#include "../../../src/3rdparty/zlib/zlib.h"
+#include "../keygen/keyinfo.h"
+#ifdef Q_OS_UNIX
+# include <sys/stat.h>
+# include <unistd.h>
+# include <sys/types.h>
+# include <utime.h>
+#endif
+
+enum ChunkType {
+ ChunkDirectory = 0,
+ ChunkFile = 1,
+ ChunkSymlink = 2,
+ ChunkBeginHeader = 3,
+ ChunkEndHeader = 4
+};
+
+static bool createDir( const QString& fullPath )
+{
+ QStringList hierarchy = QStringList::split( QDir::separator(), fullPath );
+ QString pathComponent, tmpPath;
+ QDir dirTmp;
+#ifdef Q_OS_UNIX
+ dirTmp = "/";
+#endif
+
+ for( QStringList::Iterator it = hierarchy.begin(); it != hierarchy.end(); ++it ) {
+ pathComponent = *it + QDir::separator();
+ tmpPath += pathComponent;
+ if (!dirTmp.exists(tmpPath) && !dirTmp.mkdir(tmpPath))
+ return false;
+ }
+ return true;
+}
+
+QArchive::QArchive( const QString& archivePath )
+{
+ setPath( archivePath );
+
+ bufferSize = 512 * 1024;
+}
+
+QArchive::~QArchive()
+{
+}
+
+void QArchive::setPath( const QString& archivePath )
+{
+ QString fullName = archivePath;
+ if( fullName.right( 4 ) != ".arq" )
+ fullName += ".arq";
+ arcFile.setName( fullName );
+}
+
+bool QArchive::open( int mode )
+{
+ switch( mode ) {
+ case IO_ReadOnly:
+ // Fallthrough intentional
+ case IO_WriteOnly:
+ if( arcFile.open( mode ) )
+ return true;
+ break;
+ }
+ return false;
+}
+
+void QArchive::close()
+{
+ if( arcFile.isOpen() )
+ arcFile.close();
+}
+
+bool QArchive::writeFile( const QString& fileName, const QString& localPath )
+{
+ if( arcFile.isOpen() ) {
+ QDataStream outStream( &arcFile );
+ QFileInfo fi( fileName );
+
+ QFile inFile( fi.absFilePath() );
+ QByteArray inBuffer;
+ QByteArray outBuffer( bufferSize );
+ z_stream ztream;
+ bool continueCompressing;
+
+ if(symbolicLinks() && fi.isSymLink()) {
+ outStream << (int)ChunkSymlink;
+ outStream << fi.fileName().latin1();
+ outStream << fi.readLink().latin1();
+ } else if( inFile.open( IO_ReadOnly ) ) {
+ if( inBuffer.resize( fi.size() ) ) {
+ outStream << (int)ChunkFile;
+ outStream << fi.fileName().latin1();
+ outStream << fi.lastModified();
+ {
+ int perm = -1;
+#ifdef Q_OS_UNIX
+ struct stat st;
+ if(!::stat(fi.filePath().latin1(), &st))
+ perm = (int)st.st_mode;
+#endif
+ outStream << perm;
+ }
+ if( verbosityMode & Source )
+ emit operationFeedback( "Deflating " + fi.absFilePath() + "..." );
+ else if( verbosityMode & Destination )
+ emit operationFeedback( "Deflating " + localPath + "/" + fi.fileName() + "..." );
+ ztream.next_in = (unsigned char*)inBuffer.data();
+ ztream.avail_in = inBuffer.size();
+ ztream.total_in = 0;
+ ztream.next_out = (unsigned char*)outBuffer.data();
+ ztream.avail_out = outBuffer.size();
+ ztream.total_out = 0;
+ ztream.msg = NULL;
+ ztream.zalloc = (alloc_func)NULL;
+ ztream.zfree = (free_func)NULL;
+ ztream.opaque = (voidpf)NULL;
+ ztream.data_type = Z_BINARY;
+ deflateInit( &ztream, 9 );
+ if ( inBuffer.data() )
+ inFile.readBlock( inBuffer.data(), inBuffer.size() );
+
+ continueCompressing = true;
+ while( continueCompressing ) {
+ if(qApp)
+ qApp->processEvents();
+ continueCompressing = ( deflate( &ztream, Z_FINISH ) == Z_OK );
+ if( !ztream.avail_out ) {
+ if( !outBuffer.resize( outBuffer.size() + bufferSize ) )
+ qFatal( "Could not allocate compression buffer!" );
+ ztream.next_out = (unsigned char*)&outBuffer.data()[ ztream.total_out ];
+ ztream.avail_out = bufferSize;
+ }
+ }
+
+ emit operationFeedback( QString( "done. %1 => %2 (%3%)\n" )
+ .arg( ztream.total_in )
+ .arg( ztream.total_out )
+ .arg( int(
+ double( ztream.total_out ) / double( ztream.total_in ) * 100 ) ) );
+ deflateEnd( &ztream );
+ // Now write the compressed data to the output
+ outStream << ztream.total_out;
+ outStream.writeRawBytes( outBuffer.data(), ztream.total_out );
+ }
+ inFile.close();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return false;
+}
+
+bool QArchive::setDirectory( const QString& dirName )
+{
+ if( arcFile.isOpen() ) {
+ QString fullName = dirName;
+ QDataStream outStream( &arcFile );
+ if( fullName.right( 1 ) != "/" )
+ fullName += "/";
+ outStream << (int)ChunkDirectory;
+ outStream << fullName.latin1();
+ return true;
+ }
+ return false;
+}
+
+bool QArchive::writeHeader( const QArchiveHeader header )
+{
+ if( arcFile.isOpen() ) {
+ QDataStream outStream( &arcFile );
+ outStream << (int)ChunkBeginHeader;
+ outStream << header.mayorVersion();
+ outStream << header.minorVersion();
+ outStream << header.features();
+ outStream << header.description();
+ outStream << header.extraData;
+ outStream << (int)ChunkEndHeader;
+ return true;
+ }
+ return false;
+}
+
+bool QArchive::writeDir( const QString &dirName1, bool includeLastComponent, const QString &localPath1 )
+{
+ if( arcFile.isOpen() ) {
+ QString localPath = localPath1, dirName = dirName1;
+ if(localPath.right(1) == "/")
+ localPath.truncate(localPath.length()-1);
+ if(dirName.right(1) == "/")
+ dirName.truncate(dirName.length()-1);
+
+ QFileInfo fi( dirName );
+
+ if( includeLastComponent )
+ setDirectory( fi.fileName() );
+ QDir dir( dirName );
+ const QFileInfoList* dirEntries = dir.entryInfoList();
+ QFileInfoListIterator dirIter( *dirEntries );
+ QDataStream outStream( &arcFile );
+ QFileInfo* pFi;
+
+ dirIter.toLast();
+ while( ( pFi = dirIter.current() ) ) {
+ if( pFi->fileName() != "." && pFi->fileName() != ".." ) {
+ if( pFi->isDir() )
+ writeDir( pFi->absFilePath(), true, localPath + "/" +
+ pFi->fileName() ); // Subdirs should always get its name in the archive.
+ else
+ writeFile( pFi->absFilePath(), localPath );
+ }
+ --dirIter;
+ }
+ setDirectory( ".." );
+ return true;
+ }
+ return false;
+}
+
+bool QArchive::writeFileList( const QStringList fileList )
+{
+ for( QStringList::ConstIterator it = fileList.begin(); it != fileList.end(); ++it ) {
+ if( !writeFile( (*it) ) )
+ return false;
+ }
+ return true;
+}
+
+bool QArchive::writeDirList( const QStringList dirList, bool includeLastComponent )
+{
+ for( QStringList::ConstIterator it = dirList.begin(); it != dirList.end(); ++it ) {
+ QString lastComponent = (*it).mid( (*it).findRev( "/" ) + 1 );
+ if( !writeDir( (*it), includeLastComponent, lastComponent ) )
+ return false;
+ }
+ return true;
+}
+
+void QArchive::setVerbosity( int verbosity )
+{
+ verbosityMode = verbosity;
+}
+
+QArchiveHeader* QArchive::readArchiveHeader()
+{
+ QDataStream inStream( &arcFile );
+ return readArchiveHeader( &inStream );
+}
+
+/*
+ Reads the archive header and returns it on success. If an error occurs, it
+ returns 0. The caller has to delete the object.
+*/
+QArchiveHeader* QArchive::readArchiveHeader( QDataStream *inStream )
+{
+ int chunktype;
+ QArchiveHeader *header = new QArchiveHeader;
+
+ *inStream >> chunktype;
+ if( chunktype == ChunkBeginHeader ) {
+ *inStream >> header->_mayorVersion;
+ *inStream >> header->_minorVersion;
+ if ( header->mayorVersion()!=1 || header->minorVersion()!=0 ) {
+ emit operationFeedback( "Incompatible package version" );
+ delete header;
+ return 0;
+ }
+ *inStream >> header->_features;
+ *inStream >> header->_description;
+ *inStream >> header->extraData;
+ *inStream >> chunktype;
+ if ( chunktype != ChunkEndHeader ) {
+ emit operationFeedback( "Invalid package header" );
+ delete header;
+ return 0;
+ }
+ } else {
+ emit operationFeedback( "No package header found." );
+ delete header;
+ return 0;
+ }
+ return header;
+}
+
+bool QArchive::readArchive( const QString &outpath, const QString &key )
+{
+ QDataStream inStream( &arcFile );
+ return readArchive( &inStream, outpath, key );
+}
+
+bool QArchive::readArchive( QDataStream *inStream, const QString &outpath, const QString &key )
+{
+ QDataStream outStream;
+ QFile outFile;
+ QDir outDir;
+ QByteArray inBuffer;
+ QByteArray outBuffer( bufferSize );
+ z_stream ztream;
+ bool continueDeCompressing;
+ QString entryName, dirName, symName;
+ int entryLength, chunktype;
+
+ //get the key
+ QArchiveHeader *header = readArchiveHeader( inStream );
+ if ( header == 0 )
+ return false;
+ uint infeatures = featuresForKey( key );
+ if( (header->features() & infeatures) != header->features()) {
+ emit operationFeedback( "Invalid key" );
+ return false;
+ }
+
+ // Set up the initial directory.
+ // If the dir does not exist, try to create it
+ dirName = QDir::toNativeSeparators( outpath );
+ outDir.setPath( dirName );
+ if( !outDir.exists( dirName ) && !createDir( dirName ) )
+ return false;
+ outDir.cd( dirName );
+
+ while( !inStream->atEnd() ) {
+ //get our type
+ *inStream >> chunktype;
+ if(chunktype == ChunkDirectory) {
+ *inStream >> entryLength;
+ inBuffer.resize( entryLength );
+ inStream->readRawBytes( inBuffer.data(), entryLength );
+ entryName = inBuffer.data();
+
+ if( verbosityMode & Source )
+ emit operationFeedback( "Directory " + entryName + "... " );
+ if( entryName == "../" ) {
+ outDir.cdUp();
+ } else {
+ dirName = QDir::toNativeSeparators( outDir.absPath() +
+ QString( "/" ) + entryName.left( entryName.length() - 1 ) );
+ if( verbosityMode & Destination )
+ emit operationFeedback( "Directory " + dirName + "... " );
+
+ if( !outDir.exists( dirName ) && !createDir( dirName ) ) {
+ emit operationFeedback( "Cannot create directory: " + dirName );
+ return false;
+ }
+ outDir.cd( dirName );
+ }
+ } else if(chunktype == ChunkFile) {
+ *inStream >> entryLength;
+ inBuffer.resize( entryLength );
+ inStream->readRawBytes( inBuffer.data(), entryLength );
+ entryName = inBuffer.data();
+
+ int filePerm;
+ QDateTime timeStamp;
+ QString fileName = QDir::toNativeSeparators( outDir.absPath() + QString( "/" ) + entryName );
+ outFile.setName( fileName );
+ if( outFile.open( IO_WriteOnly ) ) {
+ *inStream >> timeStamp; // Get timestamp from the archive
+ *inStream >> filePerm;
+ outStream.setDevice( &outFile );
+ *inStream >> entryLength;
+ if( verbosityMode & Source )
+ emit operationFeedback( "Expanding " + entryName + "..." );
+ else if( verbosityMode & Destination )
+ emit operationFeedback( "Expanding " + fileName + "..." );
+ inBuffer.resize( entryLength );
+ inStream->readRawBytes( inBuffer.data(), entryLength );
+ ztream.next_in = (unsigned char*)inBuffer.data();
+ ztream.avail_in = entryLength;
+ ztream.total_in = 0;
+ ztream.msg = NULL;
+ ztream.zalloc = (alloc_func)0;
+ ztream.zfree = (free_func)0;
+ ztream.opaque = (voidpf)0;
+ ztream.data_type = Z_BINARY;
+ inflateInit( &ztream );
+ continueDeCompressing = true;
+ while( continueDeCompressing ) {
+ ztream.next_out = (unsigned char*)outBuffer.data();
+ ztream.avail_out = outBuffer.size();
+ ztream.total_out = 0;
+ continueDeCompressing = ( inflate( &ztream, Z_NO_FLUSH ) == Z_OK );
+ outStream.writeRawBytes( outBuffer.data(), ztream.total_out );
+ }
+ inflateEnd( &ztream );
+ outFile.close();
+#ifdef Q_OS_UNIX
+ QDateTime t; t.setTime_t(0); //epoch
+ struct utimbuf tb;
+ tb.actime = tb.modtime = t.secsTo(timeStamp);
+ utime(fileName.local8Bit(), &tb);
+ if(filePerm != -1)
+ chmod(fileName.local8Bit(), (mode_t)filePerm);
+#endif
+ } else {
+ emit operationFeedback( "Cannot open: " + fileName );
+ return false;
+ }
+ } else if(chunktype == ChunkSymlink) {
+ *inStream >> entryLength;
+ inBuffer.resize( entryLength );
+ inStream->readRawBytes( inBuffer.data(), entryLength );
+ entryName = inBuffer.data();
+ QString fileName = QDir::toNativeSeparators( outDir.absPath() + QString( "/" ) + entryName );
+
+ *inStream >> entryLength;
+ inBuffer.resize( entryLength );
+ inStream->readRawBytes( inBuffer.data(), entryLength );
+ symName = inBuffer.data();
+ if( verbosityMode & Source )
+ emit operationFeedback( "Linking " + symName + "... " );
+ else if( verbosityMode & Destination )
+ emit operationFeedback( "Linking " + fileName + "... " );
+#ifdef Q_OS_UNIX
+ symlink( symName.local8Bit(), fileName.local8Bit() );
+#endif
+ } else {
+ if( verbosityMode & Source )
+ emit operationFeedback( QString("Unknown chunk: %d") .arg(chunktype) );
+ }
+ if( verbosityMode & Progress )
+ emit operationFeedback( inStream->device()->at() );
+ }
+ return true;
+}
+
diff --git a/util/install/archive/qarchive.h b/util/install/archive/qarchive.h
new file mode 100644
index 0000000..351a48b
--- /dev/null
+++ b/util/install/archive/qarchive.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QARCHIVE_H
+#define QARCHIVE_H
+
+#include <qstring.h>
+#include <qfile.h>
+#include <qstringlist.h>
+#include <qobject.h>
+
+class QArchiveHeader
+{
+public:
+ QArchiveHeader( uint feat, const QString& desc=QString(), uchar mayorVer = 1, uchar minorVer = 0 )
+ : _features(feat), _description(desc), _mayorVersion(mayorVer), _minorVersion(minorVer)
+ {}
+
+ uint features() const
+ { return _features; }
+
+ QString description() const
+ { return _description; }
+
+ uchar mayorVersion() const
+ { return _mayorVersion; }
+
+ uchar minorVersion() const
+ { return _minorVersion; }
+
+ void addExtraData( const QString& key, const QString& value )
+ { extraData.insert( key, value ); }
+
+ QString findExtraData( const QString& key ) const
+ { return extraData[key]; }
+
+private:
+ QArchiveHeader()
+ {}
+
+ uint _features;
+ QString _description;
+ uchar _mayorVersion;
+ uchar _minorVersion;
+ QMap<QString,QString> extraData;
+
+ friend class QArchive;
+};
+
+class QArchive : public QObject
+{
+ Q_OBJECT
+public:
+ QArchive( const QString& archivePath = QString() );
+ ~QArchive();
+
+ void setPath( const QString& archivePath );
+ void setVerbosity( int verbosity );
+
+ bool symbolicLinks() const { return doSyms; }
+ void setSymbolicLinks(bool b) { doSyms = b; }
+
+ bool open( int mode );
+ void close();
+ bool isOpen() { return arcFile.isOpen(); }
+
+ bool writeHeader( const QArchiveHeader header );
+ bool writeFile( const QString& fileName, const QString& localPath = QString() );
+ bool writeFileList( const QStringList fileList );
+ bool writeDir( const QString& dirName, bool includeLastComponent = false,
+ const QString& localPath = QString() );
+ bool writeDirList( const QStringList dirList, bool includeLastComponent = true );
+
+ QArchiveHeader* readArchiveHeader();
+ QArchiveHeader* readArchiveHeader( QDataStream *inStream );
+
+ bool readArchive( const QString &outpath, const QString &key = QString() );
+ bool readArchive( QDataStream *inStream, const QString &outpath, const QString &key = QString() );
+private:
+ QFile arcFile;
+
+ int bufferSize;
+ int verbosityMode;
+ uint doSyms : 1;
+ bool setDirectory( const QString& dirName );
+signals:
+ void operationFeedback( const QString& );
+ void operationFeedback( int );
+
+public:
+ enum {
+ NoFeedback = 0x00,
+ OnlyNames = 0x01,
+ Verbose = 0x02,
+ Source = 0x10,
+ Destination = 0x20,
+ Progress = 0x40
+ };
+};
+
+#endif
diff --git a/util/install/configure_installer.cache b/util/install/configure_installer.cache
new file mode 100644
index 0000000..9427b74
--- /dev/null
+++ b/util/install/configure_installer.cache
@@ -0,0 +1,30 @@
+-disable-table
+-disable-iconview
+-disable-workspace
+-disable-xml
+-disable-network
+-disable-canvas
+-disable-opengl
+-disable-sql
+-release
+-static
+-lean
+-no-dsp
+-no-thread
+-no-accessibility
+-qt-style-windowsxp
+-no-style-motif
+-no-style-cde
+-no-style-sgi
+-no-style-motifplus
+-no-style-platinum
+-no-big-codecs
+-no-jpeg
+-no-png
+-spec win32-msvc
+-saveconfig installer
+-D QT_NO_COLORNAMES
+-D QT_NO_BEZIER
+-D QT_NO_EFFECTS
+-D QT_NO_DIRECTPAINTER
+-D QT_NO_SVG
diff --git a/util/install/install.pro b/util/install/install.pro
new file mode 100644
index 0000000..4106453
--- /dev/null
+++ b/util/install/install.pro
@@ -0,0 +1,9 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS += archive \
+ package \
+ keygen
+
+win32:SUBDIRS += win
+mac:SUBDIRS += mac
diff --git a/util/install/keygen/keygen.pro b/util/install/keygen/keygen.pro
new file mode 100644
index 0000000..59daf75
--- /dev/null
+++ b/util/install/keygen/keygen.pro
@@ -0,0 +1,13 @@
+CONFIG += qt console
+SOURCES += keyinfo.cpp
+keychk {
+ TEMPLATE = lib
+ TARGET = keychk
+ DESTDIR = ../../../lib/
+ CONFIG -= shared dll
+ CONFIG += staticlib
+} else {
+ TEMPLATE = app
+ TARGET = keygen
+ SOURCES += main.cpp
+} \ No newline at end of file
diff --git a/util/install/keygen/keyinfo.cpp b/util/install/keygen/keyinfo.cpp
new file mode 100644
index 0000000..9ad5404
--- /dev/null
+++ b/util/install/keygen/keyinfo.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qregexp.h>
+
+#include "keyinfo.h"
+
+// Magic values
+enum {
+ ProductMagic = 0xB292,
+ PlatformMagic = 0x5C7E,
+ LicenseSchemaMagic = 0xE3B,
+ LicenseIDMagic = 0xCE57,
+ FeatureMagic = 0x4D5
+};
+
+static const char Xalphabet[] = "WX9MUEC7AJH3KS6DB4YFG2L5PQRT8VNZ";
+static const int XAlphabetSize = sizeof(Xalphabet) - 1;
+
+static QString encodeBaseX(uint k)
+{
+ QString str;
+ do {
+ str += QChar(Xalphabet[ k % XAlphabetSize ]);
+ k /= XAlphabetSize;
+ } while (k > 0u);
+ return str;
+}
+
+static uint decodeBaseX(const QString &str)
+{
+ uint k = 0;
+ int i = str.length();
+ while (i > 0) {
+ i--;
+ const char *p = strchr(Xalphabet, str[i].unicode());
+ if (p == 0) {
+ return 0;
+ } else {
+ k = (k * XAlphabetSize) + (p - Xalphabet);
+ }
+ }
+ return k;
+}
+
+static const QDate StartDate(2001, 1, 1);
+static const uint MaxDays = 4000;
+
+static QString encodedExpiryDate(const QDate &date)
+{
+ uint days = StartDate.daysTo(date);
+ if (days >= MaxDays)
+ days = MaxDays - 1;
+ uint x = (days << 7) ^ days;
+ return encodeBaseX(x ^ 0x0000beef);
+}
+
+static QDate decodedExpiryDate(const QString &encodedDate)
+{
+ QDate date;
+ uint y = decodeBaseX(encodedDate);
+ uint x = y ^ 0x0000beef;
+ uint days = ( (x >> 7) ^ x ) >> 7;
+ if (days >= MaxDays)
+ return QDate();
+ date = StartDate.addDays( days );
+ if (encodedExpiryDate(date) != encodedDate)
+ return QDate();
+ return date;
+}
+
+bool decodeLicenseKey(const QString &licenseKey,
+ uint *products,
+ uint *platforms,
+ uint *licenseSchema,
+ uint *licenseFeatures,
+ uint *licenseID,
+ QDate *expiryDate)
+{
+ QStringList licenseParts;
+ int dash = -1;
+ do {
+ int start = dash + 1;
+ dash = licenseKey.indexOf('-', start);
+ licenseParts.append(licenseKey.mid(start, dash - start));
+ } while (dash != -1);
+
+ // license keys have 7 fields
+ if (licenseParts.size() != 7) {
+ // invalid key
+ return false;
+ }
+ QString productPart = licenseParts.at(0);
+ QString platformPart = licenseParts.at(1);
+ QString licenseSchemaPart = licenseParts.at(2);
+ QString licenseFeaturesPart = licenseParts.at(3);
+ QString licenseIDPart = licenseParts.at(4);
+ QString expiryDatePart = licenseParts.at(5);
+ QString checksumPart = licenseParts.at(6);
+ QString keyPart = productPart
+ + '-' + platformPart
+ + '-' + licenseSchemaPart
+ + '-' + licenseFeaturesPart
+ + '-' + licenseIDPart
+ + '-' + expiryDatePart;
+
+ // verify the crc
+ QByteArray ba = keyPart.toLatin1();
+ int crc = qChecksum(ba.constData(), ba.size());
+ QString checksumVerification = QString("%1%2")
+ .arg((crc & 0xff),2,16,QChar('0'))
+ .arg((crc >> 8 & 0xff),2,16,QChar('0'))
+ .toUpper();
+ if (checksumPart != checksumVerification) {
+ // invalid checksum
+ return false;
+ }
+
+ *products = decodeBaseX(productPart) ^ ProductMagic;
+ *platforms = decodeBaseX(platformPart) ^ PlatformMagic;
+ *licenseSchema = decodeBaseX(licenseSchemaPart) ^ LicenseSchemaMagic;
+ *licenseFeatures = decodeBaseX(licenseFeaturesPart) ^ FeatureMagic;
+ *licenseID = decodeBaseX(licenseIDPart) ^ LicenseIDMagic;
+ *expiryDate = decodedExpiryDate(expiryDatePart);
+ return true;
+}
diff --git a/util/install/keygen/keyinfo.h b/util/install/keygen/keyinfo.h
new file mode 100644
index 0000000..9b3687a
--- /dev/null
+++ b/util/install/keygen/keyinfo.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef KEYINFO_H
+#define KEYINFO_H
+
+// Products
+enum {
+ // the first 10 bits are reserved for Qt editions
+ QtUniversal = 0x00000001,
+ QtDesktop = 0x00000002,
+ QtDesktopLight = 0x00000004,
+ QtConsole = 0x00000008,
+ QtDesignerOnly = 0x00000010,
+ QtReserved1 = 0x00000020,
+ QtReserved2 = 0x00000040,
+ QtReserved3 = 0x00000080,
+ QtReserved4 = 0x00000100,
+ QtReserved5 = 0x00000200,
+ QtProductMask = 0x000003ff,
+
+ // the next 10 bits are reserved for Qtopia editions
+ QtopiaPDA = 0x00000400,
+ QtopiaPhone = 0x00000800,
+ QtopiaRefboard = 0x00001000,
+ QtopiaReserved1 = 0x00002000,
+ QtopiaReserved2 = 0x00004000,
+ QtopiaReserved3 = 0x00008000,
+ QtopiaReserved4 = 0x00010000,
+ QtopiaReserved5 = 0x00020000,
+ QtopiaReserved6 = 0x00040000,
+ QtopiaReserved7 = 0x00080000,
+
+ // other products get the upper 12 bits
+ Teambuilder = 0x00100000,
+ Solutions = 0x00200000,
+ QSA = 0x00400000,
+ OtherReserved1 = 0x00800000,
+ OtherReserved2 = 0x01000000,
+ OtherReserved3 = 0x02000000,
+ OtherReserved4 = 0x04000000,
+ OtherReserved5 = 0x08000000,
+ OtherReserved6 = 0x10000000,
+ OtherReserved7 = 0x20000000,
+ OtherReserved8 = 0x40000000,
+ OtherReserved9 = 0x80000000,
+};
+
+// Platforms
+enum {
+ PlatformX11 = 0x01,
+ PlatformEmbedded = 0x02,
+ PlatformWindows = 0x04,
+ PlatformMac = 0x08
+};
+
+// LicenseSchema
+enum {
+ SupportedEvaluation = 0x01,
+ UnsupportedEvaluation = 0x02,
+ FullSourceEvaluation = 0x04,
+ FullCommercial = 0x08
+};
+
+// LicenseFeatures
+enum {
+ USCustomer = 0x01
+};
+
+#include <qdatetime.h>
+#include <qstring.h>
+
+/*
+ Decodes the \a licenseKey. This function returns true if 1) decoding
+ was successful and 2) the checksum matches, otherwise it returns false.
+*/
+bool decodeLicenseKey(const QString &licenseKey,
+ uint *products,
+ uint *platforms,
+ uint *licenseSchema,
+ uint *licenseFeatures,
+ uint *licenseID,
+ QDate *expiryDate);
+
+#endif
diff --git a/util/install/keygen/main.cpp b/util/install/keygen/main.cpp
new file mode 100644
index 0000000..b6eee41
--- /dev/null
+++ b/util/install/keygen/main.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qfile.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "keyinfo.h"
+
+static void printNewKey( uint features, const QDate& expiryDate )
+{
+ QFile in;
+ QFile out;
+ QString fn;
+ char block[10];
+
+ fn.sprintf( "next.%.2x", features );
+ in.setFileName( fn );
+ if ( !in.open(QFile::ReadOnly) )
+ return;
+ int ent = QString( in.readAll() ).toInt();
+ in.close();
+
+ fn.sprintf( "table.%.2x", features );
+ in.setFileName( fn );
+ if ( !in.open(QFile::ReadOnly) )
+ return;
+ in.seek( ent * 10 );
+ in.read( block, 9 );
+ block[9] = '\0';
+ in.close();
+
+ ent++;
+ if ( ent == (1 << NumRandomBits) )
+ ent = 1; // skip first entry
+
+ fn.sprintf( "next.%.2x", features );
+ out.setFileName( fn );
+ if ( !out.open(QFile::WriteOnly) )
+ return;
+ QString s = QString::number( ent ) + QChar( '\n' );
+ out.write( s.toLocal8Bit(), s.length() );
+ out.close();
+
+ if ( strlen(block) == 9 && block[4] == '-' )
+ printf( "%s%s\n", block, qPrintable(encodedExpiryDate(expiryDate)) );
+}
+
+static QString textForFeatures( uint features )
+{
+ QString text;
+
+ if ( (features & Feature_US) != 0 )
+ text += QString( " -us" );
+ if ( (features & Feature_Enterprise) != 0 )
+ text += QString( " -enterprise" );
+ if ( (features & Feature_Unix) != 0 )
+ text += QString( " -unix" );
+ if ( (features & Feature_Windows) != 0 )
+ text += QString( " -windows" );
+ if ( (features & Feature_Mac) != 0 )
+ text += QString( " -mac" );
+ if ( (features & Feature_Embedded) != 0 )
+ text += QString( " -embedded" );
+ if ( (features & Feature_Extra1) != 0 )
+ text += QString( " -extra1" );
+ if ( (features & Feature_Extra2) != 0 )
+ text += QString( " -extra2" );
+
+ text = text.trimmed();
+ if ( text.isEmpty() )
+ text = QString( "invalid key" );
+ return text;
+}
+
+static QString textForDate( const QDate& date )
+{
+ if ( date.isValid() ) {
+ return date.toString( Qt::ISODate );
+ } else {
+ return QString( "invalid date" );
+ }
+}
+
+static void reset()
+{
+ for ( uint features = 0; features < (1 << NumFeatures); features++ ) {
+ printf( "Resetting 'table.%.2x' and 'next.%.2x' (%s)\n", features,
+ features, qPrintable(textForFeatures(features)) );
+
+ QFile out;
+ QString fn;
+
+ fn.sprintf( "table.%.2x", features );
+ out.setFileName( fn );
+ if ( !out.open(QFile::WriteOnly) ) {
+ fprintf( stderr, "Cannot open '%s' for writing\n", qPrintable(fn) );
+ exit( EXIT_FAILURE );
+ }
+
+ for ( uint bits = 0; bits < (1 << NumRandomBits); bits++ ) {
+ QString k = keyForFeatures( features, bits ) + QChar( '\n' );
+ out.write( k.toLatin1(), k.length() );
+
+ /*
+ We check that the generated keys give access to the
+ correct feature sets. This accounts for most of the
+ processing time of the function.
+ */
+#if 1
+ if ( featuresForKey(k) != features ) {
+ fprintf( stderr, "Internal error in featuresForKey(\"%s\")\n",
+ qPrintable(k.trimmed()) );
+ exit( EXIT_FAILURE );
+ }
+ if ( (features & ~(Feature_US | Feature_Enterprise |
+ Feature_Unix)) == 0 ) {
+ if ( featuresForKeyOnUnix(k) != features ) {
+ fprintf( stderr,
+ "Internal error in featuresForKeyOnUnix(\"%s\")\n",
+ qPrintable(k.trimmed()) );
+ exit( EXIT_FAILURE );
+ }
+ }
+#endif
+ }
+ out.close();
+
+ fn.sprintf( "next.%.2x", features );
+ out.setFileName( fn );
+ if ( !out.open(QFile::WriteOnly) ) {
+ fprintf( stderr, "Cannot open '%s' for writing\n", qPrintable(fn) );
+ exit( EXIT_FAILURE );
+ }
+ out.write( "1\n", 2 ); // skip first key
+ out.close();
+ }
+}
+
+int main( int argc, char **argv )
+{
+ if ( argc == 1 || (strcmp(argv[1], "check") != 0 &&
+ strcmp(argv[1], "new") != 0 &&
+ strcmp(argv[1], "reset") != 0) ) {
+ fprintf( stderr, "Usage:\n"
+ " keygen check <key>\n"
+ " keygen new YYYY-MM-DD [-us] [-enterprise] [-unix]\n"
+ " [-windows] [-mac] [-embedded] [-extra1] [-extra2]\n"
+ " keygen reset\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ if ( strcmp(argv[1], "check") == 0 ) {
+ if ( argc != 3 ) {
+ fprintf( stderr, "Usage:\n"
+ " mkcode check <key>\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ QString key( argv[2] );
+
+ printf("Unix check: %s\n",
+ qPrintable(textForFeatures(featuresForKeyOnUnix(QString(argv[2])))));
+ printf("Full check: %s\n",
+ qPrintable(textForFeatures(featuresForKey(QString(argv[2])))));
+ if ( featuresForKey(QString(argv[2])) != 0 )
+ printf("Expiry date: %s\n",
+ qPrintable(textForDate(decodedExpiryDate(key.mid(9)))));
+ } else if ( strcmp(argv[1], "new") == 0 ) {
+ uint features = 0;
+
+ if ( argc < 3 ) {
+ fprintf( stderr, "Usage:\n"
+ " mkcode new YYYY-MM-DD [features]\n" );
+ exit( EXIT_FAILURE );
+ }
+
+ QDate expiryDate = QDate::fromString( QString(argv[2]), Qt::ISODate );
+ if ( !expiryDate.isValid() ) {
+ fprintf( stderr, "Date '%s' not in YYYY-MM-DD format\n", argv[2] );
+ exit( EXIT_FAILURE );
+ }
+
+ for ( int i = 3; i < argc; i++ ) {
+ if ( strcmp(argv[i], "-us") == 0 ) {
+ features |= Feature_US;
+ } else if ( strcmp(argv[i], "-enterprise") == 0 ) {
+ features |= Feature_Enterprise;
+ } else if ( strcmp(argv[i], "-unix") == 0 ) {
+ features |= Feature_Unix;
+ } else if ( strcmp(argv[i], "-windows") == 0 ) {
+ features |= Feature_Windows;
+ } else if ( strcmp(argv[i], "-mac") == 0 ) {
+ features |= Feature_Mac;
+ } else if ( strcmp(argv[i], "-embedded") == 0 ) {
+ features |= Feature_Embedded;
+ } else if ( strcmp(argv[i], "-extra1") == 0 ) {
+ features |= Feature_Extra1;
+ } else if ( strcmp(argv[i], "-extra2") == 0 ) {
+ features |= Feature_Extra2;
+ } else {
+ fprintf( stderr, "Unknown flag '%s'\n", argv[i] );
+ exit( EXIT_FAILURE );
+ }
+ }
+ printNewKey( features, expiryDate );
+ } else {
+ reset();
+ }
+ return 0;
+}
diff --git a/util/install/mac/licensedlg.ui b/util/install/mac/licensedlg.ui
new file mode 100644
index 0000000..a20bd44
--- /dev/null
+++ b/util/install/mac/licensedlg.ui
@@ -0,0 +1,134 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>LicenseDialog</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>LicenseDialog</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>582</width>
+ <height>531</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>License Agreement</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QTextView">
+ <property name="name">
+ <cstring>licenseText</cstring>
+ </property>
+ <property name="text">
+ <string>License text goes here</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name" stdset="0">
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonReject</cstring>
+ </property>
+ <property name="text">
+ <string>Reject</string>
+ </property>
+ <property name="accel">
+ <number>0</number>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonAccept</cstring>
+ </property>
+ <property name="text">
+ <string>Accept</string>
+ </property>
+ <property name="accel">
+ <number>0</number>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonReject</sender>
+ <signal>pressed()</signal>
+ <receiver>LicenseDialog</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>buttonAccept</sender>
+ <signal>clicked()</signal>
+ <receiver>LicenseDialog</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>buttonAccept</sender>
+ <signal>pressed()</signal>
+ <receiver>LicenseDialog</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/mac/licensedlgimpl.cpp b/util/install/mac/licensedlgimpl.cpp
new file mode 100644
index 0000000..ed2998a
--- /dev/null
+++ b/util/install/mac/licensedlgimpl.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "licensedlgimpl.h"
+#include <qfile.h>
+#include <qtextview.h>
+
+LicenseDialogImpl::LicenseDialogImpl( QWidget *parent )
+ : LicenseDialog( parent )
+{
+}
+
+bool LicenseDialogImpl::showLicense( bool licenseUs )
+{
+ QFile f;
+ QString path = "qt-mac-commercial-3.0.0.app/Contents/Qt/LICENSE";
+ if (licenseUs)
+ path.append( "-US" );
+ f.setName( path );
+ if ( !f.open( IO_ReadOnly ) )
+ return false;
+
+ QTextStream ts( &f );
+ licenseText->setText( ts.read() );
+ return true;
+}
+
+
diff --git a/util/install/mac/licensedlgimpl.h b/util/install/mac/licensedlgimpl.h
new file mode 100644
index 0000000..90f8809
--- /dev/null
+++ b/util/install/mac/licensedlgimpl.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef __LICENSEDLGIMPL_H__
+#define __LICENSEDLGIMPL_H__
+
+#include "licensedlg.h"
+
+class LicenseDialogImpl : public LicenseDialog
+{
+ Q_OBJECT
+
+public:
+ LicenseDialogImpl( QWidget* parent = 0 );
+ bool showLicense( bool licenseUs );
+};
+
+#endif /* __LICENSEDLGIMPL_H__ */
diff --git a/util/install/mac/mac.pro b/util/install/mac/mac.pro
new file mode 100644
index 0000000..ad13bea
--- /dev/null
+++ b/util/install/mac/mac.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+TARGET = unpackage
+mac:TARGET = qt-mac-commercial-3.0.0
+mac:RC_FILE = unpackage.icns
+HEADERS = unpackdlgimpl.h licensedlgimpl.h
+SOURCES = main.cpp unpackdlgimpl.cpp licensedlgimpl.cpp
+INTERFACES += unpackdlg.ui licensedlg.ui
+INCLUDEPATH += ../archive ../keygen
+CONFIG += qt
+unix:LIBS += -L$$QT_BUILD_TREE/util/install/archive -larq
+
diff --git a/util/install/mac/main.cpp b/util/install/mac/main.cpp
new file mode 100644
index 0000000..ede85a6
--- /dev/null
+++ b/util/install/mac/main.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "unpackdlgimpl.h"
+#include "qarchive.h"
+#include <qapplication.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+
+class ConsoleOutput : public QObject
+{
+ Q_OBJECT
+public:
+ ConsoleOutput() : QObject() { }
+ ~ConsoleOutput() { }
+public slots:
+ void updateProgress( const QString& str) { qDebug("%s", str.latin1()); }
+};
+#include "main.moc"
+
+static int usage(const char *argv0, const char *un=NULL) {
+ if(un)
+ fprintf(stderr, "Unknown command: %s\n", un);
+ else
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "%s [options] files...\n", argv0);
+
+ fprintf(stderr, "\nOptions:\n");
+ fprintf(stderr, " -k [k] : Use k as the key to open provided files\n");
+ fprintf(stderr, " -s : Quiet mode, will not output process\n");
+ fprintf(stderr, " -h : This help\n");
+ return 665;
+}
+
+int main( int argc, char** argv )
+{
+ QString key;
+ bool output = true;
+ QStringList files;
+ QApplication app( argc, argv );
+ for(int i = 1; i < argc; i++) {
+ //options
+ if(!strcmp(argv[i], "-s"))
+ output = false;
+ else if(!strcmp(argv[i], "-k"))
+ key = argv[++i];
+ else if(!strcmp(argv[i], "-h"))
+ return usage(argv[0]);
+ //files
+ else if(*(argv[i]) != '-')
+ files.append(argv[i]);
+ //unknown
+ else
+ return usage(argv[0], argv[i]);
+ }
+ if(!files.isEmpty()) {
+ QArchive archive;
+ ConsoleOutput out;
+ QObject::connect( &archive, SIGNAL( operationFeedback( const QString& ) ),
+ &out, SLOT( updateProgress( const QString& ) ) );
+ if(output)
+ archive.setVerbosity( QArchive::Destination | QArchive::Verbose );
+ for(QStringList::Iterator it = files.begin(); it != files.end(); ++it) {
+ archive.setPath( (*it) );
+ if( !archive.open( IO_ReadOnly ) ) {
+ qDebug("Failed to open input %s", (*it).latin1());
+ continue;
+ }
+ if(!archive.readArchive( QDir::currentDirPath(), key ))
+ qDebug("Failed to unpack %s", (*it).latin1());
+ archive.close();
+ }
+ } else {
+ UnpackDlgImpl dlg(key);
+ dlg.exec();
+ }
+ return 0;
+}
+
diff --git a/util/install/mac/unpackage.icns b/util/install/mac/unpackage.icns
new file mode 100644
index 0000000..20139b9
--- /dev/null
+++ b/util/install/mac/unpackage.icns
Binary files differ
diff --git a/util/install/mac/unpackdlg.ui b/util/install/mac/unpackdlg.ui
new file mode 100644
index 0000000..ba4898e
--- /dev/null
+++ b/util/install/mac/unpackdlg.ui
@@ -0,0 +1,330 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>UnpackDlg</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>UnpackDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>678</width>
+ <height>337</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Install unpacking tool</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout24</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel</cstring>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignAuto|AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout23</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>headerLabel</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Open Qt/CD Package</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout22</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout21</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout19</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>destLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Destination path:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer12</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>1</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>destPath</cstring>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>destButton</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout20</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>License Key:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer13</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>24</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>srcKey</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QTextView">
+ <property name="name">
+ <cstring>logOutput</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>unpackButton</cstring>
+ </property>
+ <property name="text">
+ <string>Unpack</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>cancelButton</cstring>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="30371">789cdd7c594f23cbb6e6fbf9155b27de8e5a716d8c01abd50f600633786286abfb105366da608cb10dc657fddf7bc51ac269a04e517b975abbbb5096fd919991b1e62122f98f7ffd71db6bfff1affff8c774666603f7872bcccb1ffff2f3d1e8fd3fffeb7ffdf73ffe59ad54fe88c7d646e58f8d7ffe8f7ffc53cdff707fa80afe43dc4f782762a30457f1bc394b18cfab19e34dbebf9730ddff2e98eeb72b4cf74f19efd0fdd6248ce77d5730df5f3076747d6811aef2fc3d3fbfcaf3b123c43b429f794a98e6f72898c7cf12a6f97519f378669430ddaf05f3fd2a61babfc398e9332661ba7f2998ef6f244cf4df0bdea0f33963a6df0e13a6f17605d378be92309ecf64fe8ec653fc3ce15fe8264ce38d198b7c5f18333de18cb1cce736e26a925fa831e6f3d95ec278de6ac134df704f58e6935f0ba6f3ee2561baff5c30d1631e18f37cf384f9fe5dc63c7f25f7f3fc4c9bf0063fdf0e180bfd743ed16b4e09cbf5ca3296eb0d63799e62ccf717680f1b69fcbc9730c9eb5630db5f83318f97df244cfab2c758e4b1245c93f9bd32e6e76533c63c9ea7f934d2f58eb15c7f9f30e9478db1e8f73963b14f7a5e6393c7731b11d7aae9fa2163996f3f611aff96b0dcaf7cc278de7519cbfc91dfb586dcef2784e5fe2c4b18cf177b8299bf0bc64caf9b264cf67c2698ae57323e3fdf2d13a6f9cbf8c28f9384c93e503f37abc25ff3cc58c6d38465bce25030db4b9b318faf2e1226fa2f05b37fb9215c677ee846c244df1be33af3eb4130dd5ff0fcea0dd63ff4a79b46e6af34639e8fa3f99a3af3d7e78cebec8f9a8c793c95254cf2ed0866fb1d11deaa32fde8bfeb1b222f7b40b8eed97eee046f3470fea784b7aa3cfebd60a66f91309d7f124cfea5088c991fe199313f2f3f466c923ce8fa447f7e4578ab5aabe2f88e318f674e12a6f17605d3f39d67ccfc513b8299bf4a305d9f3f32e6f915fb82f9fa8b84495f3a82f9fe82f036f3c7d884c9fff604d3f5d99c31cfdf22ffb622bf895f0709d3f3d279a6f79031df1f3619376a28bf7cc998e71b2e05f3f3657c4fd79b09e134df8560be7e85f1fac0e36fb33cec3861badf0a667d183166fdcd0682999f7dc1cc4f94d7569257a810deaed27cb30ee33acd27ef0a267db1778c797cbd2d98c6f7af09d3787dc1747fd64d18cfab0563d607fb9030f1775f308d1f2e12267eed08e6f15b8477449efb82597ff1feed9ae89f191016f9e81dc6cc6fffc058ec792998edf55130c7ff3bc2f2bc6012c6f9fa53c1345fb3c198e5998784897fcf82f9fa2663e66f2ef7337f3deacbb615f9e409f3f89631cfd70f09efb07db93bc1ac9f26619acf89e04d7c5ede66ccf32d0ac63c1fbbcb58f8f396305eef2682e9fa624ab8c1f2c85e04d3f5f655305d1fd0de776a22ff901396f9fbbb8489ff4782999f3b8c99ff99dccffcf655c144af4dd76f1a9caf8cc7fc0e0973be7c4138cdff50308f7fc258ec6b9f31cb571582f97c3761a207ed6fc726fadf0927fd538c79fcec5430d1137a09233de1867183ce671b09e3f9ec9c31dba7ca05337d6f82e97e759a30deef7705d7b1fecb1e090b3f4c9f31d39b6f3266fad43861d2b71661c3fc35178299bf3709d3f58e31f3a358264cfc467b83f4899f5f78c6a2af81b03ccfdf32167db109133f268299dfe709233f6c87b161792e04d3f9fc8471e0e769c1747d1809a6f1dd3161bbc1f16e2298ed7f85e9fe5dc1ccdf47c65b9ccf5e274cfe50c6dfe27c82e76f0d3f6f2b61b2df84e9fa8cf8e7c41ecc0d63d68f6c4ad8883fda13ccf6dc14ccfabe4818c7d35b82693c2798e3697ecf98f96d3a8c997f393f5ff851d88469fcba60f607b384c91f9c31667e8553c11c2f2682891e7d2198e7e304b3fd1c3166fe9aed84299f7a124ce3eb56c2943fee0be6e79d0ba6e7b903c681f3f1b784291e2e05f3f8bb09537d91eee7f8ba9d308d5f25ec581ff553c2347e5330d733370913ffe47ad647779d30c5b7b960be5f9e27fa87f1c26c8abf7433c2a23ff65930f9a3d04998ecafce98edd96f3236ac2f2f8c597fc21be1646f23c12ccf9384493f9560f687d78c591fc28660badf5f254cfe54c6dfa2fb2dcf4ff4c1e582391e68c1accf321ed3139a09533c180ae6f9ed30667df13e61f20f9960ce2f5dc224cf3bc13c9f743fe98bee09667e0f0433fd8709e3fc4c9570d2af79c2a45f23c1acbfd384e9fc9160b68f76c2c4ff743dfbf715a6f3db82997f45c2383f2df363fdd579c2f47c2598e7e712a6f30bc1ccaf9784499fdf0573bc64fe3bf617fa24611a6f28989f374998e2f9bd60ce876a8c59deea3661b2bf9660d6b746c2647f581f1927f1d1927c92ffcc170993bd9d0b26fb53ef8c99beec4a30eb7f4d305def041b8e0fb70953fc6f0b66fdae0a66fd3e4b98e27385b1c487ad84e9f9424fa0fb0be27ff267619630f1e34830e7871b09533ebf2d98e3f1306192f75830ebdb0ad37cde04d37c8ccc87f5cdbd0a6679bd254cf2ac08e67cbd9e30c5a7749ee6a7bb0953feb414ccf9c8ad609a8f67fe893eaa03c1ac8f0f09537ce909e67e712b61f217f78259bf9a09d37cae04d37cf44dc2649fc78cc57f05c1cc9fab8469be323ff657f99e60eea76c264cfac6fcf6ec8f544530c7e71bc19cdfa17ddb941f1686b0f87ff79830e97b8f31d3afb61326ff742598ef3f12ccfafe9630f9537ebef85f35104cd7ab4dc2e25fb34230fb9f61c2c41f2f98f3a5c098fda1bd4a98f44f09e67cad9630e53b5dc1dcff90e7b1feb9b9608e17fb09933dcb7cc43f1e244cf2d910ccfab897303d7f2c98fd914b98eca32598f9bdc224af07c1ccffe384e97c9db1c4d7f384c91e847fac9fc52c61ea0f3d0ae678b69130f1c70ae67a2b4f98e63f15ccfeee2c61cacf593e9ee36d3e4898e6772598e3e546c2d43f60fa3cfb138ffec27ad14f7bcd38b03e1e0bde227eed124efef34530fbc346c2144faa82d93f7704d378f96dc2e43feb8c59ffb271c294bf5c0be6783c4898fc515f30e7579782b99e3e14ccf9da5430cd47a5eb693ec51b63d657b59f30d99f16ccfdac79c2a40f35c1eccf3705b37c9b0993fe9d32967ae03561ca1f841f520fbc244ce7df05b3fe9d254cfe2017ccfeba2598f3efc38449fe5b8445df7425617a9e17ccf30909933def09e6fa649130e9df8e60f65f078c255f2b12a6e76582b9de68264cfe4b0b667f83f1c9d545dfb21bc6e2bf2f05b33e9a84c9deb61973bcb32782b93e550993bf7e12cccf3f12ccfa9f274cfa95c6a3e7bb016396afad274cf1aa10ccf1789430c59b3dc1ec5f2e1326fb9f08667b6f274cf27e15ccf9cb7dc234df343fe65743f0760dcfcf098bbeb8938469fe6782595f6cc224df8160b697a384c97fb60573fed34998ecfd5030e71bd70993bc8d60a24f6f0a66fd784f98e8ed31667d34d709d37c653cd6c7fe2c613aff2898eb519730e9d3a960b6c7b384c95ed378ec5fb384293fdf124cf4e4321efb2bdf4e98e6b32f98eda796309d7f16ccfe238dc7fd50a19ff53d7f154cf32b8e0573be72c798f5d9cc1226ff89fec3adfc4f5f30cbc3264cf181f897fc85ad264cfa9109667fdf10ccf5c4b6601e7f9830c9fb4030e973088c25ffd182b93eab08e678db4a98e623e38bfc6cc2444f2198edad9b30c9f75830cdd79f254cfe49e89778b32798ede730619acfb360b69fbb8429fff082397f6a264cf97a4d30d713070913ff7605733c95e74b3edf4f98f46d2698fb8b8d8469be3b82d9bfcaf8e2bfb612267e907ec3edecefb0bfe7933fc813a6f986bae01d9477fece98e553bc0866fa9a82595f1e0493be646dc13b16714f706313e77bcc58facb7dc12cff4230f1cfba8469bee97e7a5efe96303e4f093decfffd4c30dbc366c224cf5bc1f47c5711ccf6f64c38883fde17ccfafb2898f5f14930cf4fee97fa09f3691f84defc5270c321be232ce3db4bc17cfd91601abf3fd34a1badfeeca7b6dac1f1f1f36707dd5b3afeea3c50164afbdf7c846f1cf1ba4ce770fca6e7525cfccb3cc94b47fa3d9eb33f91e96f9249fcfc2d72c97581fc2d1ff4fbdf2def9fcae577f024c9c17c3ecae759562bbb1968f73b9eff1bede5a31df84f32fad1f5ae74cfdfc15e4abee947b2e1e3935dfdedece56b1ff599df24a7e2837dfdddec65283e0b3e1ff4236ace28da027eb7681378c4dfc3e7283e9d3f1ffe66f6e2f5931ec3cca22ce4f311a87ad613b689917e81c3027ed6d3f81da90e7ceddfc75e6630434fb3433cd673b48348e1ab7ec3dfd1aca3df5ac031d5ef48d192a9fa3bd98b476d899a3644cba6dfcd35c598b7282bd4b017bdabf79092056b6213cefd8dec05789feb7da022cefa000ecec970f616671ced66a10ff51150d142b944998cf1bee3dfe5cb7e8b5c4e60462738a338eb5398f1996eeb8eeec2ec7bbaafcfe1b8d097fa4a5feb1b7d0bbfbfd3f72897785fe577f9b2df622ffbba0a335260d51bba0633ddd475bda5b7f58e6e28ad9432cac26194535e0595a95c156aa086fa4e81f5abc7ffabf18562b7c4ef726c9798f1aa976aa4bbea498dd5b39ac0ac5fd454cdf098a979e988bf9bc2d957f5a616ea5d2dd5ae3e52d186c287677cf46f3ff577dfb11778c2091c43d564dda71c6aa4f6d5813a54477aac5aea589da85375a6da30db0ece79a6bafcd9537d38e678ac288ac7b9bad0dbea525da96b75a35fd5adbad34f30f654eda97ba0700972ab94ea2255ce2dfe84bd60ac56d5c833a1466d002535fda636e1b3aeb6d4b6da01593460f6f338b85130fb3eccba7cccf1137fe07ccf18a42ad2a38c35ce78bd3001bcb8070fff883ecf81d62a93e9efe414dfb517960b5343779a181b4c6e0a5d370333340f2403a4e4118e11ccb49b6413bfa34ccc53a4847fb4c8c88ccdb399981733057b6b452a805371c631875896e5f117ed252bd90b1d2706ee34733534afe6cd2c505f70e6c86b91c3ec8b036563de8916f8a6cdc82ccd2e52f462f64c13e4b36f0ed05bc7383506591dfe8a1ffb99bd4459c801387ad13773645ae6d89c9853a06004735ac2ff239e6dd4b4b25cc45e84a2a865ac89789c01654b944f5bef988ee9aa163c1ba85107fad1f47e947bffb9f892342b03ef5ba82373a896a6af1b668c1cc5d9e00c4dc96fad66bfb29fd5b9deca76e02752f30ebf07eb31e7e6c25c9a2b98e113cc70887941f69dbcfa3bf6122d5e6462aee1730094dc80ad47ddea1a93ac7d8e728832e927bbd125fb50289fbed9859f25caa7079f4857f4064cfdd4dc9a3b736f2a603773736daa5fd53c7fd25ec47f88dd0c74d76c40f48b966cd8024630ab51b215f155fd0f3f2b5bead12752326759aeec6c666a60399ba60e165f355b9f7a09f9a7f97d3fbe440f1933156fb6cd11c864c734924f026aac260aac688b42ea66e2bb30de4cd9cf81fb055b5fd1d7b3265d471c204fddb6d63ad5b21ef3b5396a9bd14f36fc457b89f12466816f68271bca20254bd479b48028934883cdc04769f9ad9adadc16aa61dacada0148f25c35387ac28f1db2cdf430d64ca3ada1762ae4d05439fb602eeda32ddb6d8d8ebf908f3d42461f7d4ad4ae1ba6e4294a0564429ad5b3620fa8253607ffe6ec931ddb673bb12fc6d9a99dd9b97db56f76616a4015c9a967dfc9ee8d66fbd1384e0fa95dda5d885f475cd5c5fae74162cc47dff66d7b79b37bb12eb44dbb0f163fa3d89e62f99cf88bf612e7d780391cd8437b645bf6580ded896e8307afdb537d6fcf74d7b66dc7766dcff6416630963d8f1187c763ef069862e8d05ed84ba02670f6142bba55bd937f96cbcfecc55ec108efa662afed0df033ca44a34c6e55274615e0e4083406754a4dec9dbdb7155bb51bb666376d5d3f002762351cabe8784ced9699da6d90d70ee46fe7e4b36d2346a8e401a2d67560b4a903057706a889d967ac8106a6f7b117fd4bf632b457ceea6be7209ecc536c8fb1503c30ccc216a611d7df5ce67257c08ceb7ae40668b5944f57b0ff7282f8c51cb8a17b708f6e14a36d1c0dc6eda16f331c69e7400b48d93db9b17bc67a7481f9f473c977adf5dfbe155f208b50c76e824fed925f8a76021683f6e25ee273ddd4cddcdc1e47db72affd191eb1c68cd573dea75ecd10e354cced82ba710bf76e5ba6e3966e173517e502f18af30763306b38777bfade35dd3ed4a447585d7fd187fb81bdace7a040b73b5075c82c16e82b3bc94ae66c231da4e4d01db996adb96377e20edca99ebb33d4ed68b1f3943bc4fa3e56d219c6f337d554f7ae0dd474d0766664779441a36f1c459fe8baae67725b03d9bc60b5fdb1b6ca3fdb0b1e94933eb87e9c01f8ae421dd8ba3b77179839aeb214e05ab49b2813c87227ee522df5a17b5bd365a93b629efdecae8092a1de77d7b15ae8cfb8fb3a7637a0bdb7ee2e5203f9c03bc7a6197be8c7c84177ef2a2013b07ae0d0c3daf8d917f6427ac7311ecfbee293ab1021eb6adb6dc47c9e231965f0e2c71ac6ba9adb3447d88d7883fb3efa981357d74f989d6ec0358faae5b6dcb6dbd1bbaae91afa006475e68171187d7a6b791be70bde78eb9df7baa20e809a3c1e31eeadd5a25fc9c521f67aae6a3ee8579f9942ed407d12a3631fe36017eb14f2c01d9fdba9db744db04abfaec3c9de6af0f43ec8057c982ffcc00fcdb97fd057ba03b50a7a5875e31ffdc83fb1a6f5487b25af032ddbf56337078f32f2cfd47beb539f54f2c4757b59e95d406b7d420d83ac01f85dc7a8d2659e75390644ad9efa897ff150d1629f0b3b4bcc89728f1fb20f5581dfeffa999ffb57ec059c5bebdfa0d66fd93d770df71de96bbf70cb186739cef456725133ffee97906d0e40c324beacf2c47f2317b86292f0a369f95d947e47ea77ce8b418ffd9e6ffa7d7dc8bd2eeef2f178abdc76df1d80262dfc813ff4471851a217797177eec1b7fcb1aef80079560b6473e2f7906b7db61b3c50171afed49f41b63976afe5f59b28971fd80bd1dbc4fe6306b20990ddb521a249cdd8e17ae5318e0f1ab1035eb806a3beeadcb7c1b65eb93f1c3ef4f35fc13676fd9befc48a2766291e46f43ddfd757ae0d9ca8b8aa3f572d90cd05663752ddb06ca2c7f197fe0a28bfc67cccb2adacf56b3eca85fdcb84fac2a607fa7d13bd3f669233ae4f204d8cb49885bfd5b7661be24995ebcd917e4e7139875a872263ec9dd56026775126d6f87ba0a50299c254195f051fd65637a0655011fb0d5f3398aba1ec4729e644cfd6f69ba02375b47ea2866a5e27f9d95a7c117b71c8570ffc3a055b78c6917bab5e0a771d1af6ce0d21b69ff82d8ce9867b282f3c56116b501ef35d5ff96db013a024d53694dbbfd80568da0e7021cab6114015b87f20754e4fea9a604015dd9a0ffb54bf7c8aa3312fae20ed6dbda926907529e9ad48561eadd1de071fc2aaee13df82b5fabe3e8e72018d7021b39590636cefa53c9fabaea8a9ee2e146e07e45bd10f611086e101ad739ee2ff0873804e78f4fb9019e51885b98e11b994ec25acc518879960fc7e1646d187a56cbe97783a855cb8e20ab0c44ac967d138735d094f668becc7b5c3d82ed0e2a977b694aa2cc65ea4c886e710d76580dfe1c56c3acc2ab99f26fd9b1ed6002f7aea4e308f18fd582ea2e3bcb2e0c8a785a9de420fba92c923ca680e75dfa1ad8659085fac41eeebaa6f433d089484cc8dc31c2999c6f824b5096792317e4c6d115ec31b64afc04de3752f2c4c1b3d739f7d18710146b1d16752a6bada37f0d15e42d2f1f87d17b48c74b2e3fba8bdc29f3e575c51c38eec86b6ee15f5777d0df2186af413ec06dec1ccded1a3a74a9a7361c98d63e6d50ecbb0abcf30568cc25e68725f64955bcca94b13f621c68c29bf13fb4e3d22918bec4f21dec61a215e39801c6b0746eda69e17c9e509463d0887e08d69edd1acc513f202d10b6f8571a078b2aa4b34e5c258ffe8c8f3d0b26ffa1c72805dd4fb03530fc75827cd52a48cf97f23d20279d9d0676cfdd223fa185f5672c9d15e9e5d5c8570fa309cacf5ea492e9017db853d0ea7509f288ec3ebebf96390ed9d3f349370861e76c4d9e8aada22cb9e9953bbf0037b165ef400b21cef6277af65261fe4d2a72810da6e6ce6b4729b8eec47f60287c3fa3aae750d744fe9558715e3f163d4319b878e1b834f99637d62573a8bf6f6a8a721f383701429095dee6f18d632d219ccb3cc69e8f937a89e15f790632c72c0fb138ca95ce5518f07fe9f9a5ae8bbc8ede8cbe479c32fea9750f663c09f0cb2c53e752a520f92e5a21ae1dc9eb8377706b9ebf843fc0dfa28ecf9c37011bd46e8a2adcf57f2e0efd12f15e112b470007695e926f67ab0e60cd370156351eaf3cc531c005b0ad72897951ffbaaae74124bd977cff500bed8d298e2913ba66d8e751beaf89c471baa1a64a2b462a7205778f347d89f8db5dbaa53f4245dc068296e37dc845bb0b9f8ec26e8fd84c601ca0ef59569f3733b29fb47efed2ec31dead000e79a7faa5f441ed3241bf2110b7d6907eb7acb5e32ae971c81740bc871e15a7f4ef527d62eefb692e2c988fd955af531639f42f5c37da884aaadc62e2bd635919a3713ab35d050b389b4248fac648dc0860d35c28a2ce6e68a7de75772615a396b8ffb262e14adf890a58a5c80163b05ef48757cd4f327904b0572e1a52ff455c8a91f917afd7d96498f7a9d51f7432d6c86ba83fc0ae49f61a536d1e3b015edc61c85ed923ecc1225605fe638468275b9acd98be4612297b8badd8c7a6f5fd85ee66b7201fee8d8ef7a028d8add8809d4ed077165cef8b01176205b99829dee52fe51f65da9d3ba5473b76b17a1117ca6dd75a6dcb5012b06b92cd51ef8b44b940bd9a9746823771aba0e7975e4f49473f12fea17c9a522addce574516fb10a5bb37efc3cb7737d1f7d9dd4ed99864aebc0bf6506b36a8331fec92ce3ac4526b246063876d267e6c12e329b454f53852a3aae50417e0eb1edda76504729779ba57c3946e829cbc5fec05ec4ffb8642f16f7af1c41ede2d7ec85bec7dee4ab3d83da9ef28421e8fbd4ec43a5c573b0641bd2fbef97ee979e7e0fbd024497ccab56d452b2393d527ba69285d0c23ae99db8881519dc9d65901390bda8926d7f968b4bb4e2dea1e0f4bb7b5081abafa7922f03bd8358dd056f7c021a36027e36a3efcaf2e849e37a0c75c8b9472c3e6cae646d997cfb082bbb76b8cc0a15fbc5b1eb01f9023cb7930d62af9cf3a555be305517d990fc5869cdeeabfa6525972718d9417cddd5b7d90366aca9eec6181cabbc8e6deb26f820a01c7cd93344c60baab4b86fdfe3da6396a2c3aabfd251abd5898e2dcc4656e87bf44b316f18b8b1da89fd25be66657553d7710f1c5fcaf5d65775a54d7e6c14d75c60f46ef6489911d65f31f3884f889588331dd7a44a1a34e4de0f5126ef19d5e71df263e493b15b2c729aa7be1755da5dccc8c6d91368d61862d4abe9857eacfa639f9a7433c5ff69f69c4df451796fed0fea7d5fb21792d1d29e652f54a1336f7b69d5e5458d6d136b4888d9d934c3d5225ecb33680b86b57cce1e6dc9155869ed2c5597e7d91c624aecb32ccd912a40c273a99295746566669cbd8266bfa3bdacf5f3d6e3cb87ded824f62ea1deaf676f7609baab793dbec73d32f0b9d9227b87ba33a0576e674bf0a253dff515f23d7668a81ad6e4b1c23df2b7875c794c3d96b9f428d5b9996443d0835d37771750d38c582fbbc88579b617bd58d8f04558ed39a73ecc677b29d7d04ddc21528b39ab9f664deebeaed61fe77185c2f6ed04eafddd787d063eccda2841388319b1352c8ba853e350c90e541b65d043cdfab0fe8ff9e73968da21d84303fb4a587db15ce2d51de0df5bb0196958d956febd5ce27e87107517e47397b5386b2f5113addf1676273b768bd879028a3aee363b092d8c92185da43e518dec343bcbda5927eecd40aee8b49eb9ea81c61d3f8dac9bf5b27e94a1ea82bd3c81749eb8dee982269c6717e0911e925c065ff4c7a4672972910a0b6a18d5ca2ed38a0279d7a5e4b9ea2cbb72efd8bb0fba65b7dc83b5907b507f4b6ac653d0c56b5b75adec06b2b4f65ac495b57ed65ad0a4dbec2ebb4fde4e5610694de6d4df6615b39d5591eb71be94937d5cafcccb7d798e3539d4ec55fde2c6fe926c99b30feca5609d77ee46b615ed4ac5cab565cf20d3bfc1fc784e76a26cb611c6b1fef475bb9159a4a6c375ea6a5502e41c3f2daf21dbf89dd7a171ad3a7eeff84bbb1d3b4aa02f2bb92c3ef593cbbde4d551c96a66cb5f679b5907fd8ae1ce03ae609977177d703be647591db2ca273dcbb6eca9bb858ab340df14b5700111745b2b739ded649048678d70b956a74aff6b1ebd0266d0144f9e56392073a5611739a457b1f64c75ac43b97c692f5fadd1c2f7766ec01aa7e099240e477fcbeb24666167fa1ad74162edd2f43bee36b77600740c2037b8ca1ddb2079d0fbdce741d68dd2ea395394728bd5aa2e69d83b543b4bdbd135ea11c5fe9bb9ce33ac81eda7fed8bfdb0bb3e7e6507f377005ff4cc9ea1b652173f3e03a61accf621755dd466af2dc1fe64578cd0b7de176f4301f60cd18f3ad984fdce7431b57fa67f9431c09d76ce71f7e66bc262d786a8bfc517720371ee37e67de97f355dcffc97aa5f3ad7c943fc59eb239438f3ac79c8b346266f37c6c3bfe512f6c8027eceb51fe9c4ff2977c9acf207b1fc7da249f47bd066a9af9ab6de66f26faef6959db64f6a55ee58c8fe819cff385b9d2afae1afba0e5b5b75fdc0f6383cbdff325ae26d18e84954fa3194cf35d3f024ddbc5950bf035fa31df833a6317f78a7bcc748690819e00356f20e7f7bc692631b67247efa35c5639f99cc7dfb7d15756f3038c00e26fffc4fa3e2866dd2f9d46be3d96e2367a68dcfb31ce0ffd223f522d3d7655ebb16e1f415d72e5fa9cad56f29699e1ea858218719f0d7d1fb3a325f6db3ec946aaebf89bfc383ff10d57cd4fb117baaa5dfec4fabedf32f3fc2c6fa7ae9d64f39c57c55cd316609daffadae4b8feeeb1e68c4f8b1d9f937c90774026201f57c59a27f65a1a7937ef7177f58b1fee6dcea0fe9ce833983dad1b0cd7d6773ed52f3f5bdf071b98e7fdec5aeff09a56bfbc36127d90c5d565bfe73bf979d0612fee61716fdaab235ac1cd5b489d41b9c41ed8c86ce617f9657e8571eb0b7b419b8433f9757e93df86a95404257bc97fdd5edc993b7067603377f9bda9513ce6b58719c750ac35719744ecc6297f05b54d17eabf297618e23a7e8d570e21f7d683bc12776ee5d5bccb31fe4b4b61aaa05acb376c3b4cf31aae70ad7a969fde79fae67efe870c94df17f9a69f8864d866651db3c73a1ebd9376f7793ddfb2ceb55c966fd37b30aa15ac6dbaa16965d6f4f31dbf0779d78c7a66dca3e5ff45e6c96e629c6ca865cc1fb06f67535cc9b11a34dfb7173d2d347c8ef34aa1cc5d5ce9a748873b2464ef7479271b3c5d5933b437766c0f0b53d8b8a73ff7852b7c5e140122efb9dc93fce267c994f69a9b36d4b147660a5ee309bc89f48c547acfe9dbf1450fb2a3108a4c5b0741ab2828a78abb7153964879f43b579f1df4b610e1a0fe7d80cc14324e13a93bc5a88254f07e1aea03947b2df33599509c891c3bcf16c5c0e4295f5cbdff97ff4a7cc92b51ba50cb8174a192857cd7d3feaeceaa5faf569dc08f3d97d52751bd4499aa5437764be70c57f6eb72e96176709e0db289e9adadef97d7bfbfb7df12ac1577509df9cccc8b61f1503cc60c4d7520475baed6e1d3a1a973b1c220b1f7555d2c14a34c70df56c956cc67b9c40a0f57fd4c3102aeaef6c39472c8efda4bf1640edd1ba4a5afd8d7b7c5389bd85d3354ab370f64cd57e423bb3ffac98ed6f6c2727642f5c957d1fed39e73c84741678be762f2e3f72fbe135fc02bbfe94198e18ade89aeda601f8b177b01c1f701ede691a36757a5fdc93273a89687f0437d8c1eea3ef668d25adb135fc7ab4df9f5ca76d6fa01408d392fa621d3cbd27af52fc7976266afccb68dd1ead5548b79f15abc4134bcb5b3624135e79a5c64c5a4b4237e8dc7e2f7a45b245dc0598cf1c53bbe75f2c18f41ec2fecd2765d139ebbeae5add6e3be6f2feb07af69066f5e6dc5edb92e76034b3ba4d63cacac3ab0ccb8e2ed49bdc2fe2feee19de6c77692df1605afdca4ddbfe0e121532e96c56eecfbb8abd2bcd6d6afbff9bed8873ddbd8c11ee823b793efe5c322147bf8ce08e51dbd354ad67a2ed8555a96282699a1fee4fbf9893e0bdeb66d0f3ba043eccecca21f377be602df9c1bf3be832fdf77feeefb626bc718fb9a0bc82a5aa0bfdda2e9ad1fbb0d7e07866a68b8d036e0476a51a62cfe1e7e4cb60776d3c1cca7e196c57ebeb04ddf88556f981607be1375379e233afd4d7e84fbfb2771cfc5c7daf717e2cbea28d70bf89661dc03696b7925abb87161fc6b71684eb19335fb20978fbe8adf1b330d7f691750fd76a0d28a6ba49043e73575658f7c07f7484c43cb2efd8d3e044af64a7bc6bf7a9fecdbef579679c1fb8da75071c5aea9cba02cd01093ad0bd5bcee5fc3a35de2cef0cf6fbf51be36552fa696358ba3a265b78b634dbbb6a03e811a3ed30fb666a6c5897d500a65728276f2cefb6c3cf661d6de49ff95f8f28907f8562eee9d7cc1b7d30edc89f7902bb57dcbb4f2bedfb72f763fec17a7a16d6a10552de62f0dbf9765eac27582c95ec3866b9a695681fc5bc55c1a2aad83ac1673ab980b63b5362946104fa6d177018e32996325365e9b4fbe2e979fda4be96f8cd0de08de0bfe8c3dc4d81f3bf0cff6d1d68b335ff719e408d3a8156ea896a15fb4dd65d8283af9c84ef3ad6ce81eec76dc091fee62050db1eb153e1f78a6588fe2f717bd28ba6e1fbd70c03d0443f23af4fed89fb4972ffe860856c0633d51b8a21d77a7d13a7ffc1ebd2444d4b8b30d321e9787eb70a74676c3b5ed861a853b5b8bab54402d7720788d4bdebec6bd9eb8a3788cbb8097f15335b1371af7342fb97bbfeecbbe1f5f3efcfd971ffa384b33e3fd2ab2cf6b547a3772fdefc394df975cffbdfba0176bf7fd689ebf602f3ffefb2eb8a383726afc8cbc9d970ea1eed367ead9afafa5acf759fedddfc658c3bff43ef217b259eb8508ef429a256910bdb35fbeaf1caf655fe62aa7b069afc1577f0ba8ac2b097f3bbee45fcac77f88bbab73eb7f2b21603f7efae93e1977d5835cf556567b3ecbfb6cdc9a4e7c8a31dfccc7f28fb25993cb0ffe46d257f1794d8683d55e8f8fcff918db4a357e19af8dfb4db9145ff0bf2cb3affe3eccc7fb0b5d5e4f7022aff535948fbee9836d7c96c9afd5fbf1f3447f5ea359f1245b7b3756d610e327fdd588d21bc072be7c7cf25bf4bc75b9969e9be402d7153decf7ff8abdacf3f48b7764b42af9a2c873c76fedacbfcffc950c3ffba7b2dd7c96fd4a4e701d50b22697efe6c8bf92b77dd4f9ef9effd1f3beb4a1b2effb7e7cf97fe2f84d7f7fec6ff1f9ff955cfef7fffcc7ff011f3a1368</data>
+ </image>
+ <image name="image1">
+ <data format="XPM.GZ" length="1085">789c5dd0cd6ee2301000e03b4f11911b5ad1189290a8da0324a5e90f29941e2aadf6e0d84ea10d1020849ad5befb7a3cceaa29e2e06f663c33ce55cf7a9dcfacde55e758d16acd2cb6a207abc74f9b8dfcf5fbe79f4e97f896fabb8145ba3f3addbec5ac74b715704ed5d9769c01cb73e0423368f80224c190e53e70091c389e83d98366e83942679f0c43cc7e0087c4f3307b63c8b1d559337459c6810f48df137aab49436c750f748917320f78418e4cf65993fa04b33572c4313b067a039f333de80e39e238680ff4d5d2581c69d2c0c3ad8e0db1f30619127cd1dcd00c7a4452824c80a321359d73cd8c129c1b1b0acc726030a414b31299f9989d1952a4d0ccc23073819f861c973c2133d3b904aacf6ceeda9a8c12bc5b219929de21f9005900a99bf9f8e9a8a159728a5477f5d77847367719305373b1788b14668d4c9337d95b2437ef5d03b9c84df10a28fc866fc05c9522fbf0b369c6b8d0c7ffb1fc6db57effb0bfc68acd7657ee0fedba63599dea73d18a7dca525ec6ed3aa16293a81d2bf232beb1bfc578d58a416731ad641da95381b1e3f496ca939432c9f3bb7b8c450f8fb39994b18c93493a36fda2a7b9aa8ae3e4b278b69b192aa822499dc2d6cddc68b94ff697f46c7fdd255ad6f5e2dbdbfac7c3cbd8ecf7f7baf30f538f0154</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>UnpackDlg</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>destButton</sender>
+ <signal>clicked()</signal>
+ <receiver>UnpackDlg</receiver>
+ <slot>clickedDestButton()</slot>
+ </connection>
+ <connection>
+ <sender>unpackButton</sender>
+ <signal>clicked()</signal>
+ <receiver>UnpackDlg</receiver>
+ <slot>clickedUnpack()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot>clickedDestButton()</slot>
+ <slot>clickedUnpack()</slot>
+ <slot>destroy()</slot>
+ <slot>init()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/mac/unpackdlgimpl.cpp b/util/install/mac/unpackdlgimpl.cpp
new file mode 100644
index 0000000..5538f4d
--- /dev/null
+++ b/util/install/mac/unpackdlgimpl.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "unpackdlgimpl.h"
+#include "licensedlgimpl.h"
+#include "keyinfo.h"
+#include <qdir.h>
+#include <qfiledialog.h>
+#include <qlineedit.h>
+#include <qtextview.h>
+#include <qpushbutton.h>
+#include <qarchive.h>
+#include <qmessagebox.h>
+#include <qregexp.h>
+#include <qapplication.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+UnpackDlgImpl::UnpackDlgImpl( QString key, QWidget* pParent, const char* pName, WindowFlags f ) :
+ UnpackDlg( pParent, pName, f )
+{
+ destPath->setText( QDir::currentDirPath() );
+ if(!key.isNull()) {
+ srcKey->setText(key);
+ } else if(QFile::exists( QDir::homeDirPath() + "/.qt-license")) {
+ QFile lic( QDir::homeDirPath() + "/.qt-license");
+ if( lic.open( IO_ReadOnly ) ) {
+ QString buffer;
+ while( lic.readLine( buffer, 1024 ) != -1 ) {
+ if( buffer[ 0 ] != '#' ) {
+ QStringList components = QStringList::split( '=', buffer );
+ QStringList::Iterator it = components.begin();
+ QString key = (*it++).stripWhiteSpace().replace( QRegExp( QString( "\"" ) ), QString() );
+ if(key.upper() == "LICENSEKEY") {
+ QString value = (*it++).stripWhiteSpace().replace( QRegExp( QString( "\"" ) ), QString() );
+ srcKey->setText(value);
+ }
+ }
+ }
+ lic.close();
+ }
+ }
+ connect( srcKey, SIGNAL( textChanged( const QString& ) ), this, SLOT( licenseKeyChanged() ) );
+ licenseKeyChanged();
+ logOutput->setWordWrap( QTextView::WidgetWidth );
+ logOutput->setWrapPolicy( QTextView::Anywhere );
+}
+
+void UnpackDlgImpl::clickedDestButton()
+{
+ QString dest = QFileDialog::getExistingDirectory( destPath->text(), this, NULL, "Select destination directory" );
+ if (!dest.isNull())
+ destPath->setText( dest );
+}
+
+void UnpackDlgImpl::clickedUnpack()
+{
+ QArchive archive;
+ connect( &archive, SIGNAL( operationFeedback( const QString& ) ), this, SLOT( updateProgress( const QString& ) ) );
+ connect( &archive, SIGNAL( operationFeedback( int ) ), this, SLOT( updateProgress( int ) ) );
+
+ archive.setVerbosity( QArchive::Destination | QArchive::Verbose | QArchive::Progress );
+
+ QString dest = destPath->text(), src="qt-mac-commercial-3.0.0.app/Contents/Qt/qtmac.arq";
+ if(!dest.isEmpty() && dest.right(1) != "/")
+ dest += "/";
+ archive.setPath( src );
+ if( !archive.open( IO_ReadOnly ) ) {
+ QMessageBox::critical( NULL, "Failure", "Failed to open input " + src);
+ return;
+ } else if(!QFile::exists(dest) ) {
+ QDir d;
+ if(!d.mkdir(dest)) {
+ QMessageBox::critical( NULL, "Failure", "Failed to open directory " + dest);
+ return;
+ }
+ }
+ unpackButton->setDisabled( true );
+ srcKey->setDisabled( true );
+ destPath->setDisabled( true );
+ destButton->setDisabled( true );
+ LicenseDialogImpl licenseDialog( this );
+ if((!licenseDialog.showLicense( featuresForKeyOnUnix( srcKey->text() ) & Feature_US )) ||
+ (!licenseDialog.exec())) {
+ QMessageBox::critical( NULL, "Failure", "The license agreement was rejected." );
+ updateProgress( "License rejected" );
+ unpackButton->setDisabled( false );
+ srcKey->setDisabled( false );
+ destPath->setDisabled( false );
+ destButton->setDisabled( false );
+ return;
+ }
+
+ QString srcName = "qt-mac-commercial-3.0.0.app/Contents/Qt/LICENSE";
+ QString destName = "/qt-mac-commercial-3.0.0/.LICENSE";
+ QString srcName2 = srcName;
+ if ( featuresForKeyOnUnix( srcKey->text() ) & Feature_US )
+ srcName2 = srcName2 + "-US";
+ if((!archive.readArchive( dest, srcKey->text() )) ||
+ (!copyFile( srcName, dest + destName )) ||
+ (!copyFile( srcName + "-US", dest + destName + "-US" )) ||
+ (!copyFile( srcName2, dest + "/qt-mac-commercial-3.0.0/LICENSE" )))
+ {
+ QMessageBox::critical( NULL, "Failure", "Failed to unpack " + src);
+ archive.close();
+ }
+ else {
+ QMessageBox::information( NULL, "Archive unpacked", "Qt has been "
+ "extracted to " + dest + "qt-mac-commerical-3.0.0\nPlease read "
+ "the INSTALL.macosx file for installation instructions." );
+ cancelButton->setText( "Quit" );
+ }
+}
+
+bool UnpackDlgImpl::copyFile( const QString& src, const QString& dest )
+{
+ int len;
+ const int buflen = 4096;
+ char buf[buflen];
+ QFileInfo info( src );
+ QFile srcFile( src ), destFile( dest );
+ if (!srcFile.open( IO_ReadOnly ))
+ return false;
+ destFile.remove();
+ if (!destFile.open( IO_WriteOnly )) {
+ srcFile.close();
+ return false;
+ }
+ while (!srcFile.atEnd()) {
+ len = srcFile.readBlock( buf, buflen );
+ if (len <= 0)
+ break;
+ if (destFile.writeBlock( buf, len ) != len)
+ return false;
+ }
+ destFile.flush();
+ return true;
+}
+
+void UnpackDlgImpl::updateProgress( const QString& message )
+{
+ logOutput->append( message );
+}
+
+void UnpackDlgImpl::updateProgress( int )
+{
+ qApp->processEvents();
+}
+
+void UnpackDlgImpl::licenseKeyChanged()
+{
+ QRegExp keyExpr("^....-....-....");
+ if ((keyExpr.search( srcKey->text() ) != -1) &&
+ (featuresForKey( srcKey->text() ) & Feature_Mac))
+ unpackButton->setEnabled( true );
+ else
+ unpackButton->setEnabled( false );
+}
+
+void UnpackDlgImpl::reject()
+{
+ exit( 0 );
+}
diff --git a/util/install/mac/unpackdlgimpl.h b/util/install/mac/unpackdlgimpl.h
new file mode 100644
index 0000000..11585d7
--- /dev/null
+++ b/util/install/mac/unpackdlgimpl.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef UNPACKDLGIMPL_H
+#define UNPACKDLGIMPL_H
+
+#include "unpackdlg.h"
+
+class UnpackDlgImpl : public UnpackDlg
+{
+ Q_OBJECT;
+public:
+ UnpackDlgImpl( QString key = QString(),
+ QWidget* pParent = NULL, const char* pName = NULL, WindowFlags f = 0 );
+
+ virtual void clickedDestButton();
+ virtual void clickedUnpack();
+ virtual bool copyFile( const QString& src, const QString& dest );
+public slots:
+ virtual void updateProgress( const QString& );
+ virtual void updateProgress( int );
+ virtual void licenseKeyChanged();
+ virtual void reject();
+};
+
+#endif
diff --git a/util/install/package/main.cpp b/util/install/package/main.cpp
new file mode 100644
index 0000000..39c71db
--- /dev/null
+++ b/util/install/package/main.cpp
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qarchive.h"
+#include <qapplication.h>
+#include <qfileinfo.h>
+#include "keyinfo.h"
+#if defined(Q_OS_WIN32)
+#include <windows.h>
+#endif
+
+class ConsoleOutput : public QObject
+{
+ Q_OBJECT
+public:
+ ConsoleOutput() : QObject() { }
+ ~ConsoleOutput() { }
+public slots:
+ void updateProgress( const QString& str) { qDebug("%s", str.latin1()); }
+};
+
+static int usage(const char *argv0, const char *un=NULL) {
+ if(un)
+ fprintf(stderr, "Unknown command: %s\n", un);
+ else
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "%s [options] [keyinfo] files...\n", argv0);
+
+ fprintf(stderr, "\nOptions:\n");
+ fprintf(stderr, " -o file : Outputs archive to file\n");
+ fprintf(stderr, " -n : Follow symbolic links, do not archive the link\n");
+ fprintf(stderr, " -s : Quiet mode, will not output process\n");
+ fprintf(stderr, " -desc text : Add the description text to the archive (e.g. \"Qt 3.0.0\")\n");
+ fprintf(stderr, " -extra k v : Adds the extra value v with the key k to the archive\n");
+ fprintf(stderr, " -h : This help\n");
+
+ fprintf(stderr, "\nKey Info:\n");
+ fprintf(stderr, " -win : Windows Archive\n");
+ fprintf(stderr, " -unix : Unix Archive\n");
+ fprintf(stderr, " -mac : Mac OS X Archive\n");
+ fprintf(stderr, " -embedded : Embedded Archive\n");
+
+ fprintf(stderr, "\nThe following options are not for packaging and can't be\n" );
+ fprintf(stderr, "combined with the options above or any other option:\n\n" );
+ fprintf(stderr, " -unpack file : Unpack the archive file to the current directory\n");
+ fprintf(stderr, " -getdesc file : Print the description text of the archive file\n");
+ fprintf(stderr, " -getextra k file : Print the extra value for the key k of the archive file\n");
+#if defined(Q_OS_WIN32)
+ fprintf(stderr, " -res file1 file2 : Add the archive file1 as the binary resource\n");
+ fprintf(stderr, " QT_ARQ to the excutable file2\n");
+ fprintf(stderr, " -getres file : Get the binary resource QT_ARQ from the executable\n" );
+ fprintf(stderr, " file and store it under qt.arq\n");
+ fprintf(stderr, " -namedres RES_NAME file1 file2:\n");
+ fprintf(stderr, " Add the file1 as the binary resource\n");
+ fprintf(stderr, " RES_NAME to the excutable file2\n");
+ fprintf(stderr, " -license LICENSE file2:\n");
+ fprintf(stderr, " Add the license LICENSE as the binary resource\n");
+ fprintf(stderr, " LICENSE to the excutable file2\n");
+ fprintf(stderr, " -license-us LICENSE-US file2:\n");
+ fprintf(stderr, " Add the license LICENSE-US as the binary resource\n");
+ fprintf(stderr, " LICENSE-US to the excutable file2\n");
+#endif
+ return 665;
+}
+
+static int unpack( const char *filename, bool verbose )
+{
+ QArchive arq( filename );
+ ConsoleOutput output;
+ if ( verbose )
+ output.connect( &arq, SIGNAL(operationFeedback(const QString&)), SLOT(updateProgress(const QString&)) );
+ if ( !arq.open( IO_ReadOnly ) ) {
+ fprintf(stderr, "Can't open the archive %s file to unpack", filename);
+ return 42;
+ }
+ if ( !arq.readArchive( ".", "G87A-QJFE-DQF9" ) ) {
+ fprintf(stderr, "Couldn't unpack the archive %s", filename);
+ return 42;
+ }
+ return 0;
+}
+
+static int getdesc( const char *filename )
+{
+ QArchive arq( filename );
+ ConsoleOutput output;
+ output.connect( &arq, SIGNAL(operationFeedback(const QString&)), SLOT(updateProgress(const QString&)) );
+ if ( !arq.open( IO_ReadOnly ) ) {
+ fprintf(stderr, "Can't open the archive %s file to get description", filename);
+ return 42;
+ }
+ QArchiveHeader *header = arq.readArchiveHeader();
+ if ( !header ) {
+ fprintf(stderr, "Can't find the header in the archive %s file", filename);
+ return 42;
+ }
+ if ( !header->description().isNull() ) {
+ fprintf(stdout, header->description().latin1() );
+ }
+ return 0;
+}
+
+static int getextra( const char *key, const char *filename )
+{
+ QArchive arq( filename );
+ ConsoleOutput output;
+ output.connect( &arq, SIGNAL(operationFeedback(const QString&)), SLOT(updateProgress(const QString&)) );
+ if ( !arq.open( IO_ReadOnly ) ) {
+ fprintf(stderr, "Can't open the archive %s file to get description", filename);
+ return 42;
+ }
+ QArchiveHeader *header = arq.readArchiveHeader();
+ if ( !header ) {
+ fprintf(stderr, "Can't find the header in the archive %s file", filename);
+ return 42;
+ }
+ QString extraData = header->findExtraData(key);
+ if ( !extraData.isNull() ) {
+ fprintf(stdout, extraData.latin1() );
+ }
+ return 0;
+}
+
+
+int main( int argc, char** argv )
+{
+ uint features = 0;
+ bool output = true, doSyms = true;
+ QString desc;
+ QString dest;
+ QMap<QString,QString> extra;
+#if defined(Q_OS_WIN32)
+ QString arq, exe;
+ QString resName;
+ bool doRes = false;
+ bool doLicense = false;
+ bool doLicenseUs = false;
+ bool getRes = false;
+#endif
+ QStringList files;
+ int i;
+ for( i = 1; i < argc; i++ ) {
+ //options
+ if(!strcmp(argv[i], "-o")) {
+ if ( ++i < argc )
+ dest = argv[i];
+ else
+ return usage(argv[0]);
+ } else if(!strcmp(argv[i], "-n")) {
+ doSyms = false;
+ } else if(!strcmp(argv[i], "-s")) {
+ output = false;
+ } else if(!strcmp(argv[i], "-desc")) {
+ if ( ++i < argc )
+ desc = argv[i];
+ else
+ return usage(argv[0]);
+ } else if(!strcmp(argv[i], "-extra")) {
+ QString key, value;
+ if ( ++i < argc )
+ key = argv[i];
+ else
+ return usage(argv[0]);
+ if ( ++i < argc )
+ value = argv[i];
+ else
+ return usage(argv[0]);
+ extra.insert( key, value );
+ } else if(!strcmp(argv[i], "-h")) {
+ return usage(argv[0]);
+ //keyinfo
+ } else if(!strcmp(argv[i], "-unix")) {
+ features |= Feature_Unix;
+ } else if(!strcmp(argv[i], "-win")) {
+ features |= Feature_Windows;
+ } else if(!strcmp(argv[i], "-mac")) {
+ features |= Feature_Mac;
+ } else if(!strcmp(argv[i], "-embedded")) {
+ features |= Feature_Embedded;
+ //unpack
+ } else if(!strcmp(argv[i], "-unpack")) {
+ if ( ++i < argc )
+ return unpack( argv[i], output );
+ //getdesc
+ } else if(!strcmp(argv[i], "-getdesc")) {
+ if ( ++i < argc )
+ return getdesc( argv[i] );
+ //getextra
+ } else if(!strcmp(argv[i], "-getextra")) {
+ if ( ++i < argc ) {
+ if ( ++i < argc )
+ return getextra( argv[i-1], argv[i] );
+ }
+#if defined(Q_OS_WIN32)
+ //res (Windows only)
+ } else if(!strcmp(argv[i], "-res")) {
+ doRes = true;
+ if ( ++i < argc )
+ arq = argv[i];
+ if ( ++i < argc )
+ exe = argv[i];
+ //getres (Windows only)
+ } else if(!strcmp(argv[i], "-getres")) {
+ getRes = true;
+ if ( ++i < argc )
+ exe = argv[i];
+ //res (Windows only)
+ } else if(!strcmp(argv[i], "-namedres")) {
+ doRes = true;
+ if ( ++i < argc )
+ resName = argv[i];
+ if ( ++i < argc )
+ arq = argv[i];
+ if ( ++i < argc )
+ exe = argv[i];
+ //license (Windows only)
+ } else if(!strcmp(argv[i], "-license")) {
+ doLicense = true;
+ if ( ++i < argc )
+ arq = argv[i];
+ if ( ++i < argc )
+ exe = argv[i];
+ //licenseUs (Windows only)
+ } else if(!strcmp(argv[i], "-license-us")) {
+ doLicenseUs = true;
+ if ( ++i < argc )
+ arq = argv[i];
+ if ( ++i < argc )
+ exe = argv[i];
+#endif
+ //files
+ } else if(*(argv[i]) != '-') {
+ files.append(argv[i]);
+ //unknown
+ } else {
+ return usage(argv[0], argv[i]);
+ }
+ }
+#if defined(Q_OS_WIN32)
+ if ( doRes || doLicense || doLicenseUs ) {
+ if ( arq.isEmpty() || exe.isEmpty() )
+ return usage(argv[0], argv[i]);
+ QFile fArq( arq );
+ if ( !fArq.open( IO_ReadOnly ) ) {
+ if ( doRes ) {
+ fprintf(stderr, "Could not open archive %s", arq.latin1() );
+ } else {
+ fprintf(stderr, "Could not open license %s", arq.latin1() );
+ }
+ return -1;
+ }
+ QByteArray ba = fArq.readAll();
+ // ignore wide character versions (this is for internal use only)
+ HANDLE hExe = BeginUpdateResourceA( exe.latin1(), false );
+ if ( hExe == 0 ) {
+ fprintf(stderr, "Could not load executable %s\n", exe.latin1() );
+ qSystemWarning( "" );
+ return -1;
+ }
+ if ( resName.isEmpty() ) {
+ if ( doRes ) {
+ resName = "QT_ARQ";
+ } else if ( doLicense ){
+ resName = "LICENSE";
+ } else {
+ resName = "LICENSE-US";
+ }
+ }
+ if ( !UpdateResourceA(hExe,RT_RCDATA,resName.latin1(),0,ba.data(),ba.count()) ) {
+ EndUpdateResource( hExe, true );
+ fprintf(stderr, "Could not update executable %s\n", exe.latin1() );
+ qSystemWarning( "" );
+ return -1;
+ }
+ if ( !EndUpdateResource(hExe,false) ) {
+ fprintf(stderr, "Could not update executable %s\n", exe.latin1() );
+ qSystemWarning( "" );
+ return -1;
+ }
+ return 0;
+ }
+ if ( getRes ) {
+ if ( exe.isEmpty() )
+ return usage(argv[0], argv[i]);
+ arq = "qt.arq";
+ QFile fArq( arq );
+ if ( !fArq.open( IO_WriteOnly ) ) {
+ fprintf(stderr, "Could not open archive %s\n", arq.latin1() );
+ return -1;
+ }
+ // ignore wide character versions (this is for internal use only)
+ HMODULE hExe = LoadLibraryA( exe.latin1() );
+ if ( hExe == NULL ) {
+ fprintf(stderr, "Could not load executable %s\n", exe.latin1() );
+ qSystemWarning( "" );
+ return -1;
+ }
+ HRSRC resource = FindResource( hExe, "QT_ARQ", RT_RCDATA );
+ HGLOBAL hglobal = LoadResource( hExe, resource );
+ int arSize = SizeofResource( hExe, resource );
+ if ( arSize == 0 ) {
+ fprintf(stderr, "Could not get size of resource\n" );
+ qSystemWarning( "" );
+ return -1;
+ }
+ char *arData = (char*)LockResource( hglobal );
+ if ( arData == 0 ) {
+ fprintf(stderr, "Could not lock resource\n" );
+ qSystemWarning( "" );
+ return -1;
+ }
+ fArq.writeBlock( arData, arSize );
+ FreeLibrary( hExe );
+ return 0;
+ }
+#endif
+ if(!files.isEmpty()) {
+ if(dest.isEmpty()) {
+ qDebug("Please specify an output package");
+ return 666;
+ }
+
+ QArchive archive;
+ ConsoleOutput out;
+ if(output) {
+ QObject::connect( &archive, SIGNAL( operationFeedback( const QString& ) ),
+ &out, SLOT( updateProgress( const QString& ) ) );
+ archive.setVerbosity( QArchive::Destination | QArchive::Verbose );
+ }
+ archive.setSymbolicLinks(doSyms);
+ archive.setPath( dest );
+ if( !archive.open( IO_WriteOnly ) ) {
+ qDebug("Failed to open output %s", dest.latin1());
+ return 666;
+ }
+ QArchiveHeader header( features, desc );
+ QMap<QString,QString>::Iterator exIt;
+ for ( exIt = extra.begin(); exIt != extra.end(); ++exIt ) {
+ header.addExtraData( exIt.key(), exIt.data() );
+ }
+ archive.writeHeader( header );
+ for(QStringList::Iterator it = files.begin(); it != files.end(); ++it) {
+ QFileInfo f((*it));
+ if(!f.exists()) {
+ qDebug("Failed to open %s", (*it).latin1());
+ continue;
+ }
+ if(f.isDir())
+ archive.writeDir( (*it), true, (*it) );
+ else
+ archive.writeFile( (*it), (*it) );
+ }
+ archive.close();
+ } else {
+ return usage(argv[0]);
+ }
+ return 0;
+}
+
+#include "main.moc"
diff --git a/util/install/package/package.pro b/util/install/package/package.pro
new file mode 100644
index 0000000..4edc96e
--- /dev/null
+++ b/util/install/package/package.pro
@@ -0,0 +1,25 @@
+TEMPLATE = app
+SOURCES = main.cpp
+INCLUDEPATH += ../archive $$QT_SOURCE_TREE/include ../keygen
+CONFIG += qt console
+TARGET = package
+win32:DESTDIR = ../../../bin
+unix:LIBS += -L$$QT_BUILD_TREE/util/install/archive -larq
+win32:LIBS += ../archive/arq.lib
+DEFINES -= UNICODE
+
+win32:!shared:SOURCES += \
+ ../../../src/3rdparty/zlib/adler32.c \
+ ../../../src/3rdparty/zlib/compress.c \
+ ../../../src/3rdparty/zlib/crc32.c \
+ ../../../src/3rdparty/zlib/deflate.c \
+ ../../../src/3rdparty/zlib/gzio.c \
+ ../../../src/3rdparty/zlib/infblock.c \
+ ../../../src/3rdparty/zlib/infcodes.c \
+ ../../../src/3rdparty/zlib/inffast.c \
+ ../../../src/3rdparty/zlib/inflate.c \
+ ../../../src/3rdparty/zlib/inftrees.c \
+ ../../../src/3rdparty/zlib/infutil.c \
+ ../../../src/3rdparty/zlib/trees.c \
+ ../../../src/3rdparty/zlib/uncompr.c \
+ ../../../src/3rdparty/zlib/zutil.c
diff --git a/util/install/win/archive.cpp b/util/install/win/archive.cpp
new file mode 100644
index 0000000..81f8e53
--- /dev/null
+++ b/util/install/win/archive.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "archive.h"
+#include "resource.h"
+#include <qfile.h>
+#include <qmessagebox.h>
+#include <windows.h>
+
+bool addArchive( const QString& name )
+{
+ QByteArray ba ;
+
+ // Copy the install.exe first, since we can't update our own application
+ char aName[512];
+ if ( GetModuleFileNameA( 0, aName, 512 ) == 0 ) { // we don't need wide character versions
+ QMessageBox::critical( 0,
+ "Could not add archive",
+ QString( "Could not add archive %1.\n"
+ "Could not get the name of the application.").arg(name)
+ );
+ return false;
+ }
+ QFile fromFile( aName );
+ if ( !fromFile.open( IO_ReadOnly ) ) {
+ QMessageBox::critical( 0,
+ "Could not add archive",
+ QString("Could not copy executable %1.\n").arg(aName)
+ );
+ return false;
+ }
+ QString destinationName = name;
+ if ( destinationName.right(4) == ".arq" ) {
+ destinationName =destinationName.left( destinationName.length()-4 );
+ }
+ destinationName += ".exe";
+ QFile toFile( destinationName );
+ if ( !toFile.open( IO_WriteOnly ) ) {
+ QMessageBox::critical( 0,
+ "Could not add archive",
+ QString("Could not copy executable %1 to %2.\n").arg(aName).arg(destinationName)
+ );
+ return false;
+ }
+ ba = fromFile.readAll();
+ toFile.writeBlock( ba );
+ toFile.close();
+
+ // load the .arq file
+ QFile fArq( name );
+ if ( !fArq.open( IO_ReadOnly ) ) {
+ QMessageBox::critical( 0,
+ "Could not add archive",
+ QString("Could not open archive %1.\n").arg(name)
+ );
+ return false;
+ }
+ ba = fArq.readAll();
+
+ // update the binary res
+ ResourceSaver res( destinationName );
+ QString errorMsg;
+ if ( !res.setData( "QT_ARQ", ba, &errorMsg ) ) {
+ QMessageBox::critical( 0,
+ "Could not add archive",
+ QString("Could not add archive %1.\n").arg(name) + errorMsg
+ );
+ return false;
+ }
+
+#if 0
+ QMessageBox::information( 0,
+ "Archive added",
+ QString("Added the archive %1.\n").arg(name) + errorMsg
+ );
+#endif
+ return true;
+}
diff --git a/util/install/win/archive.h b/util/install/win/archive.h
new file mode 100644
index 0000000..d470a27
--- /dev/null
+++ b/util/install/win/archive.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef ARCHIVE_H
+#define ARCHIVE_H
+
+#include <qstring.h>
+#include "resource.h"
+
+bool addArchive( const QString &name );
+
+#endif
diff --git a/util/install/win/dialogs/folderdlg.ui b/util/install/win/dialogs/folderdlg.ui
new file mode 100644
index 0000000..c5427e2
--- /dev/null
+++ b/util/install/win/dialogs/folderdlg.ui
@@ -0,0 +1,184 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>FolderDlg</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>FolderDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>323</width>
+ <height>369</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Select installation folder</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Start menu folder tree</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizeable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>folderTree</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>nameLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Folder name</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>folderName</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name" stdset="0">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>okButton</cstring>
+ </property>
+ <property name="text">
+ <string>Ok</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>cancelButton</cstring>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name" stdset="0">
+ <cstring>Spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>FolderDlg</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>FolderDlg</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>folderTree</sender>
+ <signal>expanded(QListViewItem*)</signal>
+ <receiver>FolderDlg</receiver>
+ <slot>expandedDir(QListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>folderTree</sender>
+ <signal>collapsed(QListViewItem*)</signal>
+ <receiver>FolderDlg</receiver>
+ <slot>collapsedDir(QListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>folderTree</sender>
+ <signal>selectionChanged(QListViewItem*)</signal>
+ <receiver>FolderDlg</receiver>
+ <slot>selectedDir(QListViewItem*)</slot>
+ </connection>
+ <slot access="public" language="C++">collapsedDir( QListViewItem* )</slot>
+ <slot access="protected" language="C++">destroy()</slot>
+ <slot access="public" language="C++">expandedDir( QListViewItem* )</slot>
+ <slot access="public" language="C++">selectedDir( QListViewItem* )</slot>
+ <slot access="protected" language="C++">init()</slot>
+</connections>
+<tabstops>
+ <tabstop>folderTree</tabstop>
+ <tabstop>folderName</tabstop>
+ <tabstop>okButton</tabstop>
+ <tabstop>cancelButton</tabstop>
+</tabstops>
+</UI>
diff --git a/util/install/win/dialogs/folderdlgimpl.cpp b/util/install/win/dialogs/folderdlgimpl.cpp
new file mode 100644
index 0000000..8c3c27f
--- /dev/null
+++ b/util/install/win/dialogs/folderdlgimpl.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "folderdlgimpl.h"
+#include "../shell.h"
+#include <qlineedit.h>
+#include <qlistview.h>
+#include <qpixmap.h>
+#include <qdir.h>
+
+FolderDlgImpl::FolderDlgImpl( QWidget* parent, const char* name, bool modal, WindowFlags f ) :
+ FolderDlg( parent, name, modal, f )
+{
+}
+
+void FolderDlgImpl::setup( QString programsFolder, QString folder )
+{
+ folderName->setText( folder );
+ if( programsFolder.length() ) {
+ QString topLevel = programsFolder.mid( programsFolder.findRev( '\\' ) + 1 );
+ QListViewItem* topItem = new QListViewItem( folderTree, topLevel );
+ topItem->setOpen( true );
+ topItem->setPixmap( 0, *WinShell::getOpenFolderImage() );
+
+ ScanFolder( programsFolder, topItem );
+
+ }
+}
+
+void FolderDlgImpl::ScanFolder( QString folderPath, QListViewItem* parent )
+{
+ QDir folderDir( folderPath );
+ folderDir.setFilter( QDir::Dirs );
+ folderDir.setSorting( QDir::Name | QDir::IgnoreCase );
+ const QFileInfoList* fiList = folderDir.entryInfoList();
+ QFileInfoListIterator it( *fiList );
+ QFileInfo* fi;
+
+ while( ( fi = it.current() ) ) {
+ if( fi->fileName()[0] != '.' ) { // Exclude dot-dirs
+ QListViewItem* item = new QListViewItem( parent, fi->fileName() );
+ item->setOpen( false );
+ item->setPixmap( 0, *WinShell::getClosedFolderImage() );
+ ScanFolder( fi->absFilePath(), item );
+ }
+ ++it;
+ }
+}
+
+void FolderDlgImpl::expandedDir( QListViewItem* item )
+{
+ item->setPixmap( 0, *WinShell::getOpenFolderImage() );
+}
+
+void FolderDlgImpl::collapsedDir( QListViewItem* item )
+{
+ item->setPixmap( 0, *WinShell::getClosedFolderImage() );
+}
+
+QString FolderDlgImpl::getFolderName()
+{
+ return folderName->text();
+}
+
+/*
+** This will replace the contents of the folderName lineedit widget.
+**
+** The algoritm will traverse the item tree until it gets to the toplevel
+** item, prepending each name to the folder name as it goes
+*/
+void FolderDlgImpl::selectedDir( QListViewItem* item )
+{
+ QListViewItem* currentItem = item;
+ QString newFolder;
+
+ while( currentItem->parent() ) {
+ newFolder = currentItem->text( 0 ) + QString( "\\" ) + newFolder;
+ currentItem = currentItem->parent();
+ }
+ newFolder.truncate( newFolder.length() - 1 );
+ folderName->setText( newFolder );
+}
diff --git a/util/install/win/dialogs/folderdlgimpl.h b/util/install/win/dialogs/folderdlgimpl.h
new file mode 100644
index 0000000..25e13b5
--- /dev/null
+++ b/util/install/win/dialogs/folderdlgimpl.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef FOLDERDLGIMPL_H
+#define FOLDERDLGIMPL_H
+
+#include "folderdlg.h"
+
+class WinShell;
+
+class FolderDlgImpl : public FolderDlg
+{
+ Q_OBJECT
+public:
+ FolderDlgImpl( QWidget* parent = NULL, const char* name = NULL, bool modal = false, WindowFlags f = 0 );
+
+ void setup( QString, QString );
+
+ virtual void expandedDir( QListViewItem* );
+ virtual void collapsedDir( QListViewItem* );
+ virtual void selectedDir( QListViewItem* );
+
+ QString getFolderName();
+private:
+ void ScanFolder( QString folderPath, QListViewItem* parent );
+};
+
+#endif // FOLDERDLGIMPL_H
diff --git a/util/install/win/environment.cpp b/util/install/win/environment.cpp
new file mode 100644
index 0000000..bbf5719
--- /dev/null
+++ b/util/install/win/environment.cpp
@@ -0,0 +1,362 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "environment.h"
+#include <qnamespace.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qsettings.h>
+#if defined(Q_OS_WIN32)
+#include <windows.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+QString QEnvironment::getEnv( const QString &varName, int envBlock )
+{
+#if defined(Q_OS_WIN32)
+ OSVERSIONINFOA osvi;
+ HKEY hkKey;
+ bool isWinMe = false;
+
+ if( envBlock & GlobalEnv )
+ hkKey = HKEY_LOCAL_MACHINE;
+ else
+ hkKey = HKEY_CURRENT_USER;
+
+ osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFOA );
+ GetVersionExA( &osvi );
+ if( int( qWinVersion() ) & int( Qt::WV_98 ) ) {
+ if( osvi.dwMinorVersion == 90 )
+ isWinMe = true;
+ }
+
+ if( envBlock & PersistentEnv ) {
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ HKEY env;
+ QByteArray buffer;
+ DWORD size( 0 );
+ QString value;
+
+ if( RegOpenKeyExW( hkKey, L"Environment", 0, KEY_READ, &env ) == ERROR_SUCCESS ) {
+ RegQueryValueExW( env, (const wchar_t*) varName.ucs2(), 0, NULL, NULL, &size );
+ buffer.resize( size );
+ RegQueryValueExW( env, (const wchar_t*) varName.ucs2(), 0, NULL, (unsigned char*)buffer.data(), &size );
+ for( int i = 0; i < ( int )buffer.size(); i += 2 ) {
+ QChar c( buffer[ i ], buffer[ i + 1 ] );
+ if( !c.isNull() )
+ value += c;
+ }
+ RegCloseKey( env );
+ return value;
+ }
+ else {
+ return QString();
+ }
+ }
+ else { // Win 9x
+ // Persistent environment on Windows 9x is not fully supported yet.
+ return QString( getenv( varName ) );
+ }
+ }
+ if( envBlock & LocalEnv ) {
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ int size = GetEnvironmentVariableW( (TCHAR*)varName.ucs2(), 0, 0 );
+ if ( size == 0 )
+ return QString();
+ TCHAR *data = new TCHAR[ size ];
+ GetEnvironmentVariableW( (TCHAR*)varName.ucs2(), data, size );
+ QString ret = QString::fromUcs2( data );
+ delete[] data;
+ return ret;
+ } else {
+ QCString varNameL = varName.local8Bit();
+ int size = GetEnvironmentVariableA( varNameL.data(), 0, 0 );
+ if ( size == 0 )
+ return QString();
+ char *data = new char[ size ];
+ GetEnvironmentVariableA( varNameL.data(), data, size );
+ QString ret = QString::fromLocal8Bit( data );
+ delete[] data;
+ return ret;
+ }
+ }
+#elif defined(Q_OS_UNIX)
+// Persistent environment on Unix is not supported yet.
+ if( envBlock & LocalEnv ) {
+ return QString( getenv( varName ) );
+ }
+#endif
+ return QString();
+}
+
+void QEnvironment::putEnv( const QString &varName, const QString &varValue, int envBlock )
+{
+#if defined(Q_OS_WIN32)
+ OSVERSIONINFOA osvi;
+ HKEY hkKey;
+ bool isWinMe = false;
+
+ if( envBlock & GlobalEnv )
+ hkKey = HKEY_LOCAL_MACHINE;
+ else
+ hkKey = HKEY_CURRENT_USER;
+
+ osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFOA );
+ GetVersionExA( &osvi );
+ if( int( qWinVersion() ) & int( Qt::WV_98 ) ) {
+ if( osvi.dwMinorVersion == 90 )
+ isWinMe = true;
+ }
+
+ if( envBlock & PersistentEnv ) {
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+
+ HKEY env;
+ QByteArray buffer;
+
+ buffer.resize( varValue.length() * 2 + 2 );
+ const QChar *data = varValue.unicode();
+ int i;
+ for ( i = 0; i < (int)varValue.length(); ++i ) {
+ buffer[ 2*i ] = data[ i ].cell();
+ buffer[ (2*i)+1 ] = data[ i ].row();
+ }
+ buffer[ (2*i) ] = 0;
+ buffer[ (2*i)+1 ] = 0;
+
+ if( RegOpenKeyExW( hkKey, L"Environment", 0, KEY_WRITE, &env ) == ERROR_SUCCESS ) {
+ RegSetValueExW( env, (const wchar_t*) varName.ucs2(), 0, REG_EXPAND_SZ, (const unsigned char*)buffer.data(), buffer.size() );
+ RegCloseKey( env );
+ }
+ DWORD res;
+ SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, LPARAM("Environment"), SMTO_ABORTIFHUNG | SMTO_BLOCK, 1, &res);
+ }
+ else { // Win 9x
+ QFile autoexec( "c:\\autoexec.bat" );
+ QTextStream ostream( &autoexec );
+ ostream.setEncoding( QTextStream::Locale );
+
+ if( autoexec.open( IO_Append | IO_ReadWrite | IO_Translate ) ) {
+ ostream << "set " << varName << "=" << varValue << endl;
+ autoexec.close();
+ }
+ }
+ }
+ if( envBlock & LocalEnv ) {
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ SetEnvironmentVariableW( (TCHAR*)varName.ucs2(), (const wchar_t*) varValue.ucs2() );
+ } else {
+ SetEnvironmentVariableA( varName.local8Bit(), varValue.local8Bit() );
+ }
+ }
+#else
+ if( envBlock & LocalEnv )
+ setenv( varName, varValue, 1 );
+#endif
+}
+
+void QEnvironment::removeEnv( const QString &varName, int envBlock )
+{
+#if defined(Q_OS_WIN32)
+ HKEY hkKey;
+ if( envBlock & GlobalEnv )
+ hkKey = HKEY_LOCAL_MACHINE;
+ else
+ hkKey = HKEY_CURRENT_USER;
+
+ if( envBlock & PersistentEnv ) {
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ HKEY env;
+ if( RegOpenKeyExW( hkKey, L"Environment", 0, KEY_WRITE, &env ) == ERROR_SUCCESS ) {
+ RegDeleteValue( env, (const wchar_t*) varName.ucs2() );
+ RegCloseKey( env );
+ }
+ }
+ else { // Win 9x
+ QFile autoexec( "c:\\autoexec.bat" );
+ QTextStream ostream( &autoexec );
+ ostream.setEncoding( QTextStream::Locale );
+
+ if( autoexec.open( IO_Append | IO_ReadWrite | IO_Translate ) ) {
+ ostream << "set " << varName << "=" << endl;
+ autoexec.close();
+ }
+ }
+ }
+
+ if( envBlock & LocalEnv ) {
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ SetEnvironmentVariableW( (TCHAR*)varName.ucs2(), 0 );
+ } else {
+ SetEnvironmentVariableA( varName.local8Bit(), 0 );
+ }
+ }
+#endif
+}
+
+#if defined(Q_OS_WIN32)
+void QEnvironment::recordUninstall( const QString &displayName, const QString &cmdString )
+{
+ QSettings settings;
+ settings.insertSearchPath(QSettings::Windows, "/Microsoft/Windows/CurrentVersion/Uninstall");
+ settings.beginGroup("/" + displayName);
+ settings.writeEntry("/DisplayName", displayName);
+ settings.writeEntry("/Publisher", "Nokia Corporation and/or its subsidiary(-ies)");
+ settings.writeEntry("/URLInfoAbout", "http://qtsoftware.com");
+ settings.writeEntry("/HelpLink", "http://qtsoftware.com/support");
+ settings.writeEntry("/UninstallString", cmdString);
+ settings.endGroup();
+}
+
+void QEnvironment::removeUninstall( const QString &displayName )
+{
+ QSettings settings;
+ settings.insertSearchPath(QSettings::Windows, "/Microsoft/Windows/CurrentVersion/Uninstall");
+ settings.beginGroup("/" + displayName);
+ settings.removeEntry("/DisplayName");
+ settings.removeEntry("/Publisher");
+ settings.removeEntry("/URLInfoAbout");
+ settings.removeEntry("/DisplayVersion");
+ settings.removeEntry("/HelpLink");
+ settings.removeEntry("/UninstallString");
+ settings.removeEntry("/.");
+ settings.endGroup();
+}
+
+QString QEnvironment::getRegistryString( const QString &keyName, const QString &valueName, int scope )
+{
+ QString value;
+ HKEY scopeKeys[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
+ HKEY key;
+ DWORD valueSize( 0 );
+ QByteArray buffer, expBuffer;
+
+ if( int( qWinVersion() ) & int(Qt::WV_NT_based) ) {
+ if( RegOpenKeyExW( scopeKeys[ scope ], (const wchar_t*) keyName.ucs2(), 0, KEY_READ, &key ) == ERROR_SUCCESS ) {
+ if( RegQueryValueExW( key, (const wchar_t*) valueName.ucs2(), NULL, NULL, NULL, &valueSize ) == ERROR_SUCCESS ) {
+ buffer.resize( valueSize );
+ if( RegQueryValueExW( key, (const wchar_t*) valueName.ucs2(), NULL, NULL, (unsigned char*)buffer.data(), &valueSize ) == ERROR_SUCCESS ) {
+ valueSize = ExpandEnvironmentStringsW( (WCHAR*)buffer.data(), NULL, 0 );
+ expBuffer.resize( valueSize * 2 );
+ ExpandEnvironmentStringsW( (WCHAR*)buffer.data(), (WCHAR*)expBuffer.data(), valueSize );
+ for( int i = 0; i < ( int )expBuffer.size(); i += 2 ) {
+ QChar c( expBuffer[ i ], expBuffer[ i + 1 ] );
+ if ( !c.isNull() )
+ value += c;
+ }
+ }
+ }
+ RegCloseKey( key );
+ }
+ }
+ else {
+ if( RegOpenKeyExA( scopeKeys[ scope ], keyName.local8Bit(), 0, KEY_READ, &key ) == ERROR_SUCCESS ) {
+ if( RegQueryValueExA( key, valueName.local8Bit(), NULL, NULL, NULL, &valueSize ) == ERROR_SUCCESS ) {
+ buffer.resize( valueSize );
+ if( RegQueryValueExA( key, valueName.local8Bit(), NULL, NULL, (unsigned char*)buffer.data(), &valueSize ) == ERROR_SUCCESS ) {
+ valueSize = ExpandEnvironmentStringsA( buffer.data(), NULL, 0 );
+ expBuffer.resize( valueSize );
+ ExpandEnvironmentStringsA( buffer.data(), expBuffer.data(), valueSize );
+ value = expBuffer.data();
+ }
+ }
+ RegCloseKey( key );
+ }
+ }
+ return value;
+}
+#endif
+
+QString QEnvironment::getTempPath()
+{
+#if defined(Q_OS_WIN32)
+ DWORD tmpSize;
+ QByteArray tmp;
+ QString tmpPath;
+
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ tmpSize = GetTempPathW( 0, NULL );
+ tmp.resize( tmpSize * 2 );
+ GetTempPathW( tmpSize, (WCHAR*)tmp.data() );
+ for( int i = 0; i < ( int )tmp.size(); i += 2 ) {
+ QChar c( tmp[ i ], tmp[ i + 1 ] );
+ if( !c.isNull() )
+ tmpPath += c;
+ }
+ }
+ else {
+ tmpSize = GetTempPathA( 0, NULL );
+ tmp.resize( tmpSize * 2 );
+ GetTempPathA( tmpSize, tmp.data() );
+ tmpPath = tmp.data();
+ }
+#elif defined(Q_OS_UNIX)
+ QString tmpPath = "/tmp";
+#endif
+ return tmpPath;
+}
+
+QString QEnvironment::getLastError()
+{
+ return strerror( errno );
+}
+
+QString QEnvironment::getFSFileName( const QString& fileName )
+{
+#if defined(Q_OS_WIN32)
+ QByteArray buffer( MAX_PATH );
+ QString tmp( fileName );
+
+ GetVolumeInformationA( fileName.left( fileName.find( '\\' ) + 1 ).local8Bit(), NULL, NULL, NULL, NULL, NULL, buffer.data(), buffer.size() );
+ if( QString( buffer.data() ) != "NTFS" ) {
+ DWORD dw;
+ dw = GetShortPathNameA( fileName.local8Bit(), (char*)buffer.data(), buffer.size() );
+ if( dw > 0 )
+ tmp = buffer.data();
+ }
+#elif defined(Q_OS_UNIX)
+ QString tmp( fileName );
+#endif
+ return tmp;
+}
diff --git a/util/install/win/environment.h b/util/install/win/environment.h
new file mode 100644
index 0000000..d0f45e4
--- /dev/null
+++ b/util/install/win/environment.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef ENVIRONMENT_H
+#define ENVIRONMENT_H
+
+#include <qstring.h>
+
+class QEnvironment
+{
+public:
+ static QString getEnv( const QString &varName, int envBlock = LocalEnv );
+ static void putEnv( const QString &varName, const QString &varValue, int envBlock = LocalEnv );
+ static void removeEnv( const QString &varName, int envBlock = LocalEnv );
+#if defined(Q_OS_WIN32)
+ static QString getRegistryString( const QString &keyName, const QString &valueName, int scope = CurrentUser );
+ static void recordUninstall( const QString &displayName, const QString &cmdString );
+ static void removeUninstall( const QString &displayName );
+#endif
+ static QString getTempPath();
+ static QString getLastError();
+ static QString getFSFileName( const QString& fileName );
+
+ enum {
+ LocalEnv = 1,
+ PersistentEnv = 2,
+ GlobalEnv = 4
+ };
+
+ enum {
+ CurrentUser = 0,
+ LocalMachine = 1
+ };
+};
+
+#endif
diff --git a/util/install/win/globalinformation.cpp b/util/install/win/globalinformation.cpp
new file mode 100644
index 0000000..a05db1e
--- /dev/null
+++ b/util/install/win/globalinformation.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "globalinformation.h"
+
+GlobalInformation::GlobalInformation() :
+ _qtVersionStr( QT_VERSION_STR ),
+ _reconfig( false )
+{
+#if defined(Q_OS_WIN32)
+ _sysId = Other;
+#elif defined(Q_OS_MACX)
+ _sysId = MACX;
+#else
+ _sysId = MingW32;
+#endif
+}
+
+GlobalInformation::~GlobalInformation()
+{
+}
+
+void GlobalInformation::setReconfig( bool r )
+{
+ _reconfig = r;
+}
+
+bool GlobalInformation::reconfig() const
+{
+ return _reconfig;
+}
+
+void GlobalInformation::setQtVersionStr( const QString& qvs )
+{
+ _qtVersionStr = qvs;
+}
+
+QString GlobalInformation::qtVersionStr() const
+{
+ return _qtVersionStr;
+}
+
+#if defined(QSA)
+void GlobalInformation::setQsaVersionStr( const QString& qvs )
+{
+ _qsaVersionStr = qvs;
+}
+
+QString GlobalInformation::qsaVersionStr() const
+{
+ return _qsaVersionStr;
+}
+#endif
+
+void GlobalInformation::setSysId( SysId s )
+{
+ _sysId = s;
+}
+
+GlobalInformation::SysId GlobalInformation::sysId() const
+{
+ return _sysId;
+}
+
+QString GlobalInformation::text(Text t) const
+{
+ QString str;
+
+ switch (_sysId) {
+ case MSVC:
+ if (t == IDE)
+ str = "Microsoft Visual Studio 6.0";
+ else if (t == Mkspec)
+ str = "win32-msvc";
+ else if (t == MakeTool)
+ str = "nmake.exe";
+ break;
+ case MSVCNET:
+ if (t == IDE)
+ str = "Microsoft Visual Studio .NET";
+ else if (t == Mkspec)
+ str = "win32-msvc.net";
+ else if (t == MakeTool)
+ str = "nmake.exe";
+ break;
+ case Watcom:
+ if (t == Mkspec)
+ str = "win32-watcom";
+ else if (t == MakeTool)
+ str = "wmake.exe";
+ break;
+ case Intel:
+ if (t == Mkspec)
+ str = "win32-icc";
+ else if (t == MakeTool)
+ str = "nmake.exe";
+ break;
+ case GCC:
+ if (t == Mkspec)
+ str = "win32-g++";
+ else if (t == MakeTool)
+ str = "gmake.exe";
+ break;
+ case MACX:
+ if (t == Mkspec)
+ str = "mac-g++";
+ else if (t == MakeTool)
+ str = "make";
+ break;
+ case MinGW:
+ if (t == Mkspec)
+ str = "win32-g++";
+ else if (t == MakeTool)
+ str = "mingw32-make.exe";
+ break;
+ case Borland:
+ if (t == Mkspec)
+ str = "win32-borland";
+ else if (t == MakeTool)
+ str = "make.exe";
+ break;
+ default:
+ if (t == Mkspec)
+ str = "Custom";
+ else if (t == MakeTool)
+ str = "make.exe";
+ break;
+ }
+
+ return str;
+}
diff --git a/util/install/win/globalinformation.h b/util/install/win/globalinformation.h
new file mode 100644
index 0000000..843dac6
--- /dev/null
+++ b/util/install/win/globalinformation.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef GLOBALINFORMATION_H
+#define GLOBALINFORMATION_H
+#include <qstring.h>
+
+class GlobalInformation
+{
+public:
+ GlobalInformation();
+ ~GlobalInformation();
+
+ void setReconfig( bool );
+ bool reconfig() const;
+ void setQtVersionStr( const QString& );
+ QString qtVersionStr() const;
+#if defined(QSA)
+ void setQsaVersionStr( const QString& );
+ QString qsaVersionStr() const;
+#endif
+
+ enum SysId {
+ MSVCNET = 0,
+ MSVC = 1,
+ Borland = 2,
+ MinGW = 3,
+ Other = 4,
+ Watcom = 5,
+ Intel = 6,
+ GCC = 7,
+ MACX = 8
+ };
+ void setSysId( SysId );
+ SysId sysId() const;
+
+ enum Text {
+ MakeTool,
+ IDE,
+ Mkspec
+ };
+
+ QString text(Text t) const;
+
+private:
+ bool _reconfig;
+ QString _qtVersionStr;
+#if defined(QSA)
+ QString _qsaVersionStr;
+#endif
+ SysId _sysId;
+};
+
+extern GlobalInformation globalInformation;
+
+#endif // GLOBALINFORMATION_H
diff --git a/util/install/win/install-edu.rc b/util/install/win/install-edu.rc
new file mode 100644
index 0000000..3e50c1c
--- /dev/null
+++ b/util/install/win/install-edu.rc
@@ -0,0 +1,3 @@
+IDI_ICON1 ICON DISCARDABLE "install.ico"
+LICENSE RCDATA "../../../dist/edu/LICENSE"
+QT_ARQ RCDATA "qt.arq"
diff --git a/util/install/win/install-eval.rc b/util/install/win/install-eval.rc
new file mode 100644
index 0000000..78f0477
--- /dev/null
+++ b/util/install/win/install-eval.rc
@@ -0,0 +1,3 @@
+IDI_ICON1 ICON DISCARDABLE "install.ico"
+LICENSE RCDATA "../../../dist/trial/LICENSE"
+QT_ARQ RCDATA "qt.arq"
diff --git a/util/install/win/install-noncommercial.rc b/util/install/win/install-noncommercial.rc
new file mode 100644
index 0000000..b7d5b7c
--- /dev/null
+++ b/util/install/win/install-noncommercial.rc
@@ -0,0 +1,4 @@
+IDI_ICON1 ICON DISCARDABLE "install.ico"
+LICENSE RCDATA "../../../dist/noncommercial/LICENSE"
+LICENSE-US RCDATA "../../../dist/noncommercial/LICENSE-US"
+QT_ARQ RCDATA "qt.arq"
diff --git a/util/install/win/install-qsa.rc b/util/install/win/install-qsa.rc
new file mode 100644
index 0000000..f971c3f
--- /dev/null
+++ b/util/install/win/install-qsa.rc
@@ -0,0 +1,5 @@
+IDI_ICON1 ICON DISCARDABLE "install.ico"
+LICENSE RCDATA "../../../dist/trial/LICENSE"
+LICENSE_QSA RCDATA "../../../../qsa/dist/eval/LICENSE.EVAL"
+QT_ARQ RCDATA "qt.arq"
+QSA_ARQ RCDATA "qt.arq"
diff --git a/util/install/win/install.ico b/util/install/win/install.ico
new file mode 100644
index 0000000..b996fb7
--- /dev/null
+++ b/util/install/win/install.ico
Binary files differ
diff --git a/util/install/win/install.rc b/util/install/win/install.rc
new file mode 100644
index 0000000..321c245
--- /dev/null
+++ b/util/install/win/install.rc
@@ -0,0 +1,4 @@
+IDI_ICON1 ICON DISCARDABLE "install.ico"
+LICENSE RCDATA "../../../dist/commercial/LICENSE"
+LICENSE-US RCDATA "../../../dist/commercial/LICENSE-US"
+QT_ARQ RCDATA "qt.arq"
diff --git a/util/install/win/main.cpp b/util/install/win/main.cpp
new file mode 100644
index 0000000..0c21523
--- /dev/null
+++ b/util/install/win/main.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qapplication.h>
+#include <qmessagebox.h>
+#include "setupwizardimpl.h"
+#include "resource.h"
+#include "globalinformation.h"
+#include "environment.h"
+
+#if defined Q_OS_WIN32
+#include "archive.h"
+#endif
+
+GlobalInformation globalInformation;
+SetupWizardImpl *wizard = 0;
+
+int main( int argc, char** argv )
+{
+ QApplication app( argc, argv );
+ int res( -1 );
+
+ for( int i = 0; i < app.argc(); i++ ) {
+ if( QString( app.argv()[i] ) == "-reconfig" ) {
+ globalInformation.setReconfig( true );
+
+ QString qmakespec = QEnvironment::getEnv( "QMAKESPEC" );
+ for (int mks = 0; mks <= GlobalInformation::MACX; ++mks) {
+ if (globalInformation.text(GlobalInformation::Mkspec) == qmakespec) {
+ globalInformation.setSysId((GlobalInformation::SysId)mks);
+ break;
+ }
+ }
+
+ if ( ++i < app.argc() ) {
+ globalInformation.setQtVersionStr( app.argv()[i] );
+ }
+ break;
+#if defined(Q_OS_WIN32)
+ } else if ( QString( app.argv()[i] ) == "-add-archive" ) {
+ // -add-archive is an internal option to add the
+ // binary resource QT_ARQ
+ if ( ++i < app.argc() ) {
+ if ( addArchive( app.argv()[i] ) )
+ return 0;
+ }
+ return res;
+#endif
+ }
+ }
+
+ wizard = new SetupWizardImpl( 0, 0, false, Qt::WStyle_NormalBorder | Qt::WStyle_Customize | Qt::WStyle_MinMax | Qt::WStyle_SysMenu | Qt::WStyle_Title );
+ wizard->show();
+
+ app.setMainWidget( wizard );
+ res = app.exec();
+
+ wizard->stopProcesses();
+
+ //### memory leak
+
+ return res;
+}
diff --git a/util/install/win/pages/buildpage.ui b/util/install/win/pages/buildpage.ui
new file mode 100644
index 0000000..0ab4965
--- /dev/null
+++ b/util/install/win/pages/buildpage.ui
@@ -0,0 +1,92 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>BuildPage</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>BuildPage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>462</width>
+ <height>276</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form11</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout13</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTextView">
+ <property name="name">
+ <cstring>outputDisplay</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <family>Courier</family>
+ </font>
+ </property>
+ <property name="vScrollBarMode">
+ <enum>AlwaysOn</enum>
+ </property>
+ <property name="hScrollBarMode">
+ <enum>AlwaysOn</enum>
+ </property>
+ <property name="textFormat">
+ <enum>LogText</enum>
+ </property>
+ <property name="wordWrap">
+ <enum>NoWrap</enum>
+ </property>
+ <property name="autoFormatting">
+ <set>AutoNone</set>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout12</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QProgressBar">
+ <property name="name">
+ <cstring>compileProgress</cstring>
+ </property>
+ <property name="percentageVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>restartBuild</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;Replace&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/pages/configpage.ui b/util/install/win/pages/configpage.ui
new file mode 100644
index 0000000..8223d8e
--- /dev/null
+++ b/util/install/win/pages/configpage.ui
@@ -0,0 +1,474 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>ConfigPage</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ConfigPage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>460</width>
+ <height>284</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form9</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout3</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QCheckBox" row="1" column="3">
+ <property name="name">
+ <cstring>rebuildInstallation</cstring>
+ </property>
+ <property name="text">
+ <string>Rebuild Qt after reconfiguration</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QTextView" row="0" column="2" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>explainOption</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="palette">
+ <palette>
+ <active>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>212</red>
+ <green>208</green>
+ <blue>200</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>233</red>
+ <green>231</green>
+ <blue>227</blue>
+ </color>
+ <color>
+ <red>106</red>
+ <green>104</green>
+ <blue>100</blue>
+ </color>
+ <color>
+ <red>141</red>
+ <green>138</green>
+ <blue>133</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>212</red>
+ <green>208</green>
+ <blue>200</blue>
+ </color>
+ <color>
+ <red>212</red>
+ <green>208</green>
+ <blue>200</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>10</red>
+ <green>36</green>
+ <blue>106</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </active>
+ <disabled>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>212</red>
+ <green>208</green>
+ <blue>200</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>243</red>
+ <green>239</green>
+ <blue>230</blue>
+ </color>
+ <color>
+ <red>106</red>
+ <green>104</green>
+ <blue>100</blue>
+ </color>
+ <color>
+ <red>141</red>
+ <green>138</green>
+ <blue>133</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>212</red>
+ <green>208</green>
+ <blue>200</blue>
+ </color>
+ <color>
+ <red>212</red>
+ <green>208</green>
+ <blue>200</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>10</red>
+ <green>36</green>
+ <blue>106</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </disabled>
+ <inactive>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>212</red>
+ <green>208</green>
+ <blue>200</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>243</red>
+ <green>239</green>
+ <blue>230</blue>
+ </color>
+ <color>
+ <red>106</red>
+ <green>104</green>
+ <blue>100</blue>
+ </color>
+ <color>
+ <red>141</red>
+ <green>138</green>
+ <blue>133</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>212</red>
+ <green>208</green>
+ <blue>200</blue>
+ </color>
+ <color>
+ <red>212</red>
+ <green>208</green>
+ <blue>200</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>10</red>
+ <green>36</green>
+ <blue>106</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>0</green>
+ <blue>255</blue>
+ </color>
+ </inactive>
+ </palette>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>currentInstLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Active Qt installation</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>currentInstallation</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QTabWidget" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>configTabs</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>installTab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Install</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Installation options</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizeable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>installList</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>generalTab</cstring>
+ </property>
+ <attribute name="title">
+ <string>General</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QListView" row="0" column="0">
+ <column>
+ <property name="text">
+ <string>Qt Library configuration</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizeable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>configList</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>advancedTab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Advanced</string>
+ </attribute>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Advanced options</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizeable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>advancedList</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </widget>
+ </grid>
+ </widget>
+ </hbox>
+</widget>
+<tabstops>
+ <tabstop>configTabs</tabstop>
+ <tabstop>configList</tabstop>
+ <tabstop>explainOption</tabstop>
+ <tabstop>rebuildInstallation</tabstop>
+ <tabstop>advancedList</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/pages/finishpage.ui b/util/install/win/pages/finishpage.ui
new file mode 100644
index 0000000..de6b5f7
--- /dev/null
+++ b/util/install/win/pages/finishpage.ui
@@ -0,0 +1,63 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>FinishPage</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>FinishPage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>444</width>
+ <height>284</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form12</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QTextView">
+ <property name="name">
+ <cstring>finishText</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>showReadmeCheck</cstring>
+ </property>
+ <property name="text">
+ <string>Show README file</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/pages/folderspage.ui b/util/install/win/pages/folderspage.ui
new file mode 100644
index 0000000..ada15f7
--- /dev/null
+++ b/util/install/win/pages/folderspage.ui
@@ -0,0 +1,259 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>FoldersPage</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>FoldersPage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>443</width>
+ <height>284</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form8</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout15</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>folderBox</cstring>
+ </property>
+ <property name="title">
+ <string>Folders and paths</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>folderLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Program &amp;folder</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>folderPath</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>Layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>folderPath</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>folderPathButton</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>qtDirLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Set &amp;QTDIR</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>qtDirCheck</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>devSysLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Path</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>devSysPath</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>devSysPath</cstring>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>devSysPathButton</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>groupLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Folder &amp;group</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>folderGroups</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="3" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>folderGroups</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="1">
+ <property name="name">
+ <cstring>qtDirCheck</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="1" column="2">
+ <property name="name" stdset="0">
+ <cstring>Spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name" stdset="0">
+ <cstring>Spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </hbox>
+</widget>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="379">789c5d8ecb0a02310c45f7fd8ad0ec069907f531207e82e252101769b5388b51d07121e2bf6b1f195b6f28cd3d24b7ad0ad86dd75054e23ed0d0193067ba41717cf4fd737f58bd846ce6d028984123274296606073bd9c5c8fdf1eeba92b678db36dddaa60c959abec2258cdd62a9fc3424477a50cfdc18cc5d9c0e20eaffbbf90260c2a390f35c54a1823fa9bc39fc63cc3429e4b51cccb5060398a6c5478f7bd141fb90a5251</data>
+ </image>
+</images>
+<tabstops>
+ <tabstop>folderPath</tabstop>
+ <tabstop>folderPathButton</tabstop>
+ <tabstop>qtDirCheck</tabstop>
+ <tabstop>devSysPath</tabstop>
+ <tabstop>devSysPathButton</tabstop>
+ <tabstop>folderGroups</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/pages/licenseagreementpage.ui b/util/install/win/pages/licenseagreementpage.ui
new file mode 100644
index 0000000..5349e1f
--- /dev/null
+++ b/util/install/win/pages/licenseagreementpage.ui
@@ -0,0 +1,202 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>LicenseAgreementPage</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>LicenseAgreementPage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>440</width>
+ <height>284</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form3</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>countryLayout</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>31</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>countryLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Please choose your region:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>North or South America</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Anywhere outside North and South America</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>countryCombo</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>51</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="QTextView">
+ <property name="name">
+ <cstring>introText</cstring>
+ </property>
+ <property name="text">
+ <string>The license could not be found in the package. The package might be corrupted.
+Please contact support@trolltech.com to resolve the problem.</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>156</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>licenceButtons</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="title">
+ <string></string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>acceptLicense</cstring>
+ </property>
+ <property name="text">
+ <string>I agree</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>rejectLicense</cstring>
+ </property>
+ <property name="text">
+ <string>I disagree</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>155</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/pages/licensepage.ui b/util/install/win/pages/licensepage.ui
new file mode 100644
index 0000000..9c7b98c
--- /dev/null
+++ b/util/install/win/pages/licensepage.ui
@@ -0,0 +1,264 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>LicensePage</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>LicensePage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>445</width>
+ <height>284</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form2</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout6</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>licenseeLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Licensee</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>expiryLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Support and upgrade expiry</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="5" column="1">
+ <property name="name">
+ <cstring>expiryDate</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="1">
+ <property name="name">
+ <cstring>licenseID</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>customerIDLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Customer ID</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="6" column="1">
+ <property name="name">
+ <cstring>key</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>productsLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Products</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>productsString</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="3" column="1">
+ <property name="name">
+ <cstring>licenseeName</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>licenseInfoHeader</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Enter the supplied license information here, all fields except Licensee are mandatory.
+Alternatively, the installation wizard may read them from a license file.</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="4" column="1">
+ <item>
+ <property name="text">
+ <string>qt-professional</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>qt-enterprise</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>productsString</cstring>
+ </property>
+ </widget>
+ <spacer row="8" column="1">
+ <property name="name">
+ <cstring>Spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>licenseIDLabel</cstring>
+ </property>
+ <property name="text">
+ <string>License ID</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="7" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>Layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>readLicenseButton</cstring>
+ </property>
+ <property name="text">
+ <string>Read from file...</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>customerID</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="6" column="0">
+ <property name="name">
+ <cstring>keyLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Product key</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </hbox>
+</widget>
+<tabstops>
+ <tabstop>customerID</tabstop>
+ <tabstop>licenseID</tabstop>
+ <tabstop>licenseeName</tabstop>
+ <tabstop>productsString</tabstop>
+ <tabstop>expiryDate</tabstop>
+ <tabstop>key</tabstop>
+ <tabstop>readLicenseButton</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/pages/optionspage.ui b/util/install/win/pages/optionspage.ui
new file mode 100644
index 0000000..01033d2
--- /dev/null
+++ b/util/install/win/pages/optionspage.ui
@@ -0,0 +1,503 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>OptionsPage</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>OptionsPage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>413</width>
+ <height>372</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form7</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>optionsGroup</cstring>
+ </property>
+ <property name="title">
+ <string>Installation options</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>pathLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Destination &amp;path (appr. 1Gb free space required)</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>installPath</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>pathLayout</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>installPath</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>LineEditPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>installPathButton</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QCheckBox" row="2" column="1">
+ <property name="name">
+ <cstring>installExamples</cstring>
+ </property>
+ <property name="text">
+ <string>Build &amp;Examples</string>
+ </property>
+ <property name="accel">
+ <string>Alt+E</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>installTools</cstring>
+ </property>
+ <property name="text">
+ <string>Build &amp;Tools</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="0">
+ <property name="name">
+ <cstring>installExtensions</cstring>
+ </property>
+ <property name="text">
+ <string>Build E&amp;xtensions</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="1">
+ <property name="name">
+ <cstring>installTutorials</cstring>
+ </property>
+ <property name="text">
+ <string>Build T&amp;utorials</string>
+ </property>
+ <property name="accel">
+ <string>Alt+U</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="4" column="1">
+ <property name="name">
+ <cstring>skipBuild</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Skip Build Step</string>
+ </property>
+ <property name="accel">
+ <string>Alt+S</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="4" column="0">
+ <property name="name">
+ <cstring>installDocs</cstring>
+ </property>
+ <property name="text">
+ <string>Install &amp;documentation</string>
+ </property>
+ <property name="accel">
+ <string>Alt+D</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>sysGroup</cstring>
+ </property>
+ <property name="title">
+ <string>Compiler options</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout13</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>installIDEIntegration</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Integrate with IDE</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="buttonGroupId">
+ <number>99</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer7_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout21</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout20</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>sysOther</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Other</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>4</number>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>win32-watcom</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>sysOtherCombo</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>121</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>noteLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Note: The compilers specified in the 'Other' section are not officially supported.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>sysMsvcNet</cstring>
+ </property>
+ <property name="text">
+ <string>Microsoft Visual C++ .&amp;NET</string>
+ </property>
+ <property name="accel">
+ <string>Alt+N</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>sysMsvc</cstring>
+ </property>
+ <property name="text">
+ <string>Microsoft &amp;Visual C++</string>
+ </property>
+ <property name="accel">
+ <string>Alt+V</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>sysBorland</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Borland C++</string>
+ </property>
+ <property name="accel">
+ <string>Alt+V</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>2</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>sysMinGW</cstring>
+ </property>
+ <property name="text">
+ <string>MinGW32</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>3</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>sysIntel</cstring>
+ </property>
+ <property name="text">
+ <string>Intel C++</string>
+ </property>
+ <property name="buttonGroupId">
+ <number>6</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>64</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="379">789c5d8ec10ac2300c86ef7d8ad0dc8a6cad4e3b101f41f1288887b43ae6610a3a0f22bebb766de6e65f4af27f247f9b2bd86dd7a072716fa93d7bf035dd401d1f4df3dc1f562f21cd02cc0ce660e444c80c3c6cae9753e8f1dba3d6bad03a581f6c5994d36829d8ca56365ac7b6b25d0e0b11431932ec2e8e589a8d2cedf07af71772845119e7a1a374068c11fdcde14f7d9e6721cf0d51ca1ba1c8c628b15ef1ddf7527c00b6995250</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>sysOther</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>sysOtherCombo</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>sysBorland</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installIDEIntegration</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>sysMsvcNet</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installIDEIntegration</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>sysMsvc</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installIDEIntegration</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>sysOther</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installIDEIntegration</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>sysMinGW</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installIDEIntegration</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>sysIntel</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installIDEIntegration</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>skipBuild</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installTools</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>skipBuild</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installTutorials</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>skipBuild</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installExtensions</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>skipBuild</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>installExamples</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/pages/pages.cpp b/util/install/win/pages/pages.cpp
new file mode 100644
index 0000000..3ee4093
--- /dev/null
+++ b/util/install/win/pages/pages.cpp
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "pages.h"
+#include "resource.h"
+#include "../environment.h"
+#include <qcombobox.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qvalidator.h>
+#include <qdir.h>
+#include <qbuttongroup.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qmultilineedit.h>
+#include <qfiledialog.h>
+#include <qtabwidget.h>
+#include <qmessagebox.h>
+#include <setupwizardimpl.h>
+#include <qtextbrowser.h>
+#include <qtextview.h>
+#include <qlayout.h>
+
+#if defined(Q_OS_WIN32)
+#include <windows.h>
+#endif
+
+extern SetupWizardImpl *wizard;
+
+BuildPageImpl::BuildPageImpl( QWidget* parent, const char* name, WindowFlags fl )
+ : BuildPage( parent, name, fl )
+{
+}
+
+ConfigPageImpl::ConfigPageImpl( QWidget* parent, const char* name, WindowFlags fl )
+ : ConfigPage( parent, name, fl )
+{
+ if( globalInformation.reconfig() ) {
+ currentInstLabel->show();
+ currentInstallation->show();
+#if defined(Q_OS_WIN32)
+ // Makes no sense to have the rebuild installation option on DOS based
+ // Windows
+ if ( qWinVersion() & WV_NT_based )
+#endif
+ rebuildInstallation->show();
+#if defined(Q_OS_WIN32)
+ else {
+ rebuildInstallation->setChecked( false );
+ rebuildInstallation->hide();
+ }
+#endif
+ } else {
+ currentInstLabel->hide();
+ currentInstallation->hide();
+ rebuildInstallation->hide();
+ }
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ // ### these pages should probably be included but all options should be
+ // disabled so that the evaluation customer can see how he can configure Qt
+ configTabs->removePage( generalTab );
+ configTabs->removePage( advancedTab );
+#else
+ configTabs->removePage( installTab );
+#endif
+}
+
+FinishPageImpl::FinishPageImpl( QWidget* parent, const char* name, WindowFlags fl )
+ : FinishPage( parent, name, fl )
+{
+#if !defined(Q_OS_WIN32)
+ showReadmeCheck->hide();
+#endif
+}
+
+FoldersPageImpl::FoldersPageImpl( QWidget* parent, const char* name, WindowFlags fl )
+ : FoldersPage( parent, name, fl )
+{
+#if defined(Q_OS_WIN32)
+ QByteArray buffer( 256 );
+ unsigned long buffSize( buffer.size() );
+ GetUserNameA( buffer.data(), &buffSize );
+ folderGroups->insertItem( "Anyone who uses this computer (all users)" );
+ folderGroups->insertItem( QString( "Only for me (" ) + QString( buffer.data() ) + ")" );
+#if defined(QSA)
+ folderPath->setText( QString( "QSA " ) + globalInformation.qsaVersionStr() );
+#else
+ folderPath->setText( QString( "Qt " ) + globalInformation.qtVersionStr() );
+#endif
+ if( qWinVersion() & Qt::WV_NT_based ) // On NT we also have a common folder
+ folderGroups->setEnabled( true );
+ else
+ folderGroups->setDisabled( true );
+#elif defined(Q_OS_UNIX)
+ folderGroups->setDisabled( true );
+#endif
+}
+
+LicenseAgreementPageImpl::LicenseAgreementPageImpl( QWidget* parent, const char* name, WindowFlags fl )
+ : LicenseAgreementPage( parent, name, fl ),
+ titleStr("License agreement")
+{
+#if !defined(NON_COMMERCIAL)
+ countryLabel->hide();
+ countryCombo->hide();
+ delete countryLayout;
+#else
+ connect( countryCombo, SIGNAL(activated(int)), SLOT(countryChanged(int)) );
+#endif
+ connect( licenceButtons, SIGNAL(clicked(int)), SLOT(licenseAction(int)));
+}
+
+void LicenseAgreementPageImpl::licenseAction(int act)
+{
+ if( act )
+ wizard->setNextEnabled( this, false );
+ else
+ wizard->setNextEnabled( this, true );
+}
+
+void LicenseAgreementPageImpl::countryChanged(int index)
+{
+ ResourceLoader *rcLoader;
+ if ( index == 0 )
+ rcLoader = new ResourceLoader( "LICENSE-US" );
+ else
+ rcLoader = new ResourceLoader( "LICENSE" );
+
+ if ( rcLoader->isValid() ) {
+ introText->setText( rcLoader->data() );
+ } else {
+ QMessageBox::critical( this, tr("Package corrupted"),
+ tr("Could not find the LICENSE file in the package.\nThe package might be corrupted.") );
+ }
+}
+
+LicensePageImpl::LicensePageImpl( QWidget* parent, const char* name, WindowFlags fl )
+ : LicensePage( parent, name, fl )
+{
+#if defined(Q_OS_MAC)
+ // StyledPanel style looks very windowsish
+ customerID->setFrameShape( QFrame::LineEditPanel );
+#endif
+ customerID->setFocus();
+#if defined(EVAL)
+ // ### improve text
+# if defined(QSA)
+ licenseInfoHeader->setText( tr("Thank you for your interest in QSA.\n"
+ "Please enter the license information you got for this evaluation version of QSA.") );
+# else
+ licenseInfoHeader->setText( tr("Thank you for your interest in Qt.\n"
+ "Please enter the license information you got for this evaluation version of Qt.") );
+# endif
+
+ customerIDLabel->setText( tr("Name") );
+ licenseIDLabel->setText( tr("Company name") );
+ licenseeLabel->setText( tr("Serial number") );
+ evalName = customerID;
+ evalCompany = licenseID;
+ serialNumber = licenseeName;
+
+ expiryLabel->hide();
+ expiryDate->hide();
+ productsLabel->hide();
+ productsString->hide();
+ keyLabel->hide();
+ key->hide();
+ readLicenseButton->hide();
+#elif defined(EDU)
+ licenseInfoHeader->setText( tr("Please enter the license information for the educational edition of Qt.") );
+
+ customerIDLabel->setText( tr("Educational institution") );
+ licenseeLabel->setText( tr("Serial number") );
+ university = customerID;
+ serialNumber = licenseeName;
+
+ licenseIDLabel->hide();
+ licenseID->hide();
+ expiryLabel->hide();
+ expiryDate->hide();
+ productsLabel->hide();
+ productsString->hide();
+ keyLabel->hide();
+ key->hide();
+ readLicenseButton->hide();
+#else
+ licenseID->setValidator( new QIntValidator( -1, 9999999, licenseID ) );
+
+ // expiryDate and productsString comes from the license key
+ expiryDate->setEnabled( false );
+ productsString->setEnabled( false );
+ keyLabel->setText( tr("License key") );
+ licenseInfoHeader->setText( tr("Please enter your license information.\n"
+ "The License key is required to be able to proceed with the installation process.") );
+#endif
+}
+
+QValidator::State InstallPathValidator::validate( QString& input, int& ) const
+{
+ if ( ( globalInformation.sysId() == GlobalInformation::MSVC ||
+ globalInformation.sysId() == GlobalInformation::MSVCNET )
+ && input.contains( QRegExp("\\s") ) ) {
+ QMessageBox::warning( 0, "Invalid directory", "No whitespace is allowed in the directory name due to a limitation with MSVC" );
+ return Intermediate;
+ } else if ( globalInformation.sysId() == GlobalInformation::Borland && input.contains( "-" ) ) {
+ QMessageBox::warning( 0, "Invalid directory", "No '-' characters are allowed in the directory name due to a limitation in the "
+ "Borland linker" );
+ return Intermediate;
+ }
+ return Acceptable;
+}
+
+OptionsPageImpl::OptionsPageImpl( QWidget* parent, const char* name, WindowFlags fl )
+ : OptionsPage( parent, name, fl ),
+ titleStr("Options"),
+ shortTitleStr("Choose options")
+{
+ connect( installPathButton, SIGNAL(clicked()), SLOT(choosePath()));
+ sysGroup->setButton(globalInformation.sysId());
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ sysOther->hide();
+ sysOtherCombo->hide();
+ noteLabel->hide();
+#endif
+#if defined(Q_OS_WIN32)
+ installPath->setText(
+ QString( "C:\\Qt\\" ) +
+ QString( globalInformation.qtVersionStr() ).replace( QRegExp("\\s"), "" ).replace( QRegExp("-"), "" )
+ );
+ installPath->setValidator( new InstallPathValidator( this ) );
+#elif defined(Q_OS_MAC)
+ // ### the replace for Windows is done because qmake has problems with
+ // spaces and Borland has problems with "-" in the filenames -- I don't
+ // think that there is a need for this on Mac (rms)
+ QString base("QtMac-");
+ base = QDir::homeDirPath() + QDir::separator() + base;
+#if defined(EVAL)
+ base += "Eval-";
+#elif defined(EDU)
+ base += "Edu-";
+#endif
+ installPath->setText(base + QString( globalInformation.qtVersionStr() ).replace( QRegExp("\\s"), "" ));
+ sysGroup->hide();
+#endif
+}
+
+void OptionsPageImpl::choosePath()
+{
+ QDir dir( installPath->text() );
+
+#if defined(Q_OS_WIN32)
+ if( !dir.exists() ) {
+# if defined(QSA)
+ dir.setPath( "C:\\Qt_QSA" );
+# else
+ dir.setPath( "C:\\Qt" );
+#endif
+ }
+
+ QString dest = QFileDialog::getExistingDirectory( installPath->text(), this, NULL, "Select installation directory" );
+ if ( dest.isNull() ) {
+# if defined(QSA)
+ dest = "C:\\Qt_QSA";
+# else
+ dest = "C:\\Qt";
+# endif
+ }
+ if ( dest.right(1) == "\\" ) {
+# if defined(QSA)
+ dest += "Qt_QSA";
+# else
+ dest += "Qt";
+# endif
+ }
+ if ( dest.contains( QRegExp( "\\s" ) ) && !sysBorland->isChecked() )
+ QMessageBox::warning( 0, "Invalid directory", "No whitespace is allowed in the directory name due to a limitation with MSVC" );
+ else if ( dest.contains( "-" ) && sysBorland->isChecked() )
+ QMessageBox::warning( 0, "Invalid directory", "No '-' characters are allowed in the directory name due to a limitation with the Borland linker" );
+ else {
+ dir.setPath( dest );
+ installPath->setText( QDir::toNativeSeparators(dir.absPath()) );
+ }
+#elif defined(Q_OS_MAC)
+ if( !dir.exists() )
+ dir.setPath( "/" );
+
+ QString dest = QFileDialog::getExistingDirectory( installPath->text(), this, NULL, "Select installation directory" );
+ if (!dest.isNull())
+ installPath->setText( dest );
+#endif
+}
+
+ProgressPageImpl::ProgressPageImpl( QWidget* parent, const char* name, WindowFlags fl )
+ : ProgressPage( parent, name, fl )
+{
+ // ######### At the moment, we show only one line when unpacking. So the
+ // horizontal scrollbar is never shown for now to avoid flickering.
+ filesDisplay->setHScrollBarMode( QScrollView::AlwaysOff );
+}
+
+#if defined(Q_OS_WIN32)
+WinIntroPageImpl::WinIntroPageImpl( QWidget* parent, const char* name, WindowFlags fl )
+ : WinIntroPage( parent, name, fl )
+{
+#if defined(QSA)
+ textBrowser->setText( "<p>This program installs Qt and QSA.</p>" + textBrowser->text() );
+#else
+ textBrowser->setText( "<p>This program installs Qt.</p>" + textBrowser->text() );
+#endif
+}
+#endif
diff --git a/util/install/win/pages/pages.h b/util/install/win/pages/pages.h
new file mode 100644
index 0000000..8108f42
--- /dev/null
+++ b/util/install/win/pages/pages.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef PAGES_H
+#define PAGES_H
+
+#include <qvalidator.h>
+
+#include "buildpage.h"
+#include "configpage.h"
+#include "finishpage.h"
+#include "folderspage.h"
+#include "licenseagreementpage.h"
+#include "licensepage.h"
+#include "optionspage.h"
+#include "progresspage.h"
+#include "winintropage.h"
+#include "../globalinformation.h"
+
+class Page
+{
+public:
+ virtual QString title() const = 0;
+ virtual QString shortTitle() const = 0;
+};
+
+class BuildPageImpl : public BuildPage, public Page
+{
+ Q_OBJECT
+public:
+ BuildPageImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~BuildPageImpl() {}
+ QString title() const
+ {
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ return "Building Qt Examples and Tutorial";
+#else
+ return "Building Qt";
+#endif
+ }
+ QString shortTitle() const
+ {
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ return "Build Qt Examples";
+#else
+ return "Build Qt";
+#endif
+ }
+};
+
+class ConfigPageImpl : public ConfigPage, public Page
+{
+ Q_OBJECT
+public:
+ ConfigPageImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~ConfigPageImpl() {}
+ QString title() const
+ {
+ if( globalInformation.reconfig() )
+ return "Reconfigure Qt";
+ else
+ return "Configuration";
+ }
+ QString shortTitle() const
+ { return "Configure Qt"; }
+};
+
+class FinishPageImpl : public FinishPage, public Page
+{
+ Q_OBJECT
+public:
+ FinishPageImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~FinishPageImpl() {}
+ QString title() const
+ { return "Finished"; }
+ QString shortTitle() const
+ { return "Finish"; }
+};
+
+class FoldersPageImpl : public FoldersPage, public Page
+{
+ Q_OBJECT
+public:
+ FoldersPageImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~FoldersPageImpl() {}
+ QString title() const
+ { return "Folders"; }
+ QString shortTitle() const
+ { return "Choose folders"; }
+};
+
+class LicenseAgreementPageImpl : public LicenseAgreementPage, public Page
+{
+ Q_OBJECT
+public:
+ LicenseAgreementPageImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~LicenseAgreementPageImpl() {}
+ QString title() const
+ { return titleStr; }
+ QString shortTitle() const
+ { return titleStr; }
+
+private slots:
+ void licenseAction(int);
+ void countryChanged(int);
+
+public:
+ QString titleStr;
+};
+
+class LicensePageImpl : public LicensePage, public Page
+{
+ Q_OBJECT
+public:
+ LicensePageImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~LicensePageImpl() {}
+ QString title() const
+ {
+#if defined(QSA)
+ return QString("License Information to Install QSA %1").arg(globalInformation.qsaVersionStr());
+#else
+ return QString("License Information to Install Qt %1").arg(globalInformation.qtVersionStr());
+#endif
+ }
+ QString shortTitle() const
+ { return "License information"; }
+
+#if defined(EVAL)
+ QLineEdit* evalName;
+ QLineEdit* evalCompany;
+ QLineEdit* serialNumber;
+#elif defined(EDU)
+ QLineEdit* university;
+ QLineEdit* serialNumber;
+#endif
+};
+
+class InstallPathValidator : public QValidator
+{
+public:
+ InstallPathValidator( QObject* parent = 0, const char* name = 0 ) : QValidator( parent, name ) {}
+ ~InstallPathValidator() {}
+ QValidator::State validate( QString& input, int& ) const;
+};
+
+class OptionsPageImpl : public OptionsPage, public Page
+{
+ Q_OBJECT
+public:
+ OptionsPageImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~OptionsPageImpl() {}
+ QString title() const
+ { return titleStr; }
+ QString shortTitle() const
+ { return shortTitleStr; }
+
+private slots:
+ void choosePath();
+
+public:
+ QString titleStr;
+ QString shortTitleStr;
+};
+
+class ProgressPageImpl : public ProgressPage, public Page
+{
+ Q_OBJECT
+public:
+ ProgressPageImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~ProgressPageImpl() {}
+ QString title() const
+ { return "Installing"; }
+ QString shortTitle() const
+ { return "Install files"; }
+};
+
+class WinIntroPageImpl : public WinIntroPage, public Page
+{
+ Q_OBJECT
+public:
+ WinIntroPageImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~WinIntroPageImpl() {}
+ QString title() const
+ { return "Introduction"; }
+ QString shortTitle() const
+ { return "Introduction"; }
+};
+
+#endif // PAGES_H
diff --git a/util/install/win/pages/progresspage.ui b/util/install/win/pages/progresspage.ui
new file mode 100644
index 0000000..927d975
--- /dev/null
+++ b/util/install/win/pages/progresspage.ui
@@ -0,0 +1,78 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>ProgressPage</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ProgressPage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>440</width>
+ <height>286</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form10</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTextEdit">
+ <property name="name">
+ <cstring>filesDisplay</cstring>
+ </property>
+ <property name="vScrollBarMode">
+ <enum>AlwaysOn</enum>
+ </property>
+ <property name="hScrollBarMode">
+ <enum>AlwaysOff</enum>
+ </property>
+ <property name="textFormat">
+ <enum>LogText</enum>
+ </property>
+ <property name="linkUnderline">
+ <bool>false</bool>
+ </property>
+ <property name="wordWrap">
+ <enum>NoWrap</enum>
+ </property>
+ <property name="undoDepth">
+ <number>0</number>
+ </property>
+ <property name="autoFormatting">
+ <set>AutoNone</set>
+ </property>
+ </widget>
+ <widget class="QProgressBar">
+ <property name="name">
+ <cstring>operationProgress</cstring>
+ </property>
+ <property name="centerIndicator">
+ <bool>false</bool>
+ </property>
+ <property name="percentageVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/pages/sidedecoration.ui b/util/install/win/pages/sidedecoration.ui
new file mode 100644
index 0000000..1ea5761
--- /dev/null
+++ b/util/install/win/pages/sidedecoration.ui
@@ -0,0 +1,108 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>SideDecoration</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>SideDecoration</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>122</width>
+ <height>156</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>logoPixmap</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ <property name="vAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>versionLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Installing Qt</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>editionLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>(Clear me)</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="55092">789cccbd47b7eb38b2ef397f9fa2d6e5ecae5e7cf266d0035266cb6da7ed77af1ed07b2f1aa9bf7c83883f704c56d5cd7c75bb5f95d6c9ca5f8a22114044202200f0fccffffcdbe7d3fddffef37ffe8fea625c02eb6f966f947ffb4fbb4e92ebfff57fff9fffcffff88fe160f0b7fecf68389bfe6df41fffc7fff80febf96fd6df9401ff5fcff64232ffde36244f7a762ac953fefd56f29cf35cf2a267f3072ff9f733c906e7836493f35eb2c59fd74ab6797b1f243bfcfb46b2cb7fef0a1e72799c5af2907f7f94cce5732cc963fefd483297cf3a8387d43f992999ffde0c25f3dfb79a64de5f662099dfcfe924cf386f24f3fe4a44ff0fd17e5b327f9e772799dfcfb8078fa87d662499cbebbb9249de6fc9bcbd9d2f99dab795ccc7b31a48e6e3b71a4ae6e315ed25f3f1b04f82a93f0dc1636a9ff32999daf32599f757a54ae6fde17e48e6fae23892b97e78a2bd63ea1f438cef849e97e892f9f7652b99b76f3d91cce53763f0947e6f08fd9c1137b664de5e43c83fc7f53bf0022cf475499c8be719c4f113d824de5cc01671fd0eb6895dbaff50d8ab174ae6f2ad3ac9a47f63c924df4832d73f732a99f777f324998fb73993ccfb5f7f96ccc7df3a49e6e3514592b9bd3aa664ae1fd6bd646eaf9a2b98f4ddf52573fdb58e60d89f6d49e6df9b13c97c3c1d45326fbf634826ffb2934cfee40086fdf88164de7ff65232d9eb9b646e1fa607867e9bbe641a8f816092cf14f2423f4d070c7d8b9f25f3e7bbaf60e89fb791ccfb3b15df43ffe22f30f42f13f240ffea1b18fab716bf877ee967b043dc92bf1f0ea16fdd9af3a8f740bc3dbe64f2f70bc9bcbfcd2fc9bcbfbd4432f90b4730f5cff55e3297bfc9c0187f732899f4772099c6e35b321f7f6b0fc6f8daa6649aff7692f9f3724d32d7f7cb4932ef6ffb4e32e9b302c6f86723c9dcdefc50326f9ff32e99f7975382a10fd75c32d7e795906742fdd3bd49e6df67a2bdd09ff20886beb89164fefcd54932ef9ffa2c98fca72bda0b7d6a9f25f3feb0c4f842bf9a07b0d02fd13fd0afe2090cffd6c660e85b24ae87be05a40f63e1df8277c9bc7debab643e5e575732efef6e2799cb1bfcf89ecbdbed2573fd5cfd781e1fcf952d98fa3b91cf277f74cd24f3fe0f3ec08807ba8d64ae9fc54232e98f27993faff9f13df787ae680ff4d57995cce57103c95c7fac3bc97c7c7c5f308d67b8028bf9f72299cbd3dc49e6f2981f92797fd69664de5f7e2499dbb33b92ccdb6f2dc1d067772099fca72e99b7ff6a49a6f946f437f4b9bd48267934b0d0ef77c9bc7dad68df9cee9fee25f3fe69447fcc31df88f1843eaf6e92f9f3da89649a0fee25f3f1cb85be41ff0331bed07f5f8ca7f0a7d43f13a1df9d2a99f777f32899dfffea80111faeae92b93cee41f090f7effa0c463ce77f48a6f9ee51321fafeb4930f547bb01433fecb164fe7cff5b321f2f2f92ccfb3f93d793bd745b30f421ae2593bfd94be6fd1b2692b93cde4e32b79fda164ced8ddec1d017e74332f9dbb564de5e772899e299140c7dcaa692b93db8df92797fe61d18fe3117e303fd59b792e979b164de3f8918ff05f5cf46f40ff4c715e301fdb9bd80e13f57f792797fad4a30fce906bf17f3f51ae331c4fc19a13d43f89780e693a9f0a7ed028cebfd4e321fafe6198c7cc00b2473f9bc77c95cdf4a4ff0908fc75a5c8f78bfb52553fcf02999ebbfdf08a6f10e5ec1c2bfdc49a6f97c2b99e6ff27c9642f3fbee7fab416f2407fc299643efe912f99ec692099cbd3b492b9bc9ab8ff94c63711fd0bfdb2a792c93e2ac9140f689229df5125f3feed5660e85ffd2a99fce34432efdfee00867e5e14c9941f8ec0d0bfcc904cf9572a99b7a76e25f3fe73c760a1afaa646ebf99e85fe86f2ec61bfaea0b79e11f0ba12f2eda8bfb4b7d267b98897c64dd81a1cfeb503297afbd934cf1d45e30fc93f81ef363b896ccefbf3a4a26793dc1149fae7d30f247ff2a99ea1d3fbee7fed68b05a31eb1924cf9c2083ca5f6076bc9542fd948e6fa900e2473fdbbbc09463d630246be1a6692f9f84481643edef95532b73f5df01cfd7993ccdb7be92453beb5924cf3c14432efbf5cfc7e01fffa2999e6bfb1646e5f9b022ce2cba364de3e37114cfec132c0d047f74d32f9e37b30f26b2f05431f5763c9bc7f42c1d04797e6cf99d0c71be41fc21fa52a18fe24207d9f0bfd5a1d04d3f8570fe009d573dca3642e7fbb054f697ca237c1246f3a944cf53a5b32c5a72f60f81bd796ccaf4f2bc994af2d2593be6f2453bea682e7345eed4e32d5ff14c9bcbf2f57c95cff7dd15ef8a35097ccdb93cd25537e2bfa6b3124fffd055ec2bfcc24537c548045fe518331decda7647ebd2eda6ba37fc478c01f6d44ffb8d43e1ded17e3af3960cc97f5022cf481e257a6dd149fd96bf08cc6ffe64aa6f92604c35eec4032b7efab2799e2375b30e94b2aae5f50ff58aa642e6fe148a67ce1065e927fb80d2553bd2494cc9fdf3e49a6fc45c863c07e1dc97cfcd3a3606a5f7d05633e887682497faf4bb08df8e2030cfb2bc9de17a2ff4bf49f886762f4cf10f666bd80618f3e8dff92f5177f5e914be6ed2f36e005c91b5f24533cf22598ecafeec04be467ae64f28757b041bfaf5f040f29fe68c0268d9726da63917e14a2bdd0c7f424998f5f44fdb314fd91bf83a18f8105467fdc4660e86783e789fee94a30e215e3118c78a3a0f9dc60fd45fa34072f491fc329d8a0f685a964aae7dfc0265d5f2f05537f568f60d86bb091ccfbe36248e6fad988dfbba85f8e24533e48f66f88fe892b30fa67634ba6f97508467f6d1cb0a827435ed11f35fa6388f9c9a7f8c814f157fd065e92fe5f6e6083e42f5cb0897ac417d8227dca3fc036f55fb305431fba77c1747f3b02bba4df3ad9ab29e42f669229df46fb647fe460d8d3aa0243fecd2758d4bbefc0a21eb403a33f2a8a772c263f6fff35055ba827d1f85aa2bf2f1a58f4f70a8cfb252a18febdf1c0f02701f58f2dda7f5d48a6fe9b8071fff21d2cfc83603caf51c1b87fb106433f4b1a1f87fd17eebf1b17ec903efbd43e46b0f71a0c79cb2d58c4e72d18cf2f1bb078be0dc6f3339abf5cd11f8906c6f5de1a8cf846e3f6c1cbe724df068cf6548964ae3f1b130c7f9096608c7f7603a3bde90e8ce7bb2f60b4d77e00c39f075c9f98f639e47fa34832d7e7f84c2c9eb7ba80216ffb08c6f3cc042cd64f1a30e42f9760d88fe382d19e1ced19c11e42aebf0cf17cd306435ecb04a33d610e16f20b16f1470a16ed3981457cf9443c82bdae2660e19f79bc341c8be7d70e18cfd71ec022df8ac178feaa05e379d72bf108e3df70ff369cc8fe1d8345bc9c81d1fe60452cfaeb7a03c3be74ba7e2adbd382f1fbcb3b18e3910dc1689f4df24e657fd4603cafb2c168bffb0cc6f32b1ebf0c67e2fe01e9d34cdcef1283e12faa6f30ee67f860e1ffe660a1efdc7f0ee7e2fed58c58b6e70cc6ef8d002cd6173db0a83f2dc0d0b78edbf77021e5bd078bf6aec1f87d41fabd14f2155bb0f8fd108cdfeb2330da93de83f1fc8ac6d310f2ac1a309ed772ff3734c5fdb48d64ee0fb72e58d4e75ec0f87d7202a33f0d713df4a5237bb7e4782a60b11ee681d15eed112cee1782a1cf158f4f86b6b8bf6581c5fa2af5a733823f762d30eed7d2efdd11f2efcd1d18d76bdc5e468311f2a3c007e379f5082cea75f760e8fbfa8d782cf49dfba3d150fcbebc030b7bdc83a17f099faf472371ffe64c2ceed73460e883cefb6b3416f7ab4fc463e10f2c30e46b8927e279b94b2cee6f6cc1d087ec092cec4930c6f342f24f85fc46442caef75660e8cf85fb93d18cfd9ec783f1162ceaa37cfe19cdc5fd3ceabfb990d79d80d13eeb152cd64fe9fa85f8de7c05a33df9188cf66cbec0d0c7f50d0c7df3b8ff1f2d85bcce002ce227078ceb1d0f2cfca54e3c41fb6f74bd21ef5780f17c5d058bf53beeaf46e618ebd77a2299c77f5bba9f25c6b7f4c1c2bfbd80d19eeb07f104fda1933cb678de2603e37eba01c6ef6f57b0a8ff71ff3d72c6a8b7e8d47faee88fb507c6effd188cdf3bdc1ec67d38c739e2e3c5a63393e21723269e60fde4f22c99d677b93e307577285eb7b8fd8f27ecfe9cf50e0c7d8a79ff8ca7ec7bfefb6b412cc627db81c57e823730ead9eb1158d43fb8bce399b8fe7a0716eb5d7330c663c3fb733c67eda1fa484d2cc6c39a83a11fed193ca57a651282b13e16f3f96ebc9860bdc8d880c5fe810c2cf21bae8fe3e544d4cb23c93c5ed30a30ea071b170cff92d0f81813d443d71730eaed9a07c6f53eb7b7b1c9bee7fa117c49a6f5024b30c5b3760cb6b19ec9e3adb13331e8face93ccfbaf3883f13c23013ba8a72e05d3fd0d1b8c7c734df23b53d8df86facf9da03e7e1b80f1fc82f7e76430813e6d63e229fa3be5e333194e4cd40b52b04ded31b8fe4e4653110ff2fa0a73a736f28d9a788afd67fa180cfd6a1db0588fe3fe7f32610accfb77c3f59721f2c77c493cc5fe0aaf00e37eb731788afa4e059ed1f8361f60d48f6dde1f93d914ebc7460a46bd2fe4fd37994fc7940f6cbec1e89f98cf5f93a578def5013c433d86da6f4c51bf09b9bd4dcce982f2b39cebcbc49a22fff6b83e4dec29ea15d95932adb704c433acffebf43c776ad1fd039d7886f5d315bf3f5356f09acf77d3d1d4a5fa65734f3cc3fe035d134cf7372c30ec355b824dc413dc3fb0e9906574dcdf79c4e2f74501c6fa5b74104cdfb73c3e9d4ea6d6887f7fdb10b3e791bef1f9940ddf1ceb078fe005f5b7c5e7e3e96c86f58f8d0246fd3a76c1f311f9b377b043e31bf07c693a9fa1de19df816dec07f804bb584fa3fe5accc47a86069e517b82002cd6f775b043f39bc6e3dde9923d8eeb7332035bd47f3705ec60ff824d3cc7fecf84ebefd498c19e2faf609bfa2be6f9f0d49c2d51cff5c016e5fb2b176c8f78fb8b15d8a5fa99c9e7d7a93543fdab1b831dfafde6287844f5d10e8cf1af49bfac39c63bff024f499e98ee6fb3fb937f7d023bd4fed407bb435aafb124d37e2d5d30b53f03cf87d43eeb0d8cf5dd7803c67cb7e1f63d75587f707df1e9fece7c30a2fd5d7b30f6b3469f9269fdc792cce5594dc1587fba52ffb84c1edebecd5e326f7f41faebceb19f2cda8271bfa6133ca2e727e0118d4fb2164cfa9c2892f978af4c30eca1f1c19321d7bf2bff7e3660e34ff5e53bb043cfaf5dc174bf6c0076a97fdb929805acfcfb6d0446bdbee4ed9f0d857eddd660f89b6e2298da5f05c4ac3f687e6bc0c311ad87e07a263f9f0fda77f094da537f8067245fc5f569369a1963d29f2b31eb5fdabfe20ba6e7a777e0d188ff3eb9815906c29fa78227d04f053ca3f6b65c3f6663260fd553a93d2cfca4fec91bc95cfeea041e517f5fb8fece2662fcdd023c86ff33c1d31167cd06cf21cf5c308d679d8017d41f0df72fb3e9cc1ef3ebab14ec8c69bfc05432ed47d38885fe5d4cc9b4fe37028fc8fecb37c9649f25784cf6ebbf82e7f47dbc042fe87e05f5cf4ce8936b82e7f4fb36113ca6f17a002fe8f986b8de80fe8bef4dd28fc292cce52fa68269fc4d1effb0db2f49decd0c0c7fdc92fe2ce6131a3f6d2d98fcb7bf02cf49bf370330d68fea5a30fdde38831dfabea3fe59b2fea178b0009bd41e4f03db23aeff37713decb5f00593fc2df5a7c1ee47eb6f2330eadd17156c8ea87ff7609bfc45590b267f78d5c02e714bfa6ab2f1207ff80136c87ef22918f34dfe06c67cd186c48b018dafcee3cd99c5ee47faa48217647f99609bf4c7a0f1b2160392afa3f6da6cfc68bcd69279ff949f6093daef4ec1f067f5817831a4e76de8f70ebb9ece177c806d6abfb3235ec0dfba2bc9b4df9bc6d7ed1376ae5f5c3fe703263f6f4f520a1e53fc99102f66d4be8cf7cf7cc8e4e3d7673e784c7cdd82a7d4de5a03c3fe751e9f3265c2fca09be009d94fc2e397394b87c99f186bf08cfa4fe3fd3b9fb0e7717dacc792e97c0b8f5f58f8bb20d6793d613e5f2cc7b49fc5005bd49e35b56fb1c4fcecf1fe9e2fd9f7743dfdde582ca83f8267b049ed59f3f9686eb2eb69fd782699d62fa83de67244f67de1fa3eb79643b237ef2698f4ab9e8347d4feb0008fc99e1c6a8fbd70d05f4762261e6f9f46e3e730a6f3160618fdbbe6f9c6dc5d0ea8bd0df5bf6b88f89aebdfa25f00a5f8ff4e32edd749c0636aff66019ee17939780e7de2f92a73f643e8bb031e537b7c133c237bf5dec073ba7f44f71f1a225ea3e78f447f79dfe011ddcfe3f22dc68c29feff06e379ba0e9ed2ef0b1effb1747d44f3b1fd0d5ed2f78d0236c65cdf367c7e5fb0009858bf07cfd15f7bf082f4a3492473f96f19d8257b6df8f82e66cb05f55fbe223630ff6f797cbc98b3f67079527afe82319d17e1f6b7581a03fafdc693ccc7d7a0fb194b97da7bbb111b63f2af1bae9f0bd31810eb7cbd61612d1dd2bf94da671943c8cfe7af856d8c69be6e0563be594f2573fdd7b8bd2c1c763ded0f53c01392c7bb4ae6fdd3717d5db8c684fa4bbb134cdfa767f094e28180fba3e5c080fff15fc0b309f5ef9764d24ff13dfc43cae7a3e5d0807d6cf8782d47acbdfcfeed0b783ea1fad50ebca0ef6f3ed82079a32f30f2c5644f6c627f5acce7df655fd0e1e3930460a662dc3f1cc14beaaf40133ca178a8069bf47cdf90ccc74ff3c10e8de78dfa676c8afd09b564daff5982b1ff36a6f64c58ffd2fed40b7836a1fac504bc9c50fd6101c6fc97abc426e2b3700fc67911f3018cf33ac99d643e1edd198cf3176e07463da4fa0063bf8826be47bd53e7fe773965e345fded806db217eb1d8c78f29612b3f6923ea9603cbffb0663bf4949d7b38083c663b3022f68fceb7bb043f6118682a9ff8c02ec92bfcbe9fe7dba49f5c30d18fb636c9e2f2ce7ecf7144f2a6097e4bbe5c4ecf7140fcdc0b0b734018bfde03a784af3c53504cfb15f47dc0ffb0bbb8160ecbffc002fa95e58edc1d8bf1a4dc1163d2f36c1a8575495609c5f1a4aa6f3a134febd83e2ed2f376093faafa3e72fcc01f1f50b3c217ddd5660ac37ad63f00cfe5407cf69beef5230ea35c6026c60bfe55532e55b39d8a4eb6f73b0d8df20ee6f637fe04a32cdff03b043fd757b904cf9d9168c7ae7ed2299ce7b3692697fc898d8c2f99ddb128cf3b317f49f85fa6348f75f1a06d9afb604c37ff817b04dfa1c0ec10ee9bb4ef22ecd015d7fdd8047345eb5079e907e598e60d2d7b40363ffe3762598e2d5750e16e703d692297ffc128cf35768af897afb36108cfaee5c32d56b0f9269fe2e24f3f61731d880ff5125d37ed80558ac974c25d37ec09d64de7fe64132f73fea27d8a2f15732c9b4bea008a6f655a23fb1dfb28c24d3fe470d8c7ae1ed5132e95b2099cf8fa6e82fd4e3c32fc9b4bee3125b38ef7723ff641816d99b7d03dbe48fc22bd8a1f9f95a825d9adf4af28706eb1ede5eaf060fe97aaf133ca1fc5605237e6d8ee009e5bbd5198cf58b4efc1efb6fb71730f67bae66e025c5df8a09c6fecae020998fafd248a6f3ba909fd93b6f4f71025bb0af52329ddf9849e6cf533fc036e993924ba6f96726993f2fcec00ef57ff12e99e2c34a32ed7f0cc1f017d5bb649aef7cc9bc3f22f13c97fa4fc3f859388f5a6d25f3f69443c1d86f3b06e37c4be54ae6edd354c9bc7dd791643aefdc4aa67acf2b18e7f134f13dced325a4ef26d3379affc95f9826e2cb952a99c6f7153ca57835fd0463ff691108267fb579028b78c2001b34dee14532bf7f62814df88b4832d52f2ab085f59d0118eba3752899ecff2699eae307c9b43fb405431f9454329d2fbb97ccdb938cc02ee95b2adaebd2f8b590dfc279e448974ce3f12998e67b4d30ce074713c934ff403e0be72d2dba9fc5e607defeca014fc85f5413f094e2313b954cfea0114cfe467901233fd41792a99e6a49a6f527c198afd71bc9549fb9822dea8fba944cf9502799dad782b17e6d7592c9be6782495fea42321fdff8c7f77cbcb477b043fa1deb9229ff4904e37cc697641a7f0decd27828aa647abfc45032ade7b982495f13b25fcbc2fb0c944032d9cb93606abf5949a6f314cf60bc4fc00a24f3f6b79960d29f5a914cf11dfa53d87bf82999d6df303e16ceb755a4cf369b3fc8ff7660ec3f57de04933ff0f760ac5f665bc114df2b67c1a44f57156c507f5f1cc9b49ff3198cfdc69bab60aac7ac4f601be7fd22c1781fc95132ddaf95ccdbabd492b93e794f60e883229e87fd9ef959326fbf3a964cf9e00318fe5d9d4be6fda192fed916ce83a92f92a93dbe64ca8fd11f229e4c6f92f9f3938164ca1f4f82b1fe994ae6df871f60acf79a6bc9bc7f62f49785f3b1b75230d95775914cf30bfacfc279b22df90f47c413a621995f9f7be011f99b6d2b98e2136d021e4f683d63059e4cb83e7ae2fa19dd4f3b83e734df943118f581f22099cba33c8397549f592dc026d69b8f9279fb6f9f60e453d6156c537f5a63c9644f8160aa47695330fc8dee0aa6e7c5b964f28791648a6fe692297e580aa6fa6628da8bf8c3bc974cf9642118fa38954cf58f89649acf1692e93c27e9936361ffbdd149e6df2b9e609c1f7d96ccf549ad24d37974e887d0676721998f8fba924cf1fa9364b247713df687754f92e9fc672399ea45a23d581f35af92f9f7b9f81eef13885ac1181f4b32d5dfa10f16f6a3044bc974dee9158cfd3f892399fcbb2d993fff26fa6786fd3ba23f711ef146d7bbcc7e283f7b944ce7995ec0639aafab25784af671db0a9e52feb200cfc9fe320f2cec650f5e52beae7d49a6f319e2fe4bd457766083f453bf80b11fa878154cf6b2adc1585f37c4fde0af235530f251717fc45b9e90d7c17ca848a67add5530ad1f74a160aa8f76e279c8e7c34630f97f3b174cf2379a645abf247fe35a781f90ff2818f3c1443297571d49a67cfd4930cd87da1b58e8ff5630ece74b32cd1fa564aaef7982697dc87900633f73694ae6faa0be4aa6fd789a648aa724637fd25a32ed3f79924ceb3d3330f6f325ad64de1fd98364927f2598facbd42553fd3594ccafcf311e16cecbdf22c95c5e652a99de7f267e8ff3c9e1bb641a6f4732bf3efb008bfd812f92297eb32473794b31bec87fa30a2ccea3ee0493ff30f79269bfe23718f53e6b2099ea0377609c7f34be2453fc7b914cf91c1f2f63c0e6478a0fb6e019d58be207c1538aff8fe039e503712b99e6eb5c3297a750c04b1afff22618fb1922c1347fc73bc9b47f4630f2f9eda360b2efab2e98fcd1ea158cfd83452598f47f6b48e6cf8feec1a8b7a40bc1f05f3bc9bcffb61918f596f85d32d5e3447fbaa48ff94030f6ffdc24737bf267c416f6a7ac3f2453fe580bc67e99122cceeb9c24533d6b2299f4ad108cfce30773fd500cc9341f7792a9fe6b0ba6f5da6b2399ce372ec1d85f1d9d25f3efd59b60f89f3bc9bc3fd4a364f22f6f60ec97543792797fa8a960d8c74d32f9932918f61ed49269ff832d99e44d24f3f61a23c1d43f96fc1ef1fe1c8cf763448e645a3f16cfc3fe3d632899e2955832cdafd01f0be7d5ad4a32ad9f3792b9fcc64030ced3d792b93e9723c9b41feb02c6fe67732b99f68b7c4aa6faa3180f9c17f6499ffa032dc46bf098ec5d8f24d3fe08133ca1f530ed049e527eb7f50593ffb83c48a6fd570a7846f7d36b30e6fff25b32d5ab73c1145f28ef82299ed1e660d473b64f92a9def92698fcdd5a3cdf46fd24914cfbcd74c9b43e21e445fda611f7437cb1fe124cf65edcc02edd3f7225d3fb001e05d3fc5ebd108b7879bb93ccfbc72f05937e66a9605abf538e92493f56e021d99f6249a6fa5b2b98fc9f72914cedc3785a789f52f12698e42943c964ef17c9e40fe792697e1849e6f2648e60ac470660bc9f243b4aa6fd3fa1647ebda20826f9d24c32ef0ff55e32d5d7447f60fe2f9f25933f5a4aa6f8e62c18f9502299f40ffa61e1fd4b4a2899f6279492495ed19e29e297028cf795048d64dedef05530e29137c9e47fe4efb19f740cc6fed152134ced0f55c9fcfb488c17dedf74b9934cf64dfa3c326754ffab0cc1643f510ac67a78ba04633e77466083ecb309c026cdffa921998f476582b19fa7ba0aa6f93e5e0ba6fca6188051bf4b447bb1bf4aff00237ff60f92e9fd41f792e9bc7d2599e6f717c1d8cf247e8f7a5d160ba6fecf23c1b4bf21a0f86264e13c72f82499f2fd57c1f06727c954bfcec098df755b30d9ef7a2e98ecdf78974cf54cb447d47b3d5330e2cb0fc9b4df47dc0ffbd12ea9647a9fec1e2cde07f92e99f60b1c05239e3e4ba6f9df974cf9d74932ed9ffff17b2e5f70014f90ef288261df8664b25f5332bd6f0ae36be1fc4ef92499f22d4b3297ff593c0fefb7525dc9e4df3c30de5fa53a9229feb12553bc2ec66f46f2565f92c97f37609ca7b4df25d37e825a32adff89fba39eaafb92293fea24f3ebb7627cb13ebbfd944cfbadbf2453fe37154cf287a664d257d15e715e80fa6fcce673f2af117846f94076075e503d2188c1d88f9a9b82c91f2457c954cf38832df2279ba9647adfe70a8cfaecf62098e2ef6e2699ce27ed04533cb2d5c0d8efaa3c09a6fa46f12199ec5d3c0feba51dcd9f63517f5dbd0886bd3f4be6d76f7f30d59b62c164afde5432d5271f2453bdf0118c7abd77124ced4f1ac914afae2553bd5edc0ff3b9f32498ec6d1308a6f66c55c9341fdd83313f9ba23da8ef46a564dabf664aa6fd21f27b8a37e291643abfe249a6f9ce174cfb13a2028cf78b25b9647a1fd4a364f20fdf92c97f0c25d37a512599d607a03f22bf375ac994ffa49229ff78944cf94a2618fe48fe1ef59e4632bd3f270163becf2ac994bf8beb71fe4b0d2453bd27964cf552d13fa807da2f9269ff612499e627d13ed40f424330b55f13d763bfc6ed4332c50f37c1f0f78a64daff3d964cfb43c578637daf7a138cfd39429f719e6745fa30314df21f590ec6fedd32134cfbb10c5d30f98bcb8b64da2f3c01dbd87fbc174cf5c92001e37c4d25eee760fff1b7605a0fc8b792e9fc81b8bf43f149740263ff68fe2a989eb722fb9c8878201849a6f75f9e25d3f37cc974fee15532bdaf752898ecdd0904d37a475080512faf7e30e9432e18e7f56e82914f5482c91e0bf13ce4ff7e2698c627fb924cebcfe2f7d8ff1b3e80719eaa934cfaee3992491e717ff80f6f2699f22ff13dcecfa753c9e4bf0e92293f394aa6fd139660b2cfc8904cf9df4230e68b4a32add78bf1c0feda740ec6fbebcab3648a8f2792c95fd492299e1848a67ccd164cf25b2d58f887ab64f2379d64de3fea4132bd6f4efc7e8e7827944cfb7f1e2553bd4f134cfa6c799269ffb6781eea8df14432b57f2718ebe591645a2f8b05231f15bfc77e0f652699e229f13cbc7faa9a4ba6f361427fb03f5013fa8cf5e2c495ccbfd73dc924af180fec0fd33e24737922f17c9c6f6cc91ea626f69b5e13f082fccfe64d32d547bfc0385f565ec0886fba1cecd07a663394ccfb237b05633d627b144cf6779949a6f75fd682c93f06349f4dc5fa433d154cfaace982697d721b4aa6f3c11918f585742299fce5bd64aa67958229be5ac560ac27ac12c178bfd79b64da0ff1e37b7adf95fc3dcef70592a95ebb174cfe3a10cf47fda01c08c67e1b5f32bdcfb0134cfde12a92493ed17f585fc81f25d378dc49a6f8e253308d57249e3f417c7a904cfbcd7e30c5d382b11e982592797f24df82b1de954ba67aa6907f4af69baec138af6c8d24533d692f99ea733bc1e4ff3c0b2cde37be944cfe712499f2b1b964b2675732c52bd0670bfb45d54832e58fba64da0fb301e3fd8d4a2499d67f857ee0fc72f82d99be5f81713e3e194aa6fd49e27e588fb89ec1884fae13c9d4ffa27fb0bff0229e67537fae481f66e612fb2d776083ec3debc026eaa53618f18a3b0323fe580f04d3f5c98b64da7f63825df217852e99ce77907c33113f6c4dc134df6f1f24d37c9982b17ee04f05537b9a77c9148f88dfa3deb07a92ccfb7f73168cf365778229be48bf25537d19f28bf501e55e309d4fc94f92c97fcec158cf2b12c1e41fbb4fc9b43e3d104cf3f7f6158cf87ebb170cffe448267942c1e47fba05187f1f455049a6f5614330f4ff0d8cf3b88ab83fde3770d94ba6fafc12bca0f6a557c1c80f6dc9644fb964aa7f1492a99eb1934cf3f718bc44fd632199f2ab67c914bfd782518f16e389f78346a23dd8bfa58c25d379ba4030c95b5f2453fc5c824deacfec2299f6eb6c25d37ae74630e2b94632ad170bf9b13fb87b964cf514713df61bd4aa643a9f0f7bb31cecbf10fa28f6e3f89269bd83e2adb9399f52bd33032fa6fcfef9086cd07e8d95f81eeb1b97a964b2bf0dd8a2f958ff02dbb41fbbbb825d9a3f2eb5608a3fe28560caafb6141fcd45fdb11a83b11e180f05d37e5c5f114cfe669d8051ef6f3dc1a40fab108cf3d9e55a30ce3b1a60d4d78bab649a5fe5f7645f978364dededbb360f247452899ea616730d6e7d6779269fdfb4330f9bbd4148cf8e7058cf5b8e44932bdffe25e30f6835c24d3f9d1b964b27f713decdd16ed9b937fd2f792a99ed2082679a247b0380f33964cf3ab18af05c52f57d1df381f5baf2453bcff0046fcacfe60daaf6a4aa6f9ed4b30ce7fce25d3fedd1918f65f8af1c37e6d4f954cf9cf5a32c927fa17fbede254326faf22aec77c1bd582a9fd971d58ecef3524d3fe5ea1bfd84f97d1f82ec47a83be124cf5c8ca07dba4efbab8de9df2dffba44f0b51afeb5cc1747d32154cf61eecc043ccf74f9269ffd3098cf7495c1e25d3f9c14a30ad9f281f92693de2001ee3bcf34430e94f71114cfe259883f17ef6b52599de2f36144cfaa23c4aa6fafd188cfa79d60a267de832c1345f1786649a3f7e30cd97a2bdc86ff55232c54fb9648a6fc4f367e44fbaa1649a5f669269ffb7f87e4ef6915f2453beaf4ba6f9443c1feb655a2c99e47b944cfb532493ff6bef25d3f86ec1e2bc532318ef1712fa82f3cdc55e32b5ff1b0c7b5acd25d3df9fa04ba67ac25e32bd0f44b4cfc0f95ad13f787f759c08c6fb8f34c9141f6e2453fee80b46fe22fac7c2fbafef24933f17fa8efdf9590dc6fb8d4a8a079626ceb3d513b04bfa5a527cb664f645eb65067848f359fd8369bfec063cc27ae45532d5e31f25f3f15c3d83315f5d12c9544f740553fe1e6592a93f3dc158bfb88127145ffb9560b2873a96cce5d75f25537ce90ba6fa62f283a95e2ae49bd2f82b0f82c93ef385645a6f17ed453d39984aa6fac04c32fdfd5607c1a42ff14a30cdb7b74232e5a76f60e483fe5132cdafb960c4fb5f60c4aba52218ebaf7b30d69fb6e27b9c1f0ceec1d82f962b92c95f1d24537da7148cf93d05239f534f92e9bc8bb81fcefb1547c9544fabc1383fe68af1c67e92f807d3fe43213ff6af7662fcb19fdaa37cc410f5ebfc5e30cd1f6b07ecd2f85a347e06332faa8f1cc0d0efdb17784cf6e91a82499ff44ff004eb318f92693fdebd649adf5f05937efa67c1347fe91618e7bb6e7782112faa60ac8736a1601a8fac00a31ee98c05e37d155bc1347ff8aa647a1fc009bca0f1f21682c99f9ae2fe0b6acf360763fd62bb168cfcb0148cf7790879f1be9ad4954cf53cd17fd8bfe49f24533db1164cfdbd7d07e33cd346fc1efb17b789643a4f300423bf303760bcdfec42f669b27885ee47f38169e1bc977e124cf18d3706e3fd11fa163c22fdda9482a7b43e7805c3ff058660ba9f2b9e87f364d14632d5fb4792e9ef37fe02e33cd926028bf364efe039c9b712f747fdd9ad24d3f58231fee58b601affdb9b648a6f7230dedfe12d25d3fa760a467d3817f218145fd99f9269bda1924cefdf93df23fe7e009b349f98623c2c1a5ffb2298ee97d8609c3f32e6609c3f8b2cc9646f0bc914cf3f4aa6786607c6fe958ee20f8bcdafb43f81e20b165e93fe5c3e25d37e30f13dea3ddd093cc27ede2d18f5983804e3fd1d9a25989ed7168269ff61fa089e223f9e8167d47f862699d6f39e25d3fe68152ce2b70318e7c9ec67c9f4fe12138cf70f252918f1932b9e67507caf08f9f1be9938069b648fc15e308dbf32108cf7df88e7637f627c150cff7a0163ff42f000c6f99c88ec9b4d37a867d1fc62b3f1a3fd3c743f5b8c5ff102463cb2da82117fb4df9269bde12498ec510f25d3fef01c8cfcb8b425d37eaa5232bd5f2506235ed85a9269bda4154ce31d89f6cef17ea8037841f76b447b17d84fb6012fa9fd6b211fea49978b608a4f0c156c423f3bc9b49f3602c31e6f7bc1d0bf4a32c50fe44f6c1bfb3be22918e7e93a6287d907adb70ec063eacfd51b784afdb3d1c0c85f8a5232cd97afe0398ddf652d99fcf75130e5879d09c67c961482c97eae7bb049f74b3ac9349e86649a4f2692b93cb978be8df749b88229be509660eca7f39f24d3f922713dd6afaedf8269bcd690c7c6f9d755001e52bc5b533ceb5a63d29fab2199ce63edc1139a9f82083c25f9f5068cf745dd2cf082c6238d25d3fb1d378229bf503ec178dfce6a0946fce9bd0aa6fe5ccf04e37d0af27aca77ac1bd8a2e747df9229fe2dc136f98ffc4530e9f34a934cf9f10fa6e78be739387f48fde9daa8f7273c3e310716f67b260f9269ffde1318efefb91e24537dcd06e3fd79f6156ca0deb1904cf6a080d1fe6a2199e67b5f303d4fbb801dd8fb0a8cf8f9a611db78ff5dac8211df745f60d413133e7e2c389be17ccc183c27ff97459279ffac4b30de27947e0826f94c4532bd7f5d032fa9fd6d2a784af58e21d8a0f9e1aa48a6f53f5b30d58ffd6730de5f94ad89ed01d9ef86eb2b0b2eb0feac6fc04b92af7525d3fbcd8f6093fccde64532d9cb4d30c57fe1128cfd33eb77c1a41feb028cf7355a1f82e9f9ee1cec62ffea9b60f227892918e785f0bd8dfdafe9b3601a4f270463fda81980f17ea59adbbf3966fd41ef472dc14bf2075b1b6c60fdec4132d50f0bc9944f1cc126c693dad7bf5e9ff2075c6f63bd6b45fd33b1e6549fb8adc0580fdc7682c97fdd5ab035a5f74309c67961e50bec523c1de2f736eaf7f11c3ca4feaba8bfa6d664467fffdc080c7f53b492a97e6f08a6f686776013fab4964cf69982717ed224ff30b5b15fe81608c6fbd3ce60c48b2d8dd78cdd8ff2eb5430c5839b5730f2dff60086be74a4af33d6ff148fdd8391ff6a74bf390b30693de808b6917f64c436ce8fdf1230f6bfb7345e0b6b3a27fbe9c0f319bdaf8bfcc782a5f7e43f0f60cc4705f99f256b3fedf71c826d92ef3625b627349f68dcdf9b2c9f9b927f237d3458ffd1fc5b8327f007241f530f1aaf6b00467cad51ffb2f8674efd41fed5b6711ed0e4fac192cf39b57733022fe97ecf977feda32abf7d8c9f3e26ffa7827fa74fcf0afb9da5daaac3fe58ff6a0be8f3df21cb2f72b9ecf3bb5c0afe9b90afff77f7df5116d62247f5d81ffad87ddba87590cbfd87bfb3f1f9779605f20899fa6be8cfffb79fff167b71e9f393743ffadc1663f4e33aa96fbdedf8eccf3f18b9ffff65e16dfbc90e6009240d1fa9bf2b3bc9439ee0df4d1661eb3f64f9313a3f24f3e4e717cbfa7791e5379fecfefa91d758f05a8e94457a8a7f2b590235542335561335553335570b364ea55aa917b5669f86e951ab76ec7365b2de544dd5d99f15ff9dc67eb1fe379365a3aed827652391a85bf6b963d2ecd43dfbec982c07464726dd91fdfb4e3da9f74cce7bf5817d0c76e53ff4daff5b6479e43dfdc446e699fddb597d515fb94ebda9efea87faa906ec9a9449f8c524f85607ea501da96375a24ed5993a67d2fc1bc9c25a7a5637ec9f91ba607f02d8fd92c9f2cafe6929aafaa4284cc7be15431d2ba662b18fad380af31a8aa7f8ff3d92fcf7cc954aa0844aa4c44aa2a44aa6e44ccf5ca63d2dfbf4b6622a059b45064aa954ca45a9954669954eb92a3745537465a5acffe8b5ff37cab251b6ca9db253cf8aa2ec95036bf1513929f7ca83f2a83c29cfca5979515e9537e55df9503e952ff6dfbf9581325446ca589928d37f23596c65a6cc9505d3b393b26413cd83f261288661b044c0b00dc7700dcff08dc0088dc8888dc4488dccc88dc2288dcab8a87746fddf23c99f9345b58ca6ff23a390df6677a3353ae36adc0ccdd08d95b13636c6d6b83376c69efd391847e364dcb3cf897d8e8c1fd8e7d178329e8db3f162bc1a6fc6bbf1c1b4b0cf02685e757f9b797f9aadfe999ff8af6561527c1a5feccfb7313086c6c818315fd4186363624c8d194b9916c6b2370ad3304dd3326de3683aa68b8fc73ebe19b04f684666c465eaa53a9a31936a6726666a66666e16666956e6c5accdc66ccdcebc9a375333757365aecdcd2f33b1f2eb1cfcd764311a736bde3169becd9db9e7b21ccc8379344fe6bdf9603e9a4fe6b379365fcc57f3cd7c373fcc4ff38b7dbecd8139c467648ed967c23e63736aceccb9b960992a3334e3de322cd3b22cdb722cd7f22cdf0aacd08aacd84aacd4caacdc2aac12b9dc2f91c5ffaa2c56655dac4b3f2e566d0cad5a3d5b8dd55a9d75b56e9666e9d6ca5a5b1bd6d3f7ccd96ead3bd6522689b5b3f61677bfd6019f2393666a9dac7beb817d1ead27ebd93ab351da592fd6abf566bd5b1fd6274b98bf5884b0601e3d61b3e9c0faeea3cf1fd1d1bfa2634cb31a8bfe82f001fff74a89aca135b2c6d6c49a5a336b6e2d7acdb196cc74fa4a9ed18f85b5b34d48f2439643bf4c614e6ddb766cd77ab03ddbb7033bb42326cfc178b4633bb1533bb37336abda766197ea935dd997de92fecce74fc932307756cdc6646055aa67d77663b776675fed9badd9ba71303fec95bdb6376c249ef9676fed9924625414662bcc5e602bf766681bf6d6beb377f6de3eb0cfde3eda27fb9e8debde7eb01fed27fbd93eb319d7b35fec57656fbfb1d1b07efffcafc9f27cb16a66274cb78cc6f8b4df992c1ff6a7fd657fdb037bc8faf3c47a7864bbe6dc1edb137b6a2db924bb7e64fab161ff9cb1f6ce85fd9b91bdb0972c485698ddcc1dc3311d662c8eed384cd2bde33a9ee33b8113b218f5dd89545df17fcdecfe155954d7183ab113333bb1edda499cd4c9ec2f27778a5e0ea7640ff0ed3d6b55653d3b17361acf4cc706cc6216dc6ed8ff3b356b6be3b44ca6b9d3998173756e8e66f7938feeac9cb5b3b1b7ecf78eb365d21c8d9d73e7ec9cbd73708ecec9b9771e7ec9107ecb7a7eb6a03f234b2f09f3c683fe7ecea3f3e43c3b67e7c58cadb33db1ced6b33d6656cc3ece2b6b5dc5dab5c0a7f765ec63cfe9e374f8bc39efbd24f6d20e9d0f66fd47e7d3f9ea7fe954ce379366dffff5f6cec8e9ff5acca933b3eb9fe4f8576599ab9db3b05f9c25fba1e21a6ce2b08c23f34accd3bab6ebb8aebd702a73e17ab66b1f5d9ff9a8931b981fccdacfaca5f76ec86c2ae673e6d18ddcd84d98bde0e3746e6a7acc73b02b594fbcd93336be67377373b7704bb7722f6e6d176e63356e6b358ae67656f3afe8987a70afaaeddeecd6d55cdd5db96b3626cfeec6dd9a43f7ceddb97b3622dbde86dd837bb4576e6031ed331df7e4debb0feea3fbe43e1b817b765fdc472195fbeabeb9efec5707f7c3f9703fdd2ff7db1db84377c474f1c0fe7dec4edca93b73e7eec25daabd2f6091b8a7aa81f70fbdda9f91c533d8f46d79b6e778ae937b9e71b2179eef055ec8e4601fdbf0222ff612e6030eb6d1eb8c977a99977b85577a9577f16aaff15aaff3aedecdd33cdd5b796b36e7c7c6c9db785befce7a70471ebb0b1b5d9dfd3ff36fde8e59cec1db7b07efe89dbc7bb5f01e58467af31ebcc71f5af5bb1ff853b23c79cfded97bf15ebd37a730637362dbde3bd32f2e099368cbe6f229b39ae7de76bd0fefd3fbf2bebd8137f446ded89b78536fe6cdbd85b76441d7a3aff8866ffa966ffb8e71f45ddfb31e7c9ff9e8ad6df8811ff663e547ee8069e4831ffb899ffa198bd6be51bffd523c9189fe75599e2f7eee177ee957fec5af0d6603e6d46f7a49fc967d3aff6acead27ffd6cf77bee6ebfeca5ffb1b7febdff93b7fef1ffca37f62f966a2bef8f78aea3ff88ffe93ffec9ffd17ffd57ff3df8da3bdf03ffc4fff8bf9f485bd30c74ee57ffb037fe88f8cbd3ff627fed49ff9737fa1382c27fd6679f70f597ea97dfc99d8d25f066aa004060b112da65f6aff97c0f7fae5b7811d38fe3570cd0fe31478811f04411844411c24411a64411e14411954c14509839a7d1afb3d68838ee59af3e06a3f07b7400bf460c5fc48ef0d9560ddeb99ad30d906f6c27a0e36ecaedbe02ed8057ba50e0e4a191c8353708f0af54f35ab3f2d8b1d3c048fc153f01c9ccdd829ad73f012bcf6da15bc05ef81137c049fccf38c83afe03b1804c360148c8309fb330d66c19c49b47016c1325443253442d3188416fbc39c71e8865ee88741188651c86cc73a8709f3cb4698f29881c50f61d6fbfc300f8bb00cabf012d661e32fd421d3b41fb2387f94e5e77af6cf63d25f1db661175ec39b19875aa8b3bbafac636f27e13a5c33795e8c7b2f0d37e136bc0b77e13e3c84c7f014de870fe163f8143e8767f52d7c095fc337ab08dfc38ff033fc62d2982c22f6d97ff90e07e1301c8563e3184ed82cb40dd6e1943d63e6ee99fd7c9b53f6dfe7e1225c466aa428456444e68fcacdaf5a46b288ff862c28f1d4c8525fd5d7c88e1c7f19b9e673e41987c8376751c02375a61351c8e2f7cf88e524511c25511a65c62dca8347ab65f369cafe3c4645f01895aa1255d125aaa3266a5910d345d7e8166966678ccc75d4467ab48ad6d126da4677c629da452c82f0039ef778d68ecdb40bf6bc7d74888ed129ba77d2e8217aecefcdabed866af4d1eeaff6f2932c068fb043b77516ca2e7a8a9ea373f4629ea357f6a437e6750d16a79ca37773c2e6e8aad7eae823fa8cbea2ef68a0ce153f1a2aea8f2a2c7f9e1b8da27134096d2b8ca6d1cc8aa379b48896b11a2b56111b319bac629b85166eccbc3d9f73962c7f93b29843e33ef6e3200ea3fb388ae3f081f554cadbcafc5a1f25fe2c0b7ff68f7131d4f8f9e22cd4f73889d3388bf3b888cbb86277bcb0f87111d7d6dedd5b4f7c2639b959dcc46ddcc557ff515dfdb4f662cb3bbaca5875e25bacc5ba3f8b57f13adec4dbf82edec57ba5890fea323ec6a7f83e7e881fe327e3143fb3d866c9bc7380b86e689de373fc120ce2d76011bfc5effd88736b3055a38fdeff992c0ad34726cb6b9cb8adba8a3f4c23fe649db7641ec6b09ee3da665ed3fc0c33f6dcaff83b1ec4c378a456eaca7e51ee94713c862c3c1eecff9dfdb7493c55f57816cfe345bc4c54e3c17e4894c448ccc44aecc449dcc44bfc24484263efde9b3e8bd8d887e7a42c3b65f3d6d17c4da2244e92244db2a84872b1baf07765b1c886f8155b36bbb2fe65914fa2b8499194e69b71f26fd69e8dc9d9b998dff6c13ad953e39054c925a99326d6d5f7beea9db4ccca52f40d55c1d97d95bb385332bb4abae49adc12cd38252ceb4956c93ad924dbe42eba26bb641f1c9243724cd82c657a8ec272014364d94c9b4b2f4dee9387e4d158264f09b34ab146d2e722ff4c96e499f5e198e50e2bf6efe7e4257935dfad3e3f3f276f56ff8afa7df26ece8dfb709c7c249fc957f29d0c143d192a8b64c4abe3bdc7b4fbac8dc9c264b2df93713231de9269324be6c63159d8c76469c6a99a2aa9919aa995daa9e3dfa76eeaa5bef1603a2cbfe1b2f45910cb54b769601cd3308dd2384dd294cbc2d76dfa7cc4180aaff6932c96b0fe3453466e6b97cc8e9d344f8bb4343fd22a4c98f75a5afdfe8687f4621becee75daa46ddaa5d7d451f4a04b6fa996ea91c9fd3f978549c3644957e93adda4dbf42eddb15fedd3837d4c8fe9c9d8a7f7e943fa18fae953642b7a344c9fd373fa92bed2c8902c2ca7db4681719fbea5efe947fa997ef5feb197a56f7f9f5bfd2acb8f91e17a78607dbb5412ff2139a7dfce9069eb673ae86da5f7c54ee5fa696f8f553a4ac7e9249da6b3a4b50b65c3f42c5177fe23ef31361a7d0edad724d379ba4897999a29c63163f971b4efb3e3ccecb3e2649559999d39ea57ea0475e6665ee66781e9fa81a3a06ab0eb675096e1c5599845599c25ce23b3172e8b6af5b9d52fb2889a9add3f99d14efd4a064ccf952c553eb2cc74cc2fe61b077dcecbf477613d982316e37efaeb2ccf8aaccc2a61e7e45b98b34db24b56678d5dc763f53b6bb32ebb662c62f343d6df6ff6c2fd66de9c652c99661ce3a74ccf56d93adb306bd3b36d76e74efa5999c53363a603cf76bfcd8445369691edb23d93e5901db313d31d85db7491ddff268bf28b2ca67a973d3032b24743c99eb82ccc37f67d642ebcc4661146f69c9db397ec357bcbde852c1855577d4bdaec23fb8c9e93419a655fd97736c8d8e866a36cec8eb24936355da7cc66d9bcf7ebacbf17d93257734509552b377233b7723b77d8377d3d6dc29edad74398b7cedddccbfdec900779a828ff4496be024a7dabf8bd36f63edacc23c330ee982cbd97efed70c024619219f7799c27fe364ff32c3c30597eac4172bf95e779919779a556f925aff3266f8d63dee5d75eb7dc613f1ef9cdfdeeb3e25cb316f153aee7ab7cad9eed32dfe4dbfcced67396c1b09879c8729a4bafd9feb7719f29f93e3fe4c73cc88e4c9b1392c52afe812cbd0f559209d332db2ed5263f1926f32baed05ca6678eed5877ecbfbce6f7fe5dfe104cf347a3fd690d92d97afe943f671725cecff94bfe9abfe5ef7dd4937ff49909af719cddaf6cca73628dcd8871fe997fe5dff9404d9cc833f3613ecac7f1579ff1997dbc4c51b4cfee30c9a7f92cc9988e1d59a699f47e377c0bdffe200bb75792259fab7b854d65ea77be302c63cfd2fb1dd5bc481673943bf9b2500b8545f5b3e8814547b6dcabc0575793b1fa919f0ba33059b7d9ac557d2cbfe8f312ebaeb7e4c2e96b1785cb62ad53e1157e111461112923d52ee22229d22233f67d5ec365611ac6aecdd98cb92f8aa22caa3c2459faf6b398f5f597f9e5375958c6b34f6fcc62be8b0b7be4ce74a97227646177ae8ba6688b2e288a6b714bf25f7684303d53fc645268855eac8ab5710835e7b597a5d8b06cabaf6a7ef4d5be60cd243916dbe2aed815fbe2a0d8c5317b284ec57df1503c16cc3efa1a279764614e0b268f7128cec54bf15abcfd248b1aaa7f57164fcab22bde59fe742a3ed894b5efa33c5420875c9645f1597c15dfc5a01806398ba2c90bffd8555114a3625c4c8a692f4931ebd72c989ea8c5bc8f467b5b6677e03163b12cd5ecbb544287c540d7d250c2d22cadd22e9dd2354ebc22c2ae36c7f6a1f498cdc6a55f06e1ae64290dd731f7efc822d654c40cf3adb665c472b053191b2ecbef852cfb5e16f3cb3a9749999659996749745f163f564a7824669465599597b22e9b5e92b2cd34661b565f3b6371dc985bb4e10ffaaca7ecca6b79b3be4acd0a4a9d8d67c4a45995eb72536e992cbabdeda326368e5bebbecf64cabb7257ee7b591425cd7a6d28b552fb45961fd13ef773ea8dcd103b75c56439183e1bebc81c5b7d3d2cb0674e63cfcb63792aefcb87f2b17c6271ce86e527a398c594ca9d5d97cfe5b97c295fcbb7f29d79d12eef32adafee9bb3bebec13f337b5f7eb079bc2c3fcbaff2bb1c985d392c47e5b89c94d3c42d67e5bc5c944be3c45c7d156a7c4c0f665f1939564a655466d06746a7e0d4ef2ab2aadf62fedefb3059d8b7663f36c8d834bbaa2c26cbbd19b2deec97483a264b6b06c6a1b22bc79bc5e3a00996e5c4dc562e538ba86236cfa29545e5574115329fca66bb3ea736471513d73a313946fd9a4515dbdb2aa9d22aabf2aaa84a2bacaaea52d55553b5556745c1b1ba062b362e5ba7a355b57ebda3aff254b74aabf42467b21c83a36ad9f51f641151a5cf6571d488e9e246bd315559556b264bc4662c268b193269f64c96a37bf65a6fae2e2387e9eb5bb5a9b6d55db5abf6cab53a54c7ea54f575e17be6c717d681c5d5233e26a3fe2ebd3d570f4c96c7eaa97af646d5b97ab1aaead5dc556fd57bf5517d565ff128afabef5e966ac07ac2e5f5cf678bddb11a56a36a9ce4ce23c6c5339adf627e4bca6270efba60d1ee539ac5a36a524db98e912c51af654c965335f33a8f656bca3c34ccae9a87af9eaac6ac3f17d5f2a26637f7f5a25cb81fb615f38349d17f26b406c3ee7570377d7e75312fd6c5be38e1cbc5bd78179f8d897f092e6134b8449798c9d2b91fccbadefb159cde673059946a7449823e47f6d9c7fea32ca859283c96225912f549bdbfa4ec9e593fc6fdfa9c6df523d4af3d18a774e75d2fb9925e8ad0c8eefbbcfd525eaacbe5525f9a4b6b9c2edde56a6fcdd1e5165f98bd93244764f10773e445d68e5da55df4cbeab2b6c2cbe6b2bddc5d7655a7b697fde57039ba2fbd2c173633b1d8cde27fd5d684fde2fef27079e4b2a0adfd5add3f95256071f24d29c2faf27479eeb585d61bfb95a07ecd81e9d8a377f35545b3df7975c88ca6feec72bebc5c5ecdc4383afae58daf136d8235f75dbd7e8db92c7c3d96f5f196c5dd5333bebc5f3e2e9f97afcb777cbcf06a13d388e16578195dc66c869ddb6c66cd466c967db5ee7adbbf4c2ed3cb8ccba2f0bcc2fe5d16392f4096545373b5cdcf97f9657159f6eb90bdcdb2d8b85fd50accc08d8c83a7298f8a1fb4c620fca8d55a49b6b5519bc98ac9f9565bb56def1cc38bfaf99ecd8d336ef74cc7b8341e9b3146e6dcdef82cdeac9ddaadbddaaf83484b46e9ad0eeba88eeb84e5ca9fcce3796c6e9db008f4c9dd32590e755a67756e325990875bfd0aeaeff9cbcfb2287eaa2b6e5dd4a5f25557c68149c0bc0fb3dfa8978569716cc69eee2b6aa9cc422bfc8caa9a4590ec7f0d6b5beb7eb84347cdaf2c63af9cd73063f67faa22f6ebdeaff7d27875c746f9cbfc626d5cd6d7fa566bb55eafea35d36ca77c8af27a536fcdd8b9b23cdceb6318d6239bdec2eabb7a57efcb3d932515759e3fe695d8112074cc55efd44370523ae5b13e184cb3597e7f6fdbbc12cfda581f599b4ff57dfde0b6a1556d13b77eac9fea67e3549feb17a65b8bfab59f159cd728b02d1691ceeb37bfb1b7fe376fd994b220ca89acbdfb5abfd71ff56738a8bfeaef7a500fcba01e992ed3c27db17077aec3f29881cb324b63578feb493de5b2507ef20f7264f6a797a59ffb13f6ff0d9bfda7f5ac9ed70b9657b2fc8bc52e5b7b592f9d779bcdc98dda288de13f5a35f3ca1f8dd958c64363db47f6d9374e3f438693be6ed3fbb2c665ff34a2d0def09a9af1cb1ae0d074eb5be3357e1334a1f3d4444ddc244dcafae291e54977eeaec9ac2dfb158b429bbc299ab2a9b8bdd09ca8f42b763fcb42732397c5e4b364aa8cd2cc99c77a7369eaa6316377c3eefb7039352d0b8359d6e186c6aee99a6b738badd0b48a466b74fbc18c9b557aecc7c57c6fd64cdfc76c2c3efa5cbdd9345bebdcdcb9dbbe8283d53fac9c9b5ebfb3a4d935fbe6604d9a63736aee9b0726c363f3d43c3799bbeb6be64c2fe3e6dcbc34afcd9b948559c51f65a1d95ecaa2f1959bb5faa138cd7bf3c1a22ac7ff609e89d973bfa6686f9b4fe3e0dbcd57f31dbae167ad3483669828d60b7bde283359ae356bc66c961b46611f41369366dacc9ab971b296eeb6e1e3815566167d9b9ed3354b63efad5bb5555aa3355bcbe8ebd581396efb15c45d9f2b87ba71689dd66dbdd6ef63181e7719aadfaf09ff365752a5cfa4bdc2fdfa937a8bc76de03dc65d1b1afd4afdb658703fbbed6dba8d8c531bb7499b865ef5de666d9e9fdaa22ddbcad8370fed85595585fce4beaddba66ddbaebd5e5876dfded8bcf3ddd70ee4eabfefed5aaddf1de36baddeaeda755bb35f6dda6df0dede056f5ec89eb7734a63d7eedb437b6c4f52163f38fd41161bd97abff39945bc2c951e313ddbe5b9a2b7f7ed43fbc8b4f7686ffa9d05b5d53ef55adf326fdf9edb97f6d518861f4e5c44ed5bb269df59ccb3cf3b7bc9645ef5f949fbd17eb65fed773b6887eda865b3068b697aed123b19f67e906bf6b69db0acf8d44edb593b6751cb397875ed76d12e3bb59fdbeace38754a67746667c571922779af472c8e39fe4116e75759d84c99a94967770e93e6dab99d67192cd770d89cb063be56ef7c7b5b9f7d3753baa00bbba8da767197746997b1b0b8e8ca7e6dc8db75157bfea5abbbc6df756dd775d7eed6699ddeadfaac8e723b5ec95b326b687b8fe2fb4e65dce75db7ee36eeaedb76776c02d875fbe6397aef0eddb13b75f7dd43f7f8ab2cbfc563b40fdae2fbb87b59fabdb76ef7d43de7cfddb97be95e6bc738b9ae7de8ff1a4166c38eb3eddeba77964f9cba8feeb3fbeabe9d85fad80dba6137eac6d19d195b0b33f6b56ed24dbb5937ef16ddf2aa5e95ab71358d9dfbca7763f9bd1ce6d00ffa99fd6ad97bc7bada4cbe73b7bb322bb18ee1cadd5d5deffdea3109dfaffe35b886d7280fa302b66ffe1d1d13eb0b72bf196a7fdcef5de36b52b2d65d53ebe19ab119ef6c9dddcf7eb5f79ab3ff5a5ccb6bc5e29897ebe55a5bfeb5b9b6d7ee7acd27d7db55bb321d5533b30bdf8da69c5c57d7f57573dde6937efe655aa8f4750ce623a2be06c6f7638dd87c74ecfd38d515ade7de5aaa8171bcde5d77d7bdda3847b5edab2c5993353c07367f9c07f8afd7f89ca7ebe17a8cd953afa7eb3d3dddbf998b6641d1eef5e1fa787dba3e5fcfd797eb6bad3069deaeefd78febe7f5ebfa5d75d74139bc0eafa3eb987d26d7e975769d7b6bd60b8bcccccceb92dba2f5f327f2dd7d73c7fc1c27ebcc52c3a79b7263f955348c4c36f3b9aa6dbf33591cbebef31764b99937eb66df1cd6379ecb66877edf8bad140b2fb9b139d0b8f7b51b0b346f8152ddc25b748bd5db2db9a5b7ec96df8a68d025e15755df4a7377ab6e97f0e3c626c65b5bac6e9db1ef772df0fd16d6af1f5eafb0d86cc4246aee7236b3dcaeb7db4d4bc6d133cb2d44fefb87ddf3ffb52ce6e34dbfad6eeb86c5860d1b0d663515f3f8ecff6d8fc5eecc9fe593dbe6b6bdddd5a5fa62d7cae2b65386b7fdeda0d4ea58dd869f55773bde4eb7fbcbddede1f6787bba3ddfce51623f180fb71733643e7af24759983454afa4fbbfdede54f7f67efb48068a226ac97f7d7d3f2a6e9fb7afdbf76dc02b565f2cb35c58776c86d89a73162f6d6e43e3741bddc6b7c96d9abab759eadce6f1241ef77bf56f8bc80a5fa2eab6d4d4a8d394a85202f5ac199aa9599aadb1b16e5acdedade4e78fbbef3396c82759cc58f3345f0bb4508bf242d1d20ce3f287d3597fc25e1eb5584bb454cbfad981dd7b617e7a119385f624cdedad96f733a75668a5566917ad564325615ed0b65fe289b25322add15aadd3aedacdf84c1dd573979aa6e9da4a5b6b1b7ba16da99af0ebc8b03f2a8bb1ad7667dada9db653bba0b9bddbef2c7f37642dcfa1f8f22fc8926a7beda01db59376af3db008efce9cfa1f2c3bda71eb6451633568f92e43ed517bd29eb5b3f6a2bd46b935d2de8c85f61e4fb40f36269f2c216e94246ccb2767e999da97f6ad0d3436a6edeeefd98bf5dcee2c35f2b59136d6260a8bd955d72eed525db37111f562ef2fcbf2a84db59936d716da52578d7da8318f79673d9993b86e6fecb363518056b6bac26c79a71bbad92a9dab5bc64db77527327457c97596ee844e7fe622ce597e32d4033dd4233dd6133dedc7e0d74f98f5b2447e2f95bbd7333dcfebb2d20bf6fbfe0c84266b797c86ff2b3a16157aa957fa45aff5466ff5aedf11c3f2de39af8f322fa45ffb798faffbfaa6ebbe66817ed3355dd757fa5adfe85bfdcef850bff59dbe77c6d5413fe847fda4dfeb0ffaa3fe14bd07aece722db28dde4ef86e0bf3e78fe9e8e764adbfe8af4aa36ead86cdca34abf4f6eff075c43fbd8724c9f537fdbdb8ea1ffaa7fea57febcc07588affed6ed3ca56a3f7beea637afd3a561f4733895c33d687fa888dd0589fe8537da6cff585be5ca92b6565accc95e5eddd3c7ded778d38d5ca5e39b6e1eec90f0b0ff68b2cae7170dc95bbf2567e3c535f56415f310a4e2cdeea57df6a5a7bfb73b2048fab701505b355bc4a56e92a5be5ed78555807166b6efa5ccb3afe248bc9b28265dee5ceed8565b4b755b9aa5697555dcd568d3e5ab5b1c7f7c23129dcddaaeb76abab395e752c5bbbe3f66e626ef955166f7533e3b261f9d270a5b1f178e335567efeafaf2afd9571311f57fa6ab55a6bb362b8daacb6abbbcbc76ad75767d2a05f79b0b67d0ecf64796372ec983c0adfc570cff7819ef85efea3d8cf6bdcbbdf76e87ff8cd6abf3aac8ead1d7cb84edffa7e9e679aa6b63b6627bfcae2af4eab7b9643ad570fcdfbea919fce727f3a052c4f69fca971795a3dafceab176db67ad5ebd5dbea7df5b1fa8cbff26ef595f615a31fbbddf98749f7c177bc0f9d57f6795b7daf06d17e35147b2cfbbdbccd9339ee7739b58bd5a8d72e173b9358e3acdf65b1ceab717d67ec5693d574355bcd51c3b7708ec1fdf3314c92af16abe55a5d2b6b439badcdb5b5b6d7ceda5d7bc69e45cffb1f7bdefb489eaffb32097a7b62b3105fc7e3fba9f9beea7e36627e6318266b7f1dacc3c0091cbecb91452c6431bd17f85d967e7473dbd8d7efeb681dab77e20c2d9745f9b16be9cff8b1f03198af933c5d5bc1789daeb375be2ed6e5ba5a5fd6b5b5b437741601fbf7fbd5b30fbe57a25f6bb15a16fc34ceba757416dfb3e83e9ce9d77ecd807df6ebceefd6cc62bc50c8d2eeb411f366bfd90bd7d26374b7beadb53573e4b2fee5fed5793f628aba5eaf37ebedfa6ebd5befd787f5717d5adfaf1fd68feba790c5fdd69eef5ac1b8b04fbf9ef76a7e704b3e584bbedb9f5950bffba8f7e2eb7e97fcb1df83b63eaf5f02d736cc28effa73246c8e1feb193f73d2e7373edfafe4b23c69bb7e5dbf35cafa7dfdc1e617c8f2f7f78ffdf38ff3283f69566595d196e7f5e7fa6bfdbd1eac87eb11d335bea38c568b980e4db0afbf8fa6c6acc7cffc04c6b2dfadd7cbe90f7a7bea77569a43967505d5e0a69a713e6171d79d36d1f3f5b8f776eb49bfa3b61f93cb389f38de7aba9eade7eabdd8d32b674be7afc8f2d3d9621ecf798f6a11dcaf179774bdcc5f36ea46d9181bb37faead164ebf368979c230a77db5439cb4602336661ab91436d3dc39174ba1fd0a2caa7f6511e4ae0f0b36569fdfacc6cce59f8ce3c6c9271b77e36dfc4d607da94f56f35b9bfed2b8fc7eb6381a2a9ee2da55972acd26dc449b78936cd24db6c9f9aa0bcb6eac27ffdbf68bbc782effdf76ae6549552488eee733a6f615fdba7dbb6356a899203e5a6db51f3b4444f0c14b1489987f9faa8202a4bd37b457331113b9d010943a661645669d93b6d9e37b5a6207f5ce54d90a7b630ee6244ed8f3c2d4532060d9afca32ad349d280e4d481246103617866ae8b10a11c3b2b36c86248e1fe983506f36cb7bd7f59cde1344592e9dd23decc91c0e90c0115250a0014d680104cf80a691efb672cf7c667bc1191af13a6a6c8d2ed758790ea8a041fba8a546ca6681e23a2c67047dffd9b4a1130fb9e20cbad0833e2ce34747a706bc2c0e85fef98baee722bfd4f4404187dc51957668dcd0c2d0b660004318c12b8c61025378f3347fb13bb0acbe5df0f8ab3a31cdd0e01d3ee0136ee036e9c2ddb1ed7437f7e95459c13d7169c0bcfd003fe0117eb2bb700a4ff08c94def1b9eef5e9337dca1557dfc052a8ea8aefae6ed98c216b9d45ef4ffa485524aebeeaa181333471eeaa5edbb7f71bff47100423b4421517519a70a1686ff7106f632dbe471b97ebe0a027b3a4874ec8a276354cdffc603e255ca59dee228325a4b8c2354b719e8d29bbca113774bcb961e319c8f15c1f6327bd3884873ca043ee1bdcda7dce35430f7d0c30740718e10e636fed2f7ddd7f0cc2861b3aa1161991827b3cecfa8d66ec6112bce2115354f693204dfadb96d559cd6ccab25f967cd21655d61b3627a2d61336b0892d72a03dc20e53978ef868d8fa229f5faee75a7fe935c07eb745b764495b08ec7d0311d5f514356ca3bffd70224ff774bfb3f1822818bb5ad8461d3bd8c5de6e837df6fe0507fb088787258ef015c7d68bd0fa1a7cc79ef3f0a8623d21573237714a0f6bb636061dba66de58d0211dac1b76bfe293ef6039b59ad281736c393795d713791dceebf80ee712f96e3009ddd07544a5d179e13613e6e4967d435ca3ec245389a0cad56bfd58aad7bf7aee9fc122ff178e852391e3f3ba9c7d9399eff23a234758aeb7d96b869def6fe7fb0f468e60216ac18678a2378b9890bd31a42ee18c42f1d27b720dcf09969c1fb0909d7904e76ec356026184f0baafc89d66956e3da5fecbf6f6f369d67545d6b5c5d924df135a7ec542cb5e26e49a7cbfc201afa191da8093df3604f79408ae9ab0ad576031ca9ca3caca1635c83935653d22cfb448ce3bcf6adc752c32e62a9eb9443352aa19aaaae7e288acea1ab4729f2cb50e052bf5d4871cf952b02732ae47d9db635ea9689b453c57bc2062244752ad5f5e84c592fcc3e1ee4c949995795bc152fdbea830d827ffc84c20e9088f91d2fb395e4b665b520152c3422492ebf27dce3a1163b10a2cc60916c11710bad85b6ed69a7320cdc09db863ceee0a1533e20c1ccef6c814cd995eb334f9fc9ecf4b7ebda988b5c23b67b1108e04dff03d63da7fc32f8b9a5f4caeec2fc7c9c7e6f5bc5e154b795ce2e596e3679fca7dd222b624e3bc58134fe3a1e0bbcd199677fcb81c4b3d6a7ea7d6aeb0fb7e71ceb9a3f5738b7cbeda2ba7de3ba79caf57e52fff15fb1fcbbfd3fefcfbaf3ffe0193cc32fd</data>
+ </image>
+</images>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/pages/sidedecorationimpl.cpp b/util/install/win/pages/sidedecorationimpl.cpp
new file mode 100644
index 0000000..aa25825
--- /dev/null
+++ b/util/install/win/pages/sidedecorationimpl.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "sidedecorationimpl.h"
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qgrid.h>
+#include <qregexp.h>
+
+/* XPM */
+static char *check_data[] = {
+/* width height num_colors chars_per_pixel */
+" 11 12 4 1",
+/* colors */
+". c #939393",
+"# c #dcdcdc",
+"a c None",
+"b c #191919",
+/* pixels */
+"aaaaaaaaaa#",
+"aaaaaaaaabb",
+"aaaaaaaabba",
+"aaaaaaabbaa",
+"aaaaaabbaaa",
+"a#aaabbaaaa",
+"ab.a.b.aaaa",
+"a#bbbbaaaaa",
+"aabbbaaaaaa",
+"aa#b.aaaaaa",
+"aaa.aaaaaaa",
+"aaaaaaaaaaa"
+};
+
+/* XPM */
+static char *arrow_data[] = {
+/* width height num_colors chars_per_pixel */
+" 11 11 4 1",
+/* colors */
+". c None",
+"# c #b9b9b9",
+"a c #8a8a8a",
+"b c #0d0d0d",
+/* pixels */
+"...##......",
+"...ab#.....",
+"...abb#....",
+"...abbb#...",
+"...abbbb#..",
+"...abbbba..",
+"...abbba...",
+"...abba....",
+"...aba.....",
+"...aa......",
+"..........."
+};
+
+/* XPM */
+static char *cross_data[] = {
+/* width height num_colors chars_per_pixel */
+" 11 11 3 1",
+/* colors */
+". c #cc0000",
+"# c None",
+"a c #fc3464",
+/* pixels */
+"###########",
+"###########",
+"########a.#",
+"##a####a.##",
+"##a.###.###",
+"###a...a###",
+"####...####",
+"####...a###",
+"###.a##..##",
+"##a.####aa#",
+"##.########"
+};
+
+
+SideDecorationImpl::SideDecorationImpl( QWidget* parent, const char* name, WindowFlags fl ) :
+ SideDecoration( parent, name, fl ),
+ checkPix( ( const char** ) check_data ),
+ arrowPix( ( const char** ) arrow_data ),
+ crossPix( ( const char** ) cross_data ),
+ activeBullet( -1 )
+{
+ Q_ASSERT( layout() != 0 );
+ if ( layout()->inherits("QBoxLayout") ) {
+ ((QBoxLayout*)layout())->setMargin( 0 );
+ }
+ setSizePolicy( QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding) );
+ if ( globalInformation.reconfig() ) {
+ versionLabel->setText( "Reconfigure Qt " + globalInformation.qtVersionStr() );
+ } else {
+#if defined(QSA)
+ QString versionStr = globalInformation.qsaVersionStr();
+ versionStr.replace( QRegExp(" Evaluation"), "" );
+ versionLabel->setText( versionLabel->text().replace( "Qt", "QSA" ) + " " + versionStr );
+#elif defined(EVAL)
+ QString versionStr = globalInformation.qtVersionStr();
+ versionStr.replace( QRegExp(" Evaluation"), "" );
+ versionLabel->setText( versionLabel->text() + " " + versionStr );
+#elif defined(NON_COMMERCIAL)
+ QString versionStr = globalInformation.qtVersionStr();
+ versionStr.replace( QRegExp(" Non-Commercial"), "" );
+ versionLabel->setText( versionLabel->text() + " " + versionStr );
+#elif defined(EDU)
+ QString versionStr = globalInformation.qtVersionStr();
+ versionStr.replace( QRegExp(" Educational"), "" );
+ versionLabel->setText( versionLabel->text() + " " + versionStr );
+#else
+ versionLabel->setText( versionLabel->text() + " " + globalInformation.qtVersionStr() );
+#endif
+ }
+#if defined(EVAL)
+ editionLabel->setText( "Evaluation Version" );
+#elif defined(NON_COMMERCIAL)
+ editionLabel->setText( "Non-Commercial Edition" );
+#elif defined(EDU)
+ editionLabel->setText( "Educational Edition" );
+#else
+ editionLabel->setText( "" );
+#endif
+}
+
+SideDecorationImpl::~SideDecorationImpl()
+{
+}
+
+void SideDecorationImpl::wizardPages( const QPtrList<Page>& li )
+{
+ QBoxLayout *lay = 0;
+ Q_ASSERT( layout() != 0 );
+ if ( layout()->inherits("QBoxLayout") ) {
+ lay = (QBoxLayout*)layout();
+ } else {
+ return;
+ }
+ QPtrList<Page> list = li;
+ Page *page;
+ QGrid *grid = new QGrid( 2, this );
+ grid->setSpacing( 2 );
+ for ( page=list.first(); page; page=list.next() ) {
+ QLabel *l = new QLabel( grid );
+ l->setSizePolicy( QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed) );
+ bullets.append( l );
+ l = new QLabel( page->shortTitle(), grid );
+ }
+ lay->insertWidget( -1, grid );
+ lay->insertStretch( -1 );
+}
+
+void SideDecorationImpl::wizardPageShowed( int a )
+{
+ if ( activeBullet>=0 && (uint)activeBullet<bullets.count() ) {
+ if ( a < activeBullet )
+ bullets.at(activeBullet)->clear();
+ else
+ bullets.at(activeBullet)->setPixmap( checkPix );
+ }
+ bullets.at(a)->setPixmap( arrowPix );
+ activeBullet = a;
+}
+
+void SideDecorationImpl::wizardPageFailed( int a )
+{
+ bullets.at(a)->setPixmap( crossPix );
+}
diff --git a/util/install/win/pages/sidedecorationimpl.h b/util/install/win/pages/sidedecorationimpl.h
new file mode 100644
index 0000000..f39e204
--- /dev/null
+++ b/util/install/win/pages/sidedecorationimpl.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef SIDEDECORATIONIMPL_H
+#define SIDEDECORATIONIMPL_H
+
+#include "sidedecoration.h"
+#include "pages.h"
+#include <qpixmap.h>
+#include <qlabel.h>
+
+class SideDecorationImpl : public SideDecoration
+{
+ Q_OBJECT
+
+public:
+ SideDecorationImpl( QWidget* parent = 0, const char* name = 0, WindowFlags fl = 0 );
+ ~SideDecorationImpl();
+
+public slots:
+ void wizardPages( const QPtrList<Page>& );
+ void wizardPageShowed( int );
+ void wizardPageFailed( int );
+
+private:
+ QPixmap checkPix;
+ QPixmap arrowPix;
+ QPixmap crossPix;
+ QPtrList<QLabel> bullets;
+ int activeBullet;
+};
+
+#endif // SIDEDECORATIONIMPL_H
diff --git a/util/install/win/pages/winintropage.ui b/util/install/win/pages/winintropage.ui
new file mode 100644
index 0000000..ac2545b
--- /dev/null
+++ b/util/install/win/pages/winintropage.ui
@@ -0,0 +1,39 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>WinIntroPage</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>WinIntroPage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>387</width>
+ <height>228</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QTextBrowser">
+ <property name="name">
+ <cstring>textBrowser</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;It is strongly recommended that you exit all Windows programs before running this install program.&lt;/p&gt;&lt;p&gt;Click &lt;tt&gt;Cancel&lt;/tt&gt; to quit install and then close any programs you have running.&lt;/p&gt;&lt;p&gt;Click &lt;tt&gt;Next&lt;/tt&gt; to continue with the setup program.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/qt.arq b/util/install/win/qt.arq
new file mode 100644
index 0000000..f3f1ccc
--- /dev/null
+++ b/util/install/win/qt.arq
@@ -0,0 +1,3 @@
+This is just a dummy file. Use the package program to add the real qt.arq
+file to the package.
+This file must be smaller than 500 bytes.
diff --git a/util/install/win/resource.cpp b/util/install/win/resource.cpp
new file mode 100644
index 0000000..4ea0ad8
--- /dev/null
+++ b/util/install/win/resource.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "resource.h"
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qapplication.h>
+
+#ifdef Q_OS_WIN32
+#include <windows.h>
+#endif
+
+/*
+ Tries to load the binary resource \a resourceName. If the resource is
+ smaller than \a minimumSize, the resource is not loaded and isValid()
+ returns false. isValid() returns also false when the loading failed.
+ */
+ResourceLoader::ResourceLoader( char *resourceName, int minimumSize )
+{
+#if defined(Q_OS_WIN32)
+ valid = true;
+
+ HMODULE hmodule = GetModuleHandle( 0 );
+ // we don't need wide character versions
+ HRSRC resource = FindResourceA( hmodule, resourceName, MAKEINTRESOURCEA( 10 ) );
+ HGLOBAL hglobal = LoadResource( hmodule, resource );
+ arSize = SizeofResource( hmodule, resource );
+ if ( arSize == 0 ) {
+ valid = false;
+ return;
+ }
+ if ( arSize < minimumSize ) {
+ valid = false;
+ return;
+ }
+ arData = (char*)LockResource( hglobal );
+ if ( arData == 0 ) {
+ valid = false;
+ return;
+ }
+ ba.setRawData( arData, arSize );
+#elif defined(Q_OS_MAC)
+ valid = false;
+ arSize = 0;
+ arData = 0;
+ QFile f;
+ QString appDir = qApp->argv()[0];
+ int truncpos = appDir.findRev( "/Contents/MacOS/" );
+ if (truncpos != -1)
+ appDir.truncate( truncpos );
+ QString path = appDir + "/Contents/Qt/";
+ path += resourceName;
+ f.setName( path );
+ if (!f.open( IO_ReadOnly ))
+ return;
+ QFileInfo fi(f);
+ arSize = fi.size();
+ arData = new char[arSize];
+ if (f.readBlock( arData, arSize ) != arSize)
+ {
+ delete[] arData;
+ return;
+ }
+ ba.setRawData( arData, arSize );
+ valid = true;
+ return;
+#endif
+}
+
+ResourceLoader::~ResourceLoader()
+{
+ if ( isValid() )
+ ba.resetRawData( arData, arSize );
+#if defined(Q_OS_MAC)
+ delete[] arData;
+#endif
+}
+
+bool ResourceLoader::isValid() const
+{
+ return valid;
+}
+
+QByteArray ResourceLoader::data()
+{
+ return ba;
+}
+
+
+#if defined(Q_OS_WIN32)
+ResourceSaver::ResourceSaver( const QString& appName )
+ : applicationName(appName)
+{
+}
+
+ResourceSaver::~ResourceSaver()
+{
+}
+
+bool ResourceSaver::setData( char *resourceName, const QByteArray &data, QString *errorMessage )
+{
+ // we don't need wide character versions
+ HANDLE hExe = BeginUpdateResourceA( applicationName.latin1(), false );
+ if ( hExe == 0 ) {
+ if ( errorMessage )
+ *errorMessage = QString("Could not load the executable %1.").arg(applicationName);
+ return false;
+ }
+ if ( !UpdateResourceA(hExe,(char*)RT_RCDATA,resourceName,0,data.data(),data.count()) ) {
+ EndUpdateResource( hExe, true );
+ if ( errorMessage )
+ *errorMessage = QString("Could not update the executable %1.").arg(applicationName);
+ return false;
+ }
+ if ( !EndUpdateResource(hExe,false) ) {
+ if ( errorMessage )
+ *errorMessage = QString("Could not update the executable %1.").arg(applicationName);
+ return false;
+ }
+
+ if ( errorMessage )
+ *errorMessage = QString("Updated the executable %1.").arg(applicationName);
+ return true;
+}
+#endif
diff --git a/util/install/win/resource.h b/util/install/win/resource.h
new file mode 100644
index 0000000..791edfe
--- /dev/null
+++ b/util/install/win/resource.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef RESOURCE_H
+#define RESOURCE_H
+
+#include <qcstring.h>
+#include <qstring.h>
+
+class ResourceLoader
+{
+public:
+ ResourceLoader( char *resourceName, int minimumSize=0 );
+ ~ResourceLoader();
+
+ bool isValid() const;
+ QByteArray data();
+
+private:
+ bool valid;
+ int arSize;
+ char *arData;
+ QByteArray ba;
+};
+
+#if defined(Q_OS_WIN32)
+class ResourceSaver
+{
+public:
+ ResourceSaver( const QString& appName );
+ ~ResourceSaver();
+
+ bool setData( char *resourceName, const QByteArray &data, QString *errorMessage=0 );
+
+private:
+ QString applicationName;
+};
+#endif
+
+#endif // RESOURCE_H
diff --git a/util/install/win/setupwizardimpl.cpp b/util/install/win/setupwizardimpl.cpp
new file mode 100644
index 0000000..909d986
--- /dev/null
+++ b/util/install/win/setupwizardimpl.cpp
@@ -0,0 +1,2571 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "setupwizardimpl.h"
+#include "environment.h"
+#include <qfiledialog.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qprogressbar.h>
+#include <qtextview.h>
+#include <qmultilineedit.h>
+#include <qbuttongroup.h>
+#include <qsettings.h>
+#include <qlistview.h>
+#include <qlistbox.h>
+#include <qapplication.h>
+#include <qcheckbox.h>
+#include <qtextstream.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qcombobox.h>
+#include <qmessagebox.h>
+#include <qregexp.h>
+#include <qtabwidget.h>
+#include <qarchive.h>
+#include <qvalidator.h>
+#include <qdatetime.h>
+#include <qlayout.h>
+
+#include <keyinfo.h>
+#if defined(Q_OS_WIN32)
+
+#include <process.h>
+#endif
+
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+#include <check-and-patch.h>
+#endif
+
+#if defined(EVAL)
+# define LICENSE_DEST "LICENSE.EVAL"
+#elif defined(EDU)
+# define LICENSE_DEST "LICENSE.EDU"
+#elif defined(NON_COMMERCIAL)
+# define LICENSE_DEST "LICENSE.NON_COMMERCIAL"
+#else
+# define LICENSE_DEST "LICENSE"
+#endif
+
+#include "resource.h"
+#include "pages/sidedecorationimpl.h"
+
+#define FILESTOCOPY 4582
+
+static const char* const logo_data[] = {
+"32 32 238 2",
+"Qt c None",
+"#u c #000000",
+".# c #020204",
+"a. c #102322",
+"af c #282500",
+"as c #292e26",
+"a8 c #2c686a",
+"ae c #307072",
+"#C c #322a0c",
+"#s c #36320c",
+"am c #3b3d3f",
+"#3 c #3c8082",
+"#f c #3e3a0c",
+"## c #423e0c",
+"#9 c #434341",
+"ad c #438888",
+"aU c #458d8e",
+"#g c #46420c",
+"aM c #46494a",
+"ay c #474948",
+"#D c #4a4328",
+".W c #4a4611",
+"az c #4a4641",
+"a1 c #4a4a49",
+"aH c #4b9e9e",
+"au c #4d9a9f",
+"aS c #4e9a9a",
+"an c #4f4e4a",
+".X c #504e0c",
+"a7 c #51a4a9",
+"#0 c #525250",
+"aT c #55a6a3",
+".Y c #56520c",
+"#a c #5a5604",
+".Z c #5e5a0c",
+".V c #5e5e5c",
+"a0 c #5e5e60",
+"a6 c #5ea0a6",
+".J c #625e0c",
+"bB c #64aaa9",
+"#m c #665e2c",
+"aL c #686867",
+"bw c #68acb2",
+"bo c #696928",
+"ba c #696967",
+"aE c #69aeb2",
+"#z c #6a5614",
+".K c #6a660c",
+"aZ c #6a6a65",
+"bG c #6db4b4",
+".9 c #6e5e24",
+"#. c #6e6a5c",
+"bv c #6fb6b9",
+"bC c #706d28",
+"br c #70bcc5",
+"aQ c #71b7ba",
+".I c #726234",
+".L c #726e0c",
+".0 c #72720c",
+"#w c #746d44",
+"be c #747028",
+"bH c #747428",
+".M c #76720a",
+"aR c #78c1c2",
+"#Z c #797977",
+"a2 c #7a5d3d",
+"#H c #7a6614",
+"#I c #7a760a",
+"#l c #7a7634",
+".1 c #7a7a0c",
+"#e c #7a7a5c",
+"bL c #7bc0c2",
+"b. c #7c7d82",
+"#d c #7e6e34",
+".N c #7e7a0a",
+"bP c #816c20",
+".8 c #82763c",
+"#h c #827a3c",
+".x c #827e0c",
+"#t c #827f4b",
+".O c #828204",
+"#v c #828384",
+".P c #868604",
+"bq c #87d4d9",
+"#k c #89864b",
+"#c c #8a8244",
+".y c #8a8604",
+"#j c #8d8652",
+"al c #8d8d8a",
+"#b c #8e8644",
+".z c #8e8e04",
+"aW c #8f9094",
+"#i c #908952",
+"#Q c #909021",
+"ag c #90d0d2",
+"bO c #916f34",
+"bQ c #91cdd3",
+".7 c #928a44",
+"#p c #928e6c",
+"#P c #947f2f",
+".A c #949204",
+"bh c #949495",
+".6 c #968e4c",
+"aC c #999721",
+".w c #9a8a44",
+"#M c #9a9a99",
+"ap c #9b9b21",
+".5 c #9c924c",
+"#R c #9c9a04",
+"#7 c #9d9d9b",
+"ao c #9e7641",
+".4 c #9e964c",
+"#J c #9e9b21",
+".B c #9e9e04",
+"ac c #9e9e9d",
+"#S c #a09e21",
+"ax c #a0a0a3",
+"aK c #a1a1a2",
+"aX c #a1a1a4",
+".r c #a2a204",
+"#1 c #a2a221",
+"aF c #a2e1dd",
+".3 c #a49a54",
+".2 c #a69e54",
+"bR c #a78446",
+"#6 c #a9a9a8",
+".T c #aaa254",
+".s c #aaaa04",
+"#W c #abaaa6",
+"aN c #ac8861",
+".S c #aea25c",
+".R c #aea65c",
+".t c #aeae04",
+"#L c #b0b0b0",
+"#o c #b2ae94",
+".u c #b2b204",
+"aI c #b2b2b4",
+"b# c #b3b3b2",
+"#X c #b4b4b6",
+"#V c #b5b4b4",
+".Q c #b6aa5c",
+".n c #b6b604",
+"aY c #b6b6b7",
+"bN c #b79658",
+"ah c #b7e5e3",
+"aG c #b7ebe9",
+"ar c #b9d9dc",
+"#8 c #bcbcbe",
+"ab c #bdbdbe",
+".m c #beae5c",
+".F c #beb264",
+"aq c #bef6f6",
+"aB c #c1a470",
+"#F c #c1c1c3",
+".E c #c2b664",
+"at c #c2e9eb",
+"bI c #c39c6a",
+"bs c #c3a366",
+"#U c #c3c3c0",
+"aw c #c3c3c1",
+"#G c #c3c3c7",
+"aD c #c3f1f2",
+"a# c #c6c6c3",
+"#2 c #c7edf3",
+".D c #c8ba6c",
+"bM c #c9a470",
+"#N c #c9c9c4",
+".C c #cabe6c",
+"ak c #cacaca",
+"bx c #cbb076",
+"aa c #cbcbc9",
+"a3 c #ccac7f",
+".H c #ceba54",
+"#E c #ceced0",
+"bi c #cfaf7e",
+"#Y c #cfcfcb",
+"bK c #d1ac80",
+"#5 c #d1d1cf",
+"bu c #d2ae83",
+"bm c #d3b180",
+"bD c #d3b384",
+"bF c #d4b589",
+"aJ c #d4d4d3",
+".j c #d6c664",
+".v c #d6c674",
+"#K c #d6d6d5",
+"bJ c #d7b588",
+"bd c #d8b289",
+"bz c #d8b78d",
+".q c #d8ca74",
+"aj c #d8d8d9",
+"bb c #dabd97",
+"a5 c #dcba91",
+"bE c #dcc097",
+"aA c #ddc292",
+"aP c #dec491",
+".p c #dece75",
+"bk c #dfc79c",
+"av c #e0e0e0",
+"#A c #e2dabc",
+"#O c #e2e2e4",
+"aO c #e3c898",
+"by c #e4c7a1",
+".l c #e6da84",
+"a4 c #e7c7a2",
+"bt c #eacaa5",
+".o c #eede84",
+".G c #eee284",
+".i c #eee294",
+"bn c #efd7b4",
+".k c #f2e69c",
+".e c #f2eaa4",
+"bc c #f3d8b8",
+"bj c #f5e2c8",
+"#r c #f6eea4",
+".f c #f6eeb8",
+".g c #f6f2cc",
+".c c #faf6d4",
+".d c #fafae4",
+".U c #feee95",
+"bA c #fef26c",
+"#q c #fef2ac",
+"#x c #fef2b8",
+"bp c #fef684",
+"bl c #fef690",
+"bg c #fef69c",
+"bf c #fef6a4",
+".a c #fef6b4",
+"#B c #fef6c4",
+"#y c #fef6ce",
+"a9 c #fefaac",
+"aV c #fefab7",
+"ai c #fefac4",
+"#4 c #fefad1",
+"#n c #fefadf",
+".h c #fefaec",
+"#T c #fefee6",
+".b c #fefefa",
+"QtQtQtQtQtQtQtQtQtQtQtQt.#QtQtQtQtQtQt.#QtQtQtQtQtQtQtQtQtQtQtQt",
+"QtQtQtQtQtQtQtQtQtQt.#.#.a.#QtQtQtQt.#.b.#.#QtQtQtQtQtQtQtQtQtQt",
+"QtQtQtQtQtQtQtQt.#.#.a.a.a.a.#QtQt.#.c.d.b.b.#.#QtQtQtQtQtQtQtQt",
+"QtQtQtQtQtQt.#.#.e.e.e.e.e.e.e.#.#.f.f.g.g.c.h.b.#.#QtQtQtQtQtQt",
+"QtQtQtQt.#.#.i.i.i.i.i.i.i.i.j.j.b.b.k.e.f.f.g.g.c.d.#.#QtQtQtQt",
+"QtQt.#.#.l.l.l.l.l.l.l.l.m.m.n.n.o.o.b.b.k.k.e.f.f.g.g.c.#.#QtQt",
+"Qt.#.p.p.q.p.p.p.p.p.m.m.r.s.t.u.p.q.v.v.b.b.i.i.k.e.f.f.g.g.#Qt",
+"QtQt.#.j.j.j.j.j.w.w.x.y.z.A.B.r.C.C.D.E.E.F.b.b.o.G.k.k.e.#QtQt",
+"QtQtQt.#.H.H.I.I.J.K.L.M.N.O.P.z.Q.Q.Q.R.R.R.S.T.b.b.G.G.#QtQtQt",
+"Qt.#.#.U.V.W.W.W.X.Y.Z.J.K.L.0.1.2.3.3.4.5.5.6.6.7.8.9#..b.#.#Qt",
+"QtQtQt.#.U.U.U.W.W##.W.X.Y#a.J.K.7.7#b#b#b#c#c#d#d.h.h.b.#QtQtQt",
+"QtQtQtQt.##e.U.U.U.W.W#f#g.W.X.Y#h#i#j#k#l#m#m#n#n.h#g.#QtQtQtQt",
+"QtQtQtQt.##o#p#e#q#q#r#f#f#s#f#g#t#u#v#u#w#x#y#y#g#g#z.#QtQtQtQt",
+"QtQtQtQt.#.b#A#o#p#e#B#B#B#C#C#D#u#E#F#G#u#y#g#g#H#I#J#uQtQtQtQt",
+"QtQtQtQt.#.b.h.b#A#o#p#e.d.d.d#u#K#L#M#N#O#u#P#Q#R#S#u#u#uQtQtQt",
+"QtQtQtQt.#.b#T.h#T#n#A#o#p#e#u#U#V#W#X#Y#Z#0#u#1#S#u#2#3#uQtQtQt",
+"QtQtQtQt.##T.h#T#n#T#n#4#A#u#5#6#7#6#8#Z#0#9#u#S#u#2#3a.Qt#u#uQt",
+"QtQtQtQt.##T#n#T#4#4#4#4#u#Oa#aaabac#Z#9#9#u#S#u#2adaeaf#uagah#u",
+"QtQtQtQt.##n#n#4#4#4ai#u#Oajak#Yalamanao#u#Sap#uaqar#3asagatau#u",
+"QtQtQtQt.##T#4#4#4ai#uav#O#OawaxayazaAaB#uapaC#uaDaEaFaGataH#uQt",
+"QtQtQtQt.##4#4aiaiai#uaIaJ#OaKaLaMaNaOaPao#u#uaDaQaRaSaTaU#uQtQt",
+"QtQtQtQt.##4aiaV.aaV#uaWaXaYaZa0a1a2a3a4a5ao#ua6a7a8#u#u#uQtQtQt",
+"QtQtQtQt.#aiaiaiaV.aa9#ub.b#baa0#u#1#ubbbcbdao#ua8#ube.#.#.#.#Qt",
+"QtQtQtQt.#aV.aaVaVbfbfbg#ubhba#u#1.AaC#ubibjbkao#ube#a.#.#.#.#.#",
+"QtQtQtQt.#.aa9.abfa9bgbgbg#u#ubl.AaC#uaD#ubmbna5ao#ubo.#.#.#.#Qt",
+"QtQtQtQt.#.aa9a9bgbgblblblblbpbpaC#uaDbqbr#ubsbtbuao#u.#.#QtQtQt",
+"QtQtQtQtQt.#.#bgbgbgblblbpbpbpbp#uatbvbwa8#u#ubxbybzao#uQtQtQtQt",
+"QtQtQtQtQtQtQt.#.#blblbpbpbAbp#uaDbBbwa8#ubebC#ubDbEbFao#uQtQtQt",
+"QtQtQtQtQtQtQtQtQt.#.#bAbpbA#uaDbGbwa8#ubH.#.#Qt#ubIbJbKao#uQtQt",
+"QtQtQtQtQtQtQtQtQtQtQt.#.##uaDbLbwa8#u.#.#QtQtQtQt#ubMbNbObP#uQt",
+"QtQtQtQtQtQtQtQtQtQtQtQtQt#ubQbwa8#u.#QtQtQtQtQtQtQt#ubRbO#uQtQt",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQt#u#u#uQtQtQtQtQtQtQtQtQtQt#u#uQtQtQt"};
+
+static bool findFileInPaths( const QString &fileName, const QStringList &paths )
+{
+ QDir d;
+ for( QStringList::ConstIterator it = paths.begin(); it != paths.end(); ++it ) {
+ // Remove any leading or trailing ", this is commonly used in the environment
+ // variables
+ QString path = (*it);
+ if ( path.startsWith( "\"" ) )
+ path = path.right( path.length() - 1 );
+ if ( path.endsWith( "\"" ) )
+ path = path.left( path.length() - 1 );
+ if( d.exists( path + QDir::separator() + fileName ) )
+ return true;
+ }
+ return false;
+}
+
+bool findFile( const QString &fileName )
+{
+ QString file = fileName.lower();
+ QStringList paths;
+#if defined(Q_OS_WIN32)
+ QRegExp split( "[;,]" );
+#else
+ QRegExp split( "[:]" );
+#endif
+ if ( file.endsWith( ".h" ) ) {
+ if ( globalInformation.sysId() == GlobalInformation::Borland )
+ return true;
+ paths = QStringList::split( split, QEnvironment::getEnv( "INCLUDE" ) );
+ } else if ( file.endsWith( ".lib" ) ) {
+ if ( globalInformation.sysId() == GlobalInformation::Borland )
+ return true;
+ paths = QStringList::split( split, QEnvironment::getEnv( "LIB" ) );
+ } else {
+ paths = QStringList::split( split, QEnvironment::getEnv( "PATH" ) );
+ }
+ return findFileInPaths( file, paths );
+}
+
+static bool createDir( const QString& fullPath )
+{
+ QStringList hierarchy = QStringList::split( QDir::separator(), fullPath );
+ QString pathComponent, tmpPath;
+ QDir dirTmp;
+ bool success = true;
+
+ for( QStringList::Iterator it = hierarchy.begin(); it != hierarchy.end(); ++it ) {
+ pathComponent = *it + QDir::separator();
+ tmpPath += pathComponent;
+#if defined(Q_OS_WIN32)
+ success = dirTmp.mkdir( tmpPath );
+#else
+ success = dirTmp.mkdir( QDir::separator() + tmpPath );
+#endif
+ }
+ return success;
+}
+
+SetupWizardImpl::SetupWizardImpl( QWidget* parent, const char* name, bool modal, WindowFlags flag ) :
+ QWizard( parent, name, modal, flag ),
+ tmpPath( QEnvironment::getTempPath() ),
+ fixedPath(false),
+ filesCopied( false ),
+ filesToCompile( 0 ),
+ filesCompiled( 0 ),
+ licensePage( 0 ),
+ licenseAgreementPage( 0 ),
+ licenseAgreementPageQsa( 0 ),
+ optionsPage( 0 ),
+ optionsPageQsa( 0 ),
+ foldersPage( 0 ),
+ configPage( 0 ),
+ progressPage( 0 ),
+ buildPage( 0 ),
+ finishPage( 0 )
+{
+ // initialize
+ if ( !name )
+ setName( "SetupWizard" );
+ resize( 600, 390 );
+#if defined(QSA)
+ setCaption( trUtf8( "QSA Installation Wizard" ) );
+#else
+ setCaption( trUtf8( "Qt Installation Wizard" ) );
+#endif
+ QPixmap logo( ( const char** ) logo_data );
+ setIcon( logo );
+#if defined(QSA)
+ setIconText( trUtf8( "QSA Installation Wizard" ) );
+#else
+ setIconText( trUtf8( "Qt Installation Wizard" ) );
+#endif
+ QFont f( font() );
+ f.setFamily( "Arial" );
+ f.setPointSize( 12 );
+ f.setBold( true );
+ setTitleFont( f );
+
+ totalFiles = 0;
+
+ // try to read the archive header information and use them instead of
+ // QT_VERSION_STR if possible
+ QArchiveHeader *archiveHeader = 0;
+ ResourceLoader rcLoader( "QT_ARQ", 500 );
+ if ( rcLoader.isValid() ) {
+ // First, try to find qt.arq as a binary resource to the file.
+ QArchive ar;
+ QDataStream ds( rcLoader.data(), IO_ReadOnly );
+ archiveHeader = ar.readArchiveHeader( &ds );
+ } else {
+ // If the resource could not be loaded or is smaller than 500
+ // bytes, we have the dummy qt.arq: try to find and install
+ // from qt.arq in the current directory instead.
+ QArchive ar;
+ QString archiveName = "qt.arq";
+# if defined(Q_OS_MAC)
+ QString appDir = qApp->argv()[0];
+ int truncpos = appDir.findRev( "/Contents/MacOS/" );
+ if (truncpos != -1)
+ appDir.truncate( truncpos );
+ archiveName = appDir + "/Contents/Qt/qtmac.arq";
+# endif
+ ar.setPath( archiveName );
+ if( ar.open( IO_ReadOnly ) ) {
+ archiveHeader = ar.readArchiveHeader();
+ }
+ }
+
+#if defined(QSA)
+ ResourceLoader rcLoaderQsa( "QSA_ARQ", 500 );
+ if ( rcLoaderQsa.isValid() ) {
+ // First, try to find qt.arq as a binary resource to the file.
+ QArchive ar;
+ QDataStream ds( rcLoaderQsa.data(), IO_ReadOnly );
+ QArchiveHeader *archiveHeaderQsa = ar.readArchiveHeader( &ds );
+ if ( archiveHeaderQsa ) {
+ QString qsa_version_str = archiveHeaderQsa->description();
+ if ( !qsa_version_str.isEmpty() )
+ globalInformation.setQsaVersionStr( qsa_version_str );
+ delete archiveHeaderQsa;
+ }
+ }
+#endif
+
+#if defined(Q_OS_WIN32)
+ // First check for MSVC 6.0
+ QString regValue = QEnvironment::getRegistryString( "Software\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++", "ProductDir", QEnvironment::LocalMachine );
+ if (!regValue.isEmpty())
+ globalInformation.setSysId(GlobalInformation::MSVC);
+
+ // MSVC.NET 7.0 & 7.1 takes presedence over 6.0
+ regValue = QEnvironment::getRegistryString( "Software\\Microsoft\\VisualStudio\\7.0", "InstallDir", QEnvironment::LocalMachine );
+ if (regValue.isEmpty())
+ regValue = QEnvironment::getRegistryString( "Software\\Microsoft\\VisualStudio\\7.1", "InstallDir", QEnvironment::LocalMachine );
+ if (!regValue.isEmpty())
+ globalInformation.setSysId(GlobalInformation::MSVCNET);
+
+ while (globalInformation.sysId() == GlobalInformation::Other) {
+ globalInformation.setSysId(GlobalInformation::Borland);
+ if (findFile(globalInformation.text(GlobalInformation::MakeTool)))
+ break;
+ globalInformation.setSysId(GlobalInformation::MSVCNET);
+ if (findFile(globalInformation.text(GlobalInformation::MakeTool)))
+ break;
+ globalInformation.setSysId(GlobalInformation::MinGW);
+ if (findFile(globalInformation.text(GlobalInformation::MakeTool)))
+ break;
+ globalInformation.setSysId(GlobalInformation::Watcom);
+ if (findFile(globalInformation.text(GlobalInformation::MakeTool)))
+ break;
+ }
+#endif
+
+ if ( archiveHeader ) {
+ QString qt_version_str = archiveHeader->description();
+ if ( !qt_version_str.isEmpty() )
+ globalInformation.setQtVersionStr( qt_version_str );
+
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ if ( archiveHeader->findExtraData( "compiler" ) == "borland" )
+ globalInformation.setSysId(GlobalInformation::Borland);
+#endif
+ delete archiveHeader;
+ }
+
+ initPages();
+ initConnections();
+
+ if (optionsPage) {
+#if defined(QSA)
+ optionsPage->installPath->setText(
+ QString( "C:\\Qt_QSA\\Qt" ) +
+ QString( globalInformation.qtVersionStr() ).replace( QRegExp("\\s"), "" ).replace( QRegExp("-"), "" )
+ );
+#endif
+ }
+ if ( optionsPageQsa ) {
+#if defined(QSA)
+ optionsPageQsa->installPath->setText(
+ QString( "C:\\Qt_QSA\\QSA" ) +
+ QString( globalInformation.qsaVersionStr() ).replace( QRegExp("\\s"), "" ).replace( QRegExp("-"), "" )
+ );
+#endif
+ }
+ readLicense( QDir::homeDirPath() + "/.qt-license" );
+}
+
+static bool copyFile( const QString& src, const QString& dest )
+{
+#ifdef Q_WS_WIN
+ QT_WA( {
+ return CopyFileW( (const wchar_t*)src.ucs2(), (const wchar_t*)dest.ucs2(), false );
+ }, {
+ return CopyFileA( src.local8Bit(), dest.local8Bit(), false );
+ } );
+#else
+ int len;
+ const int buflen = 4096;
+ char buf[buflen];
+ QFileInfo info( src );
+ QFile srcFile( src ), destFile( dest );
+ if (!srcFile.open( IO_ReadOnly ))
+ return false;
+ destFile.remove();
+ if (!destFile.open( IO_WriteOnly ))
+ return false;
+
+ while (!srcFile.atEnd()) {
+ len = srcFile.readBlock( buf, buflen );
+ if (len <= 0)
+ break;
+ if (destFile.writeBlock( buf, len ) != len)
+ return false;
+ }
+ destFile.flush();
+ return true;
+#endif
+}
+
+void SetupWizardImpl::initPages()
+{
+#define ADD_PAGE( var, Class ) \
+ { \
+ var = new Class( this, #var ); \
+ SideDecorationImpl *sideDeco = new SideDecorationImpl( var ); \
+ \
+ Q_ASSERT( var->layout() != 0 ); \
+ if ( var->layout()->inherits("QBoxLayout") ) { \
+ ((QBoxLayout*)var->layout())->insertWidget( 0, sideDeco ); \
+ ((QBoxLayout*)var->layout())->insertSpacing( 1, 10 ); \
+ } \
+ \
+ pages.append( var ); \
+ addPage( var, var->title() ); \
+ setHelpEnabled( var, false ); \
+ \
+ connect( this, SIGNAL(wizardPages(const QPtrList<Page>&)), \
+ sideDeco, SLOT(wizardPages(const QPtrList<Page>&)) ); \
+ connect( this, SIGNAL(wizardPageShowed(int)), \
+ sideDeco, SLOT(wizardPageShowed(int)) ); \
+ connect( this, SIGNAL(wizardPageFailed(int)), \
+ sideDeco, SLOT(wizardPageFailed(int)) ); \
+ connect( this, SIGNAL(editionString(const QString&)), \
+ sideDeco->editionLabel, SLOT(setText(const QString&)) ); \
+ }
+
+ QPtrList<Page> pages;
+ if( globalInformation.reconfig() ) {
+ ADD_PAGE( configPage, ConfigPageImpl )
+ ADD_PAGE( buildPage, BuildPageImpl )
+ ADD_PAGE( finishPage, FinishPageImpl )
+ } else {
+#if defined(Q_OS_WIN32)
+ ADD_PAGE( winIntroPage, WinIntroPageImpl )
+#endif
+#if !defined(EVAL_CD) && !defined(NON_COMMERCIAL)
+ ADD_PAGE( licensePage, LicensePageImpl )
+#endif
+ ADD_PAGE( licenseAgreementPage, LicenseAgreementPageImpl)
+#if defined(QSA)
+ ADD_PAGE( licenseAgreementPageQsa, LicenseAgreementPageImpl)
+#endif
+ ADD_PAGE( optionsPage, OptionsPageImpl )
+#if defined(QSA)
+ ADD_PAGE( optionsPageQsa, OptionsPageImpl )
+#endif
+#if !defined(Q_OS_UNIX)
+ ADD_PAGE( foldersPage, FoldersPageImpl )
+#endif
+ ADD_PAGE( configPage, ConfigPageImpl )
+ ADD_PAGE( progressPage, ProgressPageImpl )
+ ADD_PAGE( buildPage, BuildPageImpl )
+ ADD_PAGE( finishPage, FinishPageImpl )
+ }
+#undef ADD_PAGE
+
+ if ( licensePage ) {
+ setNextEnabled( licensePage, false );
+ }
+ if ( licenseAgreementPage ) {
+ setNextEnabled( licenseAgreementPage, false );
+ }
+ if ( licenseAgreementPageQsa ) {
+ setNextEnabled( licenseAgreementPageQsa, false );
+ licenseAgreementPage->titleStr = "License agreement Qt";
+ licenseAgreementPageQsa->titleStr = "License agreement QSA";
+ }
+ if ( optionsPage ) {
+ setBackEnabled( optionsPage, false );
+ }
+ if ( optionsPageQsa ) {
+ optionsPageQsa->installExamples->hide();
+ optionsPageQsa->installTools->hide();
+ optionsPageQsa->installExtensions->hide();
+ optionsPageQsa->installTutorials->hide();
+ optionsPageQsa->skipBuild->hide();
+ optionsPageQsa->installDocs->hide();
+ optionsPageQsa->sysGroup->hide();
+ optionsPageQsa->pathLabel->setText("QSA destination &path");
+
+ optionsPage->titleStr = "Options for Qt";
+ optionsPage->shortTitleStr = "Choose options for Qt";
+ optionsPageQsa->titleStr = "Options for QSA";
+ optionsPageQsa->shortTitleStr = "Choose options for QSA";
+ }
+ if ( configPage )
+ setBackEnabled( configPage, false );
+ if ( progressPage ) {
+ setBackEnabled( progressPage, false );
+ setNextEnabled( progressPage, false );
+ }
+ if ( buildPage ) {
+ setBackEnabled( buildPage, false );
+ setNextEnabled( buildPage, false );
+ }
+ if ( finishPage ) {
+ setBackEnabled( finishPage, false );
+ setFinishEnabled( finishPage, true );
+ }
+ emit wizardPages( pages );
+}
+
+void SetupWizardImpl::initConnections()
+{
+ connect( &autoContTimer, SIGNAL( timeout() ), this, SLOT( timerFired() ) );
+
+ if ( optionsPage ) {
+ connect( optionsPage->sysGroup, SIGNAL(clicked(int)), SLOT(clickedSystem(int)));
+ connect( optionsPage->sysOtherCombo, SIGNAL(activated(int)), SLOT(sysOtherComboChanged(int)));
+ }
+ if ( foldersPage ) {
+ connect( foldersPage->folderPathButton, SIGNAL(clicked()), SLOT(clickedFolderPath()));
+ connect( foldersPage->devSysPathButton, SIGNAL(clicked()), SLOT(clickedDevSysPath()));
+ }
+ if ( licensePage ) {
+ connect( licensePage->readLicenseButton, SIGNAL(clicked()), SLOT(clickedLicenseFile()));
+ connect( licensePage->customerID, SIGNAL(textChanged(const QString&)), SLOT(licenseChanged()));
+ connect( licensePage->licenseID, SIGNAL(textChanged(const QString&)), SLOT(licenseChanged()));
+ connect( licensePage->licenseeName, SIGNAL(textChanged(const QString&)), SLOT(licenseChanged()));
+ connect( licensePage->expiryDate, SIGNAL(textChanged(const QString&)), SLOT(licenseChanged()));
+ connect( licensePage->productsString, SIGNAL(activated(int)), SLOT(licenseChanged()));
+ connect( licensePage->key, SIGNAL(textChanged(const QString&)), SLOT(licenseChanged()));
+ }
+ if ( configPage ) {
+ connect( configPage->configTabs, SIGNAL(currentChanged(QWidget*)), SLOT(configPageChanged()));
+ }
+ if ( buildPage ) {
+ connect( &configure, SIGNAL( processExited() ), this, SLOT( configDone() ) );
+ connect( &configure, SIGNAL( readyReadStdout() ), this, SLOT( readConfigureOutput() ) );
+ connect( &configure, SIGNAL( readyReadStderr() ), this, SLOT( readConfigureError() ) );
+ connect( &make, SIGNAL( processExited() ), this, SLOT( makeDone() ) );
+ connect( &make, SIGNAL( readyReadStdout() ), this, SLOT( readMakeOutput() ) );
+ connect( &make, SIGNAL( readyReadStderr() ), this, SLOT( readMakeError() ) );
+ connect( buildPage->restartBuild, SIGNAL(clicked()), this, SLOT(restartBuild()) );
+ }
+}
+
+void SetupWizardImpl::stopProcesses()
+{
+ if( cleaner.isRunning() )
+ cleaner.kill();
+ if( configure.isRunning() )
+ configure.kill();
+ if( make.isRunning() )
+ make.kill();
+}
+
+void SetupWizardImpl::clickedFolderPath()
+{
+ foldersPage->folderPath->setText( shell.selectFolder( foldersPage->folderPath->text(), ( foldersPage->folderGroups->currentItem() == 0 ) ) );
+}
+
+void SetupWizardImpl::clickedDevSysPath()
+{
+ QDir dir( foldersPage->devSysPath->text() );
+ if( !dir.exists() )
+ dir.setPath( devSysFolder );
+
+ QString dest = QFileDialog::getExistingDirectory( dir.absPath(), this, 0, "Select the path to Microsoft Visual Studio" );
+ if (!dest.isNull())
+ foldersPage->devSysPath->setText( dest );
+}
+
+void SetupWizardImpl::sysOtherComboChanged(int)
+{
+ clickedSystem(GlobalInformation::Other);
+}
+
+static QString getDirectoryList(const char *envvar)
+{
+ QString environment;
+ const char *cpath = getenv(envvar);
+ if (cpath) {
+ environment = QString::fromLocal8Bit(cpath);
+ environment = QStringList::split(QRegExp("[;,]"), environment).join("\n");
+ } else {
+ environment = "<Environment variable empty>";
+ }
+ return environment;
+}
+
+void SetupWizardImpl::clickedSystem( int sys )
+{
+#ifndef Q_OS_MACX
+ if (sys == 99) // This is the Integrate with IDE checkbox
+ return;
+ globalInformation.setSysId( GlobalInformation::SysId(sys) );
+ if (sys == GlobalInformation::Other) {
+ if (optionsPage->sysOtherCombo->currentText() == "win32-watcom")
+ globalInformation.setSysId(GlobalInformation::Watcom);
+ }
+ if (!isVisible())
+ return;
+ QString makeCmd = globalInformation.text(GlobalInformation::MakeTool);
+ QString environment;
+ fixedPath = false;
+ if ( !optionsPage->skipBuild->isChecked() && optionsPage->skipBuild->isEnabled() ) {
+ QString commandTool;
+ environment = getenv("COMSPEC");
+ if( qWinVersion() & WV_DOS_based )
+ commandTool = "command.com";
+ else
+ commandTool = "cmd.exe";
+ if (!environment.isEmpty() && !environment.endsWith(commandTool, false)) {
+ if (QMessageBox::critical(this, "Environment problems",
+ "The 'COMSPEC' environment variable is not set to use\n"
+ "'" + commandTool + "'. This could cause some problems when building.\n"
+ "If you have difficulty then change it to use '" + commandTool + "'\n"
+ "and restart the installation\n\n"
+ "Please contact your local system administration if you have\n"
+ "difficulties finding the file, or if you don't know how to\n"
+ "modify the environment settings on your system.\n\n"
+ "Alternatively, by clicking yes, the installer will try to set\n"
+ "these for you.",
+ QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
+ fixEnvironment("COMSPEC", commandTool);
+ }
+ if( !findFile( makeCmd ) ) {
+ environment = getDirectoryList("PATH");
+ // ### try to adjust environment
+ if (QMessageBox::critical(this, "Environment problems",
+ "The make tool '" + makeCmd + "' could not be located in any\n"
+ "directory listed in the 'PATH' environment variable:"
+ "\n\n" + environment + "\n\n"
+ "Make sure the path to this file is present in the PATH environment\n"
+ "variable and restart the installation.\n"
+ "\n"
+ "You can find the path to the tool using the 'Find' tool\n"
+ "and add the location to the environment settings of your\n"
+ "system. Please contact your local system administration if\n"
+ "you have difficulties finding the files, or if you don't\n"
+ "know how to modifiy the environment settings of your system.\n\n"
+ "Alternatively, by clicking yes, the installer will try to set\n"
+ "these for you.",
+ QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
+ fixEnvironment("PATH", makeCmd);
+ }
+ if (globalInformation.sysId() != GlobalInformation::Borland && globalInformation.sysId() != GlobalInformation::MinGW) {
+ if (!findFile( "string.h" ) ) {
+ environment = getDirectoryList("INCLUDE");
+ // ### try to adjust environment
+ if (QMessageBox::critical(this, "Environment problems",
+ "The file 'string.h' could not be located in any directory\n"
+ "listed in the 'INCLUDE' environment variable:\n\n" + environment + "\n\n"
+ "You might have to install the platform headers, or adjust\n"
+ "the environment variables of your system, and restart the\n"
+ "installation.\n\n"
+ "Please contact your local system administration if you have\n"
+ "difficulties finding the file, or if you don't know how to\n"
+ "modify the environment settings on your system.\n\n"
+ "Alternatively, by clicking yes, the installer will try to set\n"
+ "these for you.",
+ QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
+ fixEnvironment("INCLUDE", "string.h");
+
+ }
+ if (!findFile("ole32.lib")) {
+ environment = getDirectoryList("LIB");
+ // ### try to adjust environment
+ if (QMessageBox::critical(this, "Environment problems",
+ "The file 'ole32.lib' could not be located in any directory\n"
+ "listed in the 'LIB' environment variable:\n\n" + environment + "\n\n"
+ "You might have to install the platform libraries, or adjust\n"
+ "the environment variables of your system, and restart the\n"
+ "installation.\n\n"
+ "Please contact your local system administration if you have\n"
+ "difficulties finding the file, or if you don't know how to\n"
+ "modify the environment settings on your system.\n\n"
+ "Alternatively, by clicking yes, the installer will try to set\n"
+ "these for you.",
+ QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
+ fixEnvironment("LIB", "ole32.lib");
+
+ }
+ bool foundCommonDll = false;
+ QString commonDll;
+ QString commonDllText;
+ QString presentFileText = "Make sure the path to this file is present in the PATH environment\n";
+ if (globalInformation.sysId() == GlobalInformation::MSVC) {
+ commonDll = "mspdb60.dll";
+ foundCommonDll = findFile(commonDll);
+ commonDllText = "The file 'mspdb60.dll' ";
+ } else if(globalInformation.sysId() == GlobalInformation::MSVCNET) {
+ commonDll = "mspdb70.dll";
+ foundCommonDll = findFile(commonDll);
+ if (!foundCommonDll) {
+ commonDll = "mspdb71.dll";
+ foundCommonDll = findFile(commonDll);
+ commonDllText = "The files 'mspdb70.dll' and 'mspdb71.dll' "; // VC 7.0 or VC 7.1
+ presentFileText = "Make sure the path to one of these files is present in the PATH environment\n";
+ }
+ } else {
+ foundCommonDll = true;
+ }
+ if(!foundCommonDll && !fixedPath) {
+ environment = getDirectoryList("PATH");
+ // ### try to adjust environment
+ if (QMessageBox::critical(this, "Environment problems",
+ commonDllText + "could not be located in any\n"
+ "directory listed in the 'PATH' environment variable:"
+ "\n\n" + environment + "\n\n"
+ + presentFileText +
+ "variable and restart the installation.\n"
+ "\n"
+ "You can find the path to the tool using the 'Find' tool\n"
+ "and add the location to the environment settings of your\n"
+ "system. Please contact your local system administration if\n"
+ "you have difficulties finding the files, or if you don't\n"
+ "know how to modifiy the environment settings of your system.\n\n"
+ "Alternatively, by clicking yes, the installer will try to set\n"
+ "these for you.",
+ QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
+ fixEnvironment("PATH", commonDllText);
+
+ }
+ }
+ if (globalInformation.sysId() == GlobalInformation::Intel && !findFile("icl.exe")) {
+ environment = getDirectoryList("PATH");
+ if (QMessageBox::critical(this, "Environment problems",
+ "The Intel C++ compiler (icl.exe) could not be found\n"
+ "in your PATH:\n\n" + environment + "\n\n"
+ "Make sure the path to this file is present in the PATH environment\n"
+ "variable and restart the installation.\n"
+ "\n"
+ "You can find the path to the tool using the 'Find' tool\n"
+ "and add the location to the environment settings of your\n"
+ "system. Please contact your local system administration if\n"
+ "you have difficulties finding the files, or if you don't\n"
+ "know how to modifiy the environment settings of your system.\n\n"
+ "Alternatively, by clicking yes, the installer will try to set\n"
+ "these for you.",
+ QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
+ fixEnvironment("PATH", "icl.exe");
+
+ }
+ }
+#endif
+}
+
+void SetupWizardImpl::fixEnvironment(const QString &var, const QString &file)
+{
+ if (var == "COMSPEC" || !(globalInformation.sysId() == GlobalInformation::MSVC ||
+ globalInformation.sysId() == GlobalInformation::MSVCNET)) {
+ QString fn = QDir::toNativeSeparators(QFileDialog::getOpenFileName(QString(), QString(), this, 0,
+ "Please find " + file));
+ QString envs = getenv(var);
+ if (var != "COMSPEC") {
+ fn.truncate(fn.findRev("\\") - 1);
+ fn += ";" + envs;
+ }
+ if (!fn.isEmpty())
+ QEnvironment::putEnv(var, fn, QEnvironment::PersistentEnv | QEnvironment::LocalEnv);
+ } else if (globalInformation.sysId() == GlobalInformation::MSVC) {
+ QString visualStudio =
+ QEnvironment::getRegistryString("Software\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual Studio",
+ "ProductDir", QEnvironment::LocalMachine);
+ if (var == "PATH" && !fixedPath) {
+ QString newPaths = visualStudio + "\\vc98\\bin;";
+ newPaths += visualStudio + "\\Common\\MSDev98\\Bin;";
+ if (qWinVersion() & Qt::WV_NT_based)
+ newPaths += visualStudio + "\\Common\\Tools\\WinNT;";
+ else
+ newPaths += visualStudio + "\\Common\\Tools\\Win95;";
+ QEnvironment::putEnv("PATH", newPaths + getenv("PATH"),
+ QEnvironment::PersistentEnv | QEnvironment::LocalEnv);
+ fixedPath = true;
+ } else if (var == "LIB") {
+ QString newPaths = visualStudio + "\\vc98\\lib;";
+ newPaths += visualStudio + "\\vc98\\mfc\\lib;";
+ QEnvironment::putEnv("LIB", newPaths + getenv("LIB"),
+ QEnvironment::PersistentEnv | QEnvironment::LocalEnv);
+ } else if (var == "INCLUDE") {
+ QString newPaths = visualStudio + "\\vc98\\atl\\include;";
+ newPaths += visualStudio + "\\vc98\\include;";
+ newPaths += visualStudio + "\\vc98\\mfc\\include;";
+ QEnvironment::putEnv("INCLUDE", newPaths + getenv("INCLUDE"),
+ QEnvironment::PersistentEnv | QEnvironment::LocalEnv);
+ }
+ } else if (globalInformation.sysId() == GlobalInformation::MSVCNET) {
+ QString visualStudio = QEnvironment::getRegistryString("Software\\Microsoft\\VisualStudio\\7.1\\Setup\\VS",
+ "ProductDir", QEnvironment::LocalMachine);
+ if (visualStudio.isEmpty())
+ visualStudio = QEnvironment::getRegistryString("Software\\Microsoft\\VisualStudio\\7.0\\Setup\\VS",
+ "ProductDir", QEnvironment::LocalMachine);
+ // With .NET this isn't so easily done, we need to read in the vsvars32.bat file
+ // to get this right
+ QFile f(visualStudio + "\\Common7\\Tools\\vsvars32.bat");
+ QString contents;
+ if (f.open(IO_ReadOnly)) {
+ contents = QString(f.readAll());
+ }
+ int vsinstall = contents.find("VSINSTALLDIR=")+13;
+ QString VSINSTALLDIR = contents.mid(vsinstall, contents.find("\n", vsinstall) - vsinstall);
+ int vcinstall = contents.find("VCINSTALLDIR=")+13;
+ QString VCINSTALLDIR = contents.mid(vcinstall, contents.find("\n", vcinstall) - vcinstall);
+ int framework = contents.find("FrameworkDir=")+13;
+ QString FrameworkDir = contents.mid(framework, contents.find("\n", framework) - framework);
+ int frameworkVer = contents.find("FrameworkVersion=")+17;
+ QString FrameworkVer = contents.mid(frameworkVer, contents.find("\n", frameworkVer) - frameworkVer);
+ int frameworkSDK = contents.find("FrameworkSDKDir=")+16;
+ QString FrameworkSDK = contents.mid(frameworkSDK, contents.find("\n", frameworkSDK) - frameworkSDK);
+ if (var == "PATH" && !fixedPath) {
+ QString newPaths = VSINSTALLDIR + ";";
+ newPaths += VCINSTALLDIR + "\\Bin;";
+ newPaths += VCINSTALLDIR + "\\Common7\\Tools;";
+ newPaths += VCINSTALLDIR + "\\Common7\\Tools\\bin\\prerelease;";
+ newPaths += VCINSTALLDIR + "\\Common7\\Tools\\bin;";
+ newPaths += FrameworkSDK + "\\bin;";
+ newPaths += FrameworkSDK + "\\" + FrameworkVer + ";";
+ QEnvironment::putEnv("PATH", newPaths + getenv("PATH"),
+ QEnvironment::PersistentEnv | QEnvironment::LocalEnv);
+ fixedPath = true;
+ } else if (var == "LIB") {
+ QString newPaths = VCINSTALLDIR + "\\ATLMFC\\LIB;";
+ newPaths += VCINSTALLDIR + "\\LIB;";
+ newPaths += VCINSTALLDIR + "\\PlatformSDK\\lib\\prerelease;";
+ newPaths += VCINSTALLDIR + "\\PlatformSDK\\lib;";
+ newPaths += FrameworkSDK + "\\lib;";
+ QEnvironment::putEnv("LIB", newPaths + getenv("LIB"),
+ QEnvironment::PersistentEnv | QEnvironment::LocalEnv);
+ } else if (var == "INCLUDE") {
+ QString newPaths = VCINSTALLDIR + "\\ATLMFC\\INCLUDE;";
+ newPaths += VCINSTALLDIR + "\\INCLUDE;";
+ newPaths += VCINSTALLDIR + "\\PlatformSDK\\include\\prerelease;";
+ newPaths += VCINSTALLDIR + "\\PlatformSDK\\include;";
+ newPaths += FrameworkSDK + "\\include;";
+ QEnvironment::putEnv("INCLUDE", newPaths + getenv("INCLUDE"),
+ QEnvironment::PersistentEnv | QEnvironment::LocalEnv);
+ }
+
+ }
+}
+
+void SetupWizardImpl::readCleanerOutput()
+{
+ updateDisplay( cleaner.readStdout(), currentOLine );
+}
+
+void SetupWizardImpl::readConfigureOutput()
+{
+ updateDisplay( configure.readStdout(), currentOLine );
+}
+
+void SetupWizardImpl::readMakeOutput()
+{
+ updateDisplay( make.readStdout(), currentOLine );
+}
+
+void SetupWizardImpl::readAssistantOutput()
+{
+#if defined(QSA)
+ updateDisplay( assistant.readStdout(), currentOLine );
+#endif
+}
+
+void SetupWizardImpl::readCleanerError()
+{
+ updateDisplay( cleaner.readStderr(), currentELine );
+}
+
+void SetupWizardImpl::readConfigureError()
+{
+ updateDisplay( configure.readStderr(), currentELine );
+}
+
+void SetupWizardImpl::readMakeError()
+{
+ updateDisplay( make.readStderr(), currentELine );
+}
+
+void SetupWizardImpl::readAssistantError()
+{
+#if defined(QSA)
+ updateDisplay( assistant.readStderr(), currentELine );
+#endif
+}
+
+void SetupWizardImpl::updateDisplay( const QString &input, QString &output)
+{
+ const QChar *c = input.unicode();
+ for( int i = 0; i < (int)input.length(); ++i, ++c ) {
+ switch( char( *c ) ) {
+ case '\r':
+ case 0x00:
+ break;
+ case '\t':
+ currentOLine += " "; // Simulate a TAB by using 4 spaces
+ break;
+ case '\n':
+ if( output.length() ) {
+ if ( !globalInformation.reconfig() ) {
+ if ( output.right( 4 ) == ".cpp" ||
+ output.right( 2 ) == ".c" ||
+ output.right( 4 ) == ".pro" ||
+ output.right( 3 ) == ".ui" ) {
+ buildPage->compileProgress->setProgress( ++filesCompiled );
+ }
+ }
+ logOutput( output );
+ output = "";
+ }
+ break;
+ default:
+ output += *c;
+ break;
+ }
+ }
+}
+
+#if defined(Q_OS_WIN32)
+void SetupWizardImpl::installIcons( const QString& iconFolder, const QString& dirName, bool common )
+{
+ QDir dir( dirName );
+
+ dir.setSorting( QDir::Name | QDir::IgnoreCase );
+ const QFileInfoList* filist = dir.entryInfoList();
+ if ( !filist )
+ return;
+ QFileInfoListIterator it( *filist );
+ QFileInfo* fi;
+ while( ( fi = it.current() ) ) {
+ if( fi->fileName()[0] != '.' && // Exclude dot-dirs
+ fi->fileName() != "sql" ) { // Exclude SQL-dir
+ if( fi->isDir() ) {
+ installIcons( iconFolder, fi->absFilePath(), common );
+ } else if( fi->fileName().right( 4 ) == ".exe" ) {
+ shell.createShortcut( iconFolder, common, fi->baseName(), fi->absFilePath() );
+ }
+ }
+ ++it;
+ }
+}
+#endif
+
+void SetupWizardImpl::assistantDone()
+{
+#if defined(QSA)
+ QString contentFile;
+ static int count = 0;
+ if ( count == 0 ) {
+ connect( &assistant, SIGNAL( processExited() ), this, SLOT( assistantDone() ) );
+ connect( &assistant, SIGNAL( readyReadStdout() ), this, SLOT( readAssistantOutput() ) );
+ connect( &assistant, SIGNAL( readyReadStderr() ), this, SLOT( readAssistantError() ) );
+ contentFile = "qsa.xml";
+ } else if ( count == 1 ) {
+ contentFile = "qt-script-for-applications.xml";
+ } else {
+ doIDEIntegration();
+ return;
+ }
+ ++count;
+
+ // install documentation
+ QDir html( optionsPageQsa->installPath->text() );
+ html.cd( "doc/html/" );
+
+ QStringList lst;
+ lst << "assistant";
+ lst << "-addContentFile";
+ lst << QDir::toNativeSeparators( html.filePath( contentFile ) );
+ assistant.setArguments( lst );
+ if( !assistant.start() ) {
+ logOutput( "Installing QSA documentation failed\n" );
+ assistantDone();
+ }
+#else
+ doIDEIntegration();
+#endif
+}
+
+void SetupWizardImpl::doIDEIntegration()
+{
+#if defined(Q_OS_WIN32)
+ QDir installDir( optionsPage->installPath->text() );
+ if ( optionsPage->installIDEIntegration->isChecked() && optionsPage->installIDEIntegration->isEnabled()
+ && !foldersPage->devSysPath->text().isEmpty() ) {
+ // install the precompiled MS integration
+ if ( globalInformation.sysId() == GlobalInformation::MSVC ) {
+ QDir addinsDir( foldersPage->devSysPath->text() );
+ addinsDir.cd( "Common/MSDev98/Addins" );
+ if ( copyFile( installDir.filePath("qmsdev.dll"), addinsDir.filePath("qmsdev.dll") ) ) {
+ installDir.remove( "qmsdev.dll" );
+ }
+ } else if ( globalInformation.sysId() == GlobalInformation::MSVCNET
+ || globalInformation.sysId() == GlobalInformation::Intel){
+ QString filepath = installDir.filePath("QMsNetSetup.msi");
+ filepath = filepath.replace( '/', '\\' );
+
+ int res = _spawnlp( _P_NOWAIT, "msiexec.exe", "msiexec.exe", "-i", filepath.latin1(), NULL );
+ if ( res == -1 ) {
+ //MSIExec is not in path, look up in registry (only works for NT machines)
+ QString msiexec = QEnvironment::getRegistryString( "SYSTEM\\CurrentControlSet\\Services\\MSIServer",
+ "ImagePath",
+ QEnvironment::LocalMachine );
+ if ( !msiexec.isEmpty() )
+ msiexec.remove( " /V" );
+ res = _spawnl( _P_NOWAIT, msiexec.latin1(), msiexec.latin1(), "-i", filepath.latin1(), NULL );
+ }
+
+ if ( res == -1 ) {
+ QMessageBox::warning( this, "Couldn't execute .NET addin installer script",
+ "Microsoft Installer (MSI) was not found on your system.\n"
+ "Please install MSI, then execute the .NET addin installer "
+ "script,\nlocated at " + filepath );
+ }
+ }
+
+ QFile *autoexp = 0;
+ QFile *usertype = 0;
+ switch( globalInformation.sysId() ) {
+ case GlobalInformation::MSVC:
+ autoexp = new QFile( foldersPage->devSysPath->text() + "\\Common\\MsDev98\\bin\\autoexp.dat" );
+ usertype = new QFile( foldersPage->devSysPath->text() + "\\Common\\MsDev98\\bin\\usertype.dat" );
+ break;
+ case GlobalInformation::MSVCNET:
+ autoexp = new QFile( foldersPage->devSysPath->text() + "\\Common7\\Packages\\Debugger\\autoexp.dat" );
+ usertype = new QFile( foldersPage->devSysPath->text() + "\\Common7\\Packages\\Debugger\\usertype.dat" );
+ break;
+ }
+
+ if ( autoexp ) {
+ QString autoExpContents;
+ if ( !autoexp->exists() ) {
+ autoexp->open( IO_WriteOnly );
+ } else {
+ // First try to open the file to search for existing installations
+ autoexp->open( IO_ReadOnly );
+ QByteArray bytes = autoexp->readAll();
+ autoExpContents = QString::fromLatin1(bytes.data(), bytes.size());
+ autoexp->close();
+ if ( autoExpContents.find( "; Trolltech Qt" ) == -1 )
+ autoexp->open(IO_WriteOnly | IO_Translate);
+ }
+ if( autoexp->isOpen() ) {
+ bool written = false;
+ QTextStream outstream( autoexp );
+ QStringList entries = QStringList::split("\r\n", autoExpContents, true);
+ for (QStringList::Iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ QString e(*entry);
+ outstream << e << endl;
+ if (!written && e.startsWith("[AutoExpand]")) {
+ outstream << endl;
+ outstream << "; Trolltech Qt" << endl;
+ outstream << "QString=<d->unicode,su> len=<d->len,u>" << endl;
+ outstream << "QCString =<shd->data, s>" << endl;
+ outstream << "QPoint =x=<xp> y=<yp>" << endl;
+ outstream << "QRect =x1=<x1> y1=<y1> x2=<x2> y2=<y2>" << endl;
+ outstream << "QSize =width=<wd> height=<ht>" << endl;
+ outstream << "QWMatrix =m11=<_m11> m12=<_m12> m21=<_m21> m22=<_m22> dx=<_dx> dy=<_dy>" << endl;
+ outstream << "QVariant =Type=<d->typ> value=<d->value>" << endl;
+ outstream << "QValueList<*> =Count=<sh->nodes>" << endl;
+ outstream << "QPtrList<*> =Count=<numNodes>" << endl;
+ outstream << "QGuardedPtr<*> =ptr=<priv->obj>" << endl;
+ outstream << "QEvent =type=<t>" << endl;
+ outstream << "QObject =class=<metaObj->classname,s> name=<objname,s>" << endl;
+ written = true;
+ }
+ }
+ autoexp->close();
+ }
+ delete autoexp;
+ }
+
+ if ( usertype ) {
+ if ( !usertype->exists() ) {
+ usertype->open( IO_WriteOnly | IO_Translate );
+ } else {
+ usertype->open( IO_ReadOnly );
+ QString existingUserType = usertype->readAll();
+ usertype->close();
+ if ( existingUserType.find( "Q_OBJECT" ) == -1 )
+ usertype->open(IO_WriteOnly | IO_Append | IO_Translate);
+ }
+ if ( usertype->isOpen() ) {
+ QTextStream outstream( usertype );
+ outstream << endl;
+ outstream << "Q_OBJECT" << endl;
+ outstream << "Q_PROPERTY" << endl;
+ outstream << "Q_ENUMS" << endl;
+ outstream << "Q_SETS" << endl;
+ outstream << "Q_CLASSINFO" << endl;
+ outstream << "emit" << endl;
+ outstream << "TRUE" << endl;
+ outstream << "FALSE" << endl;
+ outstream << "SIGNAL" << endl;
+ outstream << "SLOT" << endl;
+ outstream << "signals:" << endl;
+ outstream << "slots:" << endl;
+ usertype->close();
+ }
+ delete usertype;
+ }
+ }
+
+ if ( globalInformation.sysId() != GlobalInformation::MinGW )
+ installDir.remove( "Makefile.win32-g++" );
+ if (globalInformation.sysId() != GlobalInformation::MSVC)
+ installDir.remove( "qmsdev.dll" );
+ if (globalInformation.sysId() != GlobalInformation::MSVCNET)
+ installDir.remove( "QMsNetSetup.msi" );
+#endif
+
+ doStartMenuIntegration();
+}
+
+void SetupWizardImpl::doStartMenuIntegration()
+{
+#if defined(Q_OS_WIN32)
+ /*
+ ** Set up our icon folder and populate it with shortcuts.
+ ** Then move to the next page.
+ */
+ QString dirName, examplesName, tutorialsName;
+ bool common( foldersPage->folderGroups->currentItem() == 0 );
+ QString qtDir = QEnvironment::getEnv( "QTDIR" );
+
+ dirName = shell.createFolder( foldersPage->folderPath->text(), common );
+ shell.createShortcut( dirName, common, "Qt Designer", qtDir + "\\bin\\designer.exe", "GUI designer", "", qtDir );
+#if !defined(EVAL) && !defined(EDU) && !defined(NON_COMMERCIAL)
+ shell.createShortcut( dirName, common, "Reconfigure Qt",
+ qtDir + "\\bin\\install.exe",
+ "Reconfigure the Qt library",
+ QString("-reconfig \"%1\"").arg(globalInformation.qtVersionStr()),
+ qtDir );
+#endif
+#if defined(QSA)
+ shell.createShortcut( dirName, common, "License agreement for Qt", "notepad.exe", "Review the license agreement",
+ "\"" + qtDir + "\\" LICENSE_DEST "\"" );
+ shell.createShortcut( dirName, common, "Readme for Qt", "notepad.exe", "Important information",
+ "\"" + qtDir + "\\README\"" );
+ shell.createShortcut( dirName, common, "License agreement for QSA", "notepad.exe", "Review the license agreement",
+ "\"" + optionsPageQsa->installPath->text() + "\\" LICENSE_DEST "\"" );
+ shell.createShortcut( dirName, common, "Readme for QSA", "notepad.exe", "Important information",
+ "\"" + optionsPageQsa->installPath->text() + "\\README\"" );
+#else
+ shell.createShortcut( dirName, common, "License agreement", "notepad.exe", "Review the license agreement", "\"" + qtDir + "\\" LICENSE_DEST "\"" );
+ shell.createShortcut( dirName, common, "Readme", "notepad.exe", "Important information", QString( "\"" ) + qtDir + "\\README\"" );
+#endif
+ shell.createShortcut( dirName, common, "Qt Assistant", qtDir + "\\bin\\assistant.exe", "Browse the On-line documentation", "", qtDir );
+ shell.createShortcut( dirName, common, "Qt Linguist", qtDir + "\\bin\\linguist.exe", "Qt translation utility", "", qtDir );
+ shell.createInternetShortcut( dirName, common, "Trolltech.com", "http://qtsoftware.com/" );
+#if defined(EVAL_CD)
+ shell.createInternetShortcut( dirName, common, "Register for Support", "http://qtsoftware.com/products/qt/evaluate.html" );
+#endif
+
+ if ( ( ( !globalInformation.reconfig() && optionsPage->skipBuild->isChecked() )
+ || ( globalInformation.reconfig() && !configPage->rebuildInstallation->isChecked() ) )
+ || qWinVersion() & WV_DOS_based ) {
+ QString description;
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ buildQtShortcutText = "Build Qt Examples and Tutorials";
+ description = "Build the Qt Examples and Tutorials";
+#else
+ buildQtShortcutText = "Build Qt " + globalInformation.qtVersionStr();
+ description = "Build the Qt library";
+#endif
+ shell.createShortcut( dirName, common,
+ buildQtShortcutText,
+ QEnvironment::getEnv( "QTDIR" ) + "\\build.bat",
+ description );
+ }
+
+#if defined(QSA)
+ QString qsaExamplesName;
+ if( qWinVersion() & WV_DOS_based ) {
+ shell.createShortcut( dirName, common,
+ "QSA Examples",
+ optionsPageQsa->installPath->text() + "\\examples" );
+ } else {
+ qsaExamplesName = shell.createFolder( foldersPage->folderPath->text() + "\\QSA Examples", common );
+ installIcons( qsaExamplesName, optionsPageQsa->installPath->text() + "\\examples", common );
+ }
+#endif
+ if( optionsPage->installTutorials->isChecked() ) {
+ if( qWinVersion() & WV_DOS_based ) {
+ shell.createShortcut( dirName, common,
+#if defined(QSA)
+ "Qt Tutorials",
+#else
+ "Tutorials",
+#endif
+ QEnvironment::getEnv( "QTDIR" ) + "\\tutorial" );
+ } else {
+#if defined(QSA)
+ tutorialsName = shell.createFolder( foldersPage->folderPath->text() + "\\Qt Tutorials", common );
+#else
+ tutorialsName = shell.createFolder( foldersPage->folderPath->text() + "\\Tutorials", common );
+#endif
+ installIcons( tutorialsName, QEnvironment::getEnv( "QTDIR" ) + "\\tutorial", common );
+ }
+ }
+ if( optionsPage->installExamples->isChecked() ) {
+ if( qWinVersion() & WV_DOS_based ) {
+ shell.createShortcut( dirName, common,
+#if defined(QSA)
+ "Qt Examples",
+#else
+ "Examples",
+#endif
+ QEnvironment::getEnv( "QTDIR" ) + "\\examples" );
+ } else {
+#if defined(QSA)
+ examplesName = shell.createFolder( foldersPage->folderPath->text() + "\\Qt Examples", common );
+#else
+ examplesName = shell.createFolder( foldersPage->folderPath->text() + "\\Examples", common );
+#endif
+ installIcons( examplesName, QEnvironment::getEnv( "QTDIR" ) + "\\examples", common );
+ }
+ }
+#endif
+#if defined(QSA)
+#endif
+ buildPage->compileProgress->setProgress( buildPage->compileProgress->totalSteps() );
+ setNextEnabled( buildPage, true );
+ logOutput( "The build was successful", true );
+}
+
+void SetupWizardImpl::makeDone()
+{
+ makeDone( !make.normalExit() || make.exitStatus() );
+}
+
+void SetupWizardImpl::makeDone( bool error )
+{
+ if( error ) {
+ if (!backButton()->isEnabled()) {
+ logOutput( "The build process failed!\n" );
+ emit wizardPageFailed( indexOf(currentPage()) );
+ QMessageBox::critical( this, "Error", "The build process failed!\nSee the log for details." );
+ buildPage->restartBuild->setText( "Restart compile" );
+ backButton()->setEnabled(true);
+ }
+ setAppropriate( progressPage, false );
+#if defined(QSA)
+ } else if ( make.workingDirectory() == QEnvironment::getEnv( "QTDIR" ) ) {
+ QStringList args;
+ args << globalInformation.text(GlobalInformation::MakeTool);
+ args << "sub-examples";
+
+ make.setWorkingDirectory( optionsPageQsa->installPath->text() );
+ make.setArguments( args );
+
+ if( !make.start() ) {
+ logOutput( "Could not start make process.\n"
+ "Make sure that your compiler tools are installed\n"
+ "and registered correctly in your PATH environment." );
+ emit wizardPageFailed( indexOf(currentPage()) );
+ backButton()->setEnabled( true );
+ }
+#endif
+ } else {
+ // We still have some more items to do in order to finish all the
+ // integration stuff.
+ if ( !globalInformation.reconfig() ) {
+ logOutput( "Doing the final integration steps..." );
+ assistantDone();
+ } else {
+ setNextEnabled( buildPage, true );
+ logOutput( "The build was successful", true );
+ }
+ buildPage->restartBuild->setText( "Success" );
+ buildPage->restartBuild->setEnabled( false );
+ }
+}
+
+void SetupWizardImpl::configDone()
+{
+ QStringList args;
+
+ if( globalInformation.reconfig() && !configPage->rebuildInstallation->isChecked() )
+ showPage( finishPage );
+
+#if !defined(EVAL) && !defined(EDU) && !defined(NON_COMMERCIAL)
+ if( !configure.normalExit() || configure.exitStatus() ) {
+ logOutput( "The configure process failed.\n" );
+ emit wizardPageFailed( indexOf(currentPage()) );
+ buildPage->restartBuild->setText( "Restart configure" );
+ setAppropriate( progressPage, false );
+ backButton()->setEnabled(true);
+ } else
+#endif
+ {
+ args << globalInformation.text(GlobalInformation::MakeTool);
+#if !defined(EVAL) && !defined(EDU) && !defined(NON_COMMERCIAL)
+ args << "sub-src";
+ args << "sub-plugins";
+ if ( optionsPage ) {
+ if ( optionsPage->installTools->isChecked() )
+ args << "sub-tools";
+ if ( optionsPage->installTutorials->isChecked() )
+ args << "sub-tutorial";
+ if ( optionsPage->installExamples->isChecked() )
+ args << "sub-examples";
+ if ( optionsPage->installExtensions->isChecked() )
+ args << "sub-extensions";
+ } else if (globalInformation.reconfig()) {
+ args << "sub-tools"; // We want to make sure it rebuilds uic etc
+ }
+#elif defined(Q_OS_WIN32)
+ if ( optionsPage ) {
+ if ( optionsPage->installTutorials->isChecked() )
+ args << "sub-tutorial";
+ if ( optionsPage->installExamples->isChecked() )
+ args << "sub-examples";
+#if !defined(NON_COMMERCIAL)
+ if ( optionsPage->installExtensions->isChecked() )
+ args << "sub-extensions";
+#endif
+ }
+ if ( args.count() == 1 ) {
+ make.setWorkingDirectory( QEnvironment::getEnv( "QTDIR" ) );
+ makeDone( false );
+ return;
+ }
+#endif
+ if ( globalInformation.sysId() == GlobalInformation::MinGW ) {
+ args << "-fMakefile.win32-g++";
+ }
+
+ make.setWorkingDirectory( QEnvironment::getEnv( "QTDIR" ) );
+ make.setArguments( args );
+
+ if( !make.start() ) {
+ logOutput( "Could not start make process.\n"
+ "Make sure that your compiler tools are installed\n"
+ "and registered correctly in your PATH environment." );
+ emit wizardPageFailed( indexOf(currentPage()) );
+ backButton()->setEnabled( true );
+ } else {
+ buildPage->restartBuild->setText( "Stop compilation" );
+ }
+ }
+}
+
+void SetupWizardImpl::restartBuild()
+{
+ if ( configure.isRunning() ||
+ (!configure.isRunning() && (!configure.normalExit() || configure.exitStatus())) ) {
+ if ( configure.isRunning() ) { // Stop configure
+ configure.kill();
+ buildPage->restartBuild->setText( "Restart configure" );
+ logOutput( "\n*** Configure stopped by user...\n" );
+ backButton()->setEnabled( true );
+ } else { // Restart configure
+ emit wizardPageShowed( indexOf(currentPage()) );
+ backButton()->setEnabled( false );
+ cleanDone();
+ buildPage->restartBuild->setText( "Stop configure" );
+ logOutput( "\n*** Configure restarted by user...\n" );
+ }
+ } else if ( make.isRunning() ||
+ (!make.isRunning() && (!make.normalExit() || make.exitStatus())) ) {
+ if ( make.isRunning() ) { // Stop compile
+ buildPage->restartBuild->setText( "Restart compile" );
+ logOutput( "\n*** Compilation stopped by user...\n" );
+ backButton()->setEnabled( true );
+ make.kill();
+ } else { // Restart compile
+ wizardPageShowed( indexOf(currentPage()) );
+ backButton()->setEnabled( false );
+ configDone();
+ buildPage->restartBuild->setText( "Stop compile" );
+ logOutput( "\n*** Compilation restarted by user...\n" );
+ }
+ }
+}
+
+void SetupWizardImpl::saveSettings()
+{
+#if !defined(EVAL) && !defined(EDU) && !defined(NON_COMMERCIAL)
+ QApplication::setOverrideCursor( Qt::waitCursor );
+ saveSet( configPage->configList );
+ saveSet( configPage->advancedList );
+ QApplication::restoreOverrideCursor();
+#endif
+}
+
+void SetupWizardImpl::saveSet( QListView* list )
+{
+ QSettings settings;
+ settings.writeEntry( "/Trolltech/Qt/ResetDefaults", "FALSE" );
+
+ QListViewItemIterator it( list );
+ while ( it.current() ) {
+ QListViewItem *itm = it.current();
+ ++it;
+ if ( itm->rtti() != CheckListItem::RTTI )
+ continue;
+ CheckListItem *item = (CheckListItem*)itm;
+ if ( item->type() == QCheckListItem::RadioButton ) {
+ if ( item->isOn() ) {
+ QString folder;
+ QListViewItem *pItem = item;
+ while ( (pItem = pItem->parent() ) ) {
+ if ( folder.isEmpty() )
+ folder = pItem->text( 0 );
+ else
+ folder = pItem->text(0) + "/" + folder;
+ }
+
+ settings.writeEntry( "/Trolltech/Qt/" + folder, item->text() );
+ }
+ } else if ( item->type() == QCheckListItem::CheckBox ) {
+ QStringList lst;
+ QListViewItem *p = item->parent();
+ if ( p )
+ --it;
+ QString c = p->text( 0 );
+ while ( ( itm = it.current() ) &&
+ itm->rtti() == CheckListItem::RTTI &&
+ item->type() == CheckListItem::CheckBox ) {
+ item = (CheckListItem*)itm;
+ ++it;
+ if ( item->isOn() )
+ lst << item->text( 0 );
+ }
+ if ( lst.count() )
+ settings.writeEntry( "/Trolltech/Qt/" + p->text(0), lst, ',' );
+ else
+ settings.writeEntry( "/Trolltech/Qt/" + p->text(0), "Nothing selected" );
+ }
+ }
+}
+
+void SetupWizardImpl::showPage( QWidget* newPage )
+{
+ if ( currentPage() == configPage && newPage == progressPage && !verifyConfig() ) {
+ if (QMessageBox::warning( this, "Configuration with Warnings",
+ "One or more of the selected options could not be verified by the installer.\n"
+ "Do you want to continue?", "Yes", "No" ))
+ return;
+ }
+
+ QWizard::showPage( newPage );
+ setInstallStep( indexOf(newPage) + 1 );
+
+ if( newPage == licensePage ) {
+ showPageLicense();
+ } else if( newPage == licenseAgreementPage ) {
+ readLicenseAgreement();
+ } else if( newPage == licenseAgreementPageQsa ) {
+ readLicenseAgreement();
+ } else if( newPage == optionsPage ) {
+ showPageOptions();
+ } else if( newPage == foldersPage ) {
+ showPageFolders();
+ } else if( newPage == configPage ) {
+ showPageConfig();
+ } else if( newPage == progressPage ) {
+ showPageProgress();
+ } else if( newPage == buildPage ) {
+ showPageBuild();
+ } else if( newPage == finishPage ) {
+ showPageFinish();
+ }
+}
+
+void SetupWizardImpl::showPageLicense()
+{
+ licenseChanged();
+}
+
+void SetupWizardImpl::showPageOptions()
+{
+ static bool done = false;
+ if (done)
+ return;
+
+ done = true;
+
+ // First make sure that the current license information is saved
+ if( !globalInformation.reconfig() )
+ writeLicense( QDir::homeDirPath() + "/.qt-license" );
+
+ // ### unsupported
+ optionsPage->installDocs->hide();
+
+ bool enterprise = licenseInfo[ "PRODUCTS" ] == "qt-enterprise";
+ optionsPage->installExtensions->setChecked( enterprise );
+ optionsPage->installExtensions->setEnabled( enterprise );
+
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ optionsPage->installDocs->setEnabled( false );
+ optionsPage->skipBuild->setEnabled( false );
+ if ( globalInformation.sysId()==GlobalInformation::Borland ) {
+ optionsPage->sysMsvcNet->setEnabled( false );
+ optionsPage->sysMsvc->setEnabled( false );
+ optionsPage->sysBorland->setEnabled( true );
+ optionsPage->sysMinGW->setEnabled( false );
+ optionsPage->sysIntel->setEnabled( false );
+ optionsPage->sysOther->setEnabled( false );
+ } else {
+ optionsPage->sysMsvcNet->setEnabled( true );
+ optionsPage->sysMsvc->setEnabled( true );
+ optionsPage->sysBorland->setEnabled( false );
+ optionsPage->sysOther->setEnabled( false );
+ optionsPage->sysIntel->setEnabled( false );
+ optionsPage->sysMinGW->setEnabled( false );
+ }
+# if defined(Q_OS_WIN32)
+ optionsPage->installExamples->setEnabled( true );
+ optionsPage->installTutorials->setEnabled( true );
+ optionsPage->installTools->setEnabled( false );
+# if defined(NON_COMMERCIAL)
+ optionsPage->installExtensions->hide();
+# else
+ optionsPage->installExtensions->setChecked( true );
+ optionsPage->installExtensions->setEnabled( true );
+# endif
+# else
+ optionsPage->installExamples->setEnabled( false );
+ optionsPage->installTutorials->setEnabled( false );
+ optionsPage->installExtensions->setChecked( false );
+ optionsPage->installExtensions->setEnabled( false );
+# endif
+#else
+# if defined(Q_OS_WIN32)
+ // No need to offer the option of skipping the build on 9x, it's skipped anyway
+ if ( qWinVersion() & WV_DOS_based )
+ optionsPage->skipBuild->setEnabled( false );
+# endif
+#endif
+
+ // trigger environment test
+ clickedSystem(globalInformation.sysId());
+}
+
+void SetupWizardImpl::showPageFolders()
+{
+ QString ideName = globalInformation.text(GlobalInformation::IDE);
+ foldersPage->devSysLabel->setText( ideName + " path");
+ foldersPage->devSysLabel->setShown(!ideName.isEmpty());
+ foldersPage->devSysPath->setShown(!ideName.isEmpty());
+ foldersPage->devSysPathButton->setShown(!ideName.isEmpty());
+#if defined(Q_OS_WIN32)
+ if( globalInformation.sysId() == GlobalInformation::MSVC ) {
+ QString devPath = QEnvironment::getRegistryString( "Software\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual Studio", "ProductDir", QEnvironment::LocalMachine );
+ if ( devPath.isEmpty() ) {
+ // fallback for Windows 9x
+ QDir msdevDir( QEnvironment::getEnv("MSDEVDIR") );
+ msdevDir.cdUp();
+ msdevDir.cdUp();
+ devPath = QDir::toNativeSeparators( msdevDir.absPath() );
+ }
+ foldersPage->devSysPath->setText( devPath );
+ } else if ( globalInformation.sysId() == GlobalInformation::MSVCNET ) {
+ QString devPath = QEnvironment::getRegistryString( "Software\\Microsoft\\VisualStudio\\7.1\\Setup\\VS", "ProductDir", QEnvironment::LocalMachine );
+ if ( !devPath.length() )
+ devPath = QEnvironment::getRegistryString( "Software\\Microsoft\\VisualStudio\\7.0\\Setup\\VS", "ProductDir", QEnvironment::LocalMachine );
+ foldersPage->devSysPath->setText( devPath );
+ }
+#endif
+}
+
+void SetupWizardImpl::showPageProgress()
+{
+ saveSettings();
+ int totalSize = 0;
+ QFileInfo fi;
+ totalRead = 0;
+ bool copySuccessful = true;
+
+ if( !filesCopied ) {
+ createDir( optionsPage->installPath->text() );
+ if (optionsPageQsa)
+ createDir( optionsPageQsa->installPath->text() );
+ progressPage->filesDisplay->append( "Installing files...\n" );
+
+ // install the right LICENSE file
+ QDir installDir( optionsPage->installPath->text() );
+ QFile licenseFile( installDir.filePath( LICENSE_DEST ) );
+ if ( licenseFile.open( IO_WriteOnly ) ) {
+ ResourceLoader *rcLoader;
+#if defined(EVAL) || defined(EDU)
+ rcLoader = new ResourceLoader( "LICENSE" );
+#elif defined(NON_COMMERCIAL)
+ if ( licenseAgreementPage->countryCombo->currentItem() == 0 )
+ rcLoader = new ResourceLoader( "LICENSE-US" );
+ else
+ rcLoader = new ResourceLoader( "LICENSE" );
+#else
+ if ( usLicense ) {
+ rcLoader = new ResourceLoader( "LICENSE-US" );
+ } else {
+ rcLoader = new ResourceLoader( "LICENSE" );
+ }
+#endif
+ if ( rcLoader->isValid() ) {
+ licenseFile.writeBlock( rcLoader->data() );
+ } else {
+ emit wizardPageFailed( indexOf(currentPage()) );
+ QMessageBox::critical( this, tr("Package corrupted"),
+ tr("Could not find the LICENSE file in the package.\nThe package might be corrupted.") );
+ }
+ delete rcLoader;
+ licenseFile.close();
+ } else {
+ // ### error handling -- we could not write the LICENSE file
+ }
+#if defined(QSA)
+ QDir installDirQsa( optionsPageQsa->installPath->text() );
+ QFile licenseFileQsa( installDirQsa.filePath( LICENSE_DEST ) );
+ if ( licenseFileQsa.open( IO_WriteOnly ) ) {
+ ResourceLoader *rcLoader;
+ rcLoader = new ResourceLoader( "LICENSE_QSA" );
+ if ( rcLoader->isValid() ) {
+ licenseFileQsa.writeBlock( rcLoader->data() );
+ } else {
+ emit wizardPageFailed( indexOf(currentPage()) );
+ QMessageBox::critical( this, tr("Package corrupted"),
+ tr("Could not find the LICENSE file in the package.\nThe package might be corrupted.") );
+ }
+ delete rcLoader;
+ licenseFileQsa.close();
+ } else {
+ // ### error handling -- we could not write the LICENSE file
+ }
+#endif
+
+ // Install the files -- use different fallbacks if one method failed.
+ QArchive ar;
+ QString licenseKey;
+#if !defined(EVAL_CD) && !defined(NON_COMMERCIAL)
+ licenseKey = licensePage->key->text();
+#endif
+ ar.setVerbosity( QArchive::Destination | QArchive::Verbose | QArchive::Progress );
+ connect( &ar, SIGNAL( operationFeedback( const QString& ) ), this, SLOT( archiveMsg( const QString& ) ) );
+ connect( &ar, SIGNAL( operationFeedback( int ) ), progressPage->operationProgress, SLOT( setProgress( int ) ) );
+ // First, try to find qt.arq as a binary resource to the file.
+ ResourceLoader rcLoader( "QT_ARQ", 500 );
+ if ( rcLoader.isValid() ) {
+ progressPage->operationProgress->setTotalSteps( rcLoader.data().count() );
+ QDataStream ds( rcLoader.data(), IO_ReadOnly );
+ ar.readArchive( &ds, optionsPage->installPath->text(), licenseKey );
+ } else {
+ // If the resource could not be loaded or is smaller than 500
+ // bytes, we have the dummy qt.arq: try to find and install
+ // from qt.arq in the current directory instead.
+ QString archiveName = "qt.arq";
+#if defined(Q_OS_MAC)
+ QString appDir = qApp->argv()[0];
+ int truncpos = appDir.findRev( "/Contents/MacOS/" );
+ if (truncpos != -1)
+ appDir.truncate( truncpos );
+ archiveName = appDir + "/Contents/Qt/qtmac.arq";
+#endif
+ fi.setFile( archiveName );
+ if( fi.exists() )
+ totalSize = fi.size();
+ progressPage->operationProgress->setTotalSteps( totalSize );
+
+ ar.setPath( archiveName );
+ if( ar.open( IO_ReadOnly ) ) {
+ ar.readArchive( optionsPage->installPath->text(), licenseKey );
+ } else {
+ // We were not able to find any qt.arq -- so assume we have
+ // the old fashioned zip archive and simply copy the files
+ // instead.
+ progressPage->operationProgress->setTotalSteps( FILESTOCOPY );
+ copySuccessful = copyFiles( QDir::currentDirPath(), optionsPage->installPath->text(), true );
+
+ /*These lines are only to be used when changing the filecount estimate
+ QString tmp( "%1" );
+ tmp = tmp.arg( totalFiles );
+ QMessageBox::information( this, tmp, tmp );
+ */
+ progressPage->operationProgress->setProgress( FILESTOCOPY );
+ }
+ }
+
+#if defined(QSA)
+ QArchive arQsa;
+ arQsa.setVerbosity( QArchive::Destination | QArchive::Verbose | QArchive::Progress );
+ connect( &arQsa, SIGNAL( operationFeedback( const QString& ) ), this, SLOT( archiveMsg( const QString& ) ) );
+ connect( &arQsa, SIGNAL( operationFeedback( int ) ), progressPage->operationProgress, SLOT( setProgress( int ) ) );
+ ResourceLoader rcLoaderQsa( "QSA_ARQ", 500 );
+ if ( rcLoaderQsa.isValid() ) {
+ progressPage->operationProgress->setTotalSteps( rcLoaderQsa.data().count() );
+ QDataStream ds( rcLoaderQsa.data(), IO_ReadOnly );
+ arQsa.readArchive( &ds, optionsPageQsa->installPath->text(), licenseKey );
+ } else {
+ // ### error handling
+ }
+#endif
+ filesCopied = copySuccessful;
+
+ timeCounter = 30;
+ if( copySuccessful ) {
+ QDir installDir( optionsPage->installPath->text() );
+#if defined(Q_OS_WIN32)
+ QDir windowsFolderDir( shell.windowsFolderName );
+# if !defined(EVAL) && !defined(EDU) && !defined(NON_COMMERCIAL)
+ {
+ // move $QTDIR/install.exe to $QTDIR/bin/install.exe
+ // This is done because install.exe is also used to reconfigure Qt
+ // (and this expects install.exe in bin). We can't move install.exe
+ // to bin in first place, since for the snapshots, we don't have
+ // the .arq archives.
+ QString inFile( installDir.filePath("install.exe") );
+ copyFile(inFile, installDir.filePath("bin/install.exe"));
+ QFile::remove(inFile);
+ }
+# endif
+ {
+ // move the uninstaller to the Windows directory
+ // This is necessary since the uninstaller deletes all files in
+ // the installation directory (and therefore can't delete
+ // itself).
+ QString inFile( installDir.filePath("bin/quninstall.exe") );
+ copyFile(inFile, windowsFolderDir.filePath("quninstall.exe"));
+ QFile::remove(inFile);
+ }
+#endif
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ QStringList::Iterator it;
+ QDir lib( optionsPage->installPath->text() );
+ lib.cd( "lib" );
+# if !defined(EVAL_CD)
+ // patch qt*.dll
+# if !defined(Q_OS_MAC)
+ QStringList qtDlls = lib.entryList( "qt*.dll" );
+# else
+ QStringList qtDlls = lib.entryList( "libqt-mt-eval.dylib" );
+# endif
+ if ( qtDlls.count() == 0 ) {
+ copySuccessful = false;
+ QMessageBox::critical( this,
+ tr( "Error patching Qt library" ),
+# if defined(EVAL)
+ tr( "Could not patch the Qt library with the evaluation\n"
+ "license information - no Qt DLL was found." )
+# elif defined(EDU)
+ tr( "Could not patch the Qt library with the educational\n"
+ "edition license information - no Qt DLL was found." )
+# else
+ tr( "Could not patch the Qt library the installation\n"
+ "path information - no Qt DLL was found." )
+# endif
+ );
+ }
+ for ( it=qtDlls.begin(); it!=qtDlls.end(); ++it ) {
+ //### add serial number etc. to log
+ logFiles( tr("Patching the Qt library %1.").arg(*it) );
+ int ret = trDoIt( lib.absFilePath(*it),
+# if defined(EVAL)
+ licensePage->evalName->text().latin1(),
+ licensePage->evalCompany->text().latin1(),
+ licensePage->serialNumber->text().latin1(),
+# elif defined(EDU)
+ "",
+ licensePage->university->text().latin1(),
+ licensePage->serialNumber->text().latin1(),
+# endif
+ installDir.absPath()
+ );
+ if ( ret != 0 ) {
+ copySuccessful = false;
+ QMessageBox::critical( this,
+ tr( "Error patching Qt library" ),
+# if defined(EVAL)
+ tr( "Could not patch the Qt library with the evaluation\n"
+ "license information. You will not be able to execute\n"
+ "any program linked against %1. Error %2" ).arg( *it ).arg(ret)
+# elif defined(EDU)
+ tr( "Could not patch the Qt library with the educational\n"
+ "edition license information. You will not be able to\n"
+ "execute any program linked against %1." ).arg( *it )
+# else
+ tr( "Could not patch the Qt library with the installation\n"
+ "path information. You will not be able to execute\n"
+ "some programs linked against %1." ).arg( *it )
+# endif
+ );
+ }
+ }
+# endif
+# if !defined(Q_OS_MAC)
+ // copy lib/*.dll bin/
+ QStringList dlls = lib.entryList( "*.dll" );
+ for ( it=dlls.begin(); it!=dlls.end(); ++it ) {
+ copyFile( lib.absFilePath(*it), QDir::cleanDirPath(lib.absFilePath("../bin/"+*it)) );
+ }
+ // delete the non-wanted database drivers
+ QDir plugins( optionsPage->installPath->text() );
+ plugins.cd( "plugins" );
+ plugins.cd( "sqldrivers" );
+ QDir bin( optionsPage->installPath->text() );
+ bin.cd( "bin" );
+#if defined(NON_COMMERCIAL)
+ if ( sqlitePluginInstall && !sqlitePluginInstall->isOn() ) {
+ plugins.remove( "qsqlite.dll" );
+ }
+#else
+ if ( mysqlPluginInstall && !mysqlPluginInstall->isOn() ) {
+ plugins.remove( "qsqlmysql.dll" );
+ bin.remove( "libmySQL.dll" );
+ }
+ if ( ociPluginInstall && !ociPluginInstall->isOn() ) {
+ plugins.remove( "qsqloci.dll" );
+ }
+ if ( odbcPluginInstall && !odbcPluginInstall->isOn() ) {
+ plugins.remove( "qsqlodbc.dll" );
+ }
+ if ( psqlPluginInstall && !psqlPluginInstall->isOn() ) {
+ plugins.remove( "qsqlpsql.dll" );
+ bin.remove( "libpq.dll" );
+ }
+ if ( tdsPluginInstall && !tdsPluginInstall->isOn() ) {
+ plugins.remove( "qsqltds.dll" );
+ }
+ if ( db2PluginInstall && !db2PluginInstall->isOn() ) {
+ plugins.remove( "qsqldb2.dll" );
+ }
+#endif
+ // patch the .qmake.cache with the correct paths
+ QFile cacheFile( installDir.filePath(".qmake.cache") );
+ if ( cacheFile.open( IO_ReadOnly | IO_Translate ) ) {
+ QTextStream tsIn( &cacheFile );
+ QString cache = tsIn.read();
+ cacheFile.close();
+ if ( cacheFile.open( IO_WriteOnly | IO_Translate ) ) {
+ QTextStream tsOut( &cacheFile );
+ if ( globalInformation.sysId() == GlobalInformation::Borland )
+ tsOut << cache.replace( "C:/QtEvaluation/qtborland", installDir.absPath() );
+ else
+ tsOut << cache.replace( "C:/QtEvaluation/qtmsvc", installDir.absPath() );
+ cacheFile.close();
+ }
+ }
+# endif
+#endif
+ logFiles( tr("All files have been installed.\n"
+ "This log has been saved to the installation directory.\n"
+ "The build will start automatically in 30 seconds."), true );
+ } else {
+ logFiles( tr("One or more errors occurred during file installation.\n"
+ "Please review the log and try to amend the situation.\n"), true );
+ }
+ }
+ if ( copySuccessful ) {
+#if defined(Q_OS_WIN32)
+ /*
+ ** Then record the installation in the registry, and set up the uninstallation
+ */
+ QStringList uninstaller;
+ uninstaller << ( QString("\"") + shell.windowsFolderName + "\\quninstall.exe" + QString("\"") );
+ uninstaller << optionsPage->installPath->text();
+
+ if( foldersPage->folderGroups->currentItem() == 0 )
+ uninstaller << ( QString("\"") + shell.commonProgramsFolderName + QString("\\") + foldersPage->folderPath->text() + QString("\"") );
+ else
+ uninstaller << ( QString("\"") + shell.localProgramsFolderName + QString("\\") + foldersPage->folderPath->text() + QString("\"") );
+
+ uninstaller << ( QString("\"") + globalInformation.qtVersionStr() + QString("\"") );
+
+ QEnvironment::recordUninstall( QString( "Qt " ) + globalInformation.qtVersionStr(), uninstaller.join( " " ) );
+#endif
+ autoContTimer.start( 1000 );
+ }
+ else
+ emit wizardPageFailed( indexOf(currentPage()) );
+ setNextEnabled( progressPage, copySuccessful );
+}
+
+void SetupWizardImpl::showPageFinish()
+{
+ autoContTimer.stop();
+ nextButton()->setText( "Next >" );
+ QString finishMsg;
+ if ( ( ( !globalInformation.reconfig() && !optionsPage->skipBuild->isChecked() )
+ || ( globalInformation.reconfig() && configPage->rebuildInstallation->isChecked() ) )
+#if defined(Q_OS_WIN32)
+ && qWinVersion() & WV_NT_based ) {
+#else
+ ) {
+#endif
+ if( globalInformation.reconfig() ) {
+ finishMsg = "Qt has been reconfigured and rebuilt, and is ready for use.";
+ } else {
+#if defined(Q_OS_MAC)
+ finishMsg = QString( "Qt has been installed to " ) + optionsPage->installPath->text() +
+ " and is ready to use.\n\nPlease try out the developer tools in the bin folder and example "
+ "programs in the examples folder.\n\nFor further information please consult the "
+ "README.txt file included in the installation folder.";
+#else
+ finishMsg = QString( "Qt has been installed to %1 and is ready to use.\n"
+ "You might have to logoff and logon for changes to the environment to have an effect.").
+ arg(optionsPage->installPath->text());
+# if defined(QSA)
+ finishMsg = QString( "\nQSA has been installed to " ) + optionsPageQsa->installPath->text() + " and is ready to use.";
+# endif
+#endif
+ }
+ } else {
+ if( globalInformation.reconfig() ) {
+ finishMsg = "The new configuration has been written.\nThe library needs to be rebuilt to activate the ";
+ finishMsg += "new configuration.";
+#if defined(Q_OS_WIN32)
+ finishMsg += "To rebuild it, use the \"Build Qt ";
+ finishMsg += globalInformation.qtVersionStr();
+ finishMsg += "\" icon in the Qt program group in the start menu.";
+#endif
+ } else {
+ finishMsg = QString( "The Qt files have been installed to " ) + optionsPage->installPath->text() + " and is ready to be compiled.\n";
+#if defined(Q_OS_WIN32)
+ if( persistentEnv && qWinVersion() & WV_DOS_based ) {
+ finishMsg += "The environment variables needed to use Qt have been recorded into your AUTOEXEC.BAT file.\n";
+ finishMsg += "Please review this file, and take action as appropriate depending on your operating system to get them into the persistent environment. (Windows Me users, run MsConfig)\n\n";
+ }
+# if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ finishMsg += QString( "To build the examples and tutorials, use the "
+ "\"Build the Qt Examples and Tutorials\""
+ " icon which has been installed into your Start-Menu." );
+# else
+ finishMsg += QString( "To build Qt, use the "
+ "\"Build Qt " ) + globalInformation.qtVersionStr() + "\""
+ " icon which has been installed into your Start-Menu.";
+# endif
+#endif
+ }
+ }
+#if defined(EVAL_CD)
+ finishMsg += "\n\n"
+ "The Trolltech technical support service is available to "
+ "Qt Professional and Enterprise Edition licensees. As an "
+ "evaluation user, you can register for 30 days of evaluation "
+ "support at\n"
+ "http://qtsoftware.com/products/qt/evaluate.html";
+#endif
+ finishPage->finishText->setText( finishMsg );
+}
+
+void SetupWizardImpl::licenseChanged()
+{
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ int ret = trCheckIt(
+# if defined(EVAL)
+ licensePage->evalName->text().latin1(),
+ licensePage->evalCompany->text().latin1(),
+ licensePage->serialNumber->text().latin1()
+# elif defined(EDU)
+ "",
+ licensePage->university->text().latin1(),
+ licensePage->serialNumber->text().latin1()
+# else
+ "",
+ "",
+ ""
+# endif
+ );
+
+ if ( ret == 0 )
+ setNextEnabled( licensePage, true );
+ else
+ setNextEnabled( licensePage, false );
+ return;
+#else
+ QDate date;
+ uint features;
+ uint testFeature;
+ QString platformString;
+ QString licenseKey = licensePage->key->text().stripWhiteSpace();
+ if ( licenseKey.length() != 14 ) {
+ goto rejectLicense;
+ }
+ features = featuresForKey( licenseKey.upper() );
+ date = decodedExpiryDate( licenseKey.mid(9) );
+ if ( !date.isValid() ) {
+ goto rejectLicense;
+ }
+# if defined(Q_OS_MAC)
+ testFeature = Feature_Mac;
+ platformString = "Mac OS X";
+# elif defined(Q_OS_WIN32)
+ testFeature = Feature_Windows;
+ platformString = "Windows";
+# else
+ testFeature = Feature_Unix;
+ platformString = "UNIX";
+# ifdef Q_CC_GNU
+# warning "What about Qtopia Core?"
+# endif
+# endif
+ if ( !(features&testFeature) && currentPage() == licensePage ) {
+ if ( features & (Feature_Unix|Feature_Windows|Feature_Mac|Feature_Embedded) ) {
+ int ret = QMessageBox::information( this,
+ tr("No %1 license").arg(platformString),
+ tr("You are not licensed for the %1 platform.\n"
+ "Please contact sales@trolltech.com to upgrade\n"
+ "your license to include the Windows platform.").arg(platformString),
+ tr("Try again"),
+ tr("Abort installation")
+ );
+ if ( ret == 1 ) {
+ QApplication::exit();
+ } else {
+ licensePage->key->setText( "" );
+ }
+ }
+ goto rejectLicense;
+ }
+ if ( date < QDate::currentDate() && currentPage() == licensePage ) {
+ static bool alreadyShown = false;
+ if ( !alreadyShown ) {
+ QMessageBox::warning( this,
+ tr("Support and upgrade period has expired"),
+ tr("Your support and upgrade period has expired.\n"
+ "\n"
+ "You may continue to use your last licensed release\n"
+ "of Qt under the terms of your existing license\n"
+ "agreement. But you are not entitled to technical\n"
+ "support, nor are you entitled to use any more recent\n"
+ "Qt releases.\n"
+ "\n"
+ "Please contact sales@trolltech.com to renew your\n"
+ "support and upgrades for this license.")
+ );
+ alreadyShown = true;
+ }
+ }
+ if ( features & Feature_US )
+ usLicense = true;
+ else
+ usLicense = false;
+
+ licensePage->expiryDate->setText( date.toString( Qt::ISODate ) );
+ if( features & Feature_Enterprise ) {
+ licensePage->productsString->setCurrentItem( 1 );
+ emit editionString( "Enterprise Edition" );
+ } else {
+ licensePage->productsString->setCurrentItem( 0 );
+ emit editionString( "Professional Edition" );
+ }
+ setNextEnabled( licensePage, true );
+ return;
+
+rejectLicense:
+ licensePage->expiryDate->setText( "" );
+# if defined(Q_OS_WIN32)
+ //TODO: Is this a bug? It bus errors on MACX, ask rms.
+ // it should work -- if it doesn't this seems to be a bug in the MACX code,
+ // I guess (rms)
+ licensePage->productsString->setCurrentItem( -1 );
+# endif
+ emit editionString( "" );
+ setNextEnabled( licensePage, false );
+ return;
+#endif
+}
+
+void SetupWizardImpl::logFiles( const QString& entry, bool close )
+{
+ if( !fileLog.isOpen() ) {
+ fileLog.setName( optionsPage->installPath->text() + QDir::separator() + "install.log" );
+ if( !fileLog.open( IO_WriteOnly | IO_Translate ) )
+ return;
+ }
+
+#if 1
+ progressPage->filesDisplay->append(entry);
+#else
+ progressPage->filesDisplay->setText( "Installing files...\n" + entry + "\n" );
+#endif
+
+ static QTextStream outstream;
+ outstream.setDevice( &fileLog );
+ outstream << ( entry + "\n" );
+
+ if( close )
+ fileLog.close();
+}
+
+void SetupWizardImpl::logOutput( const QString& entry, bool close )
+{
+ if( !outputLog.isOpen() ) {
+ QDir installDir;
+ if ( optionsPage )
+ installDir.setPath( optionsPage->installPath->text() );
+ else
+ installDir.setPath( QEnvironment::getEnv( "QTDIR" ) );
+ outputLog.setName( installDir.filePath("build.log") );
+ if( !outputLog.open( IO_WriteOnly | IO_Translate ) )
+ return;
+ }
+
+ buildPage->outputDisplay->append(entry);
+
+ static QTextStream outstream;
+ outstream.setDevice( &outputLog );
+ outstream << ( entry + "\n" );
+
+ if( close )
+ outputLog.close();
+}
+
+void SetupWizardImpl::archiveMsg( const QString& msg )
+{
+ if( msg.right( 7 ) == ".cpp..." || msg.right( 5 ) == ".c..." || msg.right( 7 ) == ".pro..." || msg.right( 6 ) == ".ui..." )
+ filesToCompile++;
+ qApp->processEvents();
+ if ( msg.startsWith("Expanding") )
+ // only show the "Expanding" entries to avoid flickering
+ logFiles( msg );
+}
+
+#ifdef Q_WS_WIN
+static HANDLE createFile( const QString &entryName, DWORD attr1, DWORD attr2 )
+{
+ QT_WA({
+ return ::CreateFileW( entryName.ucs2(), attr1, attr2, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ }, {
+ return ::CreateFileA( entryName.local8Bit(), attr1, attr2, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ })
+}
+#endif
+
+bool SetupWizardImpl::copyFiles( const QString& sourcePath, const QString& destPath, bool topLevel )
+{
+ QDir dir( sourcePath );
+ const QFileInfoList* list = dir.entryInfoList();
+ QFileInfoListIterator it( *list );
+ QFileInfo* fi;
+ bool doCopy;
+
+ while( ( fi = it.current() ) ) {
+ if( fi->fileName()[ 0 ] != '.' ) {
+ QString entryName = sourcePath + QDir::separator() + fi->fileName();
+ QString targetName = destPath + QDir::separator() + fi->fileName();
+ doCopy = true;
+ if( fi->isDir() ) {
+ if( !dir.exists( targetName ) )
+ createDir( targetName );
+ if( topLevel ) {
+ if ( fi->fileName() == "doc" )
+ doCopy = optionsPage->installDocs->isChecked();
+ else if ( fi->fileName() == "tools" )
+ doCopy = optionsPage->installTools->isChecked();
+ else if ( fi->fileName() == "tutorial" )
+ doCopy = optionsPage->installTutorials->isChecked();
+ else if ( fi->fileName() == "examples" )
+ doCopy = optionsPage->installExamples->isChecked();
+ }
+ if( doCopy )
+ if( !copyFiles( entryName, targetName, false ) )
+ return false;
+ } else {
+ if( qApp && isShown() ) {
+ qApp->processEvents();
+ progressPage->operationProgress->setProgress( totalFiles );
+ logFiles( targetName );
+ } else {
+ return false;
+ }
+ if( entryName.right( 4 ) == ".cpp" ||
+ entryName.right( 2 ) == ".c" ||
+ entryName.right( 4 ) == ".pro" ||
+ entryName.right( 3 ) == ".ui" )
+ filesToCompile++;
+ bool res = true;
+ if ( !QFile::exists( targetName ) )
+ res = copyFile( entryName, targetName );
+#if defined(Q_OS_WIN32)
+ if ( res ) {
+ totalFiles++;
+ HANDLE inFile, outFile;
+ if( inFile = createFile( entryName, GENERIC_READ, FILE_SHARE_READ ) ){
+ if( outFile = createFile( targetName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE ) ){
+ FILETIME createTime, accessTime, writeTime;
+ ::GetFileTime( inFile, &createTime, &accessTime, &writeTime );
+ ::SetFileTime( outFile, &createTime, &accessTime, &writeTime );
+ ::CloseHandle( outFile );
+ }
+ ::CloseHandle( inFile );
+ }
+ } else {
+ QString error = QEnvironment::getLastError();
+ logFiles( QString( " ERROR: " ) + error + "\n" );
+ if( QMessageBox::warning( this, "File copy error", entryName + ": " + error, "Continue", "Cancel", QString(), 0 ) )
+ return false;
+ }
+#elif defined( Q_OS_UNIX )
+ // ### TODO: keep file date the same, handle errors
+#endif
+ }
+ }
+ ++it;
+ }
+ return true;
+}
+
+void SetupWizardImpl::setInstallStep( int step )
+{
+ QString captionTxt;
+#if defined(QSA)
+ captionTxt = tr("QSA Evaluation Version Installation Wizard");
+#elif defined(EVAL)
+ captionTxt = tr("Qt Evaluation Version Installation Wizard");
+#elif defined(EDU)
+ captionTxt = tr("Qt Educational Edition Installation Wizard");
+#elif defined(NON_COMMERCIAL)
+ captionTxt = tr("Qt Non-Commercial Edition Installation Wizard");
+#else
+ if( globalInformation.reconfig() )
+ captionTxt = tr("Qt Configuration Wizard");
+ else
+ captionTxt = tr("Qt Installation Wizard");
+#endif
+ setCaption( tr("%1 - Step %2 of %3").arg( captionTxt ).arg( step ).arg( pageCount() ) );
+ emit wizardPageShowed( step-1 );
+}
+
+void SetupWizardImpl::timerFired()
+{
+ QString tmp( "Next %1 >" );
+
+ timeCounter--;
+
+ if( timeCounter )
+ nextButton()->setText( tmp.arg( timeCounter ) );
+ else {
+ next();
+ autoContTimer.stop();
+ }
+}
+
+void SetupWizardImpl::readLicense( QString filePath)
+{
+#if !defined(EVAL) && !defined(EDU) && !defined(NON_COMMERCIAL)
+ QFile licenseFile( filePath );
+
+ if( licenseFile.open( IO_ReadOnly ) ) {
+ QString buffer;
+
+ while( licenseFile.readLine( buffer, 1024 ) != -1 ) {
+ if( buffer[ 0 ] != '#' ) {
+ QStringList components = QStringList::split( '=', buffer );
+ QStringList::Iterator it = components.begin();
+ QString keyString = (*it++).stripWhiteSpace().replace( QRegExp( QString( "\"" ) ), QString() ).upper();
+ QString value = (*it++).stripWhiteSpace().replace( QRegExp( QString( "\"" ) ), QString() );
+
+ licenseInfo[ keyString ] = value;
+ }
+ }
+ licenseFile.close();
+
+ if ( licensePage ) {
+ licensePage->customerID->setText( licenseInfo[ "CUSTOMERID" ] );
+ licensePage->licenseID->setText( licenseInfo[ "LICENSEID" ] );
+ licensePage->licenseeName->setText( licenseInfo[ "LICENSEE" ] );
+ if( licenseInfo[ "PRODUCTS" ] == "qt-enterprise" ) {
+ licensePage->productsString->setCurrentItem( 1 );
+ emit editionString( "Enterprise Edition" );
+ } else {
+ licensePage->productsString->setCurrentItem( 0 );
+ emit editionString( "Professional Edition" );
+ }
+ licensePage->expiryDate->setText( licenseInfo[ "EXPIRYDATE" ] );
+ licensePage->key->setText( licenseInfo[ "LICENSEKEY" ] );
+ }
+ }
+#endif
+}
+
+void SetupWizardImpl::writeLicense( QString filePath )
+{
+#if !defined(EVAL) && !defined(EDU) && !defined(NON_COMMERCIAL)
+ QFile licenseFile( filePath );
+
+ if( licenseFile.open( IO_WriteOnly | IO_Translate ) ) {
+ QTextStream licStream( &licenseFile );
+
+ licenseInfo[ "CUSTOMERID" ] = licensePage->customerID->text();
+ licenseInfo[ "LICENSEID" ] = licensePage->licenseID->text();
+ licenseInfo[ "LICENSEE" ] = licensePage->licenseeName->text();
+ if( licensePage->productsString->currentItem() == 0 ) {
+ licenseInfo[ "PRODUCTS" ] = "qt-professional";
+ emit editionString( "Professional Edition" );
+ } else {
+ licenseInfo[ "PRODUCTS" ] = "qt-enterprise";
+ emit editionString( "Enterprise Edition" );
+ }
+
+ licenseInfo[ "EXPIRYDATE" ] = licensePage->expiryDate->text();
+ licenseInfo[ "LICENSEKEY" ] = licensePage->key->text();
+
+ licStream << "# Toolkit license file" << endl;
+ licStream << "CustomerID=\"" << licenseInfo[ "CUSTOMERID" ].latin1() << "\"" << endl;
+ licStream << "LicenseID=\"" << licenseInfo[ "LICENSEID" ].latin1() << "\"" << endl;
+ licStream << "Licensee=\"" << licenseInfo[ "LICENSEE" ].latin1() << "\"" << endl;
+ licStream << "Products=\"" << licenseInfo[ "PRODUCTS" ].latin1() << "\"" << endl;
+ licStream << "ExpiryDate=" << licenseInfo[ "EXPIRYDATE" ].latin1() << endl;
+ licStream << "LicenseKey=" << licenseInfo[ "LICENSEKEY" ].latin1() << endl;
+
+ licenseFile.close();
+ }
+#endif
+}
+
+void SetupWizardImpl::clickedLicenseFile()
+{
+ QString licensePath = QFileDialog::getOpenFileName( optionsPage->installPath->text(), QString(), this, NULL, "Browse for license file" );
+
+ if( !licensePath.isEmpty() )
+ readLicense( licensePath );
+
+}
+
+void SetupWizardImpl::readLicenseAgreement()
+{
+ // Intropage
+ ResourceLoader *rcLoader;
+#if defined(QSA)
+ LicenseAgreementPageImpl *lap;
+ if ( currentPage() == licenseAgreementPageQsa ) {
+ lap = licenseAgreementPageQsa;
+ rcLoader = new ResourceLoader( "LICENSE_QSA" );
+ } else {
+ lap = licenseAgreementPage;
+ rcLoader = new ResourceLoader( "LICENSE" );
+ }
+#elif defined(EVAL) || defined(EDU)
+ LicenseAgreementPageImpl *lap = licenseAgreementPage;
+ rcLoader = new ResourceLoader( "LICENSE" );
+#elif defined(NON_COMMERCIAL)
+ LicenseAgreementPageImpl *lap = licenseAgreementPage;
+ if ( lap->countryCombo->currentItem() == 0 )
+ rcLoader = new ResourceLoader( "LICENSE-US" );
+ else
+ rcLoader = new ResourceLoader( "LICENSE" );
+#else
+ LicenseAgreementPageImpl *lap = licenseAgreementPage;
+ if ( usLicense ) {
+ rcLoader = new ResourceLoader( "LICENSE-US" );
+ } else {
+ rcLoader = new ResourceLoader( "LICENSE" );
+ }
+#endif
+ if ( rcLoader->isValid() ) {
+ lap->introText->setText( rcLoader->data() );
+ lap->acceptLicense->setEnabled( true );
+ } else {
+ emit wizardPageFailed( indexOf(currentPage()) );
+ QMessageBox::critical( this, tr("Package corrupted"),
+ tr("Could not find the LICENSE file in the package.\nThe package might be corrupted.") );
+ lap->acceptLicense->setEnabled( false );
+ }
+ delete rcLoader;
+}
+
+void SetupWizardImpl::accept()
+{
+#if defined(Q_OS_WIN32)
+ if ( finishPage->showReadmeCheck->isChecked() ) {
+ QProcess proc( QString("notepad.exe") );
+#if defined(QSA)
+ QString qsaDir = optionsPageQsa->installPath->text();
+ proc.addArgument( qsaDir + "\\README" );
+#else
+ QString qtDir = QEnvironment::getEnv( "QTDIR" );
+ proc.addArgument( qtDir + "\\README" );
+#endif
+ proc.start();
+ }
+#endif
+ QDialog::accept();
+}
diff --git a/util/install/win/setupwizardimpl.h b/util/install/win/setupwizardimpl.h
new file mode 100644
index 0000000..1c86f74
--- /dev/null
+++ b/util/install/win/setupwizardimpl.h
@@ -0,0 +1,276 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef SETUPWIZARDIMPL_H
+#define SETUPWIZARDIMPL_H
+
+#include "pages/pages.h"
+#include "shell.h"
+
+#include <qprocess.h>
+#include <qtimer.h>
+#include <qmap.h>
+#include <qptrdict.h>
+#include <qwizard.h>
+#include <qlistview.h>
+
+class QCheckListItem;
+class QListView;
+
+class CheckListItem : public QCheckListItem
+{
+public:
+ CheckListItem(QListView *listview, const QString &text, Type = RadioButtonController);
+ CheckListItem(QCheckListItem *parent, const QString &text, Type = RadioButtonController);
+
+ void setHelpText(const QString &help, QTextView *display);
+ void setWarningText(const QString &warning, CheckListItem *conflict = 0);
+ void addRequiredFiles(const QString &file);
+ void setRequiredFileLocation(const QString &location);
+
+ void setOpen(bool on);
+ void setOn(bool on);
+ void setCritical(bool on);
+
+ int rtti() const;
+ static int RTTI;
+
+ void displayHelp();
+ bool verify() const;
+
+ void paintCell( QPainter *, const QColorGroup & cg, int column, int width, int alignment );
+
+protected:
+ bool testAndWarn();
+ void activate();
+
+private:
+ QString help_text;
+ QString warning_text;
+ QTextView *help_display;
+ QStringList required_files;
+ QString file_location;
+ CheckListItem *conflict_with;
+ bool critical;
+};
+
+class SetupWizardImpl : public QWizard
+{
+ Q_OBJECT
+public:
+ SetupWizardImpl( QWidget* parent = 0, const char* name = NULL, bool modal = false, WindowFlags f = 0 );
+
+ void showPage( QWidget* );
+ void stopProcesses();
+
+ void optionClicked( CheckListItem * );
+
+signals:
+ void wizardPages( const QPtrList<Page>& );
+ void wizardPageShowed( int );
+ void wizardPageFailed( int );
+ void editionString( const QString& );
+
+private:
+ int totalFiles;
+ QProcess configure;
+ QProcess make;
+ QProcess cleaner;
+#if defined(QSA)
+ QProcess assistant;
+#endif
+
+ QString programsFolder;
+ QString devSysFolder;
+ QString tmpPath;
+
+ WinShell shell;
+
+ void saveSettings();
+ void saveSet( QListView* list );
+
+protected slots:
+ void accept(); // reimplemented from QDialog
+
+private slots:
+ void clickedSystem( int );
+ void sysOtherComboChanged( int );
+ void clickedFolderPath();
+ void clickedDevSysPath();
+ void clickedLicenseFile();
+ void cleanDone();
+ void configDone();
+ void makeDone();
+ void assistantDone();
+ void restartBuild();
+ void readConfigureOutput();
+ void readConfigureError();
+ void readCleanerOutput();
+ void readCleanerError();
+ void readMakeOutput();
+ void readMakeError();
+ void readAssistantOutput();
+ void readAssistantError();
+ void timerFired();
+ void configPageChanged();
+ void archiveMsg(const QString &);
+ void licenseChanged();
+ bool verifyConfig();
+
+private:
+ void showPageLicense();
+ void showPageOptions();
+ void showPageFolders();
+ void showPageConfig();
+ void showPageProgress();
+ void showPageBuild();
+ void showPageFinish();
+
+ void initPages();
+ void initConnections();
+
+ void fixEnvironment(const QString &var, const QString &file = QString());
+ void prepareEnvironment();
+
+ void makeDone( bool error );
+
+ void setStaticEnabled( bool se );
+ void setJpegDirect( bool jd );
+ void readLicenseAgreement();
+
+ bool copyFiles( const QString& sourcePath, const QString& destPath, bool topLevel );
+ int totalRead;
+
+ QString buildQtShortcutText;
+ bool fixedPath;
+ bool filesCopied;
+ bool persistentEnv;
+ int filesToCompile;
+ int filesCompiled;
+#if !defined(EVAL) && !defined(EDU) && !defined(NON_COMMERCIAL)
+ bool usLicense;
+#endif
+
+ QString currentOLine;
+ QString currentELine;
+
+ void updateDisplay(const QString &input, QString &output);
+#if defined(Q_OS_WIN32)
+ void installIcons( const QString& iconFolder, const QString& dirName, bool common );
+#endif
+ void doIDEIntegration();
+ void doStartMenuIntegration();
+ void logFiles( const QString& entry, bool close = false );
+ void logOutput( const QString& entry, bool close = false );
+
+ void setInstallStep( int step );
+ void readLicense( QString filePath );
+ void writeLicense( QString filePath );
+
+ QFile fileLog;
+ QFile outputLog;
+ QMap<QString,QString> licenseInfo;
+ QTimer autoContTimer;
+ int timeCounter;
+ QStringList allModules;
+
+ CheckListItem *accOn, *accOff;
+ CheckListItem *bigCodecsOn, *bigCodecsOff;
+ CheckListItem *tabletOn, *tabletOff;
+ CheckListItem *advancedSTL, *advancedExceptions, *advancedRTTI;
+
+ CheckListItem /* *mngPresent, */ *mngDirect, *mngPlugin, *mngOff;
+ CheckListItem /* *jpegPresent, */ *jpegDirect, *jpegPlugin, *jpegOff;
+ CheckListItem /* *pngPresent, */ *pngDirect, *pngPlugin, *pngOff;
+ CheckListItem *gifDirect, *gifOff;
+
+ CheckListItem *sgiDirect, *sgiPlugin, *sgiOff;
+ CheckListItem *cdeDirect, *cdePlugin, *cdeOff;
+ CheckListItem *motifplusDirect, *motifplusPlugin, *motifplusOff;
+ CheckListItem *platinumDirect, *platinumPlugin, *platinumOff;
+ CheckListItem *motifDirect, *motifPlugin, *motifOff;
+ CheckListItem *xpDirect, *xpPlugin, *xpOff;
+
+ CheckListItem *mysqlDirect, *mysqlPlugin, *mysqlOff;
+ CheckListItem *ociDirect, *ociPlugin, *ociOff;
+ CheckListItem *odbcDirect, *odbcPlugin, *odbcOff;
+ CheckListItem *psqlDirect, *psqlPlugin, *psqlOff;
+ CheckListItem *tdsDirect, *tdsPlugin, *tdsOff;
+ CheckListItem *db2Direct, *db2Plugin, *db2Off;
+ CheckListItem *sqliteDirect, *sqlitePlugin, *sqliteOff;
+ CheckListItem *ibaseDirect, *ibasePlugin, *ibaseOff;
+
+ CheckListItem *zlibDirect, *zlibSystem, *zlibOff;
+
+ CheckListItem *dspOff, *dspOn;
+ CheckListItem *vcprojOff, *vcprojOn;
+
+ CheckListItem *staticItem;
+
+#if defined(EVAL) || defined(EDU)
+ CheckListItem *mysqlPluginInstall;
+ CheckListItem *ociPluginInstall;
+ CheckListItem *odbcPluginInstall;
+ CheckListItem *psqlPluginInstall;
+ CheckListItem *tdsPluginInstall;
+ CheckListItem *db2PluginInstall;
+ CheckListItem *sqlitePluginInstall;
+ CheckListItem *ibasePluginInstall;
+#elif defined(NON_COMMERCIAL)
+ CheckListItem *sqlitePluginInstall;
+#endif
+
+ // wizard pages
+ LicenseAgreementPageImpl *licenseAgreementPage;
+ LicenseAgreementPageImpl *licenseAgreementPageQsa;
+ LicensePageImpl *licensePage;
+ OptionsPageImpl *optionsPage;
+ OptionsPageImpl *optionsPageQsa;
+ FoldersPageImpl *foldersPage;
+ ConfigPageImpl *configPage;
+ ProgressPageImpl *progressPage;
+ BuildPageImpl *buildPage;
+ FinishPageImpl *finishPage;
+#if defined(Q_OS_WIN32)
+ WinIntroPageImpl *winIntroPage;
+#endif
+};
+
+#endif
diff --git a/util/install/win/setupwizardimpl_config.cpp b/util/install/win/setupwizardimpl_config.cpp
new file mode 100644
index 0000000..a5959fb
--- /dev/null
+++ b/util/install/win/setupwizardimpl_config.cpp
@@ -0,0 +1,1564 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "setupwizardimpl.h"
+#include "environment.h"
+#include <qfiledialog.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qprogressbar.h>
+#include <qtextview.h>
+#include <qmultilineedit.h>
+#include <qbuttongroup.h>
+#include <qsettings.h>
+#include <qlistview.h>
+#include <qlistbox.h>
+#include <qapplication.h>
+#include <qcheckbox.h>
+#include <qtextstream.h>
+#include <qpushbutton.h>
+#include <qcombobox.h>
+#include <qmessagebox.h>
+#include <qregexp.h>
+#include <qtabwidget.h>
+#include <qarchive.h>
+#include <qvalidator.h>
+#include <qdatetime.h>
+#include <qpainter.h>
+
+bool findFile(const QString &);
+
+CheckListItem::CheckListItem(QListView *listview, const QString &text, Type type)
+: QCheckListItem(listview, text, type), help_display(0), conflict_with(0), critical(false)
+{
+ if (type == RadioButtonController || type == CheckBoxController)
+ setOpen(true);
+}
+
+CheckListItem::CheckListItem(QCheckListItem *parent, const QString &text, Type type)
+: QCheckListItem(parent, text, type), help_display(0), conflict_with(0), critical(false)
+{
+ if (type == RadioButtonController || type == CheckBoxController)
+ setOpen(true);
+}
+
+int CheckListItem::RTTI = 666;
+
+int CheckListItem::rtti() const
+{
+ return RTTI;
+}
+
+void CheckListItem::setHelpText(const QString &help, QTextView *display)
+{
+ help_text = help;
+ help_display = display;
+}
+
+void CheckListItem::setWarningText(const QString &warning, CheckListItem *conflict)
+{
+ conflict_with = conflict;
+ warning_text = warning;
+}
+
+void CheckListItem::addRequiredFiles(const QString &file)
+{
+ QStringList files = QStringList::split(",", file);
+ for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) {
+ QString f(*it);
+ required_files << f;
+ if (!findFile(f)) {
+ if (type() == QCheckListItem::RadioButtonController
+ || type() == QCheckListItem::CheckBoxController) {
+ setOpen(false);
+ } else {
+ setOn(false);
+ setEnabled(false);
+ }
+ }
+ }
+}
+
+void CheckListItem::setRequiredFileLocation(const QString &location)
+{
+ file_location = location;
+}
+
+bool CheckListItem::verify() const
+{
+ if (text(0) == "Off")
+ return true;
+
+ if (!required_files.count()) {
+ if (parent() && parent()->rtti() == RTTI)
+ return ((CheckListItem*)parent())->verify();
+ return true;
+ }
+
+ QStringList::ConstIterator it;
+ for (it = required_files.begin(); it != required_files.end(); ++it) {
+ QString file(*it);
+ if (!findFile(file))
+ return false;
+ }
+ return true;
+}
+
+bool CheckListItem::testAndWarn()
+{
+ if (!warning_text.isEmpty()) {
+ if (!conflict_with || conflict_with->isOn()) {
+ int r = QMessageBox::warning(listView()->window(), "Warning",
+ warning_text + "<br>Select anyway?", "Yes", "No" );
+ return r == 0;
+ } else {
+ return true;
+ }
+ }
+
+ QStringList files(required_files);
+ if (!required_files.count() && text(0) != "Off") {
+ if (parent() && parent()->rtti() == RTTI)
+ return ((CheckListItem*)parent())->testAndWarn();
+ return true;
+ }
+
+ if (!verify()) {
+ QString message = QString("<p>The option '%1' is <b>not verified</b> by the installer. One or more of the following "
+ "files could not be located on the system:"
+ "<p>%2"
+ "<p>Continuing with this option selected might <b>break the installation</b> process.")
+ .arg(text(0)).arg(required_files.join(", "));
+ if (!file_location.isEmpty()) {
+ message += QString("<p>The requested files are %1 and need to be installed "
+ "in the INCLUDE, PATH and LIBS environment as appropriate.").arg(file_location);
+ }
+
+ int r = QMessageBox::warning(listView()->window(), "Option not Verified",
+ message + "<p>Select anyway?", "Yes", "No" );
+ return r == 0;
+ }
+ return true;
+}
+
+void CheckListItem::displayHelp()
+{
+ if (help_display) {
+ help_display->setText(help_text);
+ return;
+ }
+ QListViewItem *p = parent();
+ if (p && p->rtti() == RTTI)
+ ((CheckListItem*)p)->displayHelp();
+}
+
+void CheckListItem::setOn(bool on)
+{
+ if (on && (type() == RadioButton || type() == CheckBox) && !testAndWarn())
+ return;
+ QCheckListItem::setOn(on);
+
+ SetupWizardImpl* wizard = qobject_cast<SetupWizardImpl*>(listView()->window());
+ if (wizard && listView()->isVisible() && listView()->updatesEnabled())
+ wizard->optionClicked(this);
+}
+
+void CheckListItem::activate()
+{
+ displayHelp();
+ QCheckListItem::activate();
+}
+
+void CheckListItem::setOpen(bool on)
+{
+ if (on && listView()->isVisible()) {
+ if (!testAndWarn())
+ return;
+ displayHelp();
+ }
+ QCheckListItem::setOpen(on);
+}
+
+void CheckListItem::setCritical(bool on)
+{
+ if (critical == on)
+ return;
+
+ critical = on;
+ repaint();
+}
+
+void CheckListItem::paintCell( QPainter *p, const QColorGroup & cg, int column, int width, int alignment )
+{
+ QColorGroup group(cg);
+ if (critical)
+ group.setColor(QColorGroup::Text, red);
+ QCheckListItem::paintCell(p, group, column, width, alignment);
+}
+
+
+
+void SetupWizardImpl::setStaticEnabled( bool se )
+{
+ bool enterprise = licenseInfo[ "PRODUCTS" ] == "qt-enterprise";
+ if ( se ) {
+ if ( accOn->isOn() ) {
+ accOn->setOn( false );
+ accOff->setOn( true );
+ }
+ if ( bigCodecsOff->isOn() ) {
+ bigCodecsOn->setOn( true );
+ bigCodecsOff->setOn( false );
+ }
+ if ( mngPlugin->isOn() ) {
+ mngDirect->setOn( true );
+ mngPlugin->setOn( false );
+ mngOff->setOn( false );
+ }
+ if ( pngPlugin->isOn() ) {
+ pngDirect->setOn( true );
+ pngPlugin->setOn( false );
+ pngOff->setOn( false );
+ }
+ if ( jpegPlugin->isOn() ) {
+ jpegDirect->setOn( true );
+ jpegPlugin->setOn( false );
+ jpegOff->setOn( false );
+ }
+ if ( sgiPlugin->isOn() ) {
+ sgiPlugin->setOn( false );
+ sgiDirect->setOn( true );
+ }
+ if ( cdePlugin->isOn() ) {
+ cdePlugin->setOn( false );
+ cdeDirect->setOn( true );
+ }
+ if ( motifplusPlugin->isOn() ) {
+ motifplusPlugin->setOn( false );
+ motifplusDirect->setOn( true );
+ }
+ if ( motifPlugin->isOn() ) {
+ motifPlugin->setOn( false );
+ motifDirect->setOn( true );
+ }
+ if ( platinumPlugin->isOn() ) {
+ platinumPlugin->setOn( false );
+ platinumDirect->setOn( true );
+ }
+ if ( xpPlugin->isOn() ) {
+ xpPlugin->setOn( false );
+ xpOff->setOn( true );
+ }
+ if ( enterprise ) {
+ if ( mysqlPlugin->isOn() ) {
+ mysqlPlugin->setOn( false );
+ mysqlDirect->setOn( true );
+ }
+ if ( ociPlugin->isOn() ) {
+ ociPlugin->setOn( false );
+ ociDirect->setOn( true );
+ }
+ if ( odbcPlugin->isOn() ) {
+ odbcPlugin->setOn( false );
+ odbcDirect->setOn( true );
+ }
+ if ( psqlPlugin->isOn() ) {
+ psqlPlugin->setOn( false );
+ psqlDirect->setOn( true );
+ }
+ if ( tdsPlugin->isOn() ) {
+ tdsPlugin->setOn( false );
+ tdsDirect->setOn( true );
+ }
+ if ( db2Plugin->isOn() ) {
+ db2Plugin->setOn( false );
+ db2Direct->setOn( true );
+ }
+ if ( sqlitePlugin->isOn() ) {
+ sqlitePlugin->setOn( false );
+ sqliteDirect->setOn( true );
+ }
+ if ( ibasePlugin->isOn() ) {
+ ibasePlugin->setOn( false );
+ ibaseDirect->setOn( true );
+ }
+ }
+ accOn->setEnabled( false );
+ bigCodecsOff->setEnabled( false );
+ mngPlugin->setEnabled( false );
+ pngPlugin->setEnabled( false );
+ jpegPlugin->setEnabled( false );
+ sgiPlugin->setEnabled( false );
+ cdePlugin->setEnabled( false );
+ motifPlugin->setEnabled( false );
+ motifplusPlugin->setEnabled( false );
+ motifPlugin->setEnabled( false );
+ platinumPlugin->setEnabled( false );
+ xpPlugin->setEnabled( false );
+ if ( enterprise ) {
+ mysqlPlugin->setEnabled( false );
+ ociPlugin->setEnabled( false );
+ odbcPlugin->setEnabled( false );
+ psqlPlugin->setEnabled( false );
+ tdsPlugin->setEnabled( false );
+ db2Plugin->setEnabled( false );
+ sqlitePlugin->setEnabled( false );
+ ibasePlugin->setEnabled( false );
+ }
+ } else {
+ accOn->setEnabled( true );
+ bigCodecsOff->setEnabled( true );
+ mngPlugin->setEnabled( true );
+ pngPlugin->setEnabled( true );
+ jpegPlugin->setEnabled( true );
+ sgiPlugin->setEnabled( true );
+ cdePlugin->setEnabled( true );
+ motifplusPlugin->setEnabled( true );
+ motifPlugin->setEnabled( true );
+ platinumPlugin->setEnabled( true );
+ xpPlugin->setEnabled( true );
+ if ( enterprise ) {
+ mysqlPlugin->setEnabled( true );
+ ociPlugin->setEnabled( true );
+ odbcPlugin->setEnabled( true );
+ psqlPlugin->setEnabled( true );
+ tdsPlugin->setEnabled( true );
+ db2Plugin->setEnabled( true );
+ sqlitePlugin->setEnabled( true );
+ ibasePlugin->setEnabled( true );
+ }
+ }
+ setJpegDirect( mngDirect->isOn() );
+}
+
+void SetupWizardImpl::setJpegDirect( bool jd )
+{
+ // direct MNG support requires also direct JPEG support
+ if ( jd ) {
+ jpegOff->setOn( false );
+ jpegPlugin->setOn( false );
+ jpegDirect->setOn( true );
+
+ jpegOff->setEnabled( false );
+ jpegPlugin->setEnabled( false );
+ jpegDirect->setEnabled( true );
+ } else {
+ jpegOff->setEnabled( true );
+ if ( !staticItem->isOn() )
+ jpegPlugin->setEnabled( true );
+ jpegDirect->setEnabled( true );
+ }
+}
+
+void SetupWizardImpl::optionClicked( CheckListItem *item )
+{
+ if ( !item || item->type() != CheckListItem::RadioButton )
+ return;
+
+ if ( item->text(0) == "Static" && item->isOn() ) {
+ setStaticEnabled( true );
+ return;
+ } else if ( item->text( 0 ) == "Shared" && item->isOn() ) {
+ setStaticEnabled( false );
+ return;
+ } else if ( item==mngDirect || item==mngPlugin || item==mngOff ) {
+ setJpegDirect( mngDirect->isOn() );
+ } else if ( item==db2Direct && odbcDirect->isOn() ) {
+ if ( odbcPlugin->isEnabled() )
+ odbcPlugin->QCheckListItem::setOn(true);
+ else
+ odbcOff->QCheckListItem::setOn(true);
+ } else if ( item==odbcDirect && db2Direct->isOn() ) {
+ if ( db2Plugin->isEnabled() )
+ db2Plugin->QCheckListItem::setOn(true);
+ else
+ db2Off->QCheckListItem::setOn(true);
+ }
+}
+
+
+void SetupWizardImpl::configPageChanged()
+{
+ if ( configPage->configList->isVisible() ) {
+ configPage->configList->setSelected( configPage->configList->currentItem(), true );
+ } else if ( configPage->advancedList->isVisible() ) {
+ configPage->advancedList->setSelected( configPage->advancedList->currentItem(), true );
+ }
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ else if ( configPage->installList->isVisible() ) {
+ configPage->installList->setSelected( configPage->installList->currentItem(), true );
+ }
+#endif
+}
+
+void SetupWizardImpl::cleanDone()
+{
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ prepareEnvironment();
+# if defined(Q_OS_WIN32)
+ QString qtdir = QEnvironment::getEnv( "QTDIR" );
+
+ // adjust the .qmake.cache
+ QFile qmakeCache( qtdir + "/.qmake.cache" );
+ if ( qmakeCache.open( IO_ReadOnly ) ) {
+ QString content = qmakeCache.readAll();
+ qmakeCache.close();
+ if ( globalInformation.sysId() == GlobalInformation::Borland )
+ content.replace( "C:\\QtEvaluation\\qtborland", qtdir );
+ else
+ content.replace( "C:\\QtEvaluation\\qtmsvc", qtdir );
+
+ if ( qmakeCache.open( IO_WriteOnly ) ) {
+ QTextStream ts( &qmakeCache );
+ ts << content;
+ qmakeCache.close();
+ } else {
+ logOutput( QString("Warning: can't open the .qmake.cache file for writing: %1\n").arg( qmakeCache.errorString() ) );
+ }
+ } else {
+ logOutput( QString("Warning: can't open the .qmake.cache file for reading: %1\n").arg( qmakeCache.errorString() ) );
+ }
+
+ QStringList args;
+ args << ( qtdir + "\\bin\\configure.exe" );
+ args << "-spec";
+ args << globalInformation.text(GlobalInformation::Mkspec);
+ if ( globalInformation.sysId() == GlobalInformation::MSVC )
+ args << "-dsp";
+ else if ( globalInformation.sysId() == GlobalInformation::MSVCNET )
+ args << "-vcproj";
+
+ if( qWinVersion() & WV_NT_based ) {
+ logOutput( "Execute configure...\n" );
+ logOutput( args.join( " " ) + "\n" );
+
+ configure.setWorkingDirectory( qtdir );
+ configure.setArguments( args );
+ // Start the configure process
+ buildPage->compileProgress->setTotalSteps( int(double(filesToCompile) * 2.6) );
+ buildPage->restartBuild->setText( "Stop configure" );
+ buildPage->restartBuild->setEnabled( true );
+ buildPage->restartBuild->show();
+ buildPage->compileProgress->show();
+ if( !configure.start() ) {
+ logOutput( "Could not start configure process" );
+ emit wizardPageFailed( indexOf(currentPage()) );
+ }
+ } else { // no proper process handling on DOS based systems - create a batch file instead
+ logOutput( "Generating batch file...\n" );
+ QDir installDir;
+ if ( optionsPage )
+ installDir.setPath( optionsPage->installPath->text() );
+ else
+ installDir.setPath( qtdir );
+ QFile outFile( installDir.filePath("build.bat") );
+ QTextStream outStream( &outFile );
+
+ if( outFile.open( IO_WriteOnly | IO_Translate ) ) {
+ if ( installDir.absPath()[1] == ':' )
+ outStream << installDir.absPath().left(2) << endl;
+ outStream << "cd %QTDIR%" << endl;
+ outStream << args.join( " " ) << endl;
+ if( !globalInformation.reconfig() ) {
+ outStream << globalInformation.text(GlobalInformation::MakeTool) << endl;
+ }
+ outFile.close();
+ }
+ logOutput( "Doing the final integration steps..." );
+ doIDEIntegration();
+ buildPage->compileProgress->setTotalSteps( buildPage->compileProgress->totalSteps() );
+ showPage( finishPage );
+ }
+# elif defined(Q_OS_UNIX)
+ buildPage->compileProgress->show();
+ buildPage->restartBuild->show();
+
+ buildPage->compileProgress->setProgress( 0 );
+ buildPage->compileProgress->setTotalSteps( int(double(filesToCompile) * 1.8) );
+ configDone();
+# endif
+#else
+ QStringList args;
+ QStringList entries;
+ QSettings settings;
+ QString entry;
+ QStringList::Iterator it;
+ QFile tmpFile;
+ QTextStream tmpStream;
+ bool settingsOK;
+
+# if defined(Q_OS_WIN32)
+ args << ( QEnvironment::getEnv( "QTDIR" ) + "\\bin\\configure.exe" );
+# elif defined(Q_OS_UNIX)
+ args << ( QEnvironment::getEnv( "QTDIR" ) + QDir::separator() + "configure" );
+# endif
+
+ entry = settings.readEntry( "/Trolltech/Qt/Build", "Debug", &settingsOK );
+ if ( entry == "Debug" )
+ args += "-debug";
+ else
+ args += "-release";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Library", "Shared", &settingsOK );
+ if ( entry == "Static" )
+ args += "-static";
+ else
+ args += "-shared";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Threading", QString(), &settingsOK );
+ if ( entry == "Threaded" )
+ args += "-thread";
+ else
+ args += "-no-thread";
+
+ entries = settings.readListEntry( "/Trolltech/Qt/Modules", ',', &settingsOK );
+ for( it = allModules.begin(); it != allModules.end(); ++it ) {
+ entry = *it;
+ if ( entries.find( entry ) != entries.end() )
+ args += QString( "-enable-" ) + entry;
+ else
+ args += QString( "-disable-") + entry;
+ }
+
+ entry = settings.readEntry( "/Trolltech/Qt/SQL Drivers/MySQL", "Off", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-sql-mysql";
+ else if ( entry == "Plugin" )
+ args += "-plugin-sql-mysql";
+ else if ( entry == "Off" )
+ args += "-no-sql-mysql";
+
+ entry = settings.readEntry( "/Trolltech/Qt/SQL Drivers/OCI", "Off", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-sql-oci";
+ else if ( entry == "Plugin" )
+ args += "-plugin-sql-oci";
+ else if ( entry == "Off" )
+ args += "-no-sql-oci";
+
+ entry = settings.readEntry( "/Trolltech/Qt/SQL Drivers/ODBC", "Off", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-sql-odbc";
+ else if ( entry == "Plugin" )
+ args += "-plugin-sql-odbc";
+ else if ( entry == "Off" )
+ args += "-no-sql-odbc";
+
+ entry = settings.readEntry( "/Trolltech/Qt/SQL Drivers/PostgreSQL", "Off", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-sql-psql";
+ else if ( entry == "Plugin" )
+ args += "-plugin-sql-psql";
+ else if ( entry == "Off" )
+ args += "-no-sql-psql";
+
+ entry = settings.readEntry( "/Trolltech/Qt/SQL Drivers/TDS", "Off", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-sql-tds";
+ else if ( entry == "Plugin" )
+ args += "-plugin-sql-tds";
+ else if ( entry == "Off" )
+ args += "-no-sql-tds";
+
+ entry = settings.readEntry( "/Trolltech/Qt/SQL Drivers/DB2", "Off", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-sql-db2";
+ else if ( entry == "Plugin" )
+ args += "-plugin-sql-db2";
+ else if ( entry == "Off" )
+ args += "-no-sql-db2";
+
+ entry = settings.readEntry( "/Trolltech/Qt/SQL Drivers/SQLite", "Off", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-sql-sqlite";
+ else if ( entry == "Plugin" )
+ args += "-plugin-sql-sqlite";
+ else if ( entry == "Off" )
+ args += "-no-sql-sqlite";
+
+ entry = settings.readEntry( "/Trolltech/Qt/SQL Drivers/iBase", "Off", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-sql-ibase";
+ else if ( entry == "Plugin" )
+ args += "-plugin-sql-ibase";
+ else if ( entry == "Off" )
+ args += "-no-sql-ibase";
+
+# if defined(Q_OS_WIN32)
+//TODO: Win only, remove these options from wizard on mac?
+ entry = settings.readEntry( "/Trolltech/Qt/Accessibility", "On", &settingsOK );
+ if ( entry == "On" )
+ args += "-accessibility";
+ else
+ args += "-no-accessibility";
+# endif
+
+ entry = settings.readEntry( "/Trolltech/Qt/Big Textcodecs", "On", &settingsOK );
+ if ( entry == "On" )
+ args += "-big-codecs";
+ else
+ args += "-no-big-codecs";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Tablet Support", "Off", &settingsOK );
+ if ( entry == "On" )
+ args += "-tablet";
+ else
+ args += "-no-tablet";
+
+ entries = settings.readListEntry( "/Trolltech/Qt/Advanced C++", ',', &settingsOK );
+ if ( entries.contains( "STL" ) )
+ args += "-stl";
+ else
+ args += "-no-stl";
+ if ( entries.contains( "Exceptions" ) )
+ args += "-exceptions";
+ else
+ args += "-no-exceptions";
+ if ( entries.contains( "RTTI" ) )
+ args += "-rtti";
+ else
+ args += "-no-rtti";
+
+# if defined(Q_OS_WIN32)
+//TODO: Win only, remove these options from wizard on mac?
+ entry = settings.readEntry( "/Trolltech/Qt/Image Formats/PNG", "Direct", &settingsOK );
+ if ( entry == "Plugin" )
+ args += "-plugin-imgfmt-png";
+ else if ( entry == "Direct" )
+ args += "-qt-imgfmt-png";
+ else if ( entry == "Off" )
+ args += "-no-imgfmt-png";
+ args += "-qt-png";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Image Formats/JPEG", "Direct", &settingsOK );
+ if ( entry == "Plugin" )
+ args += "-plugin-imgfmt-jpeg";
+ else if ( entry == "Direct" )
+ args += "-qt-imgfmt-jpeg";
+ else if ( entry == "Off" )
+ args += "-no-imgfmt-jpeg";
+ args += "-qt-jpeg";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Image Formats/MNG", "Direct", &settingsOK );
+ if ( entry == "Plugin" )
+ args += "-plugin-imgfmt-mng";
+ else if ( entry == "Direct" )
+ args += "-qt-imgfmt-mng";
+ else if ( entry == "Off" )
+ args += "-no-imgfmt-mng";
+ args += "-qt-mng";
+# endif
+
+ entry = settings.readEntry( "/Trolltech/Qt/Image Formats/GIF", "Direct", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-gif";
+ else if ( entry == "Off" )
+ args += "-no-gif";
+
+# if defined(Q_OS_WIN32)
+//TODO: Win only, remove these options from wizard on mac?
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/Windows", "Direct", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-style-windows";
+ else if ( entry == "Plugin" )
+ args += "-plugin-style-windows";
+ else if ( entry == "Off" )
+ args += "-no-style-windows";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/Windows XP", "Off", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-style-windowsxp";
+ else if ( entry == "Plugin" )
+ args += "-plugin-style-windowsxp";
+ else if ( entry == "Off" )
+ args += "-no-style-windowsxp";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/Motif", "Plugin", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-style-motif";
+ else if ( entry == "Plugin" )
+ args += "-plugin-style-motif";
+ else if ( entry == "Off" )
+ args += "-no-style-motif";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/Platinum", "Plugin", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-style-platinum";
+ else if ( entry == "Plugin" )
+ args += "-plugin-style-platinum";
+ else if ( entry == "Off" )
+ args += "-no-style-platinum";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/MotifPlus", "Plugin", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-style-motifplus";
+ else if ( entry == "Plugin" )
+ args += "-plugin-style-motifplus";
+ else if ( entry == "Off" )
+ args += "-no-style-motifplus";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/CDE", "Plugin", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-style-cde";
+ else if ( entry == "Plugin" )
+ args += "-plugin-style-cde";
+ else if ( entry == "Off" )
+ args += "-no-style-cde";
+
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/SGI", "Plugin", &settingsOK );
+ if ( entry == "Direct" )
+ args += "-qt-style-sgi";
+ else if ( entry == "Plugin" )
+ args += "-plugin-style-sgi";
+ else if ( entry == "Off" )
+ args += "-no-style-sgi";
+# endif
+
+ if ( globalInformation.sysId() == GlobalInformation::MSVC ) {
+ entry = settings.readEntry( "/Trolltech/Qt/DSP Generation", "On", &settingsOK );
+ if ( entry == "On" )
+ args += "-dsp";
+ else if ( entry == "Off" )
+ args += "-no-dsp";
+ } else if ( globalInformation.sysId() == GlobalInformation::MSVCNET ) {
+ entry = settings.readEntry( "/Trolltech/Qt/VCPROJ Generation", "On", &settingsOK );
+ if ( entry == "On" )
+ args += "-vcproj";
+ else if ( entry == "Off" )
+ args += "-no-vcproj";
+ } else if ( globalInformation.sysId() != GlobalInformation::MSVC && globalInformation.sysId() == GlobalInformation::MSVCNET ) {
+ args += "-no-dsp";
+ args += "-no-vcproj";
+ }
+
+ if ( ( ( !globalInformation.reconfig() && !optionsPage->skipBuild->isChecked() )
+ || ( globalInformation.reconfig() && configPage->rebuildInstallation->isChecked() ) )
+# if defined(Q_OS_WIN32)
+ && qWinVersion() & WV_NT_based ) {
+# else
+ ) {
+# endif
+ logOutput( "Execute configure...\n" );
+ logOutput( args.join( " " ) + "\n" );
+
+ configure.setWorkingDirectory( QEnvironment::getEnv( "QTDIR" ) );
+ configure.setArguments( args );
+ // Start the configure process
+ buildPage->compileProgress->setTotalSteps( int(double(filesToCompile) * 2.6) );
+ buildPage->restartBuild->setText( "Stop configure" );
+ buildPage->restartBuild->setEnabled( true );
+ buildPage->restartBuild->show();
+ buildPage->compileProgress->show();
+ if( !configure.start() ) {
+ logOutput( "Could not start configure process" );
+ emit wizardPageFailed( indexOf(currentPage()) );
+ }
+ } else { // no proper process handling on DOS based systems - create a batch file instead
+ logOutput( "Generating batch file...\n" );
+ QDir installDir;
+ if ( optionsPage )
+ installDir.setPath( optionsPage->installPath->text() );
+ else
+ installDir.setPath( QEnvironment::getEnv( "QTDIR" ) );
+ QFile outFile( installDir.filePath("build.bat") );
+ QTextStream outStream( &outFile );
+
+ if( outFile.open( IO_WriteOnly | IO_Translate ) ) {
+ if ( installDir.absPath()[1] == ':' )
+ outStream << installDir.absPath().left(2) << endl;
+ outStream << "cd %QTDIR%" << endl;
+
+ if ( globalInformation.reconfig() )
+ outStream << globalInformation.text(GlobalInformation::MakeTool) << " clean" << endl;
+
+ // There is a limitation on Windows 9x regarding the length of the
+ // command line. So rather use the configure.cache than specifying
+ // all configure options on the command line.
+ QFile configureCache( installDir.filePath("configure.cache") );
+ if( configureCache.open( IO_WriteOnly | IO_Translate ) ) {
+ QTextStream confCacheStream( &configureCache );
+ QStringList::Iterator it = args.begin();
+ ++it; // skip args[0] (configure)
+ while ( it != args.end() ) {
+ confCacheStream << *it << endl;
+ ++it;
+ }
+ configureCache.close();
+ outStream << args[0] << " -redo" << endl;
+ } else {
+ outStream << args.join( " " ) << endl;
+ }
+
+ outStream << globalInformation.text(GlobalInformation::MakeTool) << endl;
+ outFile.close();
+ }
+ logOutput( "Doing the final integration steps..." );
+ // No need to redo the integration step
+ if ( !globalInformation.reconfig() )
+ doIDEIntegration();
+ buildPage->compileProgress->setTotalSteps( buildPage->compileProgress->totalSteps() );
+ showPage( finishPage );
+ }
+#endif
+}
+
+void SetupWizardImpl::prepareEnvironment()
+{
+ QByteArray pathBuffer;
+ QStringList path;
+ QString qtDir;
+ int envSpec = QEnvironment::LocalEnv;
+
+ if( globalInformation.reconfig() ) {
+ qtDir = QEnvironment::getEnv( "QTDIR" );
+ if ( configPage ) {
+ configPage->currentInstallation->setText( qtDir );
+ }
+ }
+ else {
+ qtDir = QDir::toNativeSeparators( QEnvironment::getFSFileName( optionsPage->installPath->text() ) );
+ }
+
+#if defined(Q_OS_WIN32)
+ if( qWinVersion() & Qt::WV_NT_based ) {
+ // under Windows 9x, we don't compile from the installer -- so there is
+ // no need to set the local environment; and doing so, results in not
+ // setting the persistent since qtDir\bin is already in the PATH
+ path = QStringList::split( QRegExp("[;,]"), QEnvironment::getEnv( "PATH" ) );
+ if( path.findIndex( qtDir + "\\bin" ) == -1 ) {
+ path.prepend( qtDir + "\\bin" );
+ QEnvironment::putEnv( "PATH", path.join( ";" ) );
+ }
+ }
+#elif defined(Q_OS_UNIX)
+ path = QStringList::split( QRegExp("[:]"), QEnvironment::getEnv( "PATH" ) );
+ if( path.findIndex( qtDir + "/bin" ) == -1 ) {
+ path.prepend( qtDir + "/bin" );
+ QEnvironment::putEnv( "PATH", path.join( ":" ) );
+ }
+ QStringList dyld = QStringList::split( QRegExp("[:]"), QEnvironment::getEnv( "DYLD_LIBRARY_PATH" ) );
+ if( dyld.findIndex( qtDir + "/lib" ) == -1 ) {
+ dyld.prepend( qtDir + "/lib" );
+ QEnvironment::putEnv( "DYLD_LIBRARY_PATH", dyld.join( ":" ) );
+ }
+#endif
+
+#if defined(Q_OS_WIN32)
+ if( foldersPage && foldersPage->qtDirCheck->isChecked() ) {
+ envSpec |= QEnvironment::PersistentEnv;
+/*
+ if( folderGroups->currentItem() == 0 )
+ envSpec |= QEnvironment::GlobalEnv;
+*/
+ path.clear();
+
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ path = QStringList::split( ';', QEnvironment::getEnv( "PATH", QEnvironment::PersistentEnv ) );
+ if( path.findIndex( qtDir + "\\bin" ) == -1 ) {
+ path.prepend( qtDir + "\\bin" );
+ QEnvironment::putEnv( "PATH", path.join( ";" ), QEnvironment::PersistentEnv );
+ }
+ } else {
+ if( path.findIndex( qtDir + "\\bin" ) == -1 ) {
+ QEnvironment::putEnv( "PATH", qtDir + "\\bin;%PATH%", QEnvironment::PersistentEnv );
+ }
+ }
+ }
+#elif defined(Q_OS_UNIX)
+//Persistent environment not supported
+#endif
+
+ QEnvironment::putEnv( "QTDIR", qtDir, envSpec );
+ if ( globalInformation.sysId() != GlobalInformation::Other )
+ QEnvironment::putEnv( "QMAKESPEC", globalInformation.text(GlobalInformation::Mkspec), envSpec );
+ else
+ QEnvironment::putEnv( "QMAKESPEC", optionsPage->sysOtherCombo->currentText(), envSpec );
+#if defined(Q_OS_WIN32)
+ if( qWinVersion() & WV_NT_based ) {
+ SendNotifyMessageA( HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM)"Environment" );
+ SendNotifyMessageA( HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0 );
+ }
+#endif
+}
+
+void SetupWizardImpl::showPageConfig()
+{
+ if (autoContTimer.isActive()) {
+ autoContTimer.stop();
+ timeCounter = 30;
+ nextButton()->setText("Next >");
+ }
+#if defined(EVAL) || defined(EDU) || defined(NON_COMMERCIAL)
+ setBackEnabled( buildPage, false );
+
+ static bool alreadyInitialized = false;
+ if ( !alreadyInitialized ) {
+ configPage->installList->setSorting( -1 );
+ configPage->installList->setUpdatesEnabled(false);
+
+ CheckListItem *item;
+ CheckListItem *folder;
+
+ folder = new CheckListItem( configPage->installList, "Database drivers" );
+
+#if !defined(NON_COMMERCIAL)
+#if !defined(Q_OS_MACX)
+ item = new CheckListItem( folder, "DB2", QCheckListItem::CheckBox );
+ item->addRequiredFiles("db2cli.dll");
+ db2PluginInstall = item;
+ db2PluginInstall->setHelpText( tr(
+ "Installs the DB2 driver. This driver can "
+ "be used to access DB2 databases."
+ "<p><font color=\"red\">Choosing this option requires "
+ "that the DB2 Client is installed and set up. "
+ "The driver depends on the db2cli.dll.</font></p>"
+ ), configPage->explainOption );
+
+ item = new CheckListItem( folder, "TDS", QCheckListItem::CheckBox );
+ item->addRequiredFiles("ntwdblib.dll");
+ tdsPluginInstall = item;
+ tdsPluginInstall->setHelpText( tr(
+ "Installs the TDS driver to access Sybase Adaptive "
+ "Server and Microsoft SQL Server (it is recommended "
+ "to rather use ODBC instead of TDS where applicable). "
+ "<p><font color=\"red\">Choosing this option requires "
+ "that the ntwdblib.dll is available.</font></p>"
+ ), configPage->explainOption );
+
+ item = new CheckListItem( folder, "Oracle (OCI)", QCheckListItem::CheckBox );
+ item->addRequiredFiles( "oci.dll" );
+ ociPluginInstall = item;
+ ociPluginInstall->setHelpText( tr(
+ "<p>Installs the Oracale Call Interface (OCI) driver.</p> "
+ "<p><font color=\"red\">Choosing this option requires "
+ "that the Oracle Client is installed and set up. "
+ "The driver depends on the oci.dll.</font></p>"
+ ), configPage->explainOption );
+#endif
+
+ if ( globalInformation.sysId() != GlobalInformation::Borland ) {
+ // I was not able to make Postgres work with Borland
+ item = new CheckListItem( folder, "PostgreSQL", QCheckListItem::CheckBox );
+#ifndef Q_OS_MACX
+ item->addRequiredFiles( "libpq.dll" );
+#endif
+ item->setOn( item->verify() );
+ psqlPluginInstall = item;
+ psqlPluginInstall->setHelpText( tr(
+ "Installs the PostgreSQL 7.x driver. This driver can "
+ "be used to access PostgreSQL 6 databases as well "
+ "as PostgreSQL 7 databases."
+#ifdef Q_OS_MACX
+ "\n\nRequires a proper PostgreSQL installation."
+#endif
+ ), configPage->explainOption );
+ } else {
+ psqlPluginInstall = 0;
+ }
+
+ item = new CheckListItem( folder, "MySQL", QCheckListItem::CheckBox );
+#ifndef Q_OS_MACX
+ item->addRequiredFiles( "libmySQL.dll" );
+#endif
+ item->setOn( item->verify() );
+ mysqlPluginInstall = item;
+ mysqlPluginInstall->setHelpText( tr(
+ "Installs the MySQL 3.x database driver."
+#ifdef Q_OS_MACX
+ "\n\nRequires a proper MySQL installation."
+#endif
+ ), configPage->explainOption );
+
+#if !defined(Q_OS_MAC)
+ item = new CheckListItem( folder, "ODBC", QCheckListItem::CheckBox );
+ item->setOn( findFile( "odbc32.dll" ) );
+ odbcPluginInstall = item;
+ odbcPluginInstall->setHelpText( tr(
+ "Installs the Open Database Connectivity (ODBC) driver. "
+ "This driver depends on the odbc32.dll which should be "
+ "available on all modern Windows installations."
+ ), configPage->explainOption );
+#endif
+#else
+ item = new CheckListItem( folder, "SQLite", QCheckListItem::CheckBox );
+ item->setOn( true );
+ sqlitePluginInstall = item;
+ sqlitePluginInstall->setHelpText( tr(
+ "Installs the SQLite driver.\n"
+ "This driver is an in-process SQL database "
+ "driver. It is needed for some of the "
+ "examples used in the book."
+ ), configPage->explainOption );
+#endif
+
+ configPage->installList->setUpdatesEnabled(true);
+ alreadyInitialized = true;
+ }
+#else
+
+ prepareEnvironment();
+
+ bool enterprise = licenseInfo[ "PRODUCTS" ] == "qt-enterprise";
+ configPage->configList->setUpdatesEnabled(false);
+ configPage->advancedList->setUpdatesEnabled(false);
+
+ if( configPage->configList->childCount() ) {
+ QListViewItem* current = configPage->configList->firstChild();
+
+ while( current ) {
+ QListViewItem* next = current->nextSibling();
+ delete current;
+ current = next;
+ }
+
+ current = configPage->advancedList->firstChild();
+ while( current ) {
+ QListViewItem* next = current->nextSibling();
+ delete current;
+ current = next;
+ }
+ }
+ QSettings settings;
+ configPage->configList->setSorting( -1 );
+ configPage->advancedList->setSorting( -1 );
+ CheckListItem *item;
+ CheckListItem *folder;
+ QStringList::Iterator it;
+
+ // general
+ folder = new CheckListItem ( configPage->configList, "Modules" );
+ folder->setHelpText(tr("<p>Some of these modules are optional."
+ "<p>You can deselect the modules that you "
+ "don't require for your development."
+ "<p>By default, all modules are selected."), configPage->explainOption);
+ bool settingsOK;
+ QStringList entries = settings.readListEntry( "/Trolltech/Qt/Modules", ',', &settingsOK );
+ QStringList licensedModules = QStringList::split( " ", "network canvas table xml opengl sql" );
+ for( it = licensedModules.begin(); it != licensedModules.end(); ++it ) {
+ item = new CheckListItem( folder, (*it), QCheckListItem::CheckBox );
+ bool on = entries.isEmpty() || entries.find( *it ) != entries.end();
+ item->setOn( enterprise && on );
+ item->setEnabled( enterprise );
+ if ( enterprise )
+ allModules << *it;
+ }
+
+ licensedModules = QStringList::split( " ", "iconview workspace" );
+ for( it = licensedModules.begin(); it != licensedModules.end(); ++it ) {
+ item = new CheckListItem( folder, (*it), QCheckListItem::CheckBox );
+ bool on = entries.isEmpty() || entries.find( *it ) != entries.end();
+ item->setOn( on );
+ allModules << *it;
+ }
+
+ QStringList requiredModules = QStringList::split( " ", "styles dialogs widgets tools kernel" );
+ for( it = requiredModules.begin(); it != requiredModules.end(); ++it ) {
+ item = new CheckListItem( folder, (*it), QCheckListItem::CheckBox );
+ bool on = entries.isEmpty() || entries.find( *it ) != entries.end();
+ item->setOn( on );
+ item->setEnabled( false );
+ allModules << *it;
+ }
+
+ folder = new CheckListItem ( configPage->configList, "Threading" );
+ folder->setHelpText(tr("<p>Build the Qt library with or without thread support."
+ "<p>By default, threading is supported. Some classes will "
+ "not be available without thread support."), configPage->explainOption);
+ QString entry = settings.readEntry( "/Trolltech/Qt/Threading", "Threaded", &settingsOK );
+ item = new CheckListItem( folder, "Threaded", QCheckListItem::RadioButton );
+ item->setOn( entry == "Threaded" );
+ item = new CheckListItem( folder, "Non-threaded", QCheckListItem::RadioButton );
+ item->setOn( entry == "Non-threaded" );
+ CheckListItem *singleThreaded = item;
+
+ folder = new CheckListItem ( configPage->configList, "Library" );
+ folder->setHelpText(tr("<p>Build a shared or a static Qt library."
+ "<p>A shared Qt library makes it necessary to "
+ "distribute the Qt DLL together with your software. "
+ "Applications and libraries linked against a shared Qt library "
+ "are small and can make use of components and plugins."
+ "<p>All applications created with a static "
+ "library will be at least 1.5MB big. "
+ "<font color=\"red\">It is not possible to "
+ "build or use any components or plugins with a "
+ "static Qt library!</font>"), configPage->explainOption);
+ entry = settings.readEntry( "/Trolltech/Qt/Library", "Shared", &settingsOK );
+ staticItem = new CheckListItem( folder, "Static", QCheckListItem::RadioButton );
+ staticItem->setOn( entry == "Static" );
+ staticItem->setWarningText("<p>It will not be possible to build components "
+ "or plugins if you select the static build of the Qt library."
+ "<p>New features, e.g souce code editing in Qt Designer, will not "
+ "be available, and you or users of your software might not be able "
+ "to use all or new features, e.g. new styles.");
+
+ item = new CheckListItem( folder, "Shared", QCheckListItem::RadioButton );
+ item->setOn( entry == "Shared" );
+ item->setWarningText("<p>Single-threaded, shared configurations "
+ "may cause instabilities because of runtime "
+ "library conflicts.", singleThreaded);
+ singleThreaded->setWarningText("<p>Single-threaded, shared configurations "
+ "may cause instabilities because of runtime "
+ "library conflicts.", item);
+
+ folder = new CheckListItem ( configPage->configList, "Build" );
+ folder->setHelpText(tr("<p>Build a Qt library with or without debug symbols."
+ "<p>Use the debug build of the Qt library to enhance "
+ "debugging of your application. The release build "
+ "is both smaller and faster."), configPage->explainOption);
+ entry = settings.readEntry( "/Trolltech/Qt/Build", "Release", &settingsOK );
+ item = new CheckListItem( folder, "Debug", QCheckListItem::RadioButton );
+ item->setOn( entry == "Debug" );
+ item = new CheckListItem( folder, "Release", QCheckListItem::RadioButton );
+ item->setOn( entry == "Release" );
+
+ // Advanced options
+ if ( globalInformation.sysId() == GlobalInformation::MSVC ) {
+ entry = settings.readEntry( "/Trolltech/Qt/DSP Generation", "On", &settingsOK );
+ folder = new CheckListItem( configPage->advancedList, "DSP Generation" );
+ folder->setHelpText(tr("qmake can generate the Visual Studio 6 project files (dsp) as well "
+ "as makefiles when Qt is being configured."),
+ configPage->explainOption);
+ dspOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ dspOff->setOn( entry == "Off" );
+ dspOn = new CheckListItem( folder, "On", QCheckListItem::RadioButton );
+ dspOn->setOn( entry == "On" );
+ } else if ( globalInformation.sysId() == GlobalInformation::MSVCNET ) {
+ entry = settings.readEntry( "/Trolltech/Qt/VCPROJ Generation", "On", &settingsOK );
+ folder = new CheckListItem( configPage->advancedList, "VCPROJ Generation" );
+ folder->setHelpText(tr("qmake can generate the Visual Studio.NET project files (vcproj) as well "
+ "as makefiles when Qt is being configured."),
+ configPage->explainOption);
+ vcprojOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ vcprojOff->setOn( entry == "Off" );
+ vcprojOn = new CheckListItem( folder, "On", QCheckListItem::RadioButton );
+ vcprojOn->setOn( entry == "On" );
+ }
+
+ CheckListItem *imfolder = new CheckListItem( configPage->advancedList, "Image Formats" );
+ imfolder->setHelpText(tr("<p>Qt ships with support for a wide range of common image formats. "
+ "<p>Standard formats are always included in Qt, and some more special formats "
+ "can be left out from the Qt library itself and provided by a plugin instead."),
+ configPage->explainOption);
+
+ folder = new CheckListItem( imfolder, "GIF" );
+ folder->setHelpText(tr("<p>Support for GIF images in Qt."
+ "<p><font color=\"red\">If you are in a country "
+ "which recognizes software patents and in which "
+ "Unisys holds a patent on LZW compression and/or "
+ "decompression and you want to use GIF, Unisys "
+ "may require you to license the technology. Such "
+ "countries include Canada, Japan, the USA, "
+ "France, Germany, Italy and the UK.</font>"),
+ configPage->explainOption);
+ entry = settings.readEntry( "/Trolltech/Qt/Image Formats/GIF", "Off", &settingsOK );
+ gifOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ gifOff->setOn( entry == "Off" );
+ gifDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ gifDirect->setOn( entry == "Direct" );
+
+ folder = new CheckListItem( imfolder, "MNG" );
+ folder->setHelpText(tr("<p>Qt can support the \"Multiple-Image Network Graphics\" format."
+ "<p>MNG support can be compiled into Qt, provided by a plugin ",
+ "or turned off completely."),
+ configPage->explainOption);
+ entry = settings.readEntry( "/Trolltech/Qt/Image Formats/MNG", "Plugin", &settingsOK );
+#if 0
+ // ### disable using system MNG for now -- please someone take a closer look
+ entryPresent = settings.readEntry( "/Trolltech/Qt/Image Formats/MNG Present", "No", &settingsOK );
+ mngPresent = new CheckListItem( folder, "Present", QCheckListItem::CheckBox );
+ mngPresent->setOn( entry == "Yes" );
+#endif
+ mngOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ mngOff->setOn( entry == "Off" );
+ mngPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ mngPlugin->setOn( entry == "Plugin" );
+ mngDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ mngDirect->setOn( entry == "Direct" );
+
+ folder = new CheckListItem( imfolder, "JPEG" );
+ folder->setHelpText(tr("<p>Qt can support the \"Joint Photographic Experts Group\" format."
+ "<p>JPEG support can be compiled into Qt, provided by a plugin ",
+ "or turned off completely."),
+ configPage->explainOption);
+ entry = settings.readEntry( "/Trolltech/Qt/Image Formats/JPEG", "Direct", &settingsOK );
+#if 0
+ // ### disable using system JPEG for now -- please someone take a closer look
+ entryPresent = settings.readEntry( "/Trolltech/Qt/Image Formats/JPEG Present", "No", &settingsOK );
+ jpegPresent = new CheckListItem( folder, "Present", QCheckListItem::CheckBox );
+ jpegPresent->setOn( entry == "Yes" );
+#endif
+ jpegOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ jpegOff->setOn( entry == "Off" );
+ jpegPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ jpegPlugin->setOn( entry == "Plugin" );
+ jpegDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ jpegDirect->setOn( entry == "Direct" );
+
+ folder = new CheckListItem( imfolder, "PNG" );
+ folder->setHelpText(tr("<p>Qt can support the \"Portable Network Graphics\" format."
+ "<p>PNG support can be compiled into Qt, provided by a plugin ",
+ "or turned off completely."),
+ configPage->explainOption);
+ entry = settings.readEntry( "/Trolltech/Qt/Image Formats/PNG", "Direct", &settingsOK );
+#if 0
+ // ### disable using system PNG for now -- please someone take a closer look
+ entryPresent = settings.readEntry( "/Trolltech/Qt/Image Formats/PNG Present", "No", &settingsOK );
+ pngPresent = new CheckListItem( folder, "Present", QCheckListItem::CheckBox );
+ pngPresent->setOn( entry == "Yes" );
+#endif
+ pngOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ pngOff->setOn( entry == "Off" );
+ // PNG is required by the build system (ie. we use PNG), so don't allow it to be turned off
+ pngOff->setEnabled( false );
+ pngPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ pngPlugin->setOn( entry == "Plugin" );
+ pngDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ pngDirect->setOn( entry == "Direct" );
+
+ CheckListItem *sqlfolder = new CheckListItem( configPage->advancedList, "Sql Drivers" );
+ sqlfolder->setHelpText(tr("<p>Select the SQL Drivers you want to support."
+ "<p>SQL Drivers can be built into Qt or built as plugins to be more flexible "
+ "for later extensions."
+ "<p><font color=#FF0000>You must have the appropriate client libraries "
+ "and header files installed correctly before you can build the Qt SQL drivers.</font>"),
+ configPage->explainOption);
+
+ folder = new CheckListItem( sqlfolder, "iBase" );
+ folder->addRequiredFiles("ibase.h");
+ entry = settings.readEntry( "/Trolltech/Qt/Sql Drivers/iBase", "Off", &settingsOK );
+ ibaseOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ ibaseOff->setOn( true );
+ ibaseOff->setEnabled( enterprise );
+ ibasePlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ ibasePlugin->setOn( entry == "Plugin" && folder->verify() && enterprise );
+ ibasePlugin->setEnabled( enterprise );
+ ibaseDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ ibaseDirect->setOn( entry == "Direct" && folder->verify() && enterprise );
+ ibaseDirect->setEnabled( enterprise );
+ if (globalInformation.sysId() == GlobalInformation::Borland)
+ folder->addRequiredFiles("gds32.lib");
+ else
+ folder->addRequiredFiles("gds32_ms.lib");
+
+ folder = new CheckListItem( sqlfolder, "DB2" );
+ folder->addRequiredFiles("db2cli.lib,sqlcli1.h");
+ entry = settings.readEntry( "/Trolltech/Qt/Sql Drivers/DB2", "Off", &settingsOK );
+ db2Off = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ db2Off->setOn( true );
+ db2Off->setEnabled( enterprise );
+ db2Plugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ db2Plugin->setOn( entry == "Plugin" && folder->verify() && enterprise );
+ db2Plugin->setEnabled( enterprise );
+ db2Direct = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ db2Direct->setOn( entry == "Direct" && folder->verify() && enterprise );
+ db2Direct->setEnabled( enterprise );
+
+ folder = new CheckListItem( sqlfolder, "TDS" );
+ folder->addRequiredFiles("ntwdblib.lib,sqldb.h");
+ entry = settings.readEntry( "/Trolltech/Qt/Sql Drivers/TDS", "Off", &settingsOK );
+ tdsOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ tdsOff->setOn( true );
+ tdsOff->setEnabled( enterprise );
+ tdsPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ tdsPlugin->setOn( entry == "Plugin" && folder->verify() && enterprise );
+ tdsPlugin->setEnabled( enterprise );
+ tdsDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ tdsDirect->setOn( entry == "Direct" && folder->verify() && enterprise );
+ tdsDirect->setEnabled( enterprise );
+
+ folder = new CheckListItem( sqlfolder, "PostgreSQL" );
+ folder->addRequiredFiles("libpqdll.lib,libpq-fe.h");
+ entry = settings.readEntry( "/Trolltech/Qt/Sql Drivers/PostgreSQL", "Off", &settingsOK );
+ psqlOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ psqlOff->setOn( true );
+ psqlOff->setEnabled( enterprise );
+ psqlPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ psqlPlugin->setOn( entry == "Plugin" && folder->verify() && enterprise );
+ psqlPlugin->setEnabled( enterprise );
+ psqlDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ psqlDirect->setOn( entry == "Direct" && folder->verify() && enterprise );
+ psqlDirect->setEnabled( enterprise );
+
+ folder = new CheckListItem( sqlfolder, "OCI" );
+ folder->addRequiredFiles("oci.lib,oci.h");
+ entry = settings.readEntry( "/Trolltech/Qt/Sql Drivers/OCI", "Off", &settingsOK );
+ ociOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ ociOff->setOn( true );
+ ociOff->setEnabled( enterprise );
+ ociPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ ociPlugin->setOn( entry == "Plugin" && folder->verify() && enterprise );
+ ociPlugin->setEnabled( enterprise );
+ ociDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ ociDirect->setOn( entry == "Direct" && folder->verify() && enterprise );
+ ociDirect->setEnabled( enterprise );
+
+ folder = new CheckListItem( sqlfolder, "MySQL" );
+ folder->addRequiredFiles("libmysql.lib,mysql.h");
+ entry = settings.readEntry( "/Trolltech/Qt/Sql Drivers/MySQL", "Off", &settingsOK );
+ mysqlOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ mysqlOff->setOn( true );
+ mysqlOff->setEnabled( enterprise );
+ mysqlPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ mysqlPlugin->setOn( entry == "Plugin" && folder->verify() && enterprise );
+ mysqlPlugin->setEnabled( enterprise );
+ mysqlDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ mysqlDirect->setOn( entry == "Direct" && folder->verify() && enterprise );
+ mysqlDirect->setEnabled( enterprise );
+
+ folder = new CheckListItem( sqlfolder, "SQLite" );
+ entry = settings.readEntry( "/Trolltech/Qt/Sql Drivers/SQLite", "Off", &settingsOK );
+ sqliteOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ sqliteOff->setOn( true );
+ sqliteOff->setEnabled( enterprise );
+ sqlitePlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ sqlitePlugin->setOn( entry == "Plugin" && folder->verify() && enterprise );
+ sqlitePlugin->setEnabled( enterprise );
+ sqliteDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ sqliteDirect->setOn( entry == "Direct" && folder->verify() && enterprise );
+ sqliteDirect->setEnabled( enterprise );
+
+ folder = new CheckListItem( sqlfolder, "ODBC" );
+ folder->addRequiredFiles("odbc32.lib,sql.h");
+ entry = settings.readEntry( "/Trolltech/Qt/Sql Drivers/ODBC", "Off", &settingsOK );
+ odbcOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ odbcOff->setOn( true );
+ odbcOff->setEnabled( enterprise );
+ odbcPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ odbcPlugin->setOn( entry == "Plugin" && folder->verify() && enterprise );
+ odbcPlugin->setEnabled( enterprise );
+ odbcDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ odbcDirect->setOn( entry == "Direct" && folder->verify() && enterprise );
+ odbcDirect->setEnabled( enterprise );
+
+ CheckListItem *stfolder = new CheckListItem( configPage->advancedList, "Styles" );
+ stfolder->setHelpText(tr("Select support for the various GUI styles that Qt supports." ),configPage->explainOption);
+
+ folder = new CheckListItem( stfolder, "SGI" );
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/SGI", "Plugin", &settingsOK );
+ sgiOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ sgiOff->setOn( entry == "Off" );
+ sgiPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ sgiPlugin->setOn( entry == "Plugin" );
+ sgiDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ sgiDirect->setOn( entry == "Direct" );
+
+ folder = new CheckListItem( stfolder, "CDE" );
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/CDE", "Plugin", &settingsOK );
+ cdeOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ cdeOff->setOn( entry == "Off" );
+ cdePlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ cdePlugin->setOn( entry == "Plugin" );
+ cdeDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ cdeDirect->setOn( entry == "Direct" );
+
+ folder = new CheckListItem( stfolder, "MotifPlus" );
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/MotifPlus", "Plugin", &settingsOK );
+ motifplusOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ motifplusOff->setOn( entry == "Off" );
+ motifplusPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ motifplusPlugin->setOn( entry == "Plugin" );
+ motifplusDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ motifplusDirect->setOn( entry == "Direct" );
+
+ folder = new CheckListItem( stfolder, "Platinum" );
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/Platinum", "Plugin", &settingsOK );
+ platinumOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ platinumOff->setOn( entry == "Off" );
+ platinumPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ platinumPlugin->setOn( entry == "Plugin" );
+ platinumDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ platinumDirect->setOn( entry == "Direct" );
+
+ folder = new CheckListItem( stfolder, "Motif" );
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/Motif", "Plugin", &settingsOK );
+ motifOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ motifOff->setOn( entry == "Off" );
+ motifPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ motifPlugin->setOn( entry == "Plugin" );
+ motifDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ motifDirect->setOn( entry == "Direct" );
+
+ folder = new CheckListItem( stfolder, "Windows XP" );
+ folder->addRequiredFiles("uxtheme.h");
+ folder->setRequiredFileLocation("part of the Microsoft Platform SDK, which is usually available for "
+ "download from the following location:"
+ "<p>http://www.microsoft.com/msdownload/platformsdk/sdkupdate/<p>");
+
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/Windows XP", "Direct", &settingsOK );
+ xpOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ xpOff->setOn( true );
+ xpPlugin = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ xpPlugin->setOn( entry == "Plugin" && folder->verify() );
+ xpPlugin->setEnabled( folder->verify() );
+ xpDirect = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ xpDirect->setOn( entry == "Direct" && folder->verify() );
+ xpDirect->setEnabled( folder->verify() );
+
+ folder = new CheckListItem( stfolder, "Windows" );
+ entry = settings.readEntry( "/Trolltech/Qt/Styles/Windows", "Direct", &settingsOK );
+ item = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ item->setEnabled( false );
+ item->setOn( entry == "Off" );
+ item = new CheckListItem( folder, "Plugin", QCheckListItem::RadioButton );
+ item->setEnabled( false );
+ item->setOn( entry == "Plugin" );
+ item = new CheckListItem( folder, "Direct", QCheckListItem::RadioButton );
+ item->setOn( entry == "Direct" );
+
+ entries = settings.readListEntry( "/Trolltech/Qt/Advanced C++", ',', &settingsOK );
+ folder = new CheckListItem( configPage->advancedList, "Advanced C++" );
+ folder->setHelpText(tr("Qt can be built with exception handling, STL support and RTTI support "
+ "enabled or disabled. Qt itself doesn't use any of those features."
+ "The default is to disable all advanced C++ features."),
+ configPage->explainOption);
+ advancedRTTI = new CheckListItem( folder, "RTTI", QCheckListItem::CheckBox );
+ advancedRTTI->setOn( entries.contains( "RTTI" ) );
+ advancedExceptions = new CheckListItem( folder, "Exceptions", QCheckListItem::CheckBox );
+ advancedExceptions->setOn( entries.contains( "Exceptions" ) );
+ advancedSTL = new CheckListItem( folder, "STL", QCheckListItem::CheckBox );
+ advancedSTL->setOn( entries.contains( "STL" ) );
+
+ folder = new CheckListItem( configPage->advancedList, "Tablet Support" );
+ folder->addRequiredFiles("wintab.h,wintab.lib");
+ folder->setRequiredFileLocation("available at http://www.pointing.com/FTP.HTM");
+ folder->setHelpText(tr("Qt can support the Wacom brand tablet device."), configPage->explainOption);
+ entry = settings.readEntry( "/Trolltech/Qt/Tablet Support", "Off", &settingsOK );
+ tabletOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ tabletOff->setOn( true );
+ tabletOn = new CheckListItem( folder, "On", QCheckListItem::RadioButton );
+ tabletOn->setOn( entry == "On" && folder->verify() );
+
+ folder = new CheckListItem( configPage->advancedList, "Accessibility" );
+ folder->setHelpText(tr("<p>Accessibility means making software usable and accessible to a wide "
+ "range of users, including those with disabilities."
+ "This feature is only available with a shared Qt library."),
+ configPage->explainOption);
+ entry = settings.readEntry( "/Trolltech/Qt/Accessibility", "On", &settingsOK );
+ accOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ accOff->setOn( entry == "Off" );
+ accOn = new CheckListItem( folder, "On", QCheckListItem::RadioButton );
+ accOn->setOn( entry == "On" );
+
+ entry = settings.readEntry( "/Trolltech/Qt/Big Textcodecs", "On", &settingsOK );
+ folder = new CheckListItem( configPage->advancedList, "Big Textcodecs" );
+ folder->setHelpText(tr("Textcodecs provide translations between text encodings. For "
+ "languages and script systems with many characters it is necessary "
+ "to have big data tables that provide the translation. Those codecs "
+ "can be left out of the Qt library and will be loaded on demand.\n"
+ "Having the codecs in a plugin is not available with a static Qt "
+ "library."), configPage->explainOption);
+ bigCodecsOff = new CheckListItem( folder, "Off", QCheckListItem::RadioButton );
+ bigCodecsOff->setOn( entry == "Off" );
+ bigCodecsOn = new CheckListItem( folder, "On", QCheckListItem::RadioButton );
+ bigCodecsOn->setOn( entry == "On" );
+
+ setStaticEnabled( staticItem->isOn() );
+ setJpegDirect( mngDirect->isOn() );
+
+ configPage->configList->setUpdatesEnabled(true);
+ configPage->advancedList->setUpdatesEnabled(true);
+
+ // Needed to force the scrollbars to appear on Windows 9x...
+ QListViewItem *dummy = new QListViewItem(configPage->configList, "Dummy Item");
+ delete dummy;
+
+ setBackEnabled( buildPage, false );
+#endif
+}
+
+void SetupWizardImpl::showPageBuild()
+{
+ autoContTimer.stop();
+ nextButton()->setText( "Next >" );
+ saveSettings();
+
+#if defined(Q_OS_WIN32)
+ if( globalInformation.reconfig() && configPage->rebuildInstallation->isChecked() && qWinVersion() & WV_NT_based ) {
+ QStringList args;
+
+ buildPage->compileProgress->hide();
+ buildPage->restartBuild->hide();
+
+ args << globalInformation.text(GlobalInformation::MakeTool) << "clean";
+ logOutput( "Starting cleaning process" );
+ connect( &cleaner, SIGNAL( processExited() ), this, SLOT( cleanDone() ) );
+ connect( &cleaner, SIGNAL( readyReadStdout() ), this, SLOT( readCleanerOutput() ) );
+ connect( &cleaner, SIGNAL( readyReadStderr() ), this, SLOT( readCleanerError() ) );
+ cleaner.setWorkingDirectory( QEnvironment::getEnv( "QTDIR" ) );
+ cleaner.setArguments( args );
+ if( !cleaner.start() ) {
+ logOutput( "Could not start cleaning process" );
+ emit wizardPageFailed( indexOf(currentPage()) );
+ }
+ } else
+#endif
+ cleanDone(); // We're not doing a reconfig, so skip the clean step
+
+}
+
+static bool verifyHelper(QListView *listview, bool result)
+{
+ QListViewItemIterator it(listview);
+ while (it.current()) {
+ QListViewItem *item = it.current();
+ ++it;
+ if (item->rtti() != CheckListItem::RTTI)
+ continue;
+
+ CheckListItem *checkItem = (CheckListItem*)item;
+ if (!checkItem->isOn())
+ continue;
+
+ bool r = checkItem->verify();
+ checkItem->setCritical(!r);
+ if (result) result = r;
+ }
+ return result;
+}
+
+bool SetupWizardImpl::verifyConfig()
+{
+ bool result = true;
+#if !defined(EVAL) && !defined(EDU) && !defined(NON_COMMERCIAL)
+ result = verifyHelper(configPage->configList, result);
+ result = verifyHelper(configPage->advancedList, result);
+#endif
+ return result;
+}
diff --git a/util/install/win/shell.cpp b/util/install/win/shell.cpp
new file mode 100644
index 0000000..b1303a7
--- /dev/null
+++ b/util/install/win/shell.cpp
@@ -0,0 +1,472 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "shell.h"
+#include "environment.h"
+#include "dialogs/folderdlgimpl.h"
+#include <qnamespace.h>
+#include <qdir.h>
+#include <qlibrary.h>
+#if defined(Q_OS_WIN32)
+#include <windows.h>
+#include <shlobj.h>
+#else
+#include <sys/param.h>
+#include <sys/mount.h>
+#endif
+
+static const char* folder_closed_xpm[]={
+ "16 16 9 1",
+ "g c #808080",
+ "b c #c0c000",
+ "e c #c0c0c0",
+ "# c #000000",
+ "c c #ffff00",
+ ". c None",
+ "a c #585858",
+ "f c #a0a0a4",
+ "d c #ffffff",
+ "..###...........",
+ ".#abc##.........",
+ ".#daabc#####....",
+ ".#ddeaabbccc#...",
+ ".#dedeeabbbba...",
+ ".#edeeeeaaaab#..",
+ ".#deeeeeeefe#ba.",
+ ".#eeeeeeefef#ba.",
+ ".#eeeeeefeff#ba.",
+ ".#eeeeefefff#ba.",
+ ".##geefeffff#ba.",
+ "...##gefffff#ba.",
+ ".....##fffff#ba.",
+ ".......##fff#b##",
+ ".........##f#b##",
+ "...........####."
+};
+
+static const char* folder_open_xpm[]={
+ "16 16 11 1",
+ "# c #000000",
+ "g c #c0c0c0",
+ "e c #303030",
+ "a c #ffa858",
+ "b c #808080",
+ "d c #a0a0a4",
+ "f c #585858",
+ "c c #ffdca8",
+ "h c #dcdcdc",
+ "i c #ffffff",
+ ". c None",
+ "....#ab##.......",
+ "....###.........",
+ "....#acab####...",
+ "###.#acccccca#..",
+ "#ddefaaaccccca#.",
+ "#bdddbaaaacccab#",
+ ".eddddbbaaaacab#",
+ ".#bddggdbbaaaab#",
+ "..edgdggggbbaab#",
+ "..#bgggghghdaab#",
+ "...ebhggghicfab#",
+ "....#edhhiiidab#",
+ "......#egiiicfb#",
+ "........#egiibb#",
+ "..........#egib#",
+ "............#ee#"
+};
+
+static const char* file_xpm []={
+ "16 16 7 1",
+ "# c #000000",
+ "b c #ffffff",
+ "e c #000000",
+ "d c #404000",
+ "c c #c0c000",
+ "a c #ffffc0",
+ ". c None",
+ "................",
+ ".........#......",
+ "......#.#a##....",
+ ".....#b#bbba##..",
+ "....#b#bbbabbb#.",
+ "...#b#bba##bb#..",
+ "..#b#abb#bb##...",
+ ".#a#aab#bbbab##.",
+ "#a#aaa#bcbbbbbb#",
+ "#ccdc#bcbbcbbb#.",
+ ".##c#bcbbcabb#..",
+ "...#acbacbbbe...",
+ "..#aaaacaba#....",
+ "...##aaaaa#.....",
+ ".....##aa#......",
+ ".......##......."
+};
+
+static const char* info_xpm[] = {
+ "16 16 6 1",
+ "# c #0000ff",
+ "a c #6868ff",
+ "b c #d0d0ff",
+ "c c #ffffff",
+ "- c #000000",
+ ". c none",
+ ".....------.....",
+ "...--######--...",
+ "..-###acca###-..",
+ ".-####cccc####-.",
+ ".-####acca####-.",
+ "-##############-",
+ "-######bcc#####-",
+ "-####ccccc#####-",
+ "-#####cccc#####-",
+ "-#####cccc#####-",
+ "-#####cccc#####-",
+ ".-####cccc####-.",
+ ".-###cccccc###-.",
+ "..-##########-..",
+ "...--#######-...",
+ ".....------....."
+};
+
+static QPixmap* closedImage = NULL;
+static QPixmap* openImage = NULL;
+static QPixmap* fileImage = NULL;
+static QPixmap* infoImage = NULL;
+
+#if defined(Q_OS_WIN32)
+typedef BOOL (WINAPI *PtrSHGetPathFromIDListW)(LPITEMIDLIST,LPWSTR);
+static PtrSHGetPathFromIDListW ptrSHGetPathFromIDListW = 0;
+
+static void resolveLibs()
+{
+ static bool triedResolve = false;
+
+ if ( !triedResolve ) {
+ triedResolve = true;
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ QLibrary lib("shell32");
+ lib.setAutoUnload( false );
+ ptrSHGetPathFromIDListW = (PtrSHGetPathFromIDListW) lib.resolve( "SHGetPathFromIDListW" );
+ }
+ }
+}
+#endif
+
+WinShell::WinShell()
+{
+#if defined(Q_OS_WIN32)
+ HRESULT hr;
+ LPITEMIDLIST item;
+#endif
+
+ localProgramsFolderName.clear();
+ commonProgramsFolderName.clear();
+ windowsFolderName.clear();
+
+#if defined(Q_OS_WIN32)
+ resolveLibs();
+ if( ptrSHGetPathFromIDListW && int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ ushort buffer[MAX_PATH];
+ if( SUCCEEDED( hr = SHGetSpecialFolderLocation( NULL, CSIDL_PROGRAMS, &item ) ) ) {
+ if( ptrSHGetPathFromIDListW( item, (wchar_t*) buffer ) ) {
+ localProgramsFolderName = QString::fromUcs2( buffer );
+ if( SUCCEEDED( hr = SHGetSpecialFolderLocation( NULL, CSIDL_COMMON_PROGRAMS, &item ) ) ) {
+ if( ptrSHGetPathFromIDListW( item, (wchar_t*) buffer ) )
+ commonProgramsFolderName = QString::fromUcs2( buffer );
+ else
+ qDebug( "Could not get name of common programs folder" );
+ }
+ else
+ qDebug( "Could not get common programs folder location" );
+
+ if( GetWindowsDirectoryW( (wchar_t*) buffer, MAX_PATH ) )
+ windowsFolderName = QString::fromUcs2( buffer );
+ else
+ qDebug( "Could not get Windows directory" );
+ }
+ else
+ qDebug( "Could not get name of programs folder" );
+ }
+ else
+ qDebug( "Could not get programs folder location" );
+ }
+ else {
+ QByteArray buffer( MAX_PATH );
+ if( SUCCEEDED( hr = SHGetSpecialFolderLocation( NULL, CSIDL_PROGRAMS, &item ) ) ) {
+ if( SHGetPathFromIDListA( item, buffer.data() ) ) {
+ localProgramsFolderName = buffer.data();
+ commonProgramsFolderName = buffer.data();
+ }
+ else
+ qDebug( "Could not get name of programs folder" );
+ }
+ else
+ qDebug( "Could not get programs folder location" );
+ }
+#endif
+
+ closedImage = new QPixmap( folder_closed_xpm );
+ openImage = new QPixmap( folder_open_xpm );
+ fileImage = new QPixmap( file_xpm );
+ infoImage = new QPixmap( info_xpm );
+}
+
+WinShell::~WinShell()
+{
+}
+
+QString WinShell::selectFolder( QString folderName, bool common )
+{
+ QStringList folders;
+ FolderDlgImpl dlg;
+
+ if( common )
+ dlg.setup( commonProgramsFolderName, folderName );
+ else
+ dlg.setup( localProgramsFolderName, folderName );
+
+ if( dlg.exec() ) {
+ return dlg.getFolderName();
+ }
+ else
+ return folderName;
+}
+
+QString WinShell::createFolder( QString folderName, bool common )
+{
+ QDir folderDir;
+ QString folderPath;
+
+ if( common )
+ folderPath = commonProgramsFolderName + QString( "\\" ) + folderName;
+ else
+ folderPath = localProgramsFolderName + QString( "\\" ) + folderName;
+
+ folderDir.setPath( folderPath );
+
+ if( !folderDir.exists( folderPath ) )
+ if( !createDir( folderPath ) )
+ return QString();
+
+ return folderPath;
+}
+
+
+#if defined(Q_OS_WIN32)
+HRESULT WinShell::createShortcut( QString folderName, bool, QString shortcutName, QString target, QString description, QString arguments, QString wrkDir )
+{
+ IPersistFile* linkFile;
+ HRESULT hr;
+
+ // Add .lnk to shortcut name if needed
+ if( shortcutName.right( 4 ) != ".lnk" )
+ shortcutName += ".lnk";
+
+ folderName = QEnvironment::getFSFileName( folderName );
+ if( int( qWinVersion() ) & int( Qt::WV_NT_based ) ) {
+ IShellLinkW* link;
+ if( SUCCEEDED( hr = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void**)&link ) ) ) {
+ if( SUCCEEDED( hr = link->QueryInterface( IID_IPersistFile, (void**)&linkFile ) ) ) {
+ link->SetPath( (const wchar_t*) target.ucs2() );
+ QString _wrkDir = wrkDir;
+ if( !_wrkDir.length() ) {
+ _wrkDir = QDir::toNativeSeparators( target );
+ // remove the filename
+ int pos = _wrkDir.findRev( '\\' );
+ if ( pos > 0 )
+ _wrkDir = _wrkDir.left( pos );
+ else
+ _wrkDir = "";
+ }
+
+ link->SetWorkingDirectory( (const wchar_t*) _wrkDir.ucs2() );
+ if( description.length() )
+ link->SetDescription( (const wchar_t*) description.ucs2() );
+ if( arguments.length() )
+ link->SetArguments( (const wchar_t*) arguments.ucs2() );
+
+ hr = linkFile->Save( (const wchar_t*) QString( folderName + QString( "\\" ) + shortcutName ).ucs2(), false );
+
+ linkFile->Release();
+ }
+ else
+ qDebug( "Could not get link file interface" );
+
+ link->Release();
+ }
+ else
+ qDebug( "Could not instantiate link object" );
+ }
+ else {
+ IShellLinkA* link;
+ if( SUCCEEDED( hr = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkA, (void**)&link ) ) ) {
+ if( SUCCEEDED( hr = link->QueryInterface( IID_IPersistFile, (void**)&linkFile ) ) ) {
+ link->SetPath( target.local8Bit().data() );
+ QString wrkDir = QDir::toNativeSeparators( target );
+
+ // remove the filename
+ int pos = wrkDir.findRev( '\\' );
+ if ( pos > 0 )
+ wrkDir = wrkDir.left( pos );
+ else
+ wrkDir = "";
+
+ link->SetWorkingDirectory( wrkDir );
+ if( description.length() )
+ link->SetDescription( description.local8Bit() );
+ if( arguments.length() )
+ link->SetArguments( arguments.local8Bit() );
+
+ hr = linkFile->Save( (const wchar_t*) QString( folderName + QString( "\\" ) + shortcutName ).ucs2(), false );
+
+ linkFile->Release();
+ }
+ else
+ qDebug( "Could not get link file interface" );
+
+ link->Release();
+ }
+ else
+ qDebug( "Could not instantiate link object" );
+ }
+
+ return hr;
+}
+#endif
+
+#if defined(Q_OS_WIN32)
+void WinShell::createInternetShortcut( QString folderName, bool, QString shortcutName, QString url )
+{
+ // Add .url to shortcut name if needed
+ if( shortcutName.right( 4 ) != ".url" )
+ shortcutName += ".url";
+
+ // ### maybe we should use some Microsoft API instead (IShellLink, e.g.)?
+ QDir dir( folderName );
+ QFile f( dir.filePath( shortcutName ) );
+ if ( f.open( IO_WriteOnly | IO_Translate ) ) {
+ QTextStream ts( &f );
+ ts << "[InternetShortcut]" << endl
+ << "URL=" << url;
+ }
+}
+#endif
+
+bool WinShell::createDir( QString fullPath )
+{
+ QStringList hierarchy = QStringList::split( QString( "\\" ), fullPath );
+ QString pathComponent, tmpPath;
+ QDir dirTmp;
+ bool success;
+
+ for( QStringList::Iterator it = hierarchy.begin(); it != hierarchy.end(); ++it ) {
+ pathComponent = *it + "\\";
+ tmpPath += pathComponent;
+ success = dirTmp.mkdir( tmpPath );
+ }
+ return success;
+}
+
+QPixmap* WinShell::getClosedFolderImage()
+{
+ return closedImage;
+}
+
+QPixmap* WinShell::getOpenFolderImage()
+{
+ return openImage;
+}
+
+QPixmap* WinShell::getFileImage()
+{
+ return fileImage;
+}
+
+QPixmap* WinShell::getInfoImage()
+{
+ return infoImage;
+}
+
+#if defined(Q_OS_WIN32)
+QString WinShell::OLESTR2QString( LPOLESTR str )
+{
+ QString tmp;
+
+ for( int i = 0; str[ i ]; i++ )
+ tmp += QChar( str[ i ] );
+
+ return tmp;
+}
+#endif
+
+/*!
+ Returns the free space for the directory. The space is returned in bytes,
+ and should only be considered valid for this particular directory.
+*/
+#if defined(Q_OS_WIN32)
+ULARGE_INTEGER WinShell::dirFreeSpace( QString dirPath )
+{
+ QString drive = dirPath.left( dirPath.find( '\\' ) );
+ ULARGE_INTEGER freeSpace;
+
+ freeSpace.QuadPart = 0;
+
+ if( GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetDiskFreeSpaceExA" ) ) {
+ ULARGE_INTEGER ulBytesAvailable, ulBytesTotal;
+ if( GetDiskFreeSpaceExA( drive.local8Bit(), &ulBytesAvailable, &ulBytesTotal, NULL ) )
+ freeSpace = ulBytesAvailable;
+ }
+ else if( GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetDiskFreeSpaceA" ) ) {
+ DWORD dwSPC, dwBPS, dwClusters, dwTotalClusters;
+ if( GetDiskFreeSpaceA( drive.local8Bit(), &dwSPC, &dwBPS, &dwClusters, &dwTotalClusters ) )
+ freeSpace.QuadPart = dwSPC * dwBPS * dwClusters;
+ }
+ return freeSpace;
+}
+#elif defined(Q_OS_MAC)
+long WinShell::dirFreeSpace( QString dirPath )
+{
+ struct statfs buf;
+ if (statfs( dirPath.local8Bit(), &buf ) != -1)
+ return buf.f_bavail * buf.f_bsize;
+ return 0;
+}
+#endif
+
diff --git a/util/install/win/shell.h b/util/install/win/shell.h
new file mode 100644
index 0000000..4d5f9af
--- /dev/null
+++ b/util/install/win/shell.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef SHELL_H
+#define SHELL_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qpixmap.h>
+#if defined(Q_OS_WIN32)
+#include <windows.h>
+#include <shlobj.h>
+#endif
+
+class WinShell
+{
+public:
+ WinShell();
+ ~WinShell();
+
+private:
+ bool createDir( QString fullPath );
+#if defined(Q_OS_WIN32)
+ QString OLESTR2QString( LPOLESTR str );
+#endif
+public:
+ QString localProgramsFolderName;
+ QString commonProgramsFolderName;
+ QString windowsFolderName;
+ QString selectFolder( QString folderName, bool common );
+
+ QString createFolder( QString folderName, bool common );
+
+#if defined(Q_OS_WIN32)
+ HRESULT createShortcut( QString folderName, bool common, QString shortcutName, QString target, QString description = QString(), QString arguments = QString(), QString wrkDir = QString() );
+ void createInternetShortcut( QString folderName, bool common, QString shortcutName, QString url );
+#endif
+
+ static QPixmap* getOpenFolderImage();
+ static QPixmap* getClosedFolderImage();
+ static QPixmap* getFileImage();
+ static QPixmap* getInfoImage();
+#if defined(Q_OS_WIN32)
+ static ULARGE_INTEGER dirFreeSpace( QString dirPath );
+#elif defined(Q_OS_MAC)
+ static long dirFreeSpace( QString dirPath );
+#endif
+};
+
+#endif
diff --git a/util/install/win/uninstaller/quninstall.pro b/util/install/win/uninstaller/quninstall.pro
new file mode 100644
index 0000000..c64e8d2
--- /dev/null
+++ b/util/install/win/uninstaller/quninstall.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+CONFIG += qt
+HEADERS = ../environment.h uninstallimpl.h
+SOURCES = uninstaller.cpp ../environment.cpp uninstallimpl.cpp
+INTERFACES = uninstall.ui
+TARGET = quninstall
+DESTDIR = ../../../../dist/win/bin
diff --git a/util/install/win/uninstaller/uninstall.ui b/util/install/win/uninstaller/uninstall.ui
new file mode 100644
index 0000000..88f27a7
--- /dev/null
+++ b/util/install/win/uninstaller/uninstall.ui
@@ -0,0 +1,167 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>UninstallDlg</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>UninstallDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>527</width>
+ <height>365</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Uninstalling Qt</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>sideBar</cstring>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="0" column="1">
+ <property name="name">
+ <cstring>progressBox</cstring>
+ </property>
+ <property name="title">
+ <string>Uninstallation progress</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QTextView">
+ <property name="name">
+ <cstring>filesDisplay</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <family>Courier</family>
+ </font>
+ </property>
+ <property name="wordWrap">
+ <enum>NoWrap</enum>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="1">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>90</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>cleanRegButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Clean Registry</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>okButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>100</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </grid>
+</widget>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="26835">789ced5c595323bb927e3fbfa2e3e8edc6842ed8982526e601b0318bd97726e62125956df0868d59cc8df9ef93ca452e6f34f4e1ccf4c37405747fae2a293fe5a24c49ee7ffee3c7cdc9e18f7ffcf38fa7210ceffd0fdf84c18f7f84e74e67f49ffff51ffffae3cfe5a5a51ff1a7b8b1f1a3f0e7bffdf1a7811ffe8759a23f842b09af13be51bcccf78de015797e27617efe5ab13c6f05afcbf3eb09d3f3f0a0989ff7cd84f9fea360cfef879030dfef335e16f9bd172cf2c125e1f524ef6dc22cef9a62e9ff30616eff4ab0ca5f4d98efaf2a96f7af13e6fb15c122bfbf4f98fbbf532ce355669cf81c27cced9d28e6f68d132cfcec86609117b6044bff8efac7d6a43f7fc358fb0be78af9beeb09d6f1eb0bd6f1180896f6cd2ae382b467af04cbfb595bb0bcef6b84d7f579680896e7c32061e26b2f056bffbb82d53e2e222e2cebfbb02158c7635bb03c6faf1917d5febd6079df497b45ed8fdfdfd0e7c36dc2ac9f4cb0eae342b0f67f2c58ede18d319a1ff747fe541cf7772258f5779430f75767acefdb9b84d93eae0497e4fd52c2743ff4148bbedf046fc8f3649fc5241f5c0bd6f61e12e6fe1e15737b765db0b4679e12e6e797040791ff3c61baef8b8ab9bdb0c1b824fd7b8a072b056dcfef0a96f6fc4ac2ccf75531b707cf8c4bcacf254ccfbb8162f14fe92ff55f4a989fbf51cccf674dc1c2dfde26cccf9f12067d1e7604ebfd57c5c27f59b0f07119e35591cf913d940aa5c0f1213c292e6c90bc7b8c57d53e8e158bbece048b3ce12061eeef50716199da7b16acfadd502cf25c0ad6f1e7f651de22bdefac60b59f9262894f2058ed654bb1c8e7046bfb7a5ff4ebd37d89c79b8a597e77ce784dc7634fb1c8ff9e30bf7fa498df0f6b82d51eb61366794031bfefc9de578bab1b45d6c750b0c8e7cf14cbf8de2ae6f10a59c2f47e28325679a19530b7b7af58f8ae254cefc3bd60912f5414f3f3504a98fb6b286679b28e60d1bfdf51ccedd953c5dc5ea6f2a93ec85f565deaff5eb18c6f2b61eebfad58fad7e7c51e7c3b61e67fa958c6f324616acf6482351e0c1266f9de15cbfbdd84599e3ae3f582f0bd532ccfaf27ccfd51bc5d2beafb6e55b1e8b7c038bd6f13e6f79705aff27dbb9630cb73ad98db83a66090fb778aa5bf15c199d8073fefd2f325c5d25e59b03c6f2e13667b0a8ac5bf1f196fc8f86446b1f02b24ccef8f14f3fbf644b0f009f23e1464fe23fb5a5f49efbf28e6e7fd51c274df2e0996f18243c5624f8d84d93fdf05cb78002816796cc23c5ebb82753cf719abbc7ea458f8937daffbf4fe9260194fbbaa58ee737b1e94af572c7cb384f9f9a160b58fae62d1e75bc26c8f34be1b2bda7e962996f1a80b96f7dd71c22ccfabe215aa2fc263c240f6a2efeb78d6144bff4131bfef5612a6f7dd48b08ecfb26296c79c26ccf755be4cda1b32760589572f8a25de541366be65c5a2ef31e6f6453eb72af9d046c2acef55c532de5630c87c799830c7bf9162997f760567d2de9d62c947683edbf03a7efe5cb1f07d4a98c60f2e04cbf89815c5fc7cc6e3ef95af394a989fef2a16fd5e264cedfb8660198ff09230cb7fa058e66f9f30c707ab58e2db96628907db09b33cfb8a459ee384499e50535ce27af741b08eff5bc21cbf1f154b3e344c98e5bf502cfedb4f98ed6153b1f8632f61bedf129c493ed84b98fbd7f115fdda4ec29c9f14154b7c394898fd27bd2fe3c5f6e57d51fa6b24ccfdd5154b7fed8439dfeb2816ffd84e98f948ff7e4dc6f33e6196f755b1d86b53b093f84df90d94923ddd24ccf6baa698f517fa82355e9d29e6f7cd30618e17d78af97d58162cfa74a058f479a558f455562cfeb49930dbfb4031b7ef2a82459f50502cfeec12e6feb57dd127ec25ccf1f149b1e8f33d6196afa498e5f3a97fe19ffa17f99e19277b6826ccf610148b3db884f9fe9362f1cfd784599e37c5226f2161e673a098e5b535c1623f1612a6fe4e878a451e9330cbd3572ce3b79f30dbc78b62f1c76ac23c1fea7838e97f9030b7ef154bff59c27c5ffb73e28f7b09733c5e532cfdeb78d5a5bfe784d95f54debad8cb56c21c7f78fc83eadf9f2ae6f1846ac26c9f5b8a59ff9eed37a8fe602961d6cf9d6289ffe709b37e2b8ac5df2e12667b2b2a167b6b0b16fd413161f68f8e62c927d3f3228ff62ffab3a384f9be512cfc571266fe0f8a85bff627fa75278a45bff709b37e5f14cb78f512e6f1d8532cf2ed26ccf3d3b362b1f79d8479bcd6154b7cea0a16fbf08f09b37db4148bbc0f09f3fd9a62f1cfa384595e1dffbae46fd58459de03c5920fb0ff8720f1c12d2996f8b5ad58e687a384d9ff68be7125d58f3709f3fcbcaa58f4b3ac78d5d1fd75c132deaea558f2b1f78459fe8e62b18776c23cde5eb1cc27cd84e97e0682653c61a858f4aff2c8f89946c2dcff9962d17735616ebfae58fadf4b98e5bb659cc6b7af58eabf9162d15f2d611e9f65c5325f5d25cce3fd2658fc2bec2816f90b8ae579b22f17923e3a8ad78a844f05bb35ba0fbb8295df49c2cc9fc73fa83c70a658f4bf9130f77f2558ec276c26ccf70f154b7e47f6e05715670f8245dfa7c3bfefb226ff6fbe1206bdbea7afbf9bcb873c7f3b2e6389f2d7d7defbbdb94c4a19fffe2e89ff4e2e3f67b7f0b9e83d2eef51bf1f9769361f3c67be8fc9ff0e97cf58e1efcbe56bec7e372ed6d3ef803f99cdf0771d2f379e51d49a6cc0cf3dfe3408d51167bf1717dbb40dbc82c857174ef77865c22590dc863ee57f33e7f05d4cbe878b7dd091c6bf513fc42b5a4f64d8b22d7a263047d154db76f0a74bd7b7b1f9361b6b3213e2a29ed0144ebda83389c01dfb88bf9dede365488b8ddf870bca1a251e208f28355eb97b461844cf89d23f219721fe76a88ff86c7ceff9b79af7077479b224635f50d627fb6adfec08af77bb89d796ddc6ab6c2b76c756f1d35dbb67f7f1598fef1dfc665c6af610ff756f8f50c6114a7c6c4feca93db3e7f6c25eda2bba2eedb5bdc14f6eed9d5db2cbb6608bf87cb02bdfc3e4735c16cd03b939a28136f3842c4a76d5aed975947a038dcbd08f31902e439f59e38c37c164a66e47a64136e7c62dfe7d5c62eba6893ff78464c6c088da340f76605af8bb6bdaa663baa6671e4ddfe4ffc082cb08ab8179b2a766689e519f6df49f8179c17189712e4687f849dd3e7c3717bceecdab796526e60d6de3017b5ab1c18cccbbd9345b66db9449fa8a5cf359e8dd1d53256c91fdaed933fbe600a5c788877d64e44b6deca7763a34877f0797a9cf7b18938aa88f23736c4e8407a08c1f311973613e207ca2cded99537386fa79b45d8aef4d9a6f8d7dfc3e2e910deae45e6c2c5a345a16feab63cecd85b93457288bdacdce420e7936d7e6062f66738bfab9a3b79d5932cb76db144c112d4bfd9074f37d5c50cfaf631de175883a79428dac989259257d5c9bb54ff198af9fc86c9dc66260363006eedabef4e52503fa543efa152ed44acd0258fb82e200b8e4213acef33d7e9ed5ed4c71b9a127908dbd006f0b6684f6d520368dcfe6d65f995f948b7d4261026424355bd6acacd3e39e8f0855bc7684d10ebd0de91e4637a8e30cf46e62bed68833d7dfc605305a8eec1d348409cbcd32cdf298c479a620acc6ade4e23564d0b465d3c63ebf990bc5e1a8e926c6e2275b817b7b99fa372411244b1beb607a36512daec3c384eceb53fae4c8368016b4a1631ea01b638048d28b59c25fe3821cc0b46c0f7ad8cd9d30614de4b513795ce335b69647bcfa6695b31894af9f63b54eefb39759c910d48bf0137b0d037882a191b99233f158612c92f3937a0914f19d39473f6924bb998cb3636d187844b93378c6b17d81579c81f6f1eac21b8ce01d368d872d923d8ec7383aabff2832b00d65d3414b88594686b3f3540d3a6d6f9fe2d2c339be8133e3ae5d128fbf9e60b233c1a38223ba831caab08b71fb1cf630677e857d9c0563de398203a8c1211cc13132c6c7e184343a393215eac5e233a77046f99ae64e58d1fd152e1883bbd6c1395cc0738ac131285fc2a530d9812bd6075cc30ddcda77b8832558b68f508022e6cf5c6dc68aa58bd21c9906acc02b94306fde9016d76035c727d91db6b786d583c36ca013ab37bcee7f9d0be5f42bb06e2eec19ce27b9a8434c40626a1cc50d4c778d1d3970b1fa8a36d1c46b1c7d6a78c54a07301b2dda5de75d7099ccb69022a17a21406cb7ecea186d7a54c3f5a9aa7b99643266f3192e3163710dd7a45e351ae5628fbb8f4cdc03bcd88a6bd9e0dae38b183562fea31534e7429841765cc7beb9ae3d866bd74b3151a322a47efaeed1ee219b2155a59db4a2b390cbfc3827cfb65c1fedab2e79faa45d9304f0e806ee09da76e886f4fc336924c895f25264508fb646ccf8efccbd9815f74abe63a83dcea04dcab98d7b7358e5a0263be437d98c7c135ca62d0f7b7aa0d5141fad020a98d51f4b5fe319f136f61475027df7ee36cd798c38d33dc41acbdcdb81dbc2485427ddc4567beac7b6e1b63132acb8776403e4339319048fd6b1adbab2abd07a889f9275ca5fe6cda6d4a7c759b78995d6a6db99885e791b2b9b3d3772558c545df6ef311f696980ad34a256dc2e3eb3eff6dcbe3b7035db41dbddc2cfeaf6d59cba43f2c6e90c957a7447ee18ce5dc53dbb13f5405d3f9cf5fd692e512bf89eb72ddb8536565a65b2e44a9a1d53ede14edd1946eb23b29eb13ef2baf1d1e7b0b55e8c86b6e4cedd85bbb4658c4f435a8b69d8babb72d7ee862cd8cce1d2335bb612e389bb8dda1119a7d6d5e771a19991b8c4bf016739ac19c7d589915c9066007707afb680d6554f2b4b7e0e97815bc2df1db7ec0af694d6020670e48a587be13c8e36e863beea565c89e65998b90c4ab082e3e030be371745a9b95ceae358807adc75ab512b3c83249fa7fc1e67e65317d71e7aa293c3b4129bcf0407a8dd1eb5b4e9d6900979b6dd4036eb68391bf8ce3356db43388391e44733191d3ce22099983b2f8eb8f3b990a7504687b1b0e41e482bf9e842f334b60f18abcb927946af68e98aea049798eb764cc315bdc3ead1c4bc05f34be33d66a965f782b3cd7dacefb0af0a3e61139bc405c7d1f86086381a1bd15a66ed6b968be822482dd7b37d38f71945ff9d892c728dc6aaeeebb0ee1b1421984b8357c3a7b99c4629cedc1aadd2ecf8267259f5f7d842c39efa07f49b3aaf7aba1abcd98b592e64dd03dfc2ececf1e75cf29a49b27471a40ad09c8ac540d930c62fdf76719db8e63bc2a541ab0d7569ad46751bb588ba2bfb2ee52beb390b224bf3ce791be71d6cc3d47ccfdba499299f895606058d6193f178924bce4732f1e410ab15bb4e5cf2b912fd1b33c85b8cf96d9c1761721c38eff18fc40545432b2f430b7532ae4fc6d50fd271efb6644698f51d5aeffb7e60af932de73583f5266671059a63781eceb15ac8c5c4bc23fe1b73dc636a79ba468cd9d78e7f722ecf25f95b13a53ac08b2201ce1d177e680624dd0d6998ffac4b1566ec957ff62ff625b680b35419b3ecc789fc42ac0c2539c248f6352e7564136533c8e5842c23af15cecf0798d5df59e432e1191ab70efc2b45af3aeaa4847e32c8555a9c3bdae47b7189fccd8f6c912478c1faeb0533bf692ed827dae3bbdf642e7979177121a61db432e2825e799a7a555fb9a178bcedb76029e691b35cd0ba0e69a6e9da2266ffef34cf82bfcf79b4b6c9bc56fdb62fbb3249807a749b5825cdd10b0ef000e798e698cb22dfcf718933127319619e6f66b8c4569f6117eb93c8a539473387942f9cfb8adfc11a723a1bd55c987e63cdf38e1e5fb5d1b6c13cd8bef37e773a17e7c8e9b19a438f69ce9f2fe772c17a876cdda0e79fcfd14b9c59f6a1ed0f629b5098994f6256d2715564e290c958aaea4c9c35bee687b68439fd3e56270fb427d8c76a744ff492bcd41f92069750a238677c854b866dc6d5a37789f6d35c2afe08abdf3842017f4fed38e2db9477d9d3c8c41f27265593d750b4bb9a3f3117d08bb500e76d3886680de831e5296f21cbb617fef4ab5cf087b8f85e6ef548b950b58715ee1356bf8099deccde2946f2375b82f71835fcf18cb568348eda3d33170e682dbc213b7ed163defc39653aa9c214ebc49c09e7a90baa5703658d33be9f8f07c42748ad14b95c4d8d0f676203d3c5f9ed9eaca919eb13ca7a0632c7efa1846b98ade8cad8e42a66bcee62eeeb2ffd55f439aa64d016503b9e6a9b27bb8d3d68ed92e30f0dcc1eca24a7a3e83c91dde7b950d536ced963fbdb73b850e431fb36f65c8bbb326419547fc69d3e57f6a738330ee4f97c362a6bad1eb3067fe36f3d4525df31affe8e6cac473553166d1b7b48fa1b5fbef6552eb46ad2a4597f5b56c326ed1c6737b38fde4a5a20ff68989669d17acd9e3b8396afcd5421f919ea9a3c6ec92f9b4e8c1f51bba4939e39a4117cb225e132a5196c17ed81463a71996f63b19e652e34ef13177b39870b604f2835ad5c7baec089bfc3aa7c1fbd39669096e693d93a91dbd8211bdb47de7bf63166c9a8df17b2af9e6dc7b97f3e171cd92e2c7dc425f98ae694bc9a15b9948d9fcba58ff9ec1ef6cb5c62dd1e57be767d45ea135d1f9a8c5dd3ad386841d58e5027713e8a7b95b1e73eec432dd9e824976d64cf5ccc4fe6fddc7d64e2ec93b9b03773a290813ec4bdfb5eb4b1681d58b33bb71ce713ca5676644556198ded6b1cd3382b1bf87d8c137bb4e3daa295278c0438c716a03f6399f1ed13cc09f6347e7d860bb61bada66b3b381f1693f7e6e3a9c1883bc2e706317b4349ea581f16a12459fde4eaf26495388eb13b340bf7fd99ddc2da621f47a6c5f9821df91dcad8c66fc93abc5f714517a3f657b8dca3e520175bf5a539352b5601b00907685903b4f506feecdb12fac94098e47763e654bc546d4b4484b8dbb9ec57fd9a6d4bef31db38a33a769a0be6e638ba179c214f3359646314f3a3778dfc3a6513158e3e867328e482f9f729f468ed0be328f41ccf6ed7fe7ac2c6c5c66095b2b87ced32b12b00f77e036b65ac196d0b3a18d3b74d7eb7ad223fb430825e1ce631c9d7c853fe1253f1981d16bc97fa85d7c36505db6e046b77a586ac07e32ec862388baeca1ca9bab9a3dfb713316d3ce3c4bd968d0058b79cd3999f57ff2e33a572d9911f0760474ea3ed4fb8089b40d598b1bd1851a816d35d09b59db84f74845e5b8e953ace8f0781bdfe5ab8b2eda4f8eb6f40a59a7792816a65cc272fcc79f080d970b285c425ae5ea02438ba792e9355ff78dd32c7a54e3b3731bfecdb8209c976930c013f83637835cfe85371a5aee62bc8cda177de8b4759d105c5de90858c6ae4f1a84c44465ac7d8827b3374de0cc9c2c69625f6859f05da594a6b563c23cece95e2757a263272f174f66837d48d31d3e729e2483d864668ba0e9d5979c47cf001eb80be548cb9fac494c3bdbb0e0fa145eb49f35625a4d2c416dba1e34f2447ce5b24a9ce64a6813d8dcf4cb80fb938e16288cb01d6dfbdd095550765531564422f3cba17591b1cba65b70ef7b4bf9cab1931ab3f0b7dcce2dbee0ce792c1148bf1dc110712c2203c996d33b32f12239faf852156076fb2a6c435e34fb968c61c9e914dd756cc13594c75c263aea3ffbbcc75e94cc1033ef74875e4258dbe445168f813a8622edc0c2fb0075564d39f5b01ac139f9b5c9c9bcaf671705f6dc5391b7ce7335c267dc9367ccc2d56dc55e0f520e5c2b6738dd189727fd80f6f9855229f30827358c15af2912d8deb139ea7d1f71ec3bb2be227d367cad4ce62a45ccb696aacb5e87565bf1f36dd068e5a3355b1661197e90897f83d61deb04d5e2d71992c425794eb66c5be9957136b9903f49d57f41b17d751ec15d6f157710e42e1b12e88b5a35f3347762db706336b6bf36dd0982b8ca87b719e10d9682551e3d5ec5c39ffc24cab1178cfe246b9a0fd5634db75a7e6226cdb36fa57b4c93ad6352577e9dfdca5dd76555a9fad637dd2c0bf0fd11ef7423954c6b5b3c4bdc96b5a6fd17de3690f8763a52bbcc265d1fad8222e582776692ffc36ed5d731c208b404b7250735718bf57ec8169d910764235ecfa327a7cdc5fea51ce1635d742a6fbbe1af6bca319787ef59ce724cce038ecbb3e8d869fb49a4539cc022ec139ac998654f3e6aac3fcbc1d0e420d87af432bb787e60df3b322f2883ba571353766f21e3350debb6863b65272716eb733ab60f3195918d85d6ca386d1a8c12bf7f9959fcf7389b52b2c99158c66d32710d9ce622470eec6ad844388b514d52274923c9e637c88a7e87844cd4bccdeb0bdb82fbc82f19b56fd930fceea43d1921b8523db0acf188d7a93fb3b5fd40bf80e143063b6a93e9aae2beea2a59927ac692a389bbd9ceaf96bde278b3bfa8714e978cd08fbc7d8fa168e431b6b5e909c75f6d2334c58f741f4fa1a5d1336f62b5c5cc5b542df94d25afdf45e2fcd8bf612fd20b3dbd833ed286335f0403a1aa41d70a0b5aa26ce1217e1249c86b3dcf8cf6a07d984f370112e319e681696fd35bd60ff4d28842bb34911c08ca5cff9afe159c55e846b33c40a64944eb1c4d3ee9eeacf8c90818e7d05136e3063b99dcbc44cfcee873b5ba27dda8c2cb79ee7b2a8de5f74b9b6bd376f387b8fc29239c9d51ff99ec7d114f9986338c4f93e9e5a3ea7d32c2656f1a68d33c42e3e7401876119f80c703aef30e327a94dac6f8efc168e0e674b8df1ac32c9e753beefa018d78da1034fa1202795389b3126bff39776bba00f0d7b01cfa1c867aeecb6efd9edd00d2b98d91fc3b6ecc6c4eb26c76591ad617e019b7e60ce62a4744bb23ae67e89cb13edb3c4b5e3755b0e258aa6e3b596492e12a5f942bb73e863ab66151a98750e481379b9179f63ce5f96779d7d05e75e23fb152ebf2bfa697f09d089395ddc298022d67e9819718501bca6397bce72d2eea7adb06ac6275fa76bb2ea825c2d66775b7ec716ec4bfefb32bf30bf38bfc967745c0596e13cacc23bd0770fa0924e5c4df63d89afa7e49ec7587fcf5d4fa33d3fccf0c29a1dcaded02fc5319adb5e502385b8328b6c8a61dd3f41597633ccbc3a51fc293fa74eea6c71f6b2e0f31825b156dbc8ec787dff97b8c4dd2f172300fe8df39579806178cf0c5c93fd7f7c823f56fe553927fa310bba1bce17446964622fdc23c6423e3bf4933df1455706e60173ac389ff7dcb3ad650e671c97f970e9ea0b6aab8f477ad2fb75a5c9d05c7221df3a99e0819eff68af83b5551cd37a9ecb97e3d8cc7e646ccb95e10973c447f7f65336d30ca6b954e47b3f4bf0162ec3ddc4c95f5af18d7316bc99675a1b7b9895ead7b9d02ec50b7d93ad688b59b067eec8f5a4ef49df9d97edec4c31a281876318b811d6d17b31878ef50dd612c774d7114b0f712fa39b4e5dc3f770a1959718581eed10f6b12e6e6759d8c25830fe0e0c9d8d356bfe70e6b42eafcfc673b3fcc7e25b57c1857dbb8bb9705c2d7d7345d8a49569cb1e1fbfad8039f879acf778de9f94ec2bfe32c988a3017d5faf4f15ca10f38173730e711ff50933dfc9aa645e54d075166b2fc36bace4ecc8c56f89b4688770689efd80d858ca20b63d3a2c32c17e4deb23097fe57b7c5895189a6f0cd999336ff19c3f46b6badbcce2ca4b3d7df76dba7634921338c8b266768fdaa8640f98a539ac0562a555a34c7868776d296b656dd2c921f9499b7aa66f917c2b178e8a3dfd0eae3b89fbc958e33ca17e3ad0861573e4df61e0f7cc12cab20d0d5ff335cc62b6cd895f811d2c63c09d61e6d9809e8ba7a84dace0a8d2e2d34021ee15da42d6c99a188523932e8d6083f2ca6fb0b1f185759527dddcd3faa6c1eae6c4dde22721bc8417db45569829a0558cc0f8535b7667eecc744d17e5afbaa2f358b19ddb5757768ecf06d82e65f371573ceebcd6716c1ae891fd80c510f42876d573f2f7266dfe6bbe3f473319ed686696ce50b35e62ce879c4e520f58f3a0b50cfd054a5dc62abb0d4bc4009ce373e52a91ec30f08e7da073be4b74a2f881b4dfa3bff99bdb916ff6bd5c26753ca969cb67a29ae3d3d6136fcc7c92eecc9cd4fbf9b746ffba8d7dc4843e6f4e5ed3cfce709f7edf8cbf053bf1e94ffe6f8cefe52265cbc4c8d32e2e5f33e7f0e5d23548c5462bad31afefe2323b72935c663e5fc065fe08d87432339757b8f1897065f01d5ce6dbd124978fff97a485d625dafac8fabe32ce5fe1f2c1fab9997dfe6326b2b7bb405f133afa80d157e3d867b87cae8585f7276a11f120c8e3c5ed86e7f0fc9d5ce6c42133fdd4873d4c7d5f624a83dfc8e5e7e3faddd767fb9b1ec9ffcbff7fecbbafffe7f27b5e7ffef7bffff13fdcf4c93e</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>UninstallDlg</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>cleanRegButton</sender>
+ <signal>clicked()</signal>
+ <receiver>UninstallDlg</receiver>
+ <slot>cleanRegistry()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot access="protected">init()</slot>
+ <slot access="protected">destroy()</slot>
+ <slot>cleanRegistry()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/util/install/win/uninstaller/uninstaller.cpp b/util/install/win/uninstaller/uninstaller.cpp
new file mode 100644
index 0000000..9a7c529
--- /dev/null
+++ b/util/install/win/uninstaller/uninstaller.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qdir.h>
+#include <qtextview.h>
+#include <qpushbutton.h>
+#include <qmessagebox.h>
+#include "uninstallimpl.h"
+#include "../environment.h"
+
+#ifdef Q_OS_WIN32
+#include <windows.h>
+#endif
+
+QApplication* app;
+UninstallDlg* progress;
+
+void rmDirRecursive( const QDir &dir )
+{
+ const QFileInfoList* list = dir.entryInfoList( QDir::All | QDir::System | QDir::Hidden );
+ if ( list ) {
+ QFileInfoListIterator it( *list );
+ QFileInfo* fi;
+
+ while( ( fi = it.current() ) ) {
+ if( ( fi->fileName() != "." ) && ( fi->fileName() != ".." ) ){
+ progress->filesDisplay->append( fi->absFilePath() + "\n" );
+ progress->filesDisplay->scrollToBottom();
+ app->processEvents();
+ if( fi->isDir() )
+ rmDirRecursive( QDir(fi->absFilePath()) );
+ else
+ QFile::remove( fi->absFilePath() );
+ }
+ ++it;
+ }
+ }
+ // Remove this dir as well
+ dir.rmdir( dir.absPath() );
+}
+
+int main( int argc, char** argv )
+{
+ app = new QApplication( argc, argv );
+ progress = new UninstallDlgImpl( 0, 0, 0, Qt::WStyle_Customize|Qt::WStyle_NormalBorder|Qt::WStyle_Title);
+
+ if( argc != 4 )
+ qFatal( "Incorrect parameters" );
+
+ if( !QMessageBox::information( 0,
+ QString( "Uninstalling Qt %1" ).arg(argv[3]),
+ QString("Are you sure you want to uninstall Qt %1?\n"
+ "This will remove the directory this version\n"
+ "of Qt was installed to, along with ALL its contents.").arg(argv[3]),
+ "Yes", "No" ) )
+ {
+ progress->setCaption( QString( "Uninstalling Qt " ) + argv[ 3 ] );
+ progress->show();
+
+ app->setMainWidget( progress );
+
+ // Delete the two directories we have written files to during the installation.
+ // The OK button is disabled at this point.
+ // Messages will be processed during the delete process.
+
+ // Check if moc.exe exists, if not this could potentially be a
+ // corrupted registry setting
+
+ if ( QFile::exists( QString( argv[1] ) + QString( "\\bin\\moc.exe" ) ) )
+ rmDirRecursive( QDir(argv[1]) );
+ else
+ QMessageBox::warning( 0, "Uninstalling failed", "Qt could not be uninstalled, you will "
+ "need to remove Qt manually" );
+
+ rmDirRecursive( QDir(argv[2]) );
+
+ progress->okButton->setEnabled( true );
+ progress->cleanRegButton->setEnabled( true );
+ /*
+ ** Just hang around until someone clicks the "OK" button
+ */
+ app->exec();
+#if defined(Q_OS_WIN32)
+ QEnvironment::removeUninstall( QString( "Qt " ) + argv[ 3 ] );
+ QString qtEnv = QEnvironment::getEnv( "QTDIR", QEnvironment::LocalEnv );
+ QString pathEnv = QEnvironment::getEnv( "PATH", QEnvironment::PersistentEnv );
+ if ( qtEnv == QString(argv[1]) )
+ QEnvironment::removeEnv( "QTDIR", QEnvironment::LocalEnv | QEnvironment::PersistentEnv );
+ else
+ qtEnv = argv[1];
+
+ qtEnv.append("\\bin;");
+ pathEnv.replace( qtEnv, "" );
+ QEnvironment::putEnv( "PATH", pathEnv, QEnvironment::PersistentEnv );
+ if( qWinVersion() & Qt::WV_NT_based ) {
+ SendNotifyMessageA( HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM)"Environment" );
+ SendNotifyMessageA( HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0 );
+ }
+#endif
+ }
+
+ return 0;
+}
diff --git a/util/install/win/uninstaller/uninstallimpl.cpp b/util/install/win/uninstaller/uninstallimpl.cpp
new file mode 100644
index 0000000..d30358b
--- /dev/null
+++ b/util/install/win/uninstaller/uninstallimpl.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "uninstallimpl.h"
+#include <qsettings.h>
+#include <qmessagebox.h>
+
+UninstallDlgImpl::UninstallDlgImpl( QWidget* parent, const char* name, bool modal, WindowFlags f )
+ : UninstallDlg( parent, name, modal, f )
+{
+}
+
+UninstallDlgImpl::~UninstallDlgImpl()
+{
+}
+
+void UninstallDlgImpl::cleanRegistry()
+{
+ cleanRegistryHelper( "/Trolltech/Qt" );
+ cleanRegistryHelper( "/Trolltech/Qt Designer" );
+ cleanRegistryHelper( "/Trolltech/Qt Assistant" );
+ cleanRegistryHelper( "/Trolltech/Qt Linguist" );
+}
+
+void UninstallDlgImpl::cleanRegistryHelper( const QString& key )
+{
+ QSettings settings;
+ QStringList::Iterator it;
+ QStringList keys = settings.subkeyList( key );
+ for ( it = keys.begin(); it != keys.end(); ++it ) {
+ cleanRegistryHelper( key + "/" + *it );
+ }
+ QStringList entries = settings.entryList( key );
+ for ( it = entries.begin(); it != entries.end(); ++it ) {
+ settings.removeEntry( key + "/" + *it );
+ }
+ settings.removeEntry( key + "/." );
+}
diff --git a/util/install/win/uninstaller/uninstallimpl.h b/util/install/win/uninstaller/uninstallimpl.h
new file mode 100644
index 0000000..b3bff36
--- /dev/null
+++ b/util/install/win/uninstaller/uninstallimpl.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "uninstall.h"
+
+class UninstallDlgImpl : public UninstallDlg
+{
+ Q_OBJECT
+public:
+ UninstallDlgImpl( QWidget* parent = 0, const char* name = 0, bool modal = false, WindowFlags fl = 0 );
+ ~UninstallDlgImpl();
+public slots:
+ void cleanRegistry();
+private:
+ void cleanRegistryHelper( const QString& key );
+
+};
diff --git a/util/install/win/win.pro b/util/install/win/win.pro
new file mode 100644
index 0000000..470fa03
--- /dev/null
+++ b/util/install/win/win.pro
@@ -0,0 +1,136 @@
+TEMPLATE = app
+CONFIG += windows qt
+
+HEADERS = globalinformation.h \
+ setupwizardimpl.h \
+ environment.h \
+ shell.h \
+ resource.h \
+ dialogs/folderdlgimpl.h \
+ pages/pages.h \
+ pages/sidedecorationimpl.h
+
+SOURCES = main.cpp \
+ globalinformation.cpp \
+ setupwizardimpl.cpp \
+ setupwizardimpl_config.cpp \
+ environment.cpp \
+ shell.cpp \
+ resource.cpp \
+ dialogs/folderdlgimpl.cpp \
+ pages/pages.cpp \
+ pages/sidedecorationimpl.cpp
+
+INTERFACES = dialogs/folderdlg.ui \
+ pages/buildpage.ui \
+ pages/configpage.ui \
+ pages/finishpage.ui \
+ pages/folderspage.ui \
+ pages/licenseagreementpage.ui \
+ pages/licensepage.ui \
+ pages/optionspage.ui \
+ pages/progresspage.ui \
+ pages/sidedecoration.ui \
+ pages/winintropage.ui
+
+win32 {
+ SOURCES += archive.cpp
+ HEADERS += archive.h
+}
+
+TARGET = install
+DESTDIR = ../../../dist/win
+INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty $$QT_SOURCE_TREE/util/install/archive
+
+win32:RC_FILE = install.rc
+
+# Comment out one of the following lines to build the installer for:
+#
+# - a Qt/Windows evaluation version (eval),
+# - a Qt/Windows evaluation version that can be burned on CD and
+# distributed on tradeshows (eval-cd)
+# - the QSA evaluation version (qsa)
+# - educational version (edu)
+# - non-commercial version (noncommercial)
+#
+#CONFIG += eval
+#CONFIG += eval-cd
+#CONFIG += qsa
+#CONFIG += edu
+#CONFIG += noncommercial
+
+
+unix:LIBS += -L$$QT_BUILD_TREE/util/install/archive -larq
+win32:LIBS += ../archive/arq.lib
+INCLUDEPATH += ../keygen
+
+# We have the following dependencies on config:
+#
+# qsa -> eval
+# eval-cd -> eval
+# eval -> (none)
+# edu -> (none)
+# noncommercial -> (none)
+#
+# For the code this means that the following defines are defined:
+#
+# eval : EVAL
+# eval-cd : EVAL, EVAL_CD
+# qsa : EVAL, QSA
+# edu : EDU
+# noncommercial: NON_COMMERCIAL
+#
+
+qsa {
+ CONFIG += eval
+ DEFINES += QSA
+}
+
+eval-cd {
+ CONFIG += eval
+ DEFINES += EVAL_CD
+}
+
+eval {
+ !exists($(QTEVAL)/src) {
+ error(You must set the QTEVAL environment variable to the directory where you checked out //depot/qteval/main in order to be able to build the evaluation version of install.)
+ }
+ DEFINES += EVAL
+ qsa {
+ win32:RC_FILE = install-qsa.rc
+ } else {
+ win32:RC_FILE = install-eval.rc
+ }
+ mac:RC_FILE = ../../../tools/designer/app/designer.icns
+ SOURCES += $(QTEVAL)/src/check-and-patch.cpp
+ INCLUDEPATH += $(QTEVAL)/src
+ DESTDIR = ../../../bin
+}
+
+edu {
+ !exists($(QTEVAL)/src) {
+ error(You must set the QTEVAL environment variable to the directory where you checked out //depot/qteval/main in order to be able to build the evaluation version of install.)
+ }
+ DEFINES += EDU
+ win32:RC_FILE = install-edu.rc
+ SOURCES += $(QTEVAL)/src/check-and-patch.cpp
+ INCLUDEPATH += $(QTEVAL)/src
+ DESTDIR = ../../../bin
+}
+
+noncommercial {
+ !exists($(QTEVAL)/src) {
+ error(You must set the QTEVAL environment variable to the directory where you checked out //depot/qteval/main in order to be able to build the evaluation version of install.)
+ }
+ DEFINES += NON_COMMERCIAL
+ win32:RC_FILE = install-noncommercial.rc
+ SOURCES += $(QTEVAL)/src/check-and-patch.cpp
+ INCLUDEPATH += $(QTEVAL)/src
+ DESTDIR = ../../../bin
+}
+
+mystaticconfig {
+ QMAKE_LIBS_QT =
+ QMAKE_LIBS_QT_THREAD =
+ LIBS += ../../../lib/libqt-mt.a -lz -framework Carbon
+}
diff --git a/util/lexgen/README b/util/lexgen/README
new file mode 100644
index 0000000..b8e9277
--- /dev/null
+++ b/util/lexgen/README
@@ -0,0 +1,16 @@
+Lexgen
+------
+
+This is a little tool to generate lexical scanners from a rather simplistic
+configuration file. We use it internally in Qt to generate the scanner for the
+CSS parser that is built into the toolkit (used for the widget styling and the
+HTML import into QTextDocument).
+
+Beware, it's very slow (in generating the code) and it may not generate what
+you want. But I like that it generates code that operates on QChar and friends.
+
+Use at your own risk ;-)
+
+
+--
+Simon Hausmann <simon@trolltech.com>
diff --git a/util/lexgen/configfile.cpp b/util/lexgen/configfile.cpp
new file mode 100644
index 0000000..8d77689
--- /dev/null
+++ b/util/lexgen/configfile.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "configfile.h"
+
+#include <QFile>
+
+ConfigFile::SectionMap ConfigFile::parse(const QString &fileName)
+{
+ QFile f(fileName);
+ if (!f.open(QIODevice::ReadOnly))
+ return ConfigFile::SectionMap();
+ return parse(&f);
+}
+
+ConfigFile::SectionMap ConfigFile::parse(QIODevice *dev)
+{
+ SectionMap sections;
+ SectionMap::Iterator currentSection = sections.end();
+
+ ConfigFile::SectionMap result;
+ int currentLineNumber = 0;
+ while (!dev->atEnd()) {
+ QString line = QString::fromUtf8(dev->readLine()).trimmed();
+ ++currentLineNumber;
+
+ if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
+ continue;
+
+ if (line.startsWith(QLatin1Char('['))) {
+ if (!line.endsWith(']')) {
+ qWarning("Syntax error at line %d: Missing ']' at start of new section.", currentLineNumber);
+ return SectionMap();
+ }
+ line.remove(0, 1);
+ line.chop(1);
+ const QString sectionName = line;
+ currentSection = sections.insert(sectionName, Section());
+ continue;
+ }
+
+ if (currentSection == sections.end()) {
+ qWarning("Syntax error at line %d: Entry found outside of any section.", currentLineNumber);
+ return SectionMap();
+ }
+
+ Entry e;
+ e.lineNumber = currentLineNumber;
+
+ int equalPos = line.indexOf(QLatin1Char('='));
+ if (equalPos == -1) {
+ e.key = line;
+ } else {
+ e.key = line;
+ e.key.truncate(equalPos);
+ e.key = e.key.trimmed();
+ e.value = line.mid(equalPos + 1).trimmed();
+ }
+ currentSection->append(e);
+ }
+ return sections;
+}
diff --git a/util/lexgen/configfile.h b/util/lexgen/configfile.h
new file mode 100644
index 0000000..7bf3389
--- /dev/null
+++ b/util/lexgen/configfile.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CONFIGFILE_H
+#define CONFIGFILE_H
+
+#include <QStringList>
+#include <QMap>
+#include <QVector>
+
+struct ConfigFile
+{
+ struct Entry
+ {
+ inline Entry() : lineNumber(-1) {}
+ int lineNumber;
+ QString key;
+ QString value;
+ };
+ struct Section : public QVector<Entry>
+ {
+ inline bool contains(const QString &key) const
+ {
+ for (int i = 0; i < count(); ++i)
+ if (at(i).key == key)
+ return true;
+ return false;
+ }
+ inline QString value(const QString &key, const QString &defaultValue = QString()) const
+ {
+ for (int i = 0; i < count(); ++i)
+ if (at(i).key == key)
+ return at(i).value;
+ return defaultValue;
+ }
+ };
+ typedef QMap<QString, Section> SectionMap;
+
+ static SectionMap parse(const QString &fileName);
+ static SectionMap parse(QIODevice *dev);
+};
+
+#endif // CONFIGFILE_H
+
diff --git a/util/lexgen/css2-simplified.lexgen b/util/lexgen/css2-simplified.lexgen
new file mode 100644
index 0000000..3976632
--- /dev/null
+++ b/util/lexgen/css2-simplified.lexgen
@@ -0,0 +1,93 @@
+[Options]
+case-insensitive
+classname = QCssScanner_Generated
+
+[Code Generator Options]
+MapToCode[a-z] = (ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256
+TokenPrefix = QCss::
+FileHeader = ../moc/licenseheader.txt
+
+[Macros]
+escape = \\[^\r\n\f0-9a-f]
+nmstart = [_a-z]|{escape}
+nmchar = [_a-z0-9-]|{escape}
+nl = \n|\r\n|\r|\f
+string1 = \"([^\n\r\f\\"]|\\{nl}|{escape})*\"
+string2 = \'([^\n\r\f\\']|\\{nl}|{escape})*\'
+invalid1 = \"([^\n\r\f\\"]|\\{nl}|{escape})*
+invalid2 = \'([^\n\r\f\\']|\\{nl}|{escape})*
+
+ident = -?{nmstart}{nmchar}*
+name = {nmchar}+
+num = [0-9]+|[0-9]*"."[0-9]+
+string = {string1}|{string2}
+invalid = {invalid1}|{invalid2}
+url = ([!#$%&*-~]|{escape})*
+s = [ \t\r\n\f]
+w = {s}*
+
+[Tokens]
+
+S = {s}+
+
+handleCommentStart() = \/\*
+
+CDO = "<!--"
+CDC = "-->"
+INCLUDES = "~="
+DASHMATCH = "|="
+
+LBRACE = {w}"{"
+PLUS = {w}"+"
+GREATER = {w}">"
+COMMA = {w}","
+
+STRING = {string}
+INVALID = {invalid}
+
+IDENT = {ident}
+
+HASH = "#"{name}
+
+ATKEYWORD_SYM = "@"{ident}
+
+EXCLAMATION_SYM = "!"
+
+#EMS = {num}em
+#EXS = {num}ex
+#LENGTH = {num}px
+#LENGTH = {num}cm
+#LENGTH = {num}mm
+#LENGTH = {num}in
+#LENGTH = {num}pt
+#LENGTH = {num}pc
+#ANGLE = {num}deg
+#ANGLE = {num}rad
+#ANGLE = {num}grad
+#TIME = {num}ms
+#TIME = {num}s
+#FREQ = {num}hz
+#FREQ = {num}khz
+#DIMENSION = {num}{ident}
+LENGTH = {num}{ident}
+
+PERCENTAGE = {num}%
+NUMBER = {num}
+
+#URI = "url("{w}{string}{w}")"
+#URI = "url("{w}{url}{w}")"
+FUNCTION = {ident}"("
+
+COLON = :
+SEMICOLON = ;
+RBRACE = \}
+SLASH = /
+MINUS = -
+DOT = \.
+STAR = \*
+LBRACKET = \[
+RBRACKET = \]
+EQUAL = \=
+LPAREN = \(
+RPAREN = \)
+OR = \|
diff --git a/util/lexgen/generator.cpp b/util/lexgen/generator.cpp
new file mode 100644
index 0000000..a3c63f2
--- /dev/null
+++ b/util/lexgen/generator.cpp
@@ -0,0 +1,532 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "generator.h"
+
+#include <QFile>
+
+void Function::printDeclaration(CodeBlock &block, const QString &funcNamePrefix) const
+{
+ block << (iline ? "inline " : "") << signature(funcNamePrefix) << (iline ? QLatin1String(" {") : QLatin1String(";"));
+ if (!iline)
+ return;
+
+ block.indent();
+ QString tmp = body;
+ if (tmp.endsWith(QLatin1Char('\n')))
+ tmp.chop(1);
+ foreach (QString line, tmp.split(QLatin1Char('\n')))
+ block << line;
+ block.outdent();
+ block << "}";
+}
+
+QString Function::signature(const QString &funcNamePrefix) const
+{
+ QString sig;
+ if (!rtype.isEmpty()) {
+ sig += rtype;
+ sig += QLatin1Char(' ');
+ }
+ sig += funcNamePrefix;
+ sig += fname;
+ if (cnst)
+ sig += " const";
+ return sig;
+}
+
+QString Function::definition() const
+{
+ if (iline)
+ return QString();
+
+ QString result;
+ result += signature();
+ result += QLatin1String("\n{\n");
+
+ QString tmp = body;
+
+ if (tmp.endsWith(QLatin1Char('\n')))
+ tmp.chop(1);
+ if (!tmp.startsWith(QLatin1Char('\n')))
+ tmp.prepend(" ");
+
+ tmp.replace(QLatin1Char('\n'), QLatin1String("\n "));
+
+ result += tmp;
+
+ result += QLatin1String("\n}\n");
+
+ return result;
+}
+
+void Class::Section::printDeclaration(const Class *klass, CodeBlock &block) const
+{
+ foreach (Function ctor, constructors)
+ ctor.printDeclaration(block, klass->name());
+
+ if (!constructors.isEmpty())
+ block.addNewLine();
+
+ foreach (Function func, functions)
+ func.printDeclaration(block);
+
+ if (!functions.isEmpty())
+ block.addNewLine();
+
+ foreach (QString var, variables)
+ block << var << ';';
+}
+
+void Class::addConstructor(Access access, const QString &body, const QString &_args)
+{
+ Function ctor;
+ QString args = _args;
+ if (!args.startsWith(QLatin1Char('('))
+ && !args.endsWith(QLatin1Char(')'))) {
+ args.prepend('(');
+ args.append(')');
+ }
+ ctor.setName(args);
+ ctor.addBody(body);
+ sections[access].constructors.append(ctor);
+}
+
+QString Class::Section::definition(const Class *klass) const
+{
+ QString result;
+
+ foreach (Function ctor, constructors) {
+ ctor.setName(klass->name() + "::" + klass->name() + ctor.name());
+ result += ctor.definition();
+ result += QLatin1Char('\n');
+ }
+
+ foreach (Function func, functions) {
+ if (!func.hasBody()) continue;
+ func.setName(klass->name() + "::" + func.name());
+ result += func.definition();
+ result += QLatin1Char('\n');
+ }
+
+ return result;
+}
+
+QString Class::declaration() const
+{
+ CodeBlock block;
+
+ block << QLatin1String("class ") << cname;
+ block << "{";
+
+ if (!sections[PublicMember].isEmpty()) {
+ block << "public:";
+ block.indent();
+ sections[PublicMember].printDeclaration(this, block);
+ block.outdent();
+ }
+
+ if (!sections[ProtectedMember].isEmpty()) {
+ block << "protected:";
+ block.indent();
+ sections[ProtectedMember].printDeclaration(this, block);
+ block.outdent();
+ }
+
+ if (!sections[PrivateMember].isEmpty()) {
+ block << "private:";
+ block.indent();
+ sections[PrivateMember].printDeclaration(this, block);
+ block.outdent();
+ }
+
+ block << "};";
+ block.addNewLine();
+
+ return block.toString();
+}
+
+QString Class::definition() const
+{
+ return sections[PrivateMember].definition(this)
+ + sections[ProtectedMember].definition(this)
+ + sections[PublicMember].definition(this);
+}
+
+Generator::Generator(const DFA &_dfa, const Config &config)
+ : dfa(_dfa), cfg(config)
+{
+ QList<InputType> lst = cfg.maxInputSet.toList();
+ qSort(lst);
+ minInput = lst.first();
+ maxInput = lst.last();
+
+ ConfigFile::Section section = config.configSections.value("Code Generator Options");
+
+ foreach (ConfigFile::Entry entry, section) {
+ if (!entry.key.startsWith(QLatin1String("MapToCode["))
+ || !entry.key.endsWith(QLatin1Char(']')))
+ continue;
+ QString range = entry.key;
+ range.remove(0, qstrlen("MapToCode["));
+ range.chop(1);
+ if (range.length() != 3
+ || range.at(1) != QLatin1Char('-')) {
+ qWarning("Invalid range for char mapping function: %s", qPrintable(range));
+ continue;
+ }
+ TransitionSequence seq;
+ seq.first = range.at(0).unicode();
+ seq.last = range.at(2).unicode();
+ seq.testFunction = entry.value;
+ charFunctionRanges.append(seq);
+ }
+
+ QString tokenPrefix = section.value("TokenPrefix");
+ if (!tokenPrefix.isEmpty()) {
+ for (int i = 0; i < dfa.count(); ++i)
+ if (!dfa.at(i).symbol.isEmpty()
+ && !dfa.at(i).symbol.endsWith(QLatin1String("()")))
+ dfa[i].symbol.prepend(tokenPrefix);
+ }
+
+ headerFileName = section.value("FileHeader");
+}
+
+static inline bool adjacentKeys(int left, int right) { return left + 1 == right; }
+//static inline bool adjacentKeys(const InputType &left, const InputType &right)
+//{ return left.val + 1 == right.val; }
+
+static QVector<Generator::TransitionSequence> convertToSequences(const TransitionMap &transitions)
+{
+ QVector<Generator::TransitionSequence> sequences;
+ if (transitions.isEmpty())
+ return sequences;
+
+ QList<InputType> keys = transitions.keys();
+ qSort(keys);
+ int i = 0;
+ Generator::TransitionSequence sequence;
+ sequence.first = keys.at(0);
+ ++i;
+ for (; i < keys.count(); ++i) {
+ if (adjacentKeys(keys.at(i - 1), keys.at(i))
+ && transitions.value(keys.at(i)) == transitions.value(keys.at(i - 1))) {
+ continue;
+ }
+ sequence.last = keys.at(i - 1);
+ sequence.transition = transitions.value(sequence.last);
+ sequences.append(sequence);
+
+ sequence.first = keys.at(i);
+ }
+ sequence.last = keys.at(i - 1);
+ sequence.transition = transitions.value(sequence.last);
+ sequences.append(sequence);
+
+ return sequences;
+}
+
+QDebug &operator<<(QDebug &debug, const Generator::TransitionSequence &seq)
+{
+ return debug << "[first:" << seq.first << "; last:" << seq.last << "; transition:" << seq.transition
+ << (seq.testFunction.isEmpty() ? QString() : QString(QString("; testfunction:" + seq.testFunction)))
+ << "]";
+}
+
+bool Generator::isSingleReferencedFinalState(int i) const
+{
+ return backReferenceMap.value(i) == 1
+ && dfa.at(i).transitions.isEmpty()
+ && !dfa.at(i).symbol.isEmpty();
+}
+
+void Generator::generateTransitions(CodeBlock &body, const TransitionMap &transitions)
+{
+ if (transitions.isEmpty())
+ return;
+
+ QVector<TransitionSequence> sequences = convertToSequences(transitions);
+
+ bool needsCharFunction = false;
+ if (!charFunctionRanges.isEmpty()) {
+ int i = 0;
+ while (i < sequences.count()) {
+ const TransitionSequence &seq = sequences.at(i);
+ if (!seq.testFunction.isEmpty()) {
+ ++i;
+ continue;
+ }
+
+ foreach (TransitionSequence range, charFunctionRanges)
+ if (range.first >= seq.first && range.last <= seq.last) {
+ needsCharFunction = true;
+
+ TransitionSequence left, middle, right;
+
+ left.first = seq.first;
+ left.last = range.first - 1;
+ left.transition = seq.transition;
+
+ middle = range;
+ middle.transition = seq.transition;
+
+ right.first = range.last + 1;
+ right.last = seq.last;
+ right.transition = seq.transition;
+
+ sequences.remove(i);
+ if (left.last >= left.first) {
+ sequences.insert(i, left);
+ ++i;
+ }
+ sequences.insert(i, middle);
+ ++i;
+ if (right.last >= right.first) {
+ sequences.insert(i, right);
+ ++i;
+ }
+
+ i = -1;
+ break;
+ }
+
+ ++i;
+ }
+ }
+
+ //qDebug() << "sequence count" << sequences.count();
+ //qDebug() << sequences;
+
+ if (sequences.count() < 10
+ || sequences.last().last == maxInput
+ || needsCharFunction) {
+ foreach (TransitionSequence seq, sequences) {
+ const bool embedFinalState = isSingleReferencedFinalState(seq.transition);
+
+ QString brace;
+ if (embedFinalState)
+ brace = " {";
+
+ if (!seq.testFunction.isEmpty()) {
+ body << "if (" << seq.testFunction << ")" << brace;
+ } else if (seq.first == seq.last) {
+ body << "if (ch.unicode() == " << seq.first << ")" << brace;
+ } else {
+ if (seq.last < maxInput)
+ body << "if (ch.unicode() >= " << seq.first
+ << " && ch.unicode() <= " << seq.last << ")" << brace;
+ else
+ body << "if (ch.unicode() >= " << seq.first << ")" << brace;
+ }
+ body.indent();
+ if (embedFinalState) {
+ body << "token = " << dfa.at(seq.transition).symbol << ";";
+ body << "goto found;";
+
+ body.outdent();
+ body << "}";
+ } else {
+ body << "goto state_" << seq.transition << ";";
+ body.outdent();
+ }
+ }
+ } else {
+ QList<InputType> keys = transitions.keys();
+ qSort(keys);
+
+ body << "switch (ch.unicode()) {";
+ body.indent();
+ for (int k = 0; k < keys.count(); ++k) {
+ const InputType key = keys.at(k);
+ const int trans = transitions.value(key);
+
+ QString keyStr;
+ if (key == '\\')
+ keyStr = QString("\'\\\\\'");
+ else if (key >= 48 && key < 127)
+ keyStr = QString('\'') + QChar::fromLatin1(char(key)) + QChar('\'');
+ else
+ keyStr = QString::number(key);
+
+ if (k < keys.count() - 1
+ && transitions.value(keys.at(k + 1)) == trans) {
+ body << "case " << keyStr << ":";
+ } else {
+ if (isSingleReferencedFinalState(trans)) {
+ body << "case " << keyStr << ": token = " << dfa.at(trans).symbol << "; goto found;";
+ } else {
+ body << "case " << keyStr << ": goto state_" << trans << ";";
+ }
+ }
+ }
+ body.outdent();
+ body << "}";
+ }
+}
+
+QString Generator::generate()
+{
+ Class klass(cfg.className);
+
+ klass.addMember(Class::PublicMember, "QString input");
+ klass.addMember(Class::PublicMember, "int pos");
+ klass.addMember(Class::PublicMember, "int lexemStart");
+ klass.addMember(Class::PublicMember, "int lexemLength");
+
+ {
+ CodeBlock body;
+ body << "input = inp;";
+ body << "pos = 0;";
+ body << "lexemStart = 0;";
+ body << "lexemLength = 0;";
+ klass.addConstructor(Class::PublicMember, body, "const QString &inp");
+ }
+
+ {
+ Function next("QChar", "next()");
+ next.setInline(true);
+ if (cfg.caseSensitivity == Qt::CaseSensitive)
+ next.addBody("return (pos < input.length()) ? input.at(pos++) : QChar();");
+ else
+ next.addBody("return (pos < input.length()) ? input.at(pos++).toLower() : QChar();");
+ klass.addMember(Class::PublicMember, next);
+ }
+
+ /*
+ {
+ Function lexem("QString", "lexem()");
+ lexem.setConst(true);
+ lexem.setInline(true);
+ lexem.addBody("return input.mid(lexemStart, lexemLength);");
+ klass.addMember(Class::PublicMember, lexem);
+ }
+ */
+
+ for (int i = 0; i < dfa.count(); ++i)
+ if (dfa.at(i).symbol.endsWith(QLatin1String("()"))) {
+ Function handlerFunc("int", dfa.at(i).symbol);
+ klass.addMember(Class::PublicMember, handlerFunc);
+ }
+
+ Function lexFunc;
+ lexFunc.setReturnType("int");
+ lexFunc.setName("lex()");
+
+ CodeBlock body;
+ body << "lexemStart = pos;";
+ body << "lexemLength = 0;";
+ body << "int lastAcceptingPos = -1;";
+ body << "int token = -1;";
+ body << "QChar ch;";
+ body.addNewLine();
+
+ backReferenceMap.clear();
+ foreach (State s, dfa)
+ foreach (int state, s.transitions)
+ backReferenceMap[state]++;
+
+ bool haveSingleReferencedFinalState = false;
+
+ for (int i = 0; i < dfa.count(); ++i) {
+ if (isSingleReferencedFinalState(i)) {
+ haveSingleReferencedFinalState = true;
+ continue;
+ }
+
+ if (i > 0)
+ body << "state_" << i << ":";
+ else
+ body << "// initial state";
+
+ body.indent();
+
+ if (!dfa.at(i).symbol.isEmpty()) {
+ body << "lastAcceptingPos = pos;";
+ body << "token = " << dfa.at(i).symbol << ";";
+ }
+
+ body.outdent();
+
+ body.indent();
+
+ if (!dfa.at(i).transitions.isEmpty()) {
+ body << "ch = next();";
+ generateTransitions(body, dfa.at(i).transitions);
+ }
+
+ body << "goto out;";
+
+ body.outdent();
+ }
+
+ if (haveSingleReferencedFinalState) {
+ body << "found:";
+ body << "lastAcceptingPos = pos;";
+ body.addNewLine();
+ }
+
+ body << "out:";
+ body << "if (lastAcceptingPos != -1) {";
+ body.indent();
+ body << "lexemLength = lastAcceptingPos - lexemStart;";
+ body << "pos = lastAcceptingPos;";
+ body.outdent();
+ body << "}";
+ body << "return token;";
+
+ lexFunc.addBody(body);
+
+ klass.addMember(Class::PublicMember, lexFunc);
+
+ QString header;
+ QFile headerFile(headerFileName);
+ if (!headerFileName.isEmpty()
+ && headerFile.exists()
+ && headerFile.open(QIODevice::ReadOnly)) {
+ header = QString::fromUtf8(headerFile.readAll());
+ }
+
+ header += QLatin1String("// auto generated. DO NOT EDIT.\n");
+
+ return header + klass.declaration() + klass.definition();
+}
+
diff --git a/util/lexgen/generator.h b/util/lexgen/generator.h
new file mode 100644
index 0000000..047378b
--- /dev/null
+++ b/util/lexgen/generator.h
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include <QTextStream>
+#include <QStringList>
+
+#include "nfa.h"
+
+class LineStream
+{
+private:
+ struct SharedStream
+ {
+ int ref;
+ QTextStream *stream;
+ };
+
+public:
+ LineStream(QTextStream *textStream)
+ {
+ shared = new SharedStream;
+ shared->ref = 1;
+ shared->stream = textStream;
+ }
+ LineStream(const LineStream &other)
+ {
+ shared = other.shared;
+ shared->ref++;
+ }
+ LineStream &operator=(const LineStream &other)
+ {
+ if (this == &other)
+ return *this;
+ LineStream copy(other); // keep refcount up
+ qSwap(*shared, *other.shared);
+ return *this;
+ }
+ ~LineStream()
+ {
+ if (!--shared->ref) {
+ (*shared->stream) << endl;
+ delete shared;
+ }
+ }
+
+ template <typename T>
+ LineStream &operator<<(const T &value)
+ { (*shared->stream) << value; return *this; }
+
+ SharedStream *shared;
+};
+
+class CodeBlock
+{
+public:
+ inline CodeBlock() { stream.setString(&output, QIODevice::WriteOnly); }
+
+ inline void indent() { indentStr += QLatin1String(" "); }
+ inline void outdent() { indentStr.remove(0, 4); }
+
+ template <typename T>
+ LineStream operator<<(const T &value)
+ { stream << indentStr; stream << value; return LineStream(&stream); }
+
+ inline void addNewLine() { stream << endl; }
+
+ inline QString toString() const { stream.flush(); return output; }
+
+private:
+ QString output;
+ mutable QTextStream stream;
+ QString indentStr;
+};
+
+class Function
+{
+public:
+ inline Function(const QString &returnType, const QString &name)
+ : rtype(returnType), fname(name), iline(false), cnst(false) {}
+ inline Function() : iline(false), cnst(false) {}
+
+ inline void setName(const QString &name) { fname = name; }
+ inline QString name() const { return fname; }
+
+ inline void setInline(bool i) { iline = i; }
+ inline bool isInline() const { return iline; }
+
+ inline void setReturnType(const QString &type) { rtype = type; }
+ inline QString returnType() const { return rtype; }
+
+ inline void addBody(const QString &_body) { body += _body; }
+ inline void addBody(const CodeBlock &block) { body += block.toString(); }
+ inline bool hasBody() const { return !body.isEmpty(); }
+
+ inline void setConst(bool konst) { cnst = konst; }
+ inline bool isConst() const { return cnst; }
+
+ void printDeclaration(CodeBlock &block, const QString &funcNamePrefix = QString()) const;
+ QString definition() const;
+
+private:
+ QString signature(const QString &funcNamePrefix = QString()) const;
+
+ QString rtype;
+ QString fname;
+ QString body;
+ bool iline;
+ bool cnst;
+};
+
+class Class
+{
+public:
+ enum Access { PublicMember, ProtectedMember, PrivateMember };
+
+ inline Class(const QString &name) : cname(name) {}
+
+ inline void setName(const QString &name) { cname = name; }
+ inline QString name() const { return cname; }
+
+ inline void addMember(Access access, const QString &name)
+ { sections[access].variables.append(name); }
+ inline void addMember(Access access, const Function &func)
+ { sections[access].functions.append(func); }
+
+ void addConstructor(Access access, const QString &body, const QString &args = QString());
+ inline void addConstructor(Access access, const CodeBlock &body, const QString &args = QString())
+ { addConstructor(access, body.toString(), args); }
+
+ QString declaration() const;
+ QString definition() const;
+
+private:
+ QString cname;
+ struct Section
+ {
+ QVector<Function> functions;
+ QStringList variables;
+ QVector<Function> constructors;
+
+ inline bool isEmpty() const
+ { return functions.isEmpty() && variables.isEmpty() && constructors.isEmpty(); }
+
+ void printDeclaration(const Class *klass, CodeBlock &block) const;
+ QString definition(const Class *klass) const;
+ };
+
+ Section sections[3];
+};
+
+class Generator
+{
+public:
+ Generator(const DFA &dfa, const Config &config);
+
+ QString generate();
+
+private:
+ void generateTransitions(CodeBlock &body, const TransitionMap &transitions);
+ bool isSingleReferencedFinalState(int i) const;
+
+ DFA dfa;
+ Config cfg;
+ InputType minInput;
+ InputType maxInput;
+ QHash<int, int> backReferenceMap;
+ QString headerFileName;
+public:
+ struct TransitionSequence
+ {
+ inline TransitionSequence() : first(-1), last(-1), transition(-1) {}
+ InputType first;
+ InputType last;
+ int transition;
+ QString testFunction;
+ };
+private:
+ QVector<TransitionSequence> charFunctionRanges;
+};
+
+#endif
diff --git a/util/lexgen/global.h b/util/lexgen/global.h
new file mode 100644
index 0000000..01f915d
--- /dev/null
+++ b/util/lexgen/global.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#include <QHash>
+#include <QDataStream>
+#include <QSet>
+
+#include "configfile.h"
+
+#if 1
+typedef int InputType;
+
+enum SpecialInputType {
+ DigitInput,
+ SpaceInput,
+ Letter
+};
+
+#else
+
+enum SpecialInputType {
+ NoSpecialInput = 0,
+ DigitInput,
+ SpaceInput,
+ LetterOrNumberInput
+};
+
+struct InputType
+{
+ inline InputType() : val(0), specialInput(NoSpecialInput) {}
+ inline InputType(const int &val) : val(val), specialInput(NoSpecialInput) {}
+
+ inline operator int() const { return val; }
+
+ inline bool operator==(const InputType &other) const
+ { return val == other.val; }
+ inline bool operator!=(const InputType &other) const
+ { return val != other.val; }
+
+ int val;
+ SpecialInputType specialInput;
+};
+
+inline int qHash(const InputType &t) { return qHash(t.val); }
+
+inline QDataStream &operator<<(QDataStream &stream, const InputType &i)
+{
+ return stream << i;
+}
+
+inline QDataStream &operator>>(QDataStream &stream, InputType &i)
+{
+ return stream >> i;
+}
+
+#endif
+
+const InputType Epsilon = -1;
+
+struct Config
+{
+ inline Config() : caseSensitivity(Qt::CaseSensitive), debug(false), cache(false) {}
+ QSet<InputType> maxInputSet;
+ Qt::CaseSensitivity caseSensitivity;
+ QString className;
+ bool debug;
+ bool cache;
+ QString ruleFile;
+ ConfigFile::SectionMap configSections;
+};
+
+#endif // GLOBAL_H
diff --git a/util/lexgen/lexgen.lexgen b/util/lexgen/lexgen.lexgen
new file mode 100644
index 0000000..33efb8b
--- /dev/null
+++ b/util/lexgen/lexgen.lexgen
@@ -0,0 +1,24 @@
+[Options]
+case-sensitive
+classname = RegExpTokenizer
+
+[Code Generator Options]
+TokenPrefix = RE2NFA::
+
+[Macros]
+Escape = \\.{1}
+
+[Tokens]
+TOK_QUOTED_STRING = \"[^\"]*\"
+TOK_STRING = [^\{\}\(\)\,\*\|\?\.\+\[]|{Escape}
+TOK_SEQUENCE = \[([^\]]|(\\\]))*\]
+TOK_LBRACE = \{
+TOK_RBRACE = \}
+TOK_LPAREN = \(
+TOK_RPAREN = \)
+TOK_COMMA = \,
+TOK_STAR = \*
+TOK_OR = \|
+TOK_QUESTION = \?
+TOK_DOT = \.
+TOK_PLUS = \+
diff --git a/util/lexgen/lexgen.pri b/util/lexgen/lexgen.pri
new file mode 100644
index 0000000..b36e00e
--- /dev/null
+++ b/util/lexgen/lexgen.pri
@@ -0,0 +1,3 @@
+VPATH += $$PWD
+SOURCES += nfa.cpp configfile.cpp re2nfa.cpp
+INCLUDEPATH += $$PWD
diff --git a/util/lexgen/lexgen.pro b/util/lexgen/lexgen.pro
new file mode 100644
index 0000000..89ac84d
--- /dev/null
+++ b/util/lexgen/lexgen.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+TARGET = lexgen
+include(lexgen.pri)
+SOURCES += main.cpp \
+ generator.cpp
+QT = core
diff --git a/util/lexgen/main.cpp b/util/lexgen/main.cpp
new file mode 100644
index 0000000..b7b529a
--- /dev/null
+++ b/util/lexgen/main.cpp
@@ -0,0 +1,323 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nfa.h"
+#include "re2nfa.h"
+#include "configfile.h"
+#include "generator.h"
+
+#include <QFile>
+#include <QCoreApplication>
+#include <QFileInfo>
+#include <QDateTime>
+
+struct Symbol
+{
+ QString token;
+ QString lexem;
+};
+
+static QList<Symbol> tokenize(const DFA &dfa, const QString &input, Config *cfg, bool *ok = 0)
+{
+ QList<Symbol> symbols;
+ Symbol lastSymbol;
+ int state = 0;
+ int lastAcceptingState = -1;
+ QString lastAcceptingLexem;
+ int lastAcceptingPos = -1;
+ for (int i = 0; i < input.length(); ++i) {
+ QChar ch = input.at(i);
+ QChar chForInput = ch;
+ if (cfg->caseSensitivity == Qt::CaseInsensitive)
+ chForInput = chForInput.toLower();
+ int next = dfa.at(state).transitions.value(chForInput.unicode());
+ if (cfg->debug)
+ qDebug() << "input" << input.at(i) << "leads to state" << next;
+ if (next) {
+ lastSymbol.lexem.append(input.at(i));
+ lastSymbol.token = dfa.at(next).symbol;
+ if (!lastSymbol.token.isEmpty()) {
+ lastAcceptingState = next;
+ lastAcceptingLexem = lastSymbol.lexem;
+ lastAcceptingPos = i;
+ }
+ state = next;
+ } else {
+ if (lastAcceptingState != -1) {
+ if (cfg->debug)
+ qDebug() << "adding" << dfa.at(lastAcceptingState).symbol << "and backtracking to" << lastAcceptingPos;
+ Symbol s;
+ s.token = dfa.at(lastAcceptingState).symbol;
+ s.lexem = lastAcceptingLexem;
+ symbols << s;
+ lastSymbol = Symbol();
+ state = 0;
+ i = lastAcceptingPos;
+ lastAcceptingPos = -1;
+ lastAcceptingState = -1;
+ continue;
+ }
+ if (state == 0 || lastSymbol.token.isEmpty()) {
+ if (cfg->debug)
+ qDebug() << "invalid input";
+ if (ok)
+ *ok = false;
+ return symbols;
+ }
+ if (cfg->debug)
+ qDebug() << "appending symbol with token" << lastSymbol.token;
+ symbols << lastSymbol;
+ lastSymbol = Symbol();
+ state = 0;
+ lastAcceptingState = -1;
+ --i;
+ }
+ }
+ if (!lastSymbol.token.isEmpty()) {
+ if (cfg->debug)
+ qDebug() << "appending (last) symbol with token" << lastSymbol.token;
+ symbols << lastSymbol;
+ } else if (lastAcceptingState != -1) {
+ if (cfg->debug)
+ qDebug() << "appending last accepting state with token" << dfa.at(lastAcceptingState).symbol;
+ Symbol s;
+ s.lexem = lastAcceptingLexem;
+ s.token = dfa.at(lastAcceptingState).symbol;
+ symbols << s;
+ }
+ if (ok)
+ *ok = true;
+ return symbols;
+}
+
+static QSet<InputType> determineMaxInputSet(const ConfigFile::Section &section)
+{
+ QSet<InputType> set;
+
+ QString inputTypeName;
+
+ foreach (const ConfigFile::Entry &entry, section)
+ if (entry.key == QLatin1String("InputType")) {
+ if (!inputTypeName.isEmpty()) {
+ qWarning("Error: InputType field specified multiple times in config file");
+ return QSet<InputType>();
+ }
+ inputTypeName = entry.value;
+ }
+
+ if (inputTypeName.isEmpty())
+ inputTypeName = "quint8";
+
+ if (inputTypeName == "quint8") {
+ for (int i = 1; i < 256; ++i)
+ set.insert(i);
+ } /* else if ### */
+ else {
+ qWarning("Error: Unknown input type '%s'", qPrintable(inputTypeName));
+ return QSet<InputType>();
+ }
+
+ return set;
+}
+
+static bool loadConfig(const QString &ruleFile, Config *cfg)
+{
+ ConfigFile::SectionMap sections = ConfigFile::parse(ruleFile);
+ if (sections.isEmpty()) {
+ qWarning("Error parsing %s", qPrintable(ruleFile));
+ return false;
+ }
+
+ QSet<InputType> maxInputSet = determineMaxInputSet(sections.value("Options"));
+ if (maxInputSet.isEmpty())
+ return false;
+
+ Qt::CaseSensitivity cs = Qt::CaseInsensitive;
+ if (sections.value("Options").contains("case-sensitive"))
+ cs = Qt::CaseSensitive;
+
+ cfg->configSections = sections;
+ cfg->caseSensitivity = cs;
+ cfg->className = sections.value("Options").value("classname", "Scanner");
+ cfg->maxInputSet = maxInputSet;
+ cfg->ruleFile = ruleFile;
+ return true;
+}
+
+static DFA generateMachine(const Config &cfg)
+{
+ if (cfg.cache) {
+ QFileInfo ruleInfo(cfg.ruleFile);
+ QFileInfo cacheInfo(ruleInfo.baseName() + ".dfa");
+ if (cacheInfo.exists()
+ && cacheInfo.lastModified() > ruleInfo.lastModified()) {
+ QFile f(cacheInfo.absoluteFilePath());
+ f.open(QIODevice::ReadOnly);
+ QDataStream stream(&f);
+ DFA machine;
+ stream >> machine;
+ return machine;
+ }
+ }
+
+ QMap<QString, NFA> macros;
+ foreach (ConfigFile::Entry e, cfg.configSections.value("Macros")) {
+ int errCol = 0;
+ if (cfg.debug)
+ qDebug() << "parsing" << e.value;
+ NFA nfa = RE2NFA(macros, cfg.maxInputSet, cfg.caseSensitivity).parse(e.value, &errCol);
+ if (nfa.isEmpty()) {
+ qWarning("Parse error in line %d column %d", e.lineNumber, errCol);
+ return DFA();
+ }
+ macros.insert(e.key, nfa);
+ }
+
+ if (!cfg.configSections.contains("Tokens")) {
+ qWarning("Rule file does not contain a [Tokens] section!");
+ return DFA();
+ }
+
+ QVector<NFA> tokens;
+
+ foreach (ConfigFile::Entry e, cfg.configSections.value("Tokens")) {
+ int errCol = 0;
+ if (cfg.debug)
+ qDebug() << "parsing" << e.value;
+ NFA tok = RE2NFA(macros, cfg.maxInputSet, cfg.caseSensitivity).parse(e.value, &errCol);
+ if (tok.isEmpty()) {
+ qWarning("Parse error in line %d column %d while parsing token %s", e.lineNumber, errCol, e.key.toLocal8Bit().constData());
+ return DFA();
+ }
+ tok.setTerminationSymbol(e.key);
+ tokens.append(tok);
+ }
+
+ NFA giganticStateMachine;
+ foreach (NFA nfa, tokens)
+ if (giganticStateMachine.isEmpty())
+ giganticStateMachine = nfa;
+ else
+ giganticStateMachine = NFA::createAlternatingNFA(giganticStateMachine, nfa);
+
+ DFA result = giganticStateMachine.toDFA().minimize();
+ if (cfg.cache) {
+ QFileInfo ruleInfo(cfg.ruleFile);
+ QFileInfo cacheInfo(ruleInfo.baseName() + ".dfa");
+ QFile f(cacheInfo.absoluteFilePath());
+ f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ QDataStream stream(&f);
+ stream << result;
+ }
+ return result;
+}
+
+#if !defined(AUTOTEST)
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ QString ruleFile;
+ Config cfg;
+
+ const QStringList arguments = app.arguments().mid(1);
+ cfg.debug = arguments.contains("-debug");
+ const bool testRules = arguments.contains("-test");
+ cfg.cache = arguments.contains("-cache");
+
+ foreach (const QString &arg, arguments)
+ if (!arg.startsWith(QLatin1Char('-'))) {
+ ruleFile = arg;
+ break;
+ }
+
+ if (ruleFile.isEmpty()) {
+ qWarning("usage: lexgen [-test rulefile");
+ qWarning(" ");
+ qWarning(" the -test option will cause lexgen to interpret standard input");
+ qWarning(" according to the specified rules and print out pairs of token and");
+ qWarning(" lexical element");
+ return 1;
+ }
+
+ if (!loadConfig(ruleFile, &cfg))
+ return 1;
+
+ DFA machine = generateMachine(cfg);
+ if (machine.isEmpty())
+ return 1;
+
+ if (testRules) {
+ qWarning("Testing:");
+ QString input = QTextStream(stdin).readAll();
+ /*
+ qDebug() << "NFA has" << machine.stateCount() << "states";
+ qDebug() << "Converting to DFA... (this may take a while)";
+ DFA dfa = machine.toDFA();
+ qDebug() << "DFA has" << dfa.count() << "states";
+ qDebug() << "Minimizing...";
+ dfa = dfa.minimize();
+ qDebug() << "Minimized DFA has" << dfa.count() << "states";
+ */
+ DFA dfa = machine;
+ if (cfg.debug)
+ qDebug() << "tokenizing" << input;
+ bool ok = false;
+ QList<Symbol> symbols = tokenize(dfa, input, &cfg, &ok);
+ if (symbols.isEmpty()) {
+ qWarning("No tokens produced!");
+ } else {
+ foreach (Symbol s, symbols)
+ qDebug() << s.token << ":" << s.lexem;
+ }
+ if (ok)
+ qDebug() << symbols.count() << "tokens produced.";
+ else
+ qDebug() << "Error while tokenizing!";
+ } else {
+ Generator gen(machine, cfg);
+ QTextStream(stdout)
+ << gen.generate();
+ }
+
+ return 0;
+}
+#endif
+
diff --git a/util/lexgen/nfa.cpp b/util/lexgen/nfa.cpp
new file mode 100644
index 0000000..701a5e0
--- /dev/null
+++ b/util/lexgen/nfa.cpp
@@ -0,0 +1,508 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "nfa.h"
+#include <QSet>
+#include <limits.h>
+
+NFA NFA::createSingleInputNFA(InputType input)
+{
+ NFA result;
+ result.initialize(2);
+ result.addTransition(result.initialState, input, result.finalState);
+ return result;
+}
+
+NFA NFA::createSymbolNFA(const QString &symbol)
+{
+ NFA result = NFA::createSingleInputNFA(Epsilon);
+ result.states[result.finalState].symbol = symbol;
+ return result;
+}
+
+void NFA::initialize(int size)
+{
+ states.resize(size);
+ states.fill(State());
+ initialState = 0;
+ finalState = size - 1;
+}
+
+void NFA::addTransition(int from, InputType input, int to)
+{
+ assertValidState(from);
+ assertValidState(to);
+
+ states[from].transitions.insertMulti(input, to);
+}
+
+void NFA::copyFrom(const NFA &other, int baseState)
+{
+ assertValidState(baseState);
+ assertValidState(baseState + other.states.count() - 1);
+
+ for (int i = 0; i < other.states.count(); ++i) {
+ State s = other.states.at(i);
+
+ for (TransitionMap::Iterator it = s.transitions.begin(),
+ end = s.transitions.end(); it != end; ++it)
+ *it += baseState;
+
+ states[baseState + i] = s;
+ }
+}
+
+void NFA::initializeFromPair(const NFA &a, const NFA &b,
+ int *initialA, int *finalA,
+ int *initialB, int *finalB)
+{
+ initialize(a.states.count() + b.states.count() + 2);
+
+ int baseIdxA = 1;
+ int baseIdxB = 1 + a.states.count();
+
+ *initialA = a.initialState + baseIdxA;
+ *finalA = a.finalState + baseIdxA;
+
+ *initialB = b.initialState + baseIdxB;
+ *finalB = b.finalState + baseIdxB;
+
+ copyFrom(a, baseIdxA);
+ copyFrom(b, baseIdxB);
+}
+
+NFA NFA::createAlternatingNFA(const NFA &a, const NFA &b)
+{
+ NFA result;
+
+ int newInitialA, newFinalA,
+ newInitialB, newFinalB;
+
+ result.initializeFromPair(a, b, &newInitialA, &newFinalA,
+ &newInitialB, &newFinalB);
+
+ result.addTransition(result.initialState, Epsilon, newInitialA);
+ result.addTransition(result.initialState, Epsilon, newInitialB);
+
+ result.addTransition(newFinalA, Epsilon, result.finalState);
+ result.addTransition(newFinalB, Epsilon, result.finalState);
+
+ return result;
+}
+
+NFA NFA::createConcatenatingNFA(const NFA &a, const NFA &b)
+{
+ NFA result;
+
+ int initialA, finalA,
+ initialB, finalB;
+
+ result.initializeFromPair(a, b, &initialA, &finalA, &initialB, &finalB);
+
+ result.addTransition(result.initialState, Epsilon, initialA);
+ result.addTransition(finalA, Epsilon, initialB);
+ result.addTransition(finalB, Epsilon, result.finalState);
+ return result;
+}
+
+NFA NFA::createOptionalNFA(const NFA &a)
+{
+ NFA result;
+
+ result.initialize(a.states.count() + 2);
+
+ int baseIdxA = 1;
+ int initialA = a.initialState + baseIdxA;
+ int finalA = a.finalState + baseIdxA;
+
+ result.copyFrom(a, baseIdxA);
+
+ result.addTransition(result.initialState, Epsilon, initialA);
+ result.addTransition(result.initialState, Epsilon, result.finalState);
+
+ result.addTransition(finalA, Epsilon, initialA);
+ result.addTransition(finalA, Epsilon, result.finalState);
+
+ return result;
+}
+
+NFA NFA::createStringNFA(const QByteArray &str)
+{
+ NFA result;
+ foreach (char c, str) {
+ NFA ch = NFA::createSingleInputNFA(c);
+ if (result.isEmpty())
+ result = ch;
+ else
+ result = NFA::createConcatenatingNFA(result, ch);
+ }
+ return result;
+}
+
+NFA NFA::createSetNFA(const QSet<InputType> &set)
+{
+ NFA result;
+ result.initialize(set.count() + 2);
+
+ int state = 1;
+ for (QSet<InputType>::ConstIterator it = set.constBegin(), end = set.constEnd();
+ it != end; ++it, ++state) {
+ result.addTransition(result.initialState, Epsilon, state);
+ result.addTransition(state, *it, result.finalState);
+ }
+
+ /*
+ foreach (InputType input, set) {
+ NFA ch = NFA::createSingleInputNFA(input);
+ if (result.isEmpty())
+ result = ch;
+ else
+ result = NFA::createAlternatingNFA(result, ch);
+ }
+ */
+ return result;
+}
+
+NFA NFA::createZeroOrOneNFA(const NFA &a)
+{
+ NFA epsilonNFA = createSingleInputNFA(Epsilon);
+ return NFA::createAlternatingNFA(a, epsilonNFA);
+}
+
+NFA NFA::applyQuantity(const NFA &a, int minOccurrences, int maxOccurrences)
+{
+ NFA result = a;
+ NFA epsilonNFA = createSingleInputNFA(Epsilon);
+
+ if (minOccurrences == 0) {
+ result = NFA::createAlternatingNFA(result, epsilonNFA);
+ } else {
+ minOccurrences--;
+ }
+ maxOccurrences--;
+
+ for (int i = 0; i < minOccurrences; ++i)
+ result = NFA::createConcatenatingNFA(result, a);
+
+ for (int i = minOccurrences; i < maxOccurrences; ++i)
+ result = NFA::createConcatenatingNFA(result, NFA::createAlternatingNFA(a, epsilonNFA));
+
+ return result;
+}
+
+void NFA::debug()
+{
+ qDebug() << "NFA has" << states.count() << "states";
+ qDebug() << "initial state is" << initialState;
+ qDebug() << "final state is" << finalState;
+
+ for (int i = 0; i < states.count(); ++i) {
+ const State &s = states.at(i);
+ for (TransitionMap::ConstIterator it = s.transitions.constBegin(),
+ end = s.transitions.constEnd(); it != end; ++it)
+ qDebug() << "transition from state" << i << "to" << it.value() << "through"
+ << (it.key() == Epsilon ? QString("Epsilon") : QString(char(it.key())));
+ if (!s.symbol.isEmpty())
+ qDebug() << "State" << i << "leads to symbol" << s.symbol;
+ }
+}
+
+// helper
+typedef QSet<int> DFAState;
+
+// that's a bad hash, but it's good enough for us
+// and it allows us to use the nice QHash API :)
+inline uint qHash(const DFAState &state)
+{
+ uint val = 0;
+ foreach (int s, state)
+ val |= qHash(s);
+ return val;
+}
+
+DFA NFA::toDFA() const
+{
+ DFA result;
+ result.reserve(states.count());
+
+ QHash<QString, int> symbolReferenceCounts;
+ {
+ QSet<int> symbolStates;
+ for (int i = 0; i < states.count(); ++i)
+ if (!states.at(i).symbol.isEmpty())
+ symbolStates.insert(i);
+
+ QHash<int, QString> epsilonStates;
+ for (int i = 0; i < states.count(); ++i) {
+ const State &s = states.at(i);
+ for (TransitionMap::ConstIterator transition = s.transitions.constBegin(), end = s.transitions.constEnd();
+ transition != end; ++transition)
+ if (transition.key() == Epsilon && symbolStates.contains(transition.value()))
+ epsilonStates.insert(i, states.at(transition.value()).symbol);
+ }
+
+ int lastCount;
+ do {
+ lastCount = epsilonStates.count();
+ for (int i = 0; i < states.count(); ++i) {
+ const State &s = states.at(i);
+ for (TransitionMap::ConstIterator transition = s.transitions.constBegin(), end = s.transitions.constEnd();
+ transition != end; ++transition)
+ if (transition.key() == Epsilon && epsilonStates.contains(transition.value()))
+ epsilonStates.insert(i, epsilonStates.value(transition.value()));
+ }
+
+ } while (lastCount != epsilonStates.count());
+
+ for (int i = 0; i < states.count(); ++i) {
+ const State &s = states.at(i);
+ for (TransitionMap::ConstIterator transition = s.transitions.constBegin(), end = s.transitions.constEnd();
+ transition != end; ++transition) {
+ if (transition.key() == Epsilon)
+ continue;
+ if (symbolStates.contains(transition.value())) {
+ const QString symbol = states.at(transition.value()).symbol;
+ symbolReferenceCounts[symbol]++;
+ } else if (epsilonStates.contains(transition.value())) {
+ const QString symbol = epsilonStates.value(transition.value());
+ symbolReferenceCounts[symbol]++;
+ }
+ }
+ }
+ /*
+ for (QHash<QString, int>::ConstIterator symIt = symbolReferenceCounts.constBegin(), symEnd = symbolReferenceCounts.constEnd();
+ symIt != symEnd; ++symIt)
+ qDebug() << "symbol" << symIt.key() << "is reached" << symIt.value() << "times";
+ */
+ }
+
+
+ QSet<InputType> validInput;
+ foreach (const State &s, states)
+ for (TransitionMap::ConstIterator it = s.transitions.constBegin(),
+ end = s.transitions.constEnd(); it != end; ++it)
+ if (it.key() != Epsilon)
+ validInput.insert(it.key());
+
+ // A DFA state can consist of multiple NFA states.
+ // the dfaStateMap maps from these to the actual
+ // state index within the resulting DFA vector
+ QHash<DFAState, int> dfaStateMap;
+ QStack<DFAState> pendingDFAStates;
+
+ DFAState startState = epsilonClosure(QSet<int>() << initialState);
+
+ result.resize(1);
+ dfaStateMap.insert(startState, 0);
+
+ pendingDFAStates.push(startState);
+
+ while (!pendingDFAStates.isEmpty()) {
+ DFAState state = pendingDFAStates.pop();
+// qDebug() << "processing" << state << "from the stack of pending states";
+
+ foreach (InputType input, validInput) {
+
+ QSet<int> reachableStates;
+
+ foreach (int nfaState, state) {
+ const TransitionMap &transitions = states.at(nfaState).transitions;
+ TransitionMap::ConstIterator it = transitions.find(input);
+ while (it != transitions.constEnd() && it.key() == input) {
+ reachableStates.insert(it.value());
+ ++it;
+ }
+ }
+
+ if (reachableStates.isEmpty())
+ continue;
+
+// qDebug() << "can reach" << reachableStates << "from input" << char(input);
+
+ QSet<int> closure = epsilonClosure(reachableStates);
+
+// qDebug() << "closure is" << closure;
+
+ if (!dfaStateMap.contains(closure)) {
+ int dfaState = result.count();
+ result.append(State());
+
+ QString symbol;
+ int refCount = INT_MAX;
+ foreach (int nfaState, closure)
+ if (!states.at(nfaState).symbol.isEmpty()) {
+// qDebug() << "closure also contains symbol" << states.at(nfaState).symbol;
+ QString candidate = states.at(nfaState).symbol;
+ int candidateRefCount =symbolReferenceCounts.value(candidate, INT_MAX);
+ if (candidateRefCount < refCount) {
+ refCount = candidateRefCount;
+ symbol = candidate;
+ }
+ }
+ if (!symbol.isEmpty())
+ result.last().symbol = symbol;
+
+ dfaStateMap.insert(closure, dfaState);
+
+ Q_ASSERT(!pendingDFAStates.contains(closure));
+ pendingDFAStates.prepend(closure);
+ }
+
+ result[dfaStateMap.value(state)].transitions.insert(input, dfaStateMap.value(closure));
+ }
+ }
+
+ return result;
+}
+
+QSet<int> NFA::epsilonClosure(const QSet<int> &initialClosure) const
+{
+ QSet<int> closure = initialClosure;
+ closure.reserve(closure.count() * 4);
+
+ QStack<int> stateStack;
+ stateStack.resize(closure.count());
+ qCopy(closure.constBegin(), closure.constEnd(), stateStack.begin());
+
+ while (!stateStack.isEmpty()) {
+ int t = stateStack.pop();
+ const TransitionMap &transitions = states.at(t).transitions;
+ TransitionMap::ConstIterator it = transitions.find(Epsilon);
+ while (it != transitions.constEnd() && it.key() == Epsilon) {
+ const int u = it.value();
+ if (!closure.contains(u)) {
+ closure.insert(u);
+ stateStack.push(u);
+ }
+ ++it;
+ }
+ }
+
+ return closure;
+}
+
+void NFA::setTerminationSymbol(const QString &symbol)
+{
+ states[finalState].symbol = symbol;
+}
+
+void DFA::debug() const
+{
+ qDebug() << "DFA has" << count() << "states";
+
+ for (int i = 0; i < count(); ++i) {
+ const State &s = at(i);
+ if (s.transitions.isEmpty()) {
+ qDebug() << "State" << i << "has no transitions";
+ } else {
+ for (TransitionMap::ConstIterator it = s.transitions.constBegin(),
+ end = s.transitions.constEnd(); it != end; ++it)
+ qDebug() << "transition from state" << i << "to" << it.value() << "through"
+ << (it.key() == Epsilon ? QString("Epsilon") : QString(char(it.key())));
+ }
+ if (!s.symbol.isEmpty())
+ qDebug() << "State" << i << "leads to symbol" << s.symbol;
+ }
+
+}
+
+DFA DFA::minimize() const
+{
+ QVector<bool> inequivalentStates(count() * count());
+ inequivalentStates.fill(false);
+
+ for (int i = 0; i < count(); ++i)
+ for (int j = 0; j < i; ++j) {
+ if (i != j && at(i).symbol != at(j).symbol)
+ inequivalentStates[i * count() + j] = true;
+ }
+
+ bool done;
+ do {
+ done = true;
+ for (int i = 0; i < count(); ++i)
+ for (int j = 0; j < count(); ++j) {
+ if (i == j)
+ continue;
+
+ if (inequivalentStates[i * count() + j])
+ continue;
+
+ if (at(i).transitions.keys() != at(j).transitions.keys()) {
+ inequivalentStates[i * count() + j] = true;
+ done = false;
+ continue;
+ }
+
+ foreach (InputType a, at(i).transitions.keys()) {
+ int r = at(i).transitions.value(a, -1);
+ if (r == -1)
+ continue;
+ int s = at(j).transitions.value(a, -1);
+ if (s == -1)
+ continue;
+
+ if (inequivalentStates[r * count() + s]
+ || r == s) {
+ inequivalentStates[i * count() + j] = true;
+ done = false;
+ break;
+ }
+ }
+ }
+ } while (!done);
+
+ QHash<int, int> statesToEliminate;
+ for (int i = 0; i < count(); ++i)
+ for (int j = 0; j < i; ++j)
+ if (!inequivalentStates[i * count() + j]) {
+ statesToEliminate.insertMulti(i, j);
+ }
+
+ /*
+ qDebug() << "states to eliminiate:" << statesToEliminate.count();;
+ qDebug() << "merging" << statesToEliminate;
+ debug();
+ */
+
+ return *this;
+}
+
+
diff --git a/util/lexgen/nfa.h b/util/lexgen/nfa.h
new file mode 100644
index 0000000..1f25071
--- /dev/null
+++ b/util/lexgen/nfa.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NFA_H
+#define NFA_H
+
+#include <QMap>
+#include <QHash>
+#include <QString>
+#include <QVector>
+#include <QDebug>
+#include <QStack>
+#include <QByteArray>
+
+#include "global.h"
+
+typedef QHash<InputType, int> TransitionMap;
+
+struct State
+{
+ QString symbol;
+ TransitionMap transitions;
+};
+
+inline QDataStream &operator<<(QDataStream &stream, const State &state)
+{
+ return stream << state.symbol << state.transitions;
+}
+
+inline QDataStream &operator>>(QDataStream &stream, State &state)
+{
+ return stream >> state.symbol >> state.transitions;
+}
+
+struct DFA : public QVector<State>
+{
+ void debug() const;
+ DFA minimize() const;
+};
+
+class NFA
+{
+public:
+ static NFA createSingleInputNFA(InputType input);
+ static NFA createSymbolNFA(const QString &symbol);
+ static NFA createAlternatingNFA(const NFA &a, const NFA &b);
+ static NFA createConcatenatingNFA(const NFA &a, const NFA &b);
+ static NFA createOptionalNFA(const NFA &a);
+
+ // convenience
+ static NFA createStringNFA(const QByteArray &str);
+ static NFA createSetNFA(const QSet<InputType> &set);
+ static NFA createZeroOrOneNFA(const NFA &a);
+ static NFA applyQuantity(const NFA &a, int minOccurrences, int maxOccurrences);
+
+ void setTerminationSymbol(const QString &symbol);
+
+ DFA toDFA() const;
+
+ inline bool isEmpty() const { return states.isEmpty(); }
+ inline int stateCount() const { return states.count(); }
+
+ void debug();
+
+private:
+ void initialize(int size);
+ void addTransition(int from, InputType input, int to);
+ void copyFrom(const NFA &other, int baseState);
+
+ void initializeFromPair(const NFA &a, const NFA &b,
+ int *initialA, int *finalA,
+ int *initialB, int *finalB);
+
+ QSet<int> epsilonClosure(const QSet<int> &initialClosure) const;
+
+ inline void assertValidState(int state)
+ { Q_UNUSED(state); Q_ASSERT(state >= 0); Q_ASSERT(state < states.count()); }
+
+#if defined(AUTOTEST)
+public:
+#endif
+ int initialState;
+ int finalState;
+
+ QVector<State> states;
+};
+
+#endif // NFA_H
+
diff --git a/util/lexgen/re2nfa.cpp b/util/lexgen/re2nfa.cpp
new file mode 100644
index 0000000..ed58d50
--- /dev/null
+++ b/util/lexgen/re2nfa.cpp
@@ -0,0 +1,547 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "re2nfa.h"
+#include "tokenizer.cpp"
+
+RE2NFA::RE2NFA(const QMap<QString, NFA> &macros, const QSet<InputType> &maxInputSet, Qt::CaseSensitivity cs)
+ : macros(macros), index(0), errorColumn(-1), maxInputSet(maxInputSet), caseSensitivity(cs)
+{
+}
+
+NFA RE2NFA::parse(const QString &expression, int *errCol)
+{
+ tokenize(expression);
+
+ if (symbols.isEmpty())
+ return NFA();
+
+ index = 0;
+
+ NFA result = parseExpr();
+ if (result.isEmpty()) {
+ if (errCol)
+ *errCol = errorColumn;
+ }
+ return result;
+}
+
+NFA RE2NFA::parseExpr()
+{
+ NFA value = parseBranch();
+ while (test(TOK_OR)) {
+ NFA rhs = parseBranch();
+ value = NFA::createAlternatingNFA(value, rhs);
+ }
+ return value;
+}
+
+NFA RE2NFA::parseBranch()
+{
+ NFA value = parsePiece();
+ if (!hasNext())
+ return value;
+ NFA next;
+ do {
+ next = parsePiece();
+ if (!next.isEmpty())
+ value = NFA::createConcatenatingNFA(value, next);
+ } while (!next.isEmpty() && hasNext());
+ return value;
+}
+
+NFA RE2NFA::parsePiece()
+{
+ NFA atom = parseAtom();
+ if (atom.isEmpty() || !hasNext())
+ return atom;
+ return parseMaybeQuantifier(atom);
+}
+
+NFA RE2NFA::parseAtom()
+{
+ // ####
+ switch (next()) {
+ case TOK_STRING:
+ return createCharNFA();
+ case TOK_LPAREN: {
+ NFA subExpr = parseExpr();
+ next(TOK_RPAREN);
+ return subExpr;
+ }
+ case TOK_LBRACE: {
+ QString macroName = lexemUntil(TOK_RBRACE);
+ QMap<QString, NFA>::ConstIterator macro = macros.find(macroName);
+ if (macro == macros.end()) {
+ qWarning("Unknown macro '%s' - probably used before defined", qPrintable(macroName));
+ return NFA();
+ }
+ return *macro;
+ }
+ case TOK_LBRACKET: {
+ NFA set = parseSet();
+ next(TOK_RBRACKET);
+ return set;
+ }
+ case TOK_SEQUENCE:
+ return parseSet2();
+ case TOK_DOT:
+ return NFA::createSetNFA(maxInputSet);
+ default:
+ prev();
+ return NFA();
+ }
+}
+
+NFA RE2NFA::parseMaybeQuantifier(const NFA &nfa)
+{
+ // ####
+ switch (next()) {
+ case TOK_STAR:
+ return NFA::createOptionalNFA(nfa);
+ case TOK_QUESTION:
+ return NFA::createZeroOrOneNFA(nfa);
+ case TOK_PLUS:
+ return NFA::createConcatenatingNFA(nfa, NFA::createOptionalNFA(nfa));
+ case TOK_LBRACE: {
+ const int rewind = index - 1;
+
+ QString lexemBeforeComma;
+ QString lexemAfterComma;
+ bool seenComma = false;
+ forever {
+ if (test(TOK_COMMA)) {
+ if (seenComma) {
+ errorColumn = symbol().column;
+ return NFA();
+ }
+ seenComma = true;
+ } else if (test(TOK_RBRACE)) {
+ break;
+ } else {
+ next(TOK_STRING);
+ if (seenComma)
+ lexemAfterComma += symbol().lexem;
+ else
+ lexemBeforeComma += symbol().lexem;
+ }
+ }
+ bool isNumber = false;
+ int min = lexemBeforeComma.toInt(&isNumber);
+ if (!isNumber) {
+ index = rewind;
+ return nfa;
+ }
+ int max = min;
+ if (seenComma) {
+ max = lexemAfterComma.toInt(&isNumber);
+ if (!isNumber) {
+ errorColumn = symbol().column;
+ return NFA();
+ }
+ }
+ return NFA::applyQuantity(nfa, min, max);
+ }
+ default:
+ prev();
+ return nfa;
+ }
+}
+
+NFA RE2NFA::parseSet()
+{
+ QSet<InputType> set;
+ bool negate = false;
+
+ next(TOK_STRING);
+
+ do {
+ Q_ASSERT(symbol().lexem.length() == 1);
+ // ###
+ QChar ch = symbol().lexem.at(0);
+ if (set.isEmpty() && ch == QLatin1Char('^')) {
+ negate = true;
+ continue;
+ }
+
+ // look ahead for ranges like a-z
+ bool rangeFound = false;
+ if (test(TOK_STRING)) {
+ if (symbol().lexem.length() == 1
+ && symbol().lexem.at(0) == QLatin1Char('-')) {
+ next(TOK_STRING);
+ Q_ASSERT(symbol().lexem.length() == 1);
+ QChar last = symbol().lexem.at(0);
+
+ if (ch.unicode() > last.unicode())
+ qSwap(ch, last);
+
+ for (ushort i = ch.unicode(); i <= last.unicode(); ++i) {
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ set.insert(QChar(i).toLower().unicode());
+ } else {
+ set.insert(i);
+ }
+ }
+
+ rangeFound = true;
+ } else {
+ prev();
+ }
+ }
+
+ if (!rangeFound) {
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ set.insert(ch.toLower().unicode());
+ } else {
+ set.insert(ch.unicode());
+ }
+ }
+ } while (test(TOK_STRING));
+
+ if (negate) {
+ QSet<InputType> negatedSet = maxInputSet;
+ negatedSet.subtract(set);
+ set = negatedSet;
+ }
+
+ return NFA::createSetNFA(set);
+}
+
+NFA RE2NFA::parseSet2()
+{
+ QSet<InputType> set;
+ bool negate = false;
+
+ QString str = symbol().lexem;
+ // strip off brackets
+ str.chop(1);
+ str.remove(0, 1);
+
+ int i = 0;
+ while (i < str.length()) {
+ // ###
+ QChar ch = str.at(i++);
+ if (set.isEmpty() && ch == QLatin1Char('^')) {
+ negate = true;
+ continue;
+ }
+
+ // look ahead for ranges like a-z
+ bool rangeFound = false;
+ if (i < str.length() - 1 && str.at(i) == QLatin1Char('-')) {
+ ++i;
+ QChar last = str.at(i++);
+
+ if (ch.unicode() > last.unicode())
+ qSwap(ch, last);
+
+ for (ushort i = ch.unicode(); i <= last.unicode(); ++i) {
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ set.insert(QChar(i).toLower().unicode());
+ } else {
+ set.insert(i);
+ }
+ }
+
+ rangeFound = true;
+ }
+
+ if (!rangeFound) {
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ set.insert(ch.toLower().unicode());
+ } else {
+ set.insert(ch.unicode());
+ }
+ }
+ }
+
+ if (negate) {
+ QSet<InputType> negatedSet = maxInputSet;
+ negatedSet.subtract(set);
+ set = negatedSet;
+ }
+
+ return NFA::createSetNFA(set);
+}
+NFA RE2NFA::createCharNFA()
+{
+ NFA nfa;
+ // ####
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ nfa = NFA::createStringNFA(symbol().lexem.toLower().toLatin1());
+ } else {
+ nfa = NFA::createStringNFA(symbol().lexem.toLatin1());
+ }
+ return nfa;
+}
+
+static inline int skipQuote(const QString &str, int pos)
+{
+ while (pos < str.length()
+ && str.at(pos) != QLatin1Char('"')) {
+ if (str.at(pos) == QLatin1Char('\\')) {
+ ++pos;
+ if (pos >= str.length())
+ break;
+ }
+ ++pos;
+ }
+ if (pos < str.length())
+ ++pos;
+ return pos;
+}
+
+#if 0
+static const char*tokStr(Token t)
+{
+ switch (t) {
+ case TOK_INVALID: return "TOK_INVALID";
+ case TOK_STRING: return "TOK_STRING";
+ case TOK_LBRACE: return "TOK_LBRACE";
+ case TOK_RBRACE: return "TOK_RBRACE";
+ case TOK_LBRACKET: return "TOK_LBRACKET";
+ case TOK_RBRACKET: return "TOK_RBRACKET";
+ case TOK_LPAREN: return "TOK_LPAREN";
+ case TOK_RPAREN: return "TOK_RPAREN";
+ case TOK_COMMA: return "TOK_COMMA";
+ case TOK_STAR: return "TOK_STAR";
+ case TOK_OR: return "TOK_OR";
+ case TOK_QUESTION: return "TOK_QUESTION";
+ case TOK_DOT: return "TOK_DOT";
+ case TOK_PLUS: return "TOK_PLUS";
+ case TOK_SEQUENCE: return "TOK_SEQUENCE";
+ case TOK_QUOTED_STRING: return "TOK_QUOTED_STRING";
+ }
+ return "";
+}
+#endif
+
+void RE2NFA::tokenize(const QString &input)
+{
+ symbols.clear();
+#if 1
+ RegExpTokenizer tokenizer(input);
+ Symbol sym;
+ int tok = tokenizer.lex();
+ while (tok != -1) {
+ Symbol sym;
+ sym.token = static_cast<Token>(tok);
+ sym.lexem = input.mid(tokenizer.lexemStart, tokenizer.lexemLength);
+
+ if (sym.token == TOK_QUOTED_STRING) {
+ sym.lexem.chop(1);
+ sym.lexem.remove(0, 1);
+ sym.token = TOK_STRING;
+ }
+
+ if (sym.token == TOK_STRING || sym.token == TOK_SEQUENCE) {
+ for (int i = 0; i < sym.lexem.length(); ++i) {
+ if (sym.lexem.at(i) == '\\') {
+ if (i >= sym.lexem.length() - 1)
+ break;
+ QChar ch = sym.lexem.at(i + 1);
+ if (ch == QLatin1Char('n')) {
+ ch = '\n';
+ } else if (ch == QLatin1Char('r')) {
+ ch = '\r';
+ } else if (ch == QLatin1Char('t')) {
+ ch = '\t';
+ } else if (ch == QLatin1Char('f')) {
+ ch = '\f';
+ }
+ sym.lexem.replace(i, 2, ch);
+ }
+ }
+ }
+
+ /*
+ if (sym.token == TOK_SEQUENCE) {
+ Symbol s;
+ s.token = TOK_LBRACKET;
+ s.lexem = "[";
+ symbols.append(s);
+
+ for (int i = 1; i < sym.lexem.length() - 1; ++i) {
+ s.token = TOK_STRING;
+ s.lexem = sym.lexem.at(i);
+ symbols.append(s);
+ }
+
+ s.token = TOK_RBRACKET;
+ s.lexem = "]";
+ symbols.append(s);
+
+ tok = tokenizer.lex();
+ continue;
+ }
+ */
+
+ symbols.append(sym);
+ tok = tokenizer.lex();
+ }
+#else
+ int pos = 0;
+ bool insideSet = false;
+ while (pos < input.length()) {
+ QChar ch = input.at(pos);
+
+ Symbol sym;
+ sym.column = pos;
+ sym.token = TOK_INVALID;
+ sym.lexem = QString(ch);
+ switch (ch.toLatin1()) {
+ case '"': {
+ if (insideSet) {
+ sym.token = TOK_STRING;
+ sym.lexem = QString(ch);
+ symbols += sym;
+ ++pos;
+ continue;
+ }
+ if (pos + 1 >= input.length())
+ return;
+ int quoteEnd = skipQuote(input, pos + 1);
+ sym.token = TOK_STRING;
+ sym.lexem = input.mid(pos + 1, quoteEnd - pos - 2);
+ symbols += sym;
+ pos = quoteEnd;
+ continue;
+ }
+ case '{':
+ sym.token = (insideSet ? TOK_STRING : TOK_LBRACE);
+ break;
+ case '}':
+ sym.token = (insideSet ? TOK_STRING : TOK_RBRACE);
+ break;
+ case '[':
+ insideSet = true;
+ sym.token = TOK_LBRACKET;
+ break;
+ case ']':
+ insideSet = false;
+ sym.token = TOK_RBRACKET;
+ break;
+ case '(':
+ sym.token = (insideSet ? TOK_STRING : TOK_LPAREN);
+ break;
+ case ')':
+ sym.token = (insideSet ? TOK_STRING : TOK_RPAREN);
+ break;
+ case ',':
+ sym.token = (insideSet ? TOK_STRING : TOK_COMMA);
+ break;
+ case '*':
+ sym.token = (insideSet ? TOK_STRING : TOK_STAR);
+ break;
+ case '|':
+ sym.token = (insideSet ? TOK_STRING : TOK_OR);
+ break;
+ case '?':
+ sym.token = (insideSet ? TOK_STRING : TOK_QUESTION);
+ break;
+ case '.':
+ sym.token = (insideSet ? TOK_STRING : TOK_DOT);
+ break;
+ case '+':
+ sym.token = (insideSet ? TOK_STRING : TOK_PLUS);
+ break;
+ case '\\':
+ ++pos;
+ if (pos >= input.length())
+ return;
+ ch = input.at(pos);
+ if (ch == QLatin1Char('n')) {
+ ch = '\n';
+ } else if (ch == QLatin1Char('r')) {
+ ch = '\r';
+ } else if (ch == QLatin1Char('t')) {
+ ch = '\t';
+ } else if (ch == QLatin1Char('f')) {
+ ch = '\f';
+ }
+ // fall through
+ default:
+ sym.token = TOK_STRING;
+ sym.lexem = QString(ch);
+ symbols += sym;
+ ++pos;
+ continue;
+ }
+ symbols += sym;
+ ++pos;
+ }
+#endif
+#if 0
+ foreach (Symbol s, symbols) {
+ qDebug() << "Tok" << tokStr(s.token) << "lexem" << s.lexem;
+ }
+#endif
+}
+
+bool RE2NFA::next(Token t)
+{
+ if (hasNext() && next() == t)
+ return true;
+ errorColumn = symbol().column;
+ Q_ASSERT(false);
+ return false;
+}
+
+bool RE2NFA::test(Token t)
+{
+ if (index >= symbols.count())
+ return false;
+ if (symbols.at(index).token == t) {
+ ++index;
+ return true;
+ }
+ return false;
+}
+
+QString RE2NFA::lexemUntil(Token t)
+{
+ QString lexem;
+ while (hasNext() && next() != t)
+ lexem += symbol().lexem;
+ return lexem;
+}
+
diff --git a/util/lexgen/re2nfa.h b/util/lexgen/re2nfa.h
new file mode 100644
index 0000000..fc10bea
--- /dev/null
+++ b/util/lexgen/re2nfa.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RE2NFA_H
+#define RE2NFA_H
+
+#include "nfa.h"
+#include <QSet>
+
+class RE2NFA
+{
+public:
+ RE2NFA(const QMap<QString, NFA> &macros, const QSet<InputType> &maxInputSet, Qt::CaseSensitivity cs);
+
+ NFA parse(const QString &expression, int *errorColumn = 0);
+
+private:
+ NFA parseExpr();
+ NFA parseBranch();
+ NFA parsePiece();
+ NFA parseAtom();
+ NFA parseMaybeQuantifier(const NFA &nfa);
+ NFA parseSet();
+ NFA parseSet2();
+
+ NFA createCharNFA();
+
+private:
+ friend class RegExpTokenizer;
+
+ enum Token {
+ TOK_INVALID,
+ TOK_STRING,
+ TOK_LBRACE, // {
+ TOK_RBRACE, // }
+ TOK_LBRACKET, // [
+ TOK_RBRACKET, // ]
+ TOK_LPAREN, // (
+ TOK_RPAREN, // )
+ TOK_COMMA,
+ TOK_STAR,
+ TOK_OR,
+ TOK_QUESTION,
+ TOK_DOT,
+ TOK_PLUS,
+ TOK_SEQUENCE,
+ TOK_QUOTED_STRING
+ };
+
+ struct Symbol
+ {
+ inline Symbol() : token(TOK_INVALID), column(-1) {}
+ inline Symbol(Token t, const QString &l = QString()) : token(t), lexem(l), column(-1) {}
+ Token token;
+ QString lexem;
+ int column;
+ };
+
+ inline bool hasNext() const { return index < symbols.count(); }
+ inline Token next() { return symbols.at(index++).token; }
+ bool next(Token t);
+ bool test(Token t);
+ inline void prev() { index--; }
+ inline const Symbol &symbol() const { return symbols.at(index - 1); }
+ QString lexemUntil(Token t);
+
+ void tokenize(const QString &input);
+
+ QMap<QString, NFA> macros;
+ QVector<Symbol> symbols;
+ int index;
+ int errorColumn;
+ const QSet<InputType> maxInputSet;
+ Qt::CaseSensitivity caseSensitivity;
+};
+
+#endif // RE2NFA_H
+
diff --git a/util/lexgen/test.lexgen b/util/lexgen/test.lexgen
new file mode 100644
index 0000000..fd532fd
--- /dev/null
+++ b/util/lexgen/test.lexgen
@@ -0,0 +1,9 @@
+[Options]
+case-insensitive
+classname = TestScanner
+
+[Tokens]
+TOK_C = [abcd]
+TOK_B = [bc]
+TOK_A = a
+
diff --git a/util/lexgen/tests/testdata/backtrack1/input b/util/lexgen/tests/testdata/backtrack1/input
new file mode 100644
index 0000000..f5099b5
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack1/input
@@ -0,0 +1 @@
+LETX
diff --git a/util/lexgen/tests/testdata/backtrack1/output b/util/lexgen/tests/testdata/backtrack1/output
new file mode 100644
index 0000000..6893deb
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack1/output
@@ -0,0 +1 @@
+TOK_LET|LET
diff --git a/util/lexgen/tests/testdata/backtrack1/rules.lexgen b/util/lexgen/tests/testdata/backtrack1/rules.lexgen
new file mode 100644
index 0000000..ade8a15
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack1/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_LET = LET
+TOK_LETXX = LETXX
diff --git a/util/lexgen/tests/testdata/backtrack2/input b/util/lexgen/tests/testdata/backtrack2/input
new file mode 100644
index 0000000..59ff5b7
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack2/input
@@ -0,0 +1 @@
+LETXTRA
diff --git a/util/lexgen/tests/testdata/backtrack2/output b/util/lexgen/tests/testdata/backtrack2/output
new file mode 100644
index 0000000..348b382
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack2/output
@@ -0,0 +1,2 @@
+TOK_LET|LET
+TOK_XTRA|XTRA
diff --git a/util/lexgen/tests/testdata/backtrack2/rules.lexgen b/util/lexgen/tests/testdata/backtrack2/rules.lexgen
new file mode 100644
index 0000000..6f16986
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack2/rules.lexgen
@@ -0,0 +1,4 @@
+[Tokens]
+TOK_LET = LET
+TOK_LETXX = LETXX
+TOK_XTRA = XTRA
diff --git a/util/lexgen/tests/testdata/casesensitivity/input b/util/lexgen/tests/testdata/casesensitivity/input
new file mode 100644
index 0000000..72b7f48
--- /dev/null
+++ b/util/lexgen/tests/testdata/casesensitivity/input
@@ -0,0 +1 @@
+abcdAbcDABCDeFgEFGefgEfghiHIHihI
diff --git a/util/lexgen/tests/testdata/casesensitivity/output b/util/lexgen/tests/testdata/casesensitivity/output
new file mode 100644
index 0000000..3a4e819
--- /dev/null
+++ b/util/lexgen/tests/testdata/casesensitivity/output
@@ -0,0 +1,14 @@
+TOK_AB|ab
+TOK_CD|cd
+TOK_AB|Ab
+TOK_CD|cD
+TOK_AB|AB
+TOK_CD|CD
+TOK_EFG|eFg
+TOK_EFG|EFG
+TOK_EFG|efg
+TOK_EFG|Efg
+TOK_HI|hi
+TOK_HI|HI
+TOK_HI|Hi
+TOK_HI|hI
diff --git a/util/lexgen/tests/testdata/casesensitivity/rules.lexgen b/util/lexgen/tests/testdata/casesensitivity/rules.lexgen
new file mode 100644
index 0000000..3347587
--- /dev/null
+++ b/util/lexgen/tests/testdata/casesensitivity/rules.lexgen
@@ -0,0 +1,7 @@
+[Options]
+case-insensitive
+[Tokens]
+TOK_AB = ab
+TOK_CD = cd
+TOK_EFG = [e-g]{3}
+TOK_HI = [hi]{2}
diff --git a/util/lexgen/tests/testdata/comments/input b/util/lexgen/tests/testdata/comments/input
new file mode 100644
index 0000000..03873e0
--- /dev/null
+++ b/util/lexgen/tests/testdata/comments/input
@@ -0,0 +1 @@
+/* comment with stuff *//*another comment with * stars * inside*/
diff --git a/util/lexgen/tests/testdata/comments/output b/util/lexgen/tests/testdata/comments/output
new file mode 100644
index 0000000..2395ad1
--- /dev/null
+++ b/util/lexgen/tests/testdata/comments/output
@@ -0,0 +1,2 @@
+TOK_COMMENT|/* comment with stuff */
+TOK_COMMENT|/*another comment with * stars * inside*/
diff --git a/util/lexgen/tests/testdata/comments/rules.lexgen b/util/lexgen/tests/testdata/comments/rules.lexgen
new file mode 100644
index 0000000..490c759
--- /dev/null
+++ b/util/lexgen/tests/testdata/comments/rules.lexgen
@@ -0,0 +1,2 @@
+[Tokens]
+TOK_COMMENT = \/\*[^*]*\*+([^/*][^*]*\*+)*\/
diff --git a/util/lexgen/tests/testdata/dot/input b/util/lexgen/tests/testdata/dot/input
new file mode 100644
index 0000000..e5b0ad6
--- /dev/null
+++ b/util/lexgen/tests/testdata/dot/input
@@ -0,0 +1 @@
+afbcxd
diff --git a/util/lexgen/tests/testdata/dot/output b/util/lexgen/tests/testdata/dot/output
new file mode 100644
index 0000000..6a9afd4
--- /dev/null
+++ b/util/lexgen/tests/testdata/dot/output
@@ -0,0 +1,2 @@
+TOK_AB|afb
+TOK_CD|cxd
diff --git a/util/lexgen/tests/testdata/dot/rules.lexgen b/util/lexgen/tests/testdata/dot/rules.lexgen
new file mode 100644
index 0000000..03873a7
--- /dev/null
+++ b/util/lexgen/tests/testdata/dot/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_AB = a.b
+TOK_CD = c.d
diff --git a/util/lexgen/tests/testdata/negation/input b/util/lexgen/tests/testdata/negation/input
new file mode 100644
index 0000000..9447b80
--- /dev/null
+++ b/util/lexgen/tests/testdata/negation/input
@@ -0,0 +1 @@
+aycabd
diff --git a/util/lexgen/tests/testdata/negation/output b/util/lexgen/tests/testdata/negation/output
new file mode 100644
index 0000000..0b73263
--- /dev/null
+++ b/util/lexgen/tests/testdata/negation/output
@@ -0,0 +1,2 @@
+TOK_A|ayc
+TOK_B|abd
diff --git a/util/lexgen/tests/testdata/negation/rules.lexgen b/util/lexgen/tests/testdata/negation/rules.lexgen
new file mode 100644
index 0000000..179810b
--- /dev/null
+++ b/util/lexgen/tests/testdata/negation/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_A = a[^b]c
+TOK_B = abd
diff --git a/util/lexgen/tests/testdata/quoteinset/input b/util/lexgen/tests/testdata/quoteinset/input
new file mode 100644
index 0000000..5a9b680
--- /dev/null
+++ b/util/lexgen/tests/testdata/quoteinset/input
@@ -0,0 +1 @@
+"a
diff --git a/util/lexgen/tests/testdata/quoteinset/output b/util/lexgen/tests/testdata/quoteinset/output
new file mode 100644
index 0000000..7ba8890
--- /dev/null
+++ b/util/lexgen/tests/testdata/quoteinset/output
@@ -0,0 +1 @@
+TOK_QUOTEA|"a
diff --git a/util/lexgen/tests/testdata/quoteinset/rules.lexgen b/util/lexgen/tests/testdata/quoteinset/rules.lexgen
new file mode 100644
index 0000000..9838276
--- /dev/null
+++ b/util/lexgen/tests/testdata/quoteinset/rules.lexgen
@@ -0,0 +1,2 @@
+[Tokens]
+TOK_QUOTEA = ["]a
diff --git a/util/lexgen/tests/testdata/quotes/input b/util/lexgen/tests/testdata/quotes/input
new file mode 100644
index 0000000..ac54450
--- /dev/null
+++ b/util/lexgen/tests/testdata/quotes/input
@@ -0,0 +1 @@
+quotedstring
diff --git a/util/lexgen/tests/testdata/quotes/output b/util/lexgen/tests/testdata/quotes/output
new file mode 100644
index 0000000..c538e32
--- /dev/null
+++ b/util/lexgen/tests/testdata/quotes/output
@@ -0,0 +1 @@
+TOK_STR|quotedstring
diff --git a/util/lexgen/tests/testdata/quotes/rules.lexgen b/util/lexgen/tests/testdata/quotes/rules.lexgen
new file mode 100644
index 0000000..d528cdd
--- /dev/null
+++ b/util/lexgen/tests/testdata/quotes/rules.lexgen
@@ -0,0 +1,2 @@
+[Tokens]
+TOK_STR = "quotedstring"
diff --git a/util/lexgen/tests/testdata/simple/input b/util/lexgen/tests/testdata/simple/input
new file mode 100644
index 0000000..acbe86c
--- /dev/null
+++ b/util/lexgen/tests/testdata/simple/input
@@ -0,0 +1 @@
+abcd
diff --git a/util/lexgen/tests/testdata/simple/output b/util/lexgen/tests/testdata/simple/output
new file mode 100644
index 0000000..a37a58e
--- /dev/null
+++ b/util/lexgen/tests/testdata/simple/output
@@ -0,0 +1,2 @@
+TOK_AB|ab
+TOK_CD|cd
diff --git a/util/lexgen/tests/testdata/simple/rules.lexgen b/util/lexgen/tests/testdata/simple/rules.lexgen
new file mode 100644
index 0000000..5d958c4
--- /dev/null
+++ b/util/lexgen/tests/testdata/simple/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_AB = ab
+TOK_CD = cd
diff --git a/util/lexgen/tests/testdata/subsets1/input b/util/lexgen/tests/testdata/subsets1/input
new file mode 100644
index 0000000..47f66d1
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets1/input
@@ -0,0 +1 @@
+abaf
diff --git a/util/lexgen/tests/testdata/subsets1/output b/util/lexgen/tests/testdata/subsets1/output
new file mode 100644
index 0000000..75dd936
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets1/output
@@ -0,0 +1,2 @@
+TOK_AB|ab
+TOK_AZ|af
diff --git a/util/lexgen/tests/testdata/subsets1/rules.lexgen b/util/lexgen/tests/testdata/subsets1/rules.lexgen
new file mode 100644
index 0000000..94f51a9
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets1/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_AB = ab
+TOK_AZ = a[a-z]
diff --git a/util/lexgen/tests/testdata/subsets2/input b/util/lexgen/tests/testdata/subsets2/input
new file mode 100644
index 0000000..4d0dc3a
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets2/input
@@ -0,0 +1 @@
+abd
diff --git a/util/lexgen/tests/testdata/subsets2/output b/util/lexgen/tests/testdata/subsets2/output
new file mode 100644
index 0000000..d5a7bc5
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets2/output
@@ -0,0 +1,3 @@
+TOK_A|a
+TOK_B|b
+TOK_D|d
diff --git a/util/lexgen/tests/testdata/subsets2/rules.lexgen b/util/lexgen/tests/testdata/subsets2/rules.lexgen
new file mode 100644
index 0000000..e0a7629
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets2/rules.lexgen
@@ -0,0 +1,4 @@
+[Tokens]
+TOK_D = [abcd]
+TOK_B = [bc]
+TOK_A = a
diff --git a/util/lexgen/tests/tests.pro b/util/lexgen/tests/tests.pro
new file mode 100644