diff options
48 files changed, 2560 insertions, 178 deletions
@@ -7577,6 +7577,9 @@ FNR == 1 { if ( \$3 == "moc" || \$3 ~ /^Qt/ ) { target_file = first matched_target = 1 + } else if ( \$3 == "lrelease" || \$3 == "qm_phony_target" ) { + target_file = second + matched_target = 1 } } @@ -7661,6 +7664,7 @@ for part in $CFG_BUILD_PARTS; do case "$part" in tools) PART_ROOTS="$PART_ROOTS tools" ;; libs) PART_ROOTS="$PART_ROOTS src" ;; + translations) PART_ROOTS="$PART_ROOTS tools/linguist/lrelease translations" ;; examples) PART_ROOTS="$PART_ROOTS examples demos" ;; *) ;; esac @@ -7688,7 +7692,7 @@ for file in .projects .projects.3; do *s60main/s60main.pro) continue ;; *examples/activeqt/*) continue ;; */qmake/qmake.pro) continue ;; - *tools/bootstrap*|*tools/moc*|*tools/rcc*|*tools/uic*) SPEC=$QMAKESPEC ;; + *tools/bootstrap*|*tools/moc*|*tools/rcc*|*tools/uic*|*linguist/lrelease*) SPEC=$QMAKESPEC ;; *) SPEC=$XQMAKESPEC ;; esac dir=`dirname "$a" | sed -e "s;$sepath;.;g"` diff --git a/configure.exe b/configure.exe Binary files differindex 7fe4a93..77c7863 100755 --- a/configure.exe +++ b/configure.exe diff --git a/projects.pro b/projects.pro index aa1eb71..497acd0 100644 --- a/projects.pro +++ b/projects.pro @@ -45,7 +45,12 @@ for(PROJECT, $$list($$lower($$unique(QT_BUILD_PARTS)))) { } else:isEqual(PROJECT, docs) { contains(QT_BUILD_PARTS, tools):include(doc/doc.pri) } else:isEqual(PROJECT, translations) { - contains(QT_BUILD_PARTS, tools):include(translations/translations.pri) + contains(QT_BUILD_PARTS, tools) { + include(translations/translations.pri) # ts targets + } else { + SUBDIRS += tools/linguist/lrelease + } + SUBDIRS += translations # qm build step } else:isEqual(PROJECT, qmake) { # SUBDIRS += qmake } else { diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index 77785e8..1c52d4c 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -217,6 +217,9 @@ // Session Manager //#define QT_NO_SESSIONMANAGER +// QSettings +//#define QT_NO_SETTINGS + // QSharedMemory //#define QT_NO_SHAREDMEMORY @@ -352,6 +355,11 @@ #define QT_NO_IMAGEFORMAT_XPM #endif +// QLibrary +#if !defined(QT_NO_LIBRARY) && (defined(QT_NO_SETTINGS)) +#define QT_NO_LIBRARY +#endif + // QMenu #if !defined(QT_NO_MENU) && (defined(QT_NO_ACTION)) #define QT_NO_MENU @@ -367,6 +375,11 @@ #define QT_NO_PHONON_SEEKSLIDER #endif +// Phonon::AbstractMediaStream +#if !defined(QT_NO_PHONON_SETTINGSGROUP) && (defined(QT_NO_SETTINGS)) +#define QT_NO_PHONON_SETTINGSGROUP +#endif + // Phonon::VideoPlayer #if !defined(QT_NO_PHONON_VIDEOPLAYER) && (defined(QT_NO_PHONON_VIDEO)) #define QT_NO_PHONON_VIDEOPLAYER @@ -422,11 +435,6 @@ #define QT_NO_SCROLLBAR #endif -// QSettings -#if !defined(QT_NO_SETTINGS) && (defined(QT_NO_TEXTSTREAM)) -#define QT_NO_SETTINGS -#endif - // SOCKS5 #if !defined(QT_NO_SOCKS5) && (defined(QT_NO_NETWORKPROXY)) #define QT_NO_SOCKS5 @@ -507,14 +515,14 @@ #define QT_NO_HTTP #endif -// QLibrary -#if !defined(QT_NO_LIBRARY) && (defined(QT_NO_SETTINGS)) -#define QT_NO_LIBRARY +// QInputContext +#if !defined(QT_NO_IM) && (defined(QT_NO_LIBRARY)) +#define QT_NO_IM #endif -// Phonon::AbstractMediaStream -#if !defined(QT_NO_PHONON_SETTINGSGROUP) && (defined(QT_NO_SETTINGS)) -#define QT_NO_PHONON_SETTINGSGROUP +// Phonon::PlatformPlugin +#if !defined(QT_NO_PHONON_PLATFORMPLUGIN) && (defined(QT_NO_LIBRARY)) +#define QT_NO_PHONON_PLATFORMPLUGIN #endif // QScrollArea @@ -562,21 +570,11 @@ #define QT_NO_GRAPHICSVIEW #endif -// QInputContext -#if !defined(QT_NO_IM) && (defined(QT_NO_LIBRARY)) -#define QT_NO_IM -#endif - // QMdiArea #if !defined(QT_NO_MDIAREA) && (defined(QT_NO_SCROLLAREA)) #define QT_NO_MDIAREA #endif -// Phonon::PlatformPlugin -#if !defined(QT_NO_PHONON_PLATFORMPLUGIN) && (defined(QT_NO_LIBRARY)) -#define QT_NO_PHONON_PLATFORMPLUGIN -#endif - // Phonon::VolumeSlider #if !defined(QT_NO_PHONON_VOLUMESLIDER) && (defined(QT_NO_SLIDER) || defined(QT_NO_TOOLBUTTON)) #define QT_NO_PHONON_VOLUMESLIDER @@ -587,6 +585,11 @@ #define QT_NO_PRINTER #endif +// QWSInputMethod +#if !defined(QT_NO_QWS_INPUTMETHODS) && (defined(QT_NO_IM)) +#define QT_NO_QWS_INPUTMETHODS +#endif + // QSpinBox #if !defined(QT_NO_SPINBOX) && (defined(QT_NO_SPINWIDGET) || defined(QT_NO_LINEEDIT) || defined(QT_NO_VALIDATOR)) #define QT_NO_SPINBOX @@ -627,6 +630,11 @@ #define QT_NO_TABDIALOG #endif +// QTextCodecPlugin +#if !defined(QT_NO_TEXTCODECPLUGIN) && (defined(QT_NO_TEXTCODEC) || defined(QT_NO_LIBRARY)) +#define QT_NO_TEXTCODECPLUGIN +#endif + // QColorDialog #if !defined(QT_NO_COLORDIALOG) && (defined(QT_NO_SPINBOX)) #define QT_NO_COLORDIALOG @@ -647,11 +655,6 @@ #define QT_NO_MENUBAR #endif -// QWSInputMethod -#if !defined(QT_NO_QWS_INPUTMETHODS) && (defined(QT_NO_IM)) -#define QT_NO_QWS_INPUTMETHODS -#endif - // Sound Server #if !defined(QT_NO_QWS_SOUNDSERVER) && (defined(QT_NO_SOUND) || defined(QT_NO_HOSTINFO) || defined(QT_NO_QWS_MULTIPROCESS)) #define QT_NO_QWS_SOUNDSERVER @@ -672,11 +675,6 @@ #define QT_NO_TABWIDGET #endif -// QTextCodecPlugin -#if !defined(QT_NO_TEXTCODECPLUGIN) && (defined(QT_NO_TEXTCODEC) || defined(QT_NO_LIBRARY)) -#define QT_NO_TEXTCODECPLUGIN -#endif - // QTextEdit #if !defined(QT_NO_TEXTEDIT) && (defined(QT_NO_SCROLLAREA) || defined(QT_NO_PROPERTIES)) #define QT_NO_TEXTEDIT @@ -757,6 +755,11 @@ #define QT_NO_COMPLETER #endif +// Common UNIX Printing System +#if !defined(QT_NO_CUPS) && (defined(QT_NO_PRINTER) || defined(QT_NO_LIBRARY)) +#define QT_NO_CUPS +#endif + // QDataWidgetMapper #if !defined(QT_NO_DATAWIDGETMAPPER) && (defined(QT_NO_ITEMVIEWS) || defined(QT_NO_PROPERTIES)) #define QT_NO_DATAWIDGETMAPPER @@ -787,11 +790,6 @@ #define QT_NO_TREEWIDGET #endif -// Common UNIX Printing System -#if !defined(QT_NO_CUPS) && (defined(QT_NO_PRINTER) || defined(QT_NO_LIBRARY)) -#define QT_NO_CUPS -#endif - // QDirModel #if !defined(QT_NO_DIRMODEL) && (defined(QT_NO_ITEMVIEWS) || defined(QT_NO_FILESYSTEMMODEL)) #define QT_NO_DIRMODEL diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index ec4945f..251391e 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -216,7 +216,7 @@ SeeAlso: ??? Feature: SETTINGS Description: Supports persistent application settings. Section: File I/O -Requires: TEXTSTREAM +Requires: Name: QSettings SeeAlso: ??? diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 15325ae..77a86bb 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -46,7 +46,11 @@ #include "qlibraryinfo.h" #include "qscopedpointer.h" -#ifdef QT_BUILD_QMAKE +#if defined(QT_BUILD_QMAKE) || defined(QT_BOOTSTRAPPED) +# define BOOTSTRAPPING +#endif + +#ifdef BOOTSTRAPPING QT_BEGIN_NAMESPACE extern QString qmake_libraryInfoFile(); QT_END_NAMESPACE @@ -91,7 +95,7 @@ public: QLibrarySettings::QLibrarySettings() : settings(QLibraryInfoPrivate::findConfiguration()) { -#ifndef QT_BUILD_QMAKE +#ifndef BOOTSTRAPPING qAddPostRoutine(QLibraryInfoPrivate::cleanup); #endif } @@ -99,7 +103,7 @@ QLibrarySettings::QLibrarySettings() QSettings *QLibraryInfoPrivate::findConfiguration() { QString qtconfig = QLatin1String(":/qt/etc/qt.conf"); -#ifdef QT_BUILD_QMAKE +#ifdef BOOTSTRAPPING if(!QFile::exists(qtconfig)) qtconfig = qmake_libraryInfoFile(); #else @@ -425,7 +429,7 @@ QLibraryInfo::location(LibraryLocation loc) if (QDir::isRelativePath(ret)) { if (loc == PrefixPath) { // we make the prefix path absolute to the executable's directory -#ifdef QT_BUILD_QMAKE +#ifdef BOOTSTRAPPING return QFileInfo(qmake_libraryInfoFile()).absolutePath(); #else if (QCoreApplication::instance()) { diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index 19e86a6..b10d603 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -42,7 +42,7 @@ #include "qdatastream.h" #include "qdatastream_p.h" -#ifndef QT_NO_DATASTREAM +#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) #include "qbuffer.h" #include "qstring.h" #include <stdio.h> diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h index f61a59c..2e4e7c1 100644 --- a/src/corelib/io/qdatastream.h +++ b/src/corelib/io/qdatastream.h @@ -66,7 +66,7 @@ template <typename T> class QSet; template <class Key, class T> class QHash; template <class Key, class T> class QMap; -#ifndef QT_NO_DATASTREAM +#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) class QDataStreamPrivate; class Q_CORE_EXPORT QDataStream { diff --git a/src/corelib/io/qdatastream_p.h b/src/corelib/io/qdatastream_p.h index 157fee9..98dd21f 100644 --- a/src/corelib/io/qdatastream_p.h +++ b/src/corelib/io/qdatastream_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_DATASTREAM +#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) class QDataStreamPrivate { public: diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index d8557e5..f4fdd26 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -48,9 +48,7 @@ #include "qlocale_p.h" #include "qunicodetables_p.h" #include "qscopedpointer.h" -#ifndef QT_NO_DATASTREAM #include <qdatastream.h> -#endif #ifndef QT_NO_COMPRESS #include <zlib.h> @@ -2640,7 +2638,7 @@ void QByteArray::clear() d->ref.ref(); } -#ifndef QT_NO_DATASTREAM +#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) /*! \relates QByteArray diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index e258481..e6b828d 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -572,7 +572,7 @@ inline QByteArray &QByteArray::setNum(float n, char f, int prec) { return setNum(double(n),f,prec); } -#ifndef QT_NO_DATASTREAM +#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QByteArray &); Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QByteArray &); #endif diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index f7321ef..3b358a2 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -7204,7 +7204,7 @@ QString QString::fromRawData(const QChar *unicode, int size) */ -#ifndef QT_NO_DATASTREAM +#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) /*! \fn QDataStream &operator<<(QDataStream &stream, const QString &string) \relates QString diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 74f93a4..55d6d03 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1065,7 +1065,7 @@ inline QChar &QString::ref(uint i) } #endif -#ifndef QT_NO_DATASTREAM +#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QString &); Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QString &); #endif diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 4aa358f..5a14cfe 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -11866,8 +11866,7 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) isVisible() returns false for a widget, that widget cannot call grabMouse(). - \sa releaseMouse() grabKeyboard() releaseKeyboard() grabKeyboard() - focusWidget() + \sa releaseMouse() grabKeyboard() releaseKeyboard() */ /*! diff --git a/src/tools/bootstrap/bootstrap.pri b/src/tools/bootstrap/bootstrap.pri index b4f9b2f..b3ee948 100644 --- a/src/tools/bootstrap/bootstrap.pri +++ b/src/tools/bootstrap/bootstrap.pri @@ -38,7 +38,7 @@ DEPENDPATH += $$INCLUDEPATH \ $$QT_SOURCE_TREE/src/xml hpux-acc*|hpuxi-acc* { - LIBS += ../bootstrap/libbootstrap.a + LIBS += $$QT_BUILD_TREE/src/tools/bootstrap/libbootstrap.a } else { contains(CONFIG, debug_and_release_target) { CONFIG(debug, debug|release) { diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 1f81a6c..722981c 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -31,6 +31,7 @@ win32:DEFINES += QT_NODLL INCLUDEPATH += $$QT_BUILD_TREE/include \ $$QT_BUILD_TREE/include/QtCore \ $$QT_BUILD_TREE/include/QtXml \ + $$QT_BUILD_TREE/src/corelib/global # qlibraryinfo.cpp includes qconfig.cpp DEPENDPATH += $$INCLUDEPATH \ ../../corelib/global \ @@ -48,10 +49,12 @@ SOURCES += \ ../../corelib/codecs/qtsciicodec.cpp \ ../../corelib/codecs/qutfcodec.cpp \ ../../corelib/global/qglobal.cpp \ + ../../corelib/global/qlibraryinfo.cpp \ ../../corelib/global/qmalloc.cpp \ ../../corelib/global/qnumeric.cpp \ ../../corelib/io/qabstractfileengine.cpp \ ../../corelib/io/qbuffer.cpp \ + ../../corelib/io/qdatastream.cpp \ ../../corelib/io/qdir.cpp \ ../../corelib/io/qdiriterator.cpp \ ../../corelib/io/qfile.cpp \ @@ -62,6 +65,7 @@ SOURCES += \ ../../corelib/io/qtemporaryfile.cpp \ ../../corelib/io/qtextstream.cpp \ ../../corelib/io/qurl.cpp \ + ../../corelib/io/qsettings.cpp \ ../../corelib/kernel/qmetatype.cpp \ ../../corelib/kernel/qvariant.cpp \ ../../corelib/tools/qbitarray.cpp \ @@ -86,11 +90,12 @@ unix:SOURCES += ../../corelib/io/qfsfileengine_unix.cpp \ ../../corelib/io/qfsfileengine_iterator_unix.cpp win32:SOURCES += ../../corelib/io/qfsfileengine_win.cpp \ - ../../corelib/io/qfsfileengine_iterator_win.cpp + ../../corelib/io/qfsfileengine_iterator_win.cpp \ + ../../corelib/io/qsettings_win.cpp macx: { QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported) - SOURCES += ../../corelib/kernel/qcore_mac.cpp + SOURCES += ../../corelib/kernel/qcore_mac.cpp ../../corelib/io/qsettings_mac.cpp LIBS += -framework CoreServices } diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 1690c2e..74a4b9d 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -670,10 +670,13 @@ void WriteInitialization::acceptWidget(DomWidget *node) m_layoutWidget = false; if (className == QLatin1String("QWidget") && !node->hasAttributeNative()) { - if (m_widgetChain.top() - && m_widgetChain.top()->attributeClass() != QLatin1String("QMainWindow") - && !m_uic->isContainer(m_widgetChain.top()->attributeClass())) + if (const DomWidget* parentWidget = m_widgetChain.top()) { + const QString parentClass = parentWidget->attributeClass(); + if (parentClass != QLatin1String("QMainWindow") + && !m_uic->isCustomWidgetContainer(parentClass) + && !m_uic->isContainer(parentClass)) m_layoutWidget = true; + } } m_widgetChain.push(node); m_layoutChain.push(0); diff --git a/src/tools/uic/customwidgetsinfo.cpp b/src/tools/uic/customwidgetsinfo.cpp index 70adba2..ca3fd19 100644 --- a/src/tools/uic/customwidgetsinfo.cpp +++ b/src/tools/uic/customwidgetsinfo.cpp @@ -88,6 +88,14 @@ bool CustomWidgetsInfo::extends(const QString &classNameIn, const QLatin1String return false; } +bool CustomWidgetsInfo::isCustomWidgetContainer(const QString &className) const +{ + if (const DomCustomWidget *dcw = m_customWidgets.value(className, 0)) + if (dcw->hasElementContainer()) + return dcw->elementContainer() != 0; + return false; +} + QString CustomWidgetsInfo::realClassName(const QString &className) const { if (className == QLatin1String("Line")) diff --git a/src/tools/uic/customwidgetsinfo.h b/src/tools/uic/customwidgetsinfo.h index 1471118..d5be5a2 100644 --- a/src/tools/uic/customwidgetsinfo.h +++ b/src/tools/uic/customwidgetsinfo.h @@ -78,6 +78,8 @@ public: bool extends(const QString &className, const QLatin1String &baseClassName) const; + bool isCustomWidgetContainer(const QString &className) const; + private: typedef QMap<QString, DomCustomWidget*> NameCustomWidgetMap; NameCustomWidgetMap m_customWidgets; diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index 32e5e3d..71b6ac1 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -363,6 +363,11 @@ bool Uic::isContainer(const QString &className) const || customWidgetsInfo()->extends(className, QLatin1String("QDockWidget")); } +bool Uic::isCustomWidgetContainer(const QString &className) const +{ + return customWidgetsInfo()->isCustomWidgetContainer(className); +} + bool Uic::isStatusBar(const QString &className) const { return customWidgetsInfo()->extends(className, QLatin1String("QStatusBar")); diff --git a/src/tools/uic/uic.h b/src/tools/uic/uic.h index 3e072a4..5175ea9 100644 --- a/src/tools/uic/uic.h +++ b/src/tools/uic/uic.h @@ -115,6 +115,7 @@ public: bool isStatusBar(const QString &className) const; bool isButton(const QString &className) const; bool isContainer(const QString &className) const; + bool isCustomWidgetContainer(const QString &className) const; bool isMenuBar(const QString &className) const; bool isMenu(const QString &className) const; diff --git a/src/tools/uic3/uic.cpp b/src/tools/uic3/uic.cpp index 7872866..6761eaf 100644 --- a/src/tools/uic3/uic.cpp +++ b/src/tools/uic3/uic.cpp @@ -322,6 +322,11 @@ bool Uic::isContainer(const QString &className) const || customWidgetsInfo()->extends(className, QLatin1String("QDockWidget")); } +bool Uic::isCustomWidgetContainer(const QString &className) const +{ + return customWidgetsInfo()->isCustomWidgetContainer(className); +} + bool Uic::isStatusBar(const QString &className) const { return customWidgetsInfo()->extends(className, QLatin1String("QStatusBar")); diff --git a/src/tools/uic3/uic.h b/src/tools/uic3/uic.h index 50aa71c..63a1f8d 100644 --- a/src/tools/uic3/uic.h +++ b/src/tools/uic3/uic.h @@ -114,6 +114,7 @@ public: bool isStatusBar(const QString &className) const; bool isButton(const QString &className) const; bool isContainer(const QString &className) const; + bool isCustomWidgetContainer(const QString &className) const; bool isMenuBar(const QString &className) const; bool isMenu(const QString &className) const; diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 46f26f8..da1f7ca 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -10,7 +10,8 @@ TEMPLATE = subdirs linguist \ moc \ uic \ - uic3 + uic3 \ + guiapplauncher Q3SUBDIRS += \ q3accel \ q3action \ diff --git a/tests/auto/guiapplauncher/README.txt b/tests/auto/guiapplauncher/README.txt new file mode 100644 index 0000000..317f9d0 --- /dev/null +++ b/tests/auto/guiapplauncher/README.txt @@ -0,0 +1,14 @@ +This test launches gui applications (tools, demos and prominent examples), +keeps them running a while (grabbing their top level from the window manager) +and sends them a Close event via window manager. + +It checks that they do not crash nor produce unexpected error output. + +Note: Do not play with the machine while it is running as otherwise +the top-level find algorithm might get confused (especially on Windows). + +Environment variables are checked to turned off some tests (see code). + +It is currently implemented for X11 (Skips unless DISPLAY is set) and +Windows, pending an implementation of the WindowManager class and deployment +on the other platforms. diff --git a/tests/auto/guiapplauncher/guiapplauncher.pro b/tests/auto/guiapplauncher/guiapplauncher.pro new file mode 100644 index 0000000..27c3553 --- /dev/null +++ b/tests/auto/guiapplauncher/guiapplauncher.pro @@ -0,0 +1,20 @@ +# ------------------------------------------------- +# Project created by QtCreator 2009-11-10T14:39:06 +# ------------------------------------------------- + +# Link against gui for X11,etc. + +DEFINES += SRCDIR=\\\"$$PWD/\\\" +TARGET = tst_guiapplauncher +CONFIG += console +CONFIG -= app_bundle +CONFIG += qtestlib +TEMPLATE = app +SOURCES += tst_guiapplauncher.cpp \ + windowmanager.cpp +HEADERS += windowmanager.h + +win32 { + # process enumeration,etc. + LIBS+=user32.lib +} diff --git a/tests/auto/guiapplauncher/test.ts b/tests/auto/guiapplauncher/test.ts new file mode 100644 index 0000000..79c9c76 --- /dev/null +++ b/tests/auto/guiapplauncher/test.ts @@ -0,0 +1,973 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="de"> +<context> + <name>AssistantServer</name> + <message> + <location filename="../tools/assistant/compat/main.cpp" line="+225"/> + <source>Qt Assistant</source> + <translation>Qt Assistant</translation> + </message> + <message> + <location line="+1"/> + <source>Failed to bind to port %1</source> + <translation>Kann Port %1 nicht binden</translation> + </message> +</context> +<context> + <name>FontPanel</name> + <message> + <location filename="../tools/shared/fontpanel/fontpanel.cpp" line="+63"/> + <source>Font</source> + <translation>Schrift</translation> + </message> + <message> + <location line="+11"/> + <source>&Writing system</source> + <translation>S&kript</translation> + </message> + <message> + <location line="+3"/> + <source>&Family</source> + <translation>&Schriftart</translation> + </message> + <message> + <location line="+4"/> + <source>&Style</source> + <translation>S&chriftschnitt</translation> + </message> + <message> + <location line="+4"/> + <source>&Point size</source> + <translation>Schriftg&rad</translation> + </message> +</context> +<context> + <name>FontSettingsDialog</name> + <message> + <location filename="../tools/assistant/compat/fontsettingsdialog.cpp" line="+63"/> + <source>Font Settings</source> + <translation>Schriftart</translation> + </message> + <message> + <location line="+7"/> + <source>Font settings for:</source> + <translation>Schriftart für:</translation> + </message> + <message> + <location line="+4"/> + <source>Browser</source> + <translation>Hilfeseiten</translation> + </message> + <message> + <location line="+1"/> + <source>Application</source> + <translation>Anwendung</translation> + </message> + <message> + <location line="+6"/> + <source>Use custom settings</source> + <translation>Erweitere Einstellungen nutzen</translation> + </message> +</context> +<context> + <name>HelpDialog</name> + <message> + <location filename="../tools/assistant/compat/helpdialog.ui"/> + <source>Con&tents</source> + <translation>Inhal&t</translation> + </message> + <message> + <location filename="../tools/assistant/compat/helpdialog.cpp" line="+376"/> + <location line="+16"/> + <location line="+661"/> + <source>Qt Assistant</source> + <translation>Qt Assistant</translation> + </message> + <message> + <location line="-771"/> + <source>Open Link in New Window</source> + <translation>Öffne Link in neuem Fenster</translation> + </message> + <message> + <location line="+76"/> + <location line="+82"/> + <source>Prepare...</source> + <translation>Initialisiere...</translation> + </message> + <message> + <location line="-47"/> + <source>Cannot open the index file %1</source> + <translation>Kann Indexdatei %1 nicht öffnen</translation> + </message> + <message> + <location line="+58"/> + <location line="+124"/> + <location line="+8"/> + <source>Warning</source> + <translation>Warnung</translation> + </message> + <message> + <location line="-131"/> + <location line="+124"/> + <source>Documentation file %1 does not exist! +Skipping file.</source> + <translation>Dokumentation %1 existiert nicht! +Überspringe Datei.</translation> + </message> + <message> + <location line="-112"/> + <location line="+133"/> + <source>Parse Error</source> + <translation>Syntaxfehler</translation> + </message> + <message> + <location line="+35"/> + <location line="+469"/> + <source>Done</source> + <translation>Fertig</translation> + </message> + <message> + <location line="-18"/> + <source>Indexing files...</source> + <translation>Indiziere Dokumentation...</translation> + </message> + <message> + <location line="+15"/> + <source>Reading dictionary...</source> + <translation>Lese Suchindex...</translation> + </message> + <message> + <location line="+46"/> + <location line="+9"/> + <source>Full Text Search</source> + <translation>Volltextsuche</translation> + </message> + <message> + <location line="-8"/> + <source>Using a wildcard within phrases is not allowed.</source> + <translation>Wildcards innerhalb von Phrasen sind nicht zugelassen.</translation> + </message> + <message> + <location line="+9"/> + <source>The closing quotation mark is missing.</source> + <translation>Das schließende Anführungszeichen fehlt.</translation> + </message> + <message numerus="yes"> + <location line="+7"/> + <source>%n document(s) found.</source> + <translation> + <numerusform>%n Dokumente gefunden.</numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location line="-882"/> + <source>Open Link in Current Tab</source> + <translation>Link im Aktuellen Tab öffnen</translation> + </message> + <message> + <location line="+6"/> + <source>Open Link in New Tab</source> + <translation>Link in einem neuen Tab öffnen</translation> + </message> + <message> + <location line="+91"/> + <source>Failed to load keyword index file +Assistant will not work!</source> + <translation>Die Indexdatei konnte nicht geladen werden. +Der Assistent ist nicht einsatzbereit!</translation> + </message> + <message> + <location line="+208"/> + <source>Documentation file %1 is not compatible! +Skipping file.</source> + <translation>Dokumentation %1 ist nicht kompatibel! Datei wird übersprungen.</translation> + </message> + <message> + <location line="+470"/> + <source>Failed to save fulltext search index +Assistant will not work!</source> + <translation>Der Index für die Volltextsuche konnte nicht gespeichert werden. +Assistent ist nicht einsatzbereit!</translation> + </message> + <message> + <location filename="../tools/assistant/compat/helpdialog.ui"/> + <source>Help</source> + <translation>Hilfe</translation> + </message> + <message> + <location/> + <source><b>Help</b><p>Choose the topic you want help on from the contents list, or search the index for keywords.</p></source> + <translation><b>Hilfe</b><p>Wählen Sie ein Hilfethema aus dem Inhalt oder suchen Sie im Index nach Schlüsselwörtern.</p></translation> + </message> + <message> + <location/> + <source>Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search.</source> + <translation>Zeigt Hilfethemen geordnet nach Kategorie, Index oder Lesezeichen an. Ein weiterer Abschnitt enthält die Volltextsuche.</translation> + </message> + <message> + <location/> + <source><b>Help topics organized by category.</b><p>Double-click an item to see the topics in that category. To view a topic, just double-click it.</p></source> + <translation><b>Hilfethemen geordnet nach Kategorie.</b><p>Doppelklicken Sie einen Eintrag, um die Themen dieser Kategorie zu sehen. Doppelklicken Sie ein Thema, um es angezeigt zu bekommen.</p></translation> + </message> + <message> + <location/> + <source>column 1</source> + <translation>Spalte 1</translation> + </message> + <message> + <location/> + <source>&Index</source> + <translation>&Index</translation> + </message> + <message> + <location/> + <source>&Look For:</source> + <translation>Suchen &nach:</translation> + </message> + <message> + <location/> + <source>Enter keyword</source> + <translation>Geben Sie ein Schlüsselwort ein</translation> + </message> + <message> + <location/> + <source><b>Enter a keyword.</b><p>The list will select an item that matches the entered string best.</p></source> + <translation><b>Geben Sie ein Schlüsselwort ein.</b><p>Es wird dann der Eintrag aus der Liste ausgewählt, der am besten mit dem eingegebenen Begriff übereinstimmt.</p></translation> + </message> + <message> + <location/> + <source><b>List of available help topics.</b><p>Double-click on an item to open its help page. If more than one is found, you must specify which page you want.</p></source> + <translation><b>Liste aller verfügbaren Hilfethemen.</b><p>Doppelklicken Sie auf einen Eintrag, um die Hilfe zu öffnen. Wenn mehr als eine Seite gefunden wurde, wählen Sie die gewünschte Seite aus.</p></translation> + </message> + <message> + <location/> + <source>&Bookmarks</source> + <translation>L&esezeichen</translation> + </message> + <message> + <location/> + <source>Displays the list of bookmarks.</source> + <translation>Zeigt alle Lesezeichen an.</translation> + </message> + <message> + <location/> + <source>Add new bookmark</source> + <translation>Füge neues Lesezeichen hinzu</translation> + </message> + <message> + <location/> + <source>Add the currently displayed page as a new bookmark.</source> + <translation>Füge aktuelle Seite zu den Lesezeichen hinzu.</translation> + </message> + <message> + <location/> + <source>&New</source> + <translation>&Neu</translation> + </message> + <message> + <location/> + <source>Delete bookmark</source> + <translation>Lösche Lesezeichen</translation> + </message> + <message> + <location/> + <source>Delete the selected bookmark.</source> + <translation>Lösche markiertes Lesezeichen.</translation> + </message> + <message> + <location/> + <source>&Delete</source> + <translation>&Löschen</translation> + </message> + <message> + <location/> + <source>&Search</source> + <translation>&Suche</translation> + </message> + <message> + <location/> + <source>Searching f&or:</source> + <translation>Suche &nach:</translation> + </message> + <message> + <location/> + <source><b>Enter search word(s).</b><p>Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.</p></source> + <translation><b>Geben Sie Suchbegriffe ein.</b><p>Geben Sie hier die gesuchten Begriffe ein. Die Begriffe können Wildcards (*) enthalten. Eine Phrase muß in Anführungszeichen stehen.</p></translation> + </message> + <message> + <location/> + <source><b>Found documents</b><p>This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.</p></source> + <translation><b>Gefundene Dokumente</b><p>Diese Liste beinhaltet alle gefundenen Dokumente der letzten Suche. Die Dokumente sind nach der Häufigkeit der Treffer geordnet.</p></translation> + </message> + <message> + <location/> + <source>Found &Documents:</source> + <translation>Gefundene &Dokumente:</translation> + </message> + <message> + <location/> + <source>Display the help page for the full text search.</source> + <translation>Zeigt die Hilfeseite für die Volltextsuche an.</translation> + </message> + <message> + <location/> + <source>He&lp</source> + <translation>Hi&lfe</translation> + </message> + <message> + <location/> + <source>Pressing this button starts the search.</source> + <translation>Startet die Suche.</translation> + </message> + <message> + <location/> + <source>Preparing...</source> + <translation>Initialisiere...</translation> + </message> + <message> + <location/> + <source>Enter searchword(s)</source> + <translation>Geben Sie Suchbegriffe ein</translation> + </message> + <message> + <location/> + <source>Display the help page</source> + <translation>Hilfeseite anzeigen</translation> + </message> + <message> + <location/> + <source>Start searching</source> + <translation>Suche beginnen</translation> + </message> +</context> +<context> + <name>HelpWindow</name> + <message> + <location filename="../tools/assistant/compat/helpwindow.cpp" line="+97"/> + <source>Help</source> + <translation>Hilfe</translation> + </message> + <message> + <location line="+93"/> + <source>Open Link in New Window Shift+LMB</source> + <translation>Öffne Link in neuem Fenster</translation> + </message> + <message> + <location line="-2"/> + <source>Open Link in New Tab</source> + <translation>Link in einem neuen Tab öffnen</translation> + </message> + <message> + <location line="-90"/> + <source>Unable to launch web browser. +</source> + <translation>Der Webbrowser konnte nicht gestartet werden. +</translation> + </message> + <message> + <location line="+1"/> + <source>OK</source> + <translation>OK</translation> + </message> + <message> + <location line="+27"/> + <source>Failed to open link: '%1'</source> + <translation>Der Link '%1' konnte nicht geöffnet werden</translation> + </message> + <message> + <location line="+1"/> + <source><div align="center"><h1>The page could not be found</h1><br><h3>'%1'</h3></div></source> + <translation><div align="center"><h1>Die Seite wurde nicht gefunden</h1><br><h3>'%1'</h3></div></translation> + </message> + <message> + <location line="+2"/> + <source>Error...</source> + <translation>Fehler ...</translation> + </message> + <message> + <location line="+56"/> + <source>Copy &Link Location</source> + <translation>Link-Adresse kopieren</translation> + </message> +</context> +<context> + <name>Index</name> + <message> + <location filename="../tools/assistant/compat/index.cpp" line="+385"/> + <source>Untitled</source> + <translation>Unbenannt</translation> + </message> +</context> +<context> + <name>MainWindow</name> + <message> + <location filename="../tools/assistant/compat/mainwindow.ui"/> + <source>Toolbar</source> + <translation>Werkzeugleiste</translation> + </message> + <message> + <location/> + <source>&Print...</source> + <translation>&Drucken...</translation> + </message> + <message> + <location/> + <source>E&xit</source> + <translation>&Beenden</translation> + </message> + <message> + <location/> + <source>&Copy</source> + <translation>&Kopieren</translation> + </message> + <message> + <location/> + <source>&Find in Text...</source> + <translation>Text&suche...</translation> + </message> + <message> + <location/> + <source>&Home</source> + <translation>St&artseite</translation> + </message> + <message> + <location/> + <source>&Previous</source> + <translation>&Vorherige</translation> + </message> + <message> + <location/> + <source>&Next</source> + <translation>&Nächste</translation> + </message> + <message> + <location/> + <source>About Qt</source> + <translation>Über Qt</translation> + </message> + <message> + <location/> + <source>Zoom &in</source> + <translation>Vergrößern</translation> + </message> + <message> + <location/> + <source>Zoom &out</source> + <translation>Ver&kleinern</translation> + </message> + <message> + <location/> + <source>New Window</source> + <translation>Neues Fenster...</translation> + </message> + <message> + <location filename="../tools/assistant/compat/mainwindow.cpp" line="+198"/> + <source>Ctrl+T</source> + <translation>Strg+T +</translation> + </message> + <message> + <location line="+1"/> + <source>Ctrl+I</source> + <translation>Strg+I</translation> + </message> + <message> + <location line="+1"/> + <source>Ctrl+B</source> + <translation>Strg+E</translation> + </message> + <message> + <location line="+129"/> + <location line="+1"/> + <source>Qt Assistant</source> + <translation>Qt Assistant</translation> + </message> + <message> + <location filename="../tools/assistant/compat/mainwindow.ui"/> + <source>&Add Bookmark</source> + <translation>&Füge Lesezeichen hinzu</translation> + </message> + <message> + <location/> + <source>&File</source> + <translation>&Datei</translation> + </message> + <message> + <location/> + <source>&Edit</source> + <translation>&Bearbeiten</translation> + </message> + <message> + <location/> + <source>&View</source> + <translation>&Ansicht</translation> + </message> + <message> + <location/> + <source>&Go</source> + <translation>&Gehe zu</translation> + </message> + <message> + <location/> + <source>Boo&kmarks</source> + <translation>&Lesezeichen</translation> + </message> + <message> + <location/> + <source>Qt Assistant by Nokia</source> + <translation>Qt Assistant von Nokia</translation> + </message> + <message> + <location/> + <source>&Help</source> + <translation>&Hilfe</translation> + </message> + <message> + <location/> + <source>Print the currently displayed page.</source> + <translation>Drucke aktuelle Seite.</translation> + </message> + <message> + <location/> + <source>Ctrl+P</source> + <translation>Strg+P</translation> + </message> + <message> + <location/> + <source>Quit Qt Assistant.</source> + <translation>Qt Assistant beenden.</translation> + </message> + <message> + <location/> + <source>Ctrl+Q</source> + <translation>Strg+Q</translation> + </message> + <message> + <location/> + <source>Copy the selected text to the clipboard.</source> + <translation>Den markierten Text in die Zwischenablage kopieren.</translation> + </message> + <message> + <location/> + <source>Ctrl+C</source> + <translation>Strg+C</translation> + </message> + <message> + <location/> + <source>Open the Find dialog. Qt Assistant will search the currently displayed page for the text you enter.</source> + <translation>Den Suchdialog öffnen. Qt Assistant sucht in der aktuellen Seite nach dem eingegebenen Text.</translation> + </message> + <message> + <location/> + <source>Ctrl+F</source> + <translation>Strg+F</translation> + </message> + <message> + <location/> + <source>Go to the home page. Qt Assistant's home page is the Qt Reference Documentation.</source> + <translation>Zur Startseite gehen. Startseite im Qt Assistant ist die Qt-Referenzdokumentation.</translation> + </message> + <message> + <location/> + <source>Ctrl+Home</source> + <translation>Strg+Pos1</translation> + </message> + <message> + <location/> + <source>Go to the previous page.</source> + <translation>Gehe zur vorherigen Seite.</translation> + </message> + <message> + <location/> + <source>Alt+Left</source> + <translation>Alt+Links</translation> + </message> + <message> + <location/> + <source>Go to the next page.</source> + <translation>Gehe zur nächsten Seite.</translation> + </message> + <message> + <location/> + <source>Alt+Right</source> + <translation>Alt+Rechts</translation> + </message> + <message> + <location/> + <source>Display further information about Qt Assistant.</source> + <translation>Zeigt das Handbuch zum Qt Designer an.</translation> + </message> + <message> + <location/> + <source>Zoom in on the document, i.e. increase the font size.</source> + <translation>Vergrößert die Schrift.</translation> + </message> + <message> + <location/> + <source>Ctrl++</source> + <translation>Strg++</translation> + </message> + <message> + <location/> + <source>Zoom out on the document, i.e. decrease the font size.</source> + <translation>Verkleinert die Schrift.</translation> + </message> + <message> + <location/> + <source>Ctrl+-</source> + <translation>Strg+-</translation> + </message> + <message> + <location/> + <source>Open a new window.</source> + <translation>Öffnet ein neues Fenster.</translation> + </message> + <message> + <location/> + <source>Ctrl+N</source> + <translation>Strg+N</translation> + </message> + <message> + <location/> + <source>&Close</source> + <translation>&Schließen</translation> + </message> + <message> + <location/> + <source>Close the current window.</source> + <translation>Schließt das aktuelle Fenster.</translation> + </message> + <message> + <location/> + <source>Qt Assistant Manual</source> + <translation>Handbuch zu Qt Assistant</translation> + </message> + <message> + <location/> + <source>F1</source> + <translation>F1</translation> + </message> + <message> + <location/> + <source>Add the currently displayed page as a new bookmark.</source> + <translation>Aktuelle Seite zu den Lesezeichen hinzufügen.</translation> + </message> + <message> + <location/> + <source>What's This?</source> + <translation>Direkthilfe</translation> + </message> + <message> + <location/> + <source>"What's This?" context sensitive help.</source> + <translation>Kontextbezogene Direkthilfe.</translation> + </message> + <message> + <location/> + <source>Shift+F1</source> + <translation>Umschalt+F1</translation> + </message> + <message> + <location filename="../tools/assistant/compat/mainwindow.cpp" line="-129"/> + <source>Ctrl+S</source> + <translation>Strg+S</translation> + </message> + <message> + <location line="-33"/> + <source>Initializing Qt Assistant...</source> + <translation>Qt Assistant wird initialisiert...</translation> + </message> + <message> + <location filename="../tools/assistant/compat/mainwindow.ui"/> + <source>Go</source> + <translation>Gehe zu</translation> + </message> + <message> + <location/> + <source>Find &Next</source> + <translation>Weitersuchen</translation> + </message> + <message> + <location/> + <source>F3</source> + <translation>F3</translation> + </message> + <message> + <location/> + <source>Find &Previous</source> + <translation>Vorheriges suchen</translation> + </message> + <message> + <location/> + <source>Shift+F3</source> + <translation>Umschalt+F3</translation> + </message> + <message> + <location/> + <source>About Qt Assistant</source> + <translation>Über Qt Assistent</translation> + </message> + <message> + <location/> + <source>Add Tab</source> + <translation>Tab einfügen</translation> + </message> + <message> + <location/> + <source>Ctrl+Alt+N</source> + <translation></translation> + </message> + <message> + <location/> + <source>Next Tab</source> + <translation>Nächster Tab</translation> + </message> + <message> + <location/> + <source>Ctrl+Alt+Right</source> + <translation></translation> + </message> + <message> + <location/> + <source>Previous Tab</source> + <translation>Voriger Tab</translation> + </message> + <message> + <location/> + <source>Ctrl+Alt+Left</source> + <translation></translation> + </message> + <message> + <location/> + <source>Close Tab</source> + <translation>Tab schließen</translation> + </message> + <message> + <location/> + <source>Ctrl+Alt+Q</source> + <translation></translation> + </message> + <message> + <location filename="../tools/assistant/compat/mainwindow.cpp" line="+181"/> + <source>Failed to open about application contents in file: '%1'</source> + <translation>Fehler beim Öffnen des Inhalts in Datei: '%1'</translation> + </message> + <message> + <location line="-246"/> + <source>Sidebar</source> + <translation>Sidebar</translation> + </message> + <message> + <location line="+18"/> + <source>&Window</source> + <translation>&Fenster</translation> + </message> + <message> + <location line="+2"/> + <source>Minimize</source> + <translation>Minimieren</translation> + </message> + <message> + <location line="+1"/> + <source>Ctrl+M</source> + <translation>Strg+M</translation> + </message> + <message> + <location line="+70"/> + <source>SHIFT+CTRL+=</source> + <translation>Umschalt+Strg+=</translation> + </message> + <message> + <location filename="../tools/assistant/compat/mainwindow.ui"/> + <source>Ctrl+W</source> + <translation>Strg+W</translation> + </message> + <message> + <location filename="../tools/assistant/compat/mainwindow.cpp" line="+8"/> + <source>Ctrl+]</source> + <translation>Strg+AltGr+]</translation> + </message> + <message> + <location line="+1"/> + <source>Ctrl+[</source> + <translation>Strg+AltGr+[</translation> + </message> + <message> + <location line="+7"/> + <source>Views</source> + <translation>Menüleisten/Sidebar</translation> + </message> + <message> + <location line="+80"/> + <source>Displays the main page of a specific documentation set.</source> + <translation>Zeigt die Hauptseite eines Dokumentensets an.</translation> + </message> + <message> + <location line="+262"/> + <source>...</source> + <translation>...</translation> + </message> + <message> + <location line="+238"/> + <location line="+6"/> + <source>Save Page</source> + <translation>Seite speichern</translation> + </message> + <message> + <location line="+0"/> + <source>Cannot open file for writing!</source> + <translation>Die Datei konnte nicht zum Schreiben geöffnet werden.</translation> + </message> + <message> + <location filename="../tools/assistant/compat/mainwindow.ui"/> + <source>Save Page As...</source> + <translation>Seite speichern als...</translation> + </message> + <message> + <location/> + <source>Ctrl+Alt+S</source> + <translation>Strg+Alt+S</translation> + </message> + <message> + <location/> + <source>Sync with Table of Contents</source> + <translation>Seite mit Inhalt-Tab syncronisieren</translation> + </message> + <message> + <location/> + <source>Select the page in contents tab.</source> + <translation>Wählt die Seite im Inhalt-Tab aus.</translation> + </message> + <message> + <location/> + <source>Font Settings...</source> + <translation>Schriftart...</translation> + </message> +</context> +<context> + <name>QObject</name> + <message> + <location filename="../tools/assistant/compat/config.cpp" line="+350"/> + <source>Qt Assistant by Nokia</source> + <translation>Qt Assistant von Nokia</translation> + </message> +</context> +<context> + <name>TabbedBrowser</name> + <message> + <location filename="../tools/assistant/compat/tabbedbrowser.ui"/> + <source>TabbedBrowser</source> + <translation></translation> + </message> + <message> + <location/> + <source>Untitled</source> + <translation>Unbenannt</translation> + </message> + <message> + <location filename="../tools/assistant/compat/tabbedbrowser.cpp" line="+235"/> + <source>Add page</source> + <translation>Seite einfügen</translation> + </message> + <message> + <location line="+9"/> + <source>Close page</source> + <translation>Seite schließen</translation> + </message> + <message> + <location line="-95"/> + <source>...</source> + <translation>...</translation> + </message> + <message> + <location line="+338"/> + <source>New Tab</source> + <translation>Neuer Tab</translation> + </message> + <message> + <location line="+1"/> + <source>Close Tab</source> + <translation>Tab schließen</translation> + </message> + <message> + <location line="+1"/> + <source>Close Other Tabs</source> + <translation>Andere Tabs schließen</translation> + </message> + <message> + <location filename="../tools/assistant/compat/tabbedbrowser.ui"/> + <source>Previous</source> + <translation>Vorheriger</translation> + </message> + <message> + <location/> + <source>Next</source> + <translation>Nächster</translation> + </message> + <message> + <location/> + <source>Case Sensitive</source> + <translation>Groß-/Kleinschreibung beachten</translation> + </message> + <message> + <location/> + <source>Whole words</source> + <translation>Ganze Wörter</translation> + </message> + <message> + <location/> + <source><img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped</source> + <translation><img src=":/trolltech/assistant/images/wrap.png">&nbsp;Seitenende</translation> + </message> +</context> +<context> + <name>TopicChooser</name> + <message> + <location filename="../tools/assistant/compat/topicchooser.cpp" line="+56"/> + <source>Choose a topic for <b>%1</b></source> + <translation>Wählen Sie ein Thema für <b>%1</b></translation> + </message> + <message> + <location filename="../tools/assistant/compat/topicchooser.ui"/> + <source>Choose Topic</source> + <translation>Thema wählen</translation> + </message> + <message> + <location/> + <source>Select a topic from the list and click the <b>Display</b>-button to open the online help.</source> + <translation>Wählen Sie ein Thema aus der Liste aus und klicken Sie <b>Anzeigen</b> um die Hilfe zu öffnen.</translation> + </message> + <message> + <location/> + <source>&Topics</source> + <translation>&Themen</translation> + </message> + <message> + <location/> + <source>Displays a list of available help topics for the keyword.</source> + <translation>Zeigt eine Liste der verfügbaren Hilfethemen für diesen Begriff an.</translation> + </message> + <message> + <location/> + <source>&Display</source> + <translation>&Anzeigen</translation> + </message> + <message> + <location/> + <source>Open the topic selected in the list.</source> + <translation>Öffne das gewählte Thema aus der Liste.</translation> + </message> + <message> + <location/> + <source>&Close</source> + <translation>&Schließen</translation> + </message> + <message> + <location/> + <source>Close the Dialog.</source> + <translation>Schließt den Dialog.</translation> + </message> +</context> +</TS> diff --git a/tests/auto/guiapplauncher/test.ui b/tests/auto/guiapplauncher/test.ui new file mode 100644 index 0000000..02efcd4 --- /dev/null +++ b/tests/auto/guiapplauncher/test.ui @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPlainTextEdit" name="plainTextEdit"/> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>23</height> + </rect> + </property> + <widget class="QMenu" name="menuFile"> + <property name="title"> + <string>File</string> + </property> + <addaction name="actionExit"/> + </widget> + <addaction name="menuFile"/> + </widget> + <widget class="QStatusBar" name="statusbar"/> + <action name="actionExit"> + <property name="text"> + <string>Exit</string> + </property> + </action> + </widget> + <resources/> + <connections> + <connection> + <sender>actionExit</sender> + <signal>triggered()</signal> + <receiver>MainWindow</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>399</x> + <y>299</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/tests/auto/guiapplauncher/tst_guiapplauncher.cpp b/tests/auto/guiapplauncher/tst_guiapplauncher.cpp new file mode 100644 index 0000000..a61bd5e --- /dev/null +++ b/tests/auto/guiapplauncher/tst_guiapplauncher.cpp @@ -0,0 +1,526 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "windowmanager.h" + +#include <QtCore/QDir> +#include <QtCore/QString> +#include <QtTest/QtTest> +#include <QtCore/QProcess> +#include <QtCore/QByteArray> +#include <QtCore/QLibraryInfo> +#include <QtCore/QVariant> +#include <QtCore/QDateTime> +#include <QtCore/QMap> + +// AppLaunch: Launch gui applications, keep them running a while +// (grabbing their top level from the window manager) and send +// them a Close event via window manager. Verify that they do not +// not crash nor produces unexpected error output. +// Note: Do not play with the machine while it is running as otherwise +// the top-level find algorithm might get confused (especially on Windows). +// Environment variables are checked to turned off some tests +// It is currently implemented for X11 and Windows, pending an +// implementation of the WindowManager class and deployment on +// the other platforms. + +enum { defaultUpTimeMS = 3000, defaultTopLevelWindowTimeoutMS = 30000, + defaultTerminationTimeoutMS = 35000 }; + +// List the examples to test (Gui examples only). +struct Example { + const char *name; + const char *directory; + const char *binary; + unsigned priority; // 0-highest + int upTimeMS; +}; + +const struct Example examples[] = { + {"animation/animatedtiles Example", "animation/animatedtiles", "animatedtiles", 0, -1}, + {"animation/appchooser Example", "animation/appchooser", "appchooser", 10, -1}, + {"animation/easing Example", "animation/easing", "easing", 10, -1}, + {"animation/moveblocks Example", "animation/moveblocks", "moveblocks", 10, -1}, + {"animation/states Example", "animation/states", "states", 10, -1}, + {"animation/stickman Example", "animation/stickman", "stickman", 10, -1}, + {"designer/calculatorbuilder Example", "designer/calculatorbuilder", "calculatorbuilder", 10, -1}, + {"dialogs/standarddialogs Example", "dialogs/standarddialogs", "standarddialogs", 10, -1}, + {"draganddrop/dropsite Example", "draganddrop/dropsite", "dropsite", 10, -1}, + {"draganddrop/fridgemagnets Example", "draganddrop/fridgemagnets", "fridgemagnets", 10, -1}, + {"draganddrop/puzzle Example", "draganddrop/puzzle", "puzzle", 10, -1}, + {"effects/blurpicker Example", "effects/blurpicker", "blurpicker", 10, -1}, + {"effects/customshader Example", "effects/customshader", "customshader", 10, -1}, + {"effects/fademessage Example", "effects/fademessage", "fademessage", 10, -1}, + {"effects/lighting Example", "effects/lighting", "lighting", 10, -1}, + {"graphicsview/anchorlayout Example", "graphicsview/anchorlayout", "anchorlayout", 10, -1}, + {"graphicsview/basicgraphicslayouts Example", "graphicsview/basicgraphicslayouts", "basicgraphicslayouts", 0, -1}, + {"graphicsview/collidingmice Example", "graphicsview/collidingmice", "collidingmice", 10, -1}, + {"graphicsview/diagramscene Example", "graphicsview/diagramscene", "diagramscene", 10, -1}, + {"graphicsview/dragdroprobot Example", "graphicsview/dragdroprobot", "dragdroprobot", 10, -1}, + {"graphicsview/elasticnodes Example", "graphicsview/elasticnodes", "elasticnodes", 10, -1}, + {"graphicsview/flowlayout Example", "graphicsview/flowlayout", "flowlayout", 10, -1}, + {"graphicsview/padnavigator Example", "graphicsview/padnavigator", "padnavigator", 0, -1}, + {"graphicsview/portedasteroids Example", "graphicsview/portedasteroids", "portedasteroids", 10, -1}, + {"graphicsview/portedcanvas Example", "graphicsview/portedcanvas", "portedcanvas", 10, -1}, + {"graphicsview/weatheranchorlayout Example", "graphicsview/weatheranchorlayout", "weatheranchorlayout", 10, -1}, + {"itemviews/addressbook Example", "itemviews/addressbook", "addressbook", 0, -1}, + {"itemviews/basicsortfiltermodel Example", "itemviews/basicsortfiltermodel", "basicsortfiltermodel", 10, -1}, + {"itemviews/chart Example", "itemviews/chart", "chart", 0, -1}, + {"itemviews/coloreditorfactory Example", "itemviews/coloreditorfactory", "coloreditorfactory", 10, -1}, + {"itemviews/combowidgetmapper Example", "itemviews/combowidgetmapper", "combowidgetmapper", 6, -1}, + {"itemviews/customsortfiltermodel Example", "itemviews/customsortfiltermodel", "customsortfiltermodel", 6, -1}, + {"itemviews/dirview Example", "itemviews/dirview", "dirview", 0, -1}, + {"itemviews/editabletreemodel Example", "itemviews/editabletreemodel", "editabletreemodel", 0, -1}, + {"itemviews/fetchmore Example", "itemviews/fetchmore", "fetchmore", 10, -1}, + {"itemviews/frozencolumn Example", "itemviews/frozencolumn", "frozencolumn", 10, -1}, + {"itemviews/pixelator Example", "itemviews/pixelator", "pixelator", 10, -1}, + {"itemviews/puzzle Example", "itemviews/puzzle", "puzzle", 10, -1}, + {"itemviews/simpledommodel Example", "itemviews/simpledommodel", "simpledommodel", 10, -1}, + {"itemviews/simpletreemodel Example", "itemviews/simpletreemodel", "simpletreemodel", 10, -1}, + {"itemviews/simplewidgetmapper Example", "itemviews/simplewidgetmapper", "simplewidgetmapper", 10, -1}, + {"itemviews/spinboxdelegate Example", "itemviews/spinboxdelegate", "spinboxdelegate", 0, -1}, + {"itemviews/stardelegate Example", "itemviews/stardelegate", "stardelegate", 10, -1}, + {"layouts/basiclayouts Example", "layouts/basiclayouts", "basiclayouts", 0, -1}, + {"layouts/borderlayout Example", "layouts/borderlayout", "borderlayout", 10, -1}, + {"layouts/dynamiclayouts Example", "layouts/dynamiclayouts", "dynamiclayouts", 10, -1}, + {"layouts/flowlayout Example", "layouts/flowlayout", "flowlayout", 10, -1}, + {"mainwindows/application Example", "mainwindows/application", "application", 6, -1}, + {"mainwindows/dockwidgets Example", "mainwindows/dockwidgets", "dockwidgets", 0, -1}, + {"mainwindows/mdi Example", "mainwindows/mdi", "mdi", 0, -1}, + {"mainwindows/menus Example", "mainwindows/menus", "menus", 10, -1}, + {"mainwindows/recentfiles Example", "mainwindows/recentfiles", "recentfiles", 10, -1}, + {"mainwindows/sdi Example", "mainwindows/sdi", "sdi", 10, -1}, + {"multitouch/dials Example", "multitouch/dials", "dials", 10, -1}, + {"multitouch/fingerpaint Example", "multitouch/fingerpaint", "fingerpaint", 10, -1}, + {"multitouch/knobs Example", "multitouch/knobs", "knobs", 10, -1}, + {"multitouch/pinchzoom Example", "multitouch/pinchzoom", "pinchzoom", 10, -1}, + {"opengl/2dpainting Example", "opengl/2dpainting", "2dpainting", 10, -1}, + {"opengl/grabber Example", "opengl/grabber", "grabber", 10, -1}, + {"opengl/hellogl Example", "opengl/hellogl", "hellogl", 10, -1}, + {"opengl/overpainting Example", "opengl/overpainting", "overpainting", 10, -1}, + {"opengl/samplebuffers Example", "opengl/samplebuffers", "samplebuffers", 10, -1}, + {"opengl/textures Example", "opengl/textures", "textures", 10, -1}, + {"painting/basicdrawing Example", "painting/basicdrawing", "basicdrawing", 10, -1}, + {"painting/concentriccircles Example", "painting/concentriccircles", "concentriccircles", 0, -1}, + {"painting/fontsampler Example", "painting/fontsampler", "fontsampler", 0, -1}, + {"painting/imagecomposition Example", "painting/imagecomposition", "imagecomposition", 10, -1}, + {"painting/painterpaths Example", "painting/painterpaths", "painterpaths", 10, -1}, + {"painting/svggenerator Example", "painting/svggenerator", "svggenerator", 10, -1}, + {"painting/svgviewer Example", "painting/svgviewer", "svgviewer", 0, -1}, + {"painting/transformations Example", "painting/transformations", "transformations", 0, -1}, + {"qtconcurrent/imagescaling Example", "qtconcurrent/imagescaling", "imagescaling", 10, -1}, + {"richtext/calendar Example", "richtext/calendar", "calendar", 0, -1}, + {"richtext/orderform Example", "richtext/orderform", "orderform", 10, -1}, + {"richtext/syntaxhighlighter Example", "richtext/syntaxhighlighter", "syntaxhighlighter", 0, -1}, + {"richtext/textobject Example", "richtext/textobject", "textobject", 10, -1}, + {"script/calculator Example", "script/calculator", "calculator", 6, -1}, + {"script/qstetrix Example", "script/qstetrix", "qstetrix", 0, -1}, + {"statemachine/eventtransitions Example", "statemachine/eventtransitions", "eventtransitions", 10, -1}, + {"statemachine/rogue Example", "statemachine/rogue", "rogue", 10, -1}, + {"statemachine/trafficlight Example", "statemachine/trafficlight", "trafficlight", 0, -1}, + {"statemachine/twowaybutton Example", "statemachine/twowaybutton", "twowaybutton", 10, -1}, + {"tutorials/addressbook/part7 Example", "tutorials/addressbook/part7", "part7", 0, -1}, + {"webkit/fancybrowser Example", "webkit/fancybrowser", "fancybrowser", 0, 7000}, + {"widgets/analogclock Example", "widgets/analogclock", "analogclock", 6, -1}, + {"widgets/calculator Example", "widgets/calculator", "calculator", 6, -1}, + {"widgets/calendarwidget Example", "widgets/calendarwidget", "calendarwidget", 10, -1}, + {"widgets/charactermap Example", "widgets/charactermap", "charactermap", 10, -1}, + {"widgets/codeeditor Example", "widgets/codeeditor", "codeeditor", 0, -1}, + {"widgets/digitalclock Example", "widgets/digitalclock", "digitalclock", 10, -1}, + {"widgets/groupbox Example", "widgets/groupbox", "groupbox", 10, -1}, + {"widgets/icons Example", "widgets/icons", "icons", 10, -1}, + {"widgets/imageviewer Example", "widgets/imageviewer", "imageviewer", 10, -1}, + {"widgets/lineedits Example", "widgets/lineedits", "lineedits", 10, -1}, + {"widgets/scribble Example", "widgets/scribble", "scribble", 10, -1}, + {"widgets/sliders Example", "widgets/sliders", "sliders", 10, -1}, + {"widgets/spinboxes Example", "widgets/spinboxes", "spinboxes", 10, -1}, + {"widgets/styles Example", "widgets/styles", "styles", 0, -1}, + {"widgets/stylesheet Example", "widgets/stylesheet", "stylesheet", 0, -1}, + {"widgets/tablet Example", "widgets/tablet", "tablet", 10, -1}, + {"widgets/tetrix Example", "widgets/tetrix", "tetrix", 0, -1}, + {"widgets/tooltips Example", "widgets/tooltips", "tooltips", 10, -1}, + {"widgets/validators Example", "widgets/validators", "validators", 10, -1}, + {"widgets/wiggly Example", "widgets/wiggly", "wiggly", 10, -1} +}; + +const struct Example demos[] = { + {"Affine Demo", "affine", "affine", 0, -1}, + {"Books Demo", "books", "books", 0, -1}, + {"Browser Demo", "browser", "browser", 0, 0000}, + {"Chip Demo", "chip", "chip", 0, -1}, + {"Composition Demo", "composition", "composition", 0, -1}, + {"Deform Demo", "deform", "deform", 0, -1}, + {"Embeddeddialogs Demo", "embeddeddialogs", "embeddeddialogs", 0, -1}, + {"Gradients Demo", "gradients", "gradients", 0, -1}, + {"Interview Demo", "interview", "interview", 0, -1}, + {"Mainwindow Demo", "mainwindow", "mainwindow", 0, -1}, + {"PathStroke Demo", "pathstroke", "pathstroke", 0, -1}, + {"Spreadsheet Demo", "spreadsheet", "spreadsheet", 0, -1}, + {"Sub-Attac Demo", "sub-attaq", "sub-attaq", 0, -1}, + {"TextEdit Demo", "textedit", "textedit", 0, -1}, + {"Undo Demo", "undo", "undo", 0, -1} +}; + +// Data struct used in tests, specifying paths and timeouts +struct AppLaunchData { + AppLaunchData(); + void clear(); + + QString binary; + QStringList args; + QString workingDirectory; + int upTimeMS; + int topLevelWindowTimeoutMS; + int terminationTimeoutMS; + bool splashScreen; +}; + +AppLaunchData::AppLaunchData() : + upTimeMS(defaultUpTimeMS), + topLevelWindowTimeoutMS(defaultTopLevelWindowTimeoutMS), + terminationTimeoutMS(defaultTerminationTimeoutMS), + splashScreen(false) +{ +} + +void AppLaunchData::clear() +{ + binary.clear(); + args.clear(); + workingDirectory.clear(); + upTimeMS = defaultUpTimeMS; + topLevelWindowTimeoutMS = defaultTopLevelWindowTimeoutMS; + terminationTimeoutMS = defaultTerminationTimeoutMS; + splashScreen = false; +} + +Q_DECLARE_METATYPE(AppLaunchData) + + +class tst_GuiAppLauncher : public QObject +{ + Q_OBJECT + +public: + // Test name (static const char title!) + data + typedef QPair<const char*, AppLaunchData> TestDataEntry; + typedef QList<TestDataEntry> TestDataEntries; + + enum { TestTools = 0x1, TestDemo = 0x2, TestExamples = 0x4, + TestAll = TestTools|TestDemo|TestExamples }; + + tst_GuiAppLauncher(); + +private Q_SLOTS: + void initTestCase(); + + void run(); + void run_data(); + + void cleanupTestCase(); + +private: + QString workingDir() const; + +private: + bool runApp(const AppLaunchData &data, QString *errorMessage) const; + TestDataEntries testData() const; + + const unsigned m_testMask; + const unsigned m_examplePriority; + const QString m_dir; + const QSharedPointer<WindowManager> m_wm; +}; + +// Test mask from enviroment as test lib does not allow options. +static inline unsigned testMask() +{ + unsigned testMask = tst_GuiAppLauncher::TestAll; + if (!qgetenv("QT_TEST_NOTOOLS").isEmpty()) + testMask &= ~ tst_GuiAppLauncher::TestTools; + if (!qgetenv("QT_TEST_NOEXAMPLES").isEmpty()) + testMask &= ~tst_GuiAppLauncher::TestExamples; + if (!qgetenv("QT_TEST_NODEMOS").isEmpty()) + testMask &= ~tst_GuiAppLauncher::TestDemo; + return testMask; +} + +static inline unsigned testExamplePriority() +{ + const QByteArray priorityD = qgetenv("QT_TEST_EXAMPLE_PRIORITY"); + if (!priorityD.isEmpty()) { + bool ok; + const unsigned rc = priorityD.toUInt(&ok); + if (ok) + return rc; + } + return 5; +} + +tst_GuiAppLauncher::tst_GuiAppLauncher() : + m_testMask(testMask()), + m_examplePriority(testExamplePriority()), + m_dir(QLatin1String(SRCDIR)), + m_wm(WindowManager::create()) +{ +} + +void tst_GuiAppLauncher::initTestCase() +{ + QString message = QString::fromLatin1("### App Launcher test on %1 in %2 (%3)"). + arg(QDateTime::currentDateTime().toString(), QDir::currentPath()). + arg(QLibraryInfo::buildKey()); + qDebug("%s", qPrintable(message)); + qWarning("### PLEASE LEAVE THE MACHINE UNATTENDED WHILE THIS TEST IS RUNNING\n"); + + // Does a window manager exist on the platform? + if (!m_wm->openDisplay(&message)) { + QSKIP(message.toLatin1().constData(), SkipAll); + } + + // Paranoia: Do we have our test file? + const QDir workDir(m_dir); + if (!workDir.exists()) { + message = QString::fromLatin1("Invalid working directory %1").arg(m_dir); + QFAIL(message.toLocal8Bit().constData()); + } +} + +void tst_GuiAppLauncher::run() +{ + QString errorMessage; + QFETCH(AppLaunchData, data); + const bool rc = runApp(data, &errorMessage); + if (!rc) // Wait for windows to disappear after kill + WindowManager::sleepMS(500); + QVERIFY2(rc, qPrintable(errorMessage)); +} + +// Cross platform galore! +static inline QString guiBinary(QString in) +{ +#ifdef Q_OS_MAC + return in + QLatin1String(".app/Contents/MacOS/") + in; +#endif + in[0] = in.at(0).toLower(); +#ifdef Q_OS_WIN + in += QLatin1String(".exe"); +#endif + return in; +} + +void tst_GuiAppLauncher::run_data() +{ + QTest::addColumn<AppLaunchData>("data"); + foreach(const TestDataEntry &data, testData()) + QTest::newRow(data.first) << data.second; +} + +// Read out the examples array structures and convert to test data. +static tst_GuiAppLauncher::TestDataEntries exampleData(unsigned priority, + const QString &path, + bool debug, + const Example *exArray, + unsigned n) +{ + Q_UNUSED(debug) + tst_GuiAppLauncher::TestDataEntries rc; + const QChar slash = QLatin1Char('/'); + AppLaunchData data; + for (unsigned e = 0; e < n; e++) { + const Example &example = exArray[e]; + if (example.priority <= priority) { + data.clear(); + const QString examplePath = path + slash + QLatin1String(example.directory); + data.binary = examplePath + slash; +#ifdef Q_OS_WIN + data.binary += debug? QLatin1String("debug/") : QLatin1String("release/"); +#endif + data.binary += guiBinary(QLatin1String(example.binary)); + data.workingDirectory = examplePath; + if (example.upTimeMS > 0) + data.upTimeMS = example.upTimeMS; + rc.append(tst_GuiAppLauncher::TestDataEntry(example.name, data)); + } + } + return rc; +} + +tst_GuiAppLauncher::TestDataEntries tst_GuiAppLauncher::testData() const +{ + TestDataEntries rc; + const QChar slash = QLatin1Char('/'); + const QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + slash; + const bool debug = QLibraryInfo::buildKey().contains(QLatin1String("debug")); + Q_UNUSED(debug) + + AppLaunchData data; + + if (m_testMask & TestTools) { + data.binary = binPath + guiBinary(QLatin1String("Designer")); + data.args.append(m_dir + QLatin1String("test.ui")); + rc.append(TestDataEntry("Qt Designer", data)); + + data.clear(); + data.binary = binPath + guiBinary(QLatin1String("Linguist")); + data.splashScreen = true; + data.upTimeMS = 5000; // Slow loading + data.args.append(m_dir + QLatin1String("test.ts")); + rc.append(TestDataEntry("Qt Linguist", data)); + } + + if (m_testMask & TestDemo) { + data.clear(); + data.upTimeMS = 5000; // Startup animation + data.binary = binPath + guiBinary(QLatin1String("qtdemo")); + rc.append(TestDataEntry("Qt Demo", data)); + + const QString demosPath = QLibraryInfo::location(QLibraryInfo::DemosPath); + if (!demosPath.isEmpty()) + rc += exampleData(m_examplePriority, demosPath, debug, demos, sizeof(demos)/sizeof(Example)); + } + + if (m_testMask & TestExamples) { + const QString examplesPath = QLibraryInfo::location(QLibraryInfo::ExamplesPath); + if (!examplesPath.isEmpty()) + rc += exampleData(m_examplePriority, examplesPath, debug, examples, sizeof(examples)/sizeof(Example)); + } + qDebug("Running %d tests...", rc.size()); + return rc; +} + +static inline void ensureTerminated(QProcess *p) +{ + if (p->state() != QProcess::Running) + return; + p->terminate(); + if (p->waitForFinished(300)) + return; + p->kill(); + if (!p->waitForFinished(500)) + qWarning("Unable to terminate process"); +} + +static const QStringList &stderrWhiteList() +{ + static QStringList rc; + if (rc.empty()) { + rc << QLatin1String("QPainter::begin: Paint device returned engine == 0, type: 2") + << QLatin1String("QPainter::setRenderHint: Painter must be active to set rendering hints") + << QLatin1String("QPainter::setPen: Painter not active") + << QLatin1String("QPainter::setBrush: Painter not active") + << QLatin1String("QPainter::end: Painter not active, aborted"); + } + return rc; +} + +bool tst_GuiAppLauncher::runApp(const AppLaunchData &data, QString *errorMessage) const +{ + qDebug("Launching: %s\n", qPrintable(data.binary)); + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + if (!data.workingDirectory.isEmpty()) + process.setWorkingDirectory(data.workingDirectory); + process.start(data.binary, data.args); + process.closeWriteChannel(); + if (!process.waitForStarted()) { + *errorMessage = QString::fromLatin1("Unable to execute %1: %2").arg(data.binary, process.errorString()); + return false; + } + // Get window id. + const QString winId = m_wm->waitForTopLevelWindow(data.splashScreen ? 2 : 1, process.pid(), data.topLevelWindowTimeoutMS, errorMessage); + if (winId.isEmpty()) { + ensureTerminated(&process); + return false; + } + qDebug("Window: %s\n", qPrintable(winId)); + // Wait a bit, then send close + WindowManager::sleepMS(data.upTimeMS); + if (m_wm->sendCloseEvent(winId, process.pid(), errorMessage)) { + qDebug("Sent close to window: %s\n", qPrintable(winId)); + } else { + ensureTerminated(&process); + return false; + } + // Terminate + if (!process.waitForFinished(data.terminationTimeoutMS)) { + *errorMessage = QString::fromLatin1("%1: Timeout %2ms").arg(data.binary).arg(data.terminationTimeoutMS); + ensureTerminated(&process); + return false; + } + if (process.exitStatus() != QProcess::NormalExit) { + *errorMessage = QString::fromLatin1("%1: Startup crash").arg(data.binary); + return false; + } + + const int exitCode = process.exitCode(); + // check stderr + const QStringList stderrOutput = QString::fromLocal8Bit(process.readAllStandardOutput()).split(QLatin1Char('\n')); + foreach(const QString &stderrLine, stderrOutput) { + // Skip expected QPainter warnings from oxygen. + if (stderrWhiteList().contains(stderrLine)) { + qWarning("%s: stderr: %s\n", qPrintable(data.binary), qPrintable(stderrLine)); + } else { + if (!stderrLine.isEmpty()) { // Split oddity gives empty messages + *errorMessage = QString::fromLatin1("%1: Unexpected output (ex=%2): '%3'").arg(data.binary).arg(exitCode).arg(stderrLine); + return false; + } + } + } + + if (exitCode != 0) { + *errorMessage = QString::fromLatin1("%1: Exit code %2").arg(data.binary).arg(exitCode); + return false; + } + return true; +} + +void tst_GuiAppLauncher::cleanupTestCase() +{ +} + +#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) +QTEST_NOOP_MAIN +#else +QTEST_APPLESS_MAIN(tst_GuiAppLauncher) +#endif + +#include "tst_guiapplauncher.moc" diff --git a/tests/auto/guiapplauncher/windowmanager.cpp b/tests/auto/guiapplauncher/windowmanager.cpp new file mode 100644 index 0000000..758a14e --- /dev/null +++ b/tests/auto/guiapplauncher/windowmanager.cpp @@ -0,0 +1,508 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "windowmanager.h" +#include <QtCore/QTime> +#include <QtCore/QThread> +#include <QtCore/QDebug> +#include <QtCore/QTextStream> + +#ifdef Q_WS_X11 +# include <string.h> // memset +# include <X11/Xlib.h> +# include <X11/Xatom.h> // XA_WM_STATE +# include <X11/Xutil.h> +# include <X11/Xmd.h> // CARD32 +#endif + +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +# include <windows.h> +#endif + +// Export the sleep function +class FriendlySleepyThread : public QThread { +public: + static void sleepMS(int milliSeconds) { msleep(milliSeconds); } +}; + +#ifdef Q_WS_X11 +// X11 Window manager + +// Register our own error handler to prevent the defult crashing +// behaviour. It simply counts errors in global variables that +// can be checked after calls. + +static unsigned x11ErrorCount = 0; +static const char *currentX11Function = 0; + +int xErrorHandler(Display *, XErrorEvent *e) +{ + x11ErrorCount++; + + QString msg; + QTextStream str(&msg); + str << "An X11 error (#" << x11ErrorCount<< ") occurred: "; + if (currentX11Function) + str << ' ' << currentX11Function << "()"; + str << " code: " << e->error_code; + str.setIntegerBase(16); + str << " resource: 0x" << e->resourceid; + qWarning("%s", qPrintable(msg)); + + return 0; +} + +static bool isMapped(Display *display, Atom xa_wm_state, Window window, bool *isMapped) +{ + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long bytes_after; + unsigned char *prop; + + *isMapped = false; + currentX11Function = "XGetWindowProperty"; + const int retv = XGetWindowProperty(display, window, xa_wm_state, 0L, 1L, False, xa_wm_state, + &actual_type, &actual_format, &nitems, &bytes_after, &prop); + + if (retv != Success || actual_type == None || actual_type != xa_wm_state + || nitems != 1 || actual_format != 32) + return false; + + const CARD32 state = * reinterpret_cast<CARD32 *>(prop); + + switch ((int) state) { + case WithdrawnState: + *isMapped = false; + break; + case NormalState: + case IconicState: + *isMapped = true; + break; + default: + *isMapped = true; + break; + } + return true; +} + +// Wait until a X11 top level has been mapped, courtesy of xtoolwait. +static Window waitForTopLevelMapped(Display *display, unsigned count, int timeOutMS, QString * errorMessage) +{ + unsigned mappingsCount = count; + Atom xa_wm_state; + XEvent event; + + // Discard all pending events + currentX11Function = "XSync"; + XSync(display, True); + + // Listen for top level creation + currentX11Function = "XSelectInput"; + XSelectInput(display, DefaultRootWindow(display), SubstructureNotifyMask); + + /* We assume that the window manager provides the WM_STATE property on top-level + * windows, as required by ICCCM 2.0. + * If the window manager has not yet completed its initialisation, the WM_STATE atom + * might not exist, in which case we create it. */ + +#ifdef XA_WM_STATE /* probably in X11R7 */ + xa_wm_state = XA_WM_STATE; +#else + xa_wm_state = XInternAtom(display, "WM_STATE", False); +#endif + + QTime elapsedTime; + elapsedTime.start(); + while (mappingsCount) { + if (elapsedTime.elapsed() > timeOutMS) { + *errorMessage = QString::fromLatin1("X11: Timed out waiting for toplevel %1ms").arg(timeOutMS); + return 0; + } + currentX11Function = "XNextEvent"; + unsigned errorCount = x11ErrorCount; + XNextEvent(display, &event); + if (x11ErrorCount > errorCount) { + *errorMessage = QString::fromLatin1("X11: Error in XNextEvent"); + return 0; + } + switch (event.type) { + case CreateNotify: + // Window created, listen for its mapping now + if (!event.xcreatewindow.send_event && !event.xcreatewindow.override_redirect) + XSelectInput(display, event.xcreatewindow.window, PropertyChangeMask); + break; + case PropertyNotify: + // Watch for map + if (!event.xproperty.send_event && event.xproperty.atom == xa_wm_state) { + bool mapped; + if (isMapped(display, xa_wm_state, event.xproperty.window, &mapped)) { + if (mapped && --mappingsCount == 0) + return event.xproperty.window; + // Past splash screen, listen for next window to be created + XSelectInput(display, DefaultRootWindow(display), SubstructureNotifyMask); + } else { + // Some temporary window disappeared. Listen for next creation + XSelectInput(display, DefaultRootWindow(display), SubstructureNotifyMask); + } + // Main app window opened? + } + break; + default: + break; + } + } + *errorMessage = QString::fromLatin1("X11: Timed out waiting for toplevel %1ms").arg(timeOutMS); + return 0; +} + + +class X11_WindowManager : public WindowManager +{ +public: + X11_WindowManager(); + ~X11_WindowManager(); + +protected: + virtual bool isDisplayOpenImpl() const; + virtual bool openDisplayImpl(QString *errorMessage); + virtual QString waitForTopLevelWindowImpl(unsigned count, Q_PID, int timeOutMS, QString *errorMessage); + virtual bool sendCloseEventImpl(const QString &winId, Q_PID pid, QString *errorMessage); + +private: + Display *m_display; + const QByteArray m_displayVariable; + XErrorHandler m_oldErrorHandler; +}; + +X11_WindowManager::X11_WindowManager() : + m_display(0), + m_displayVariable(qgetenv("DISPLAY")), + m_oldErrorHandler(0) +{ +} + +X11_WindowManager::~X11_WindowManager() +{ + if (m_display) { + XSetErrorHandler(m_oldErrorHandler); + XCloseDisplay(m_display); + } +} + +bool X11_WindowManager::isDisplayOpenImpl() const +{ + return m_display != 0; +} + +bool X11_WindowManager::openDisplayImpl(QString *errorMessage) +{ + if (m_displayVariable.isEmpty()) { + *errorMessage = QLatin1String("X11: Display not set"); + return false; + } + m_display = XOpenDisplay(NULL); + if (!m_display) { + *errorMessage = QString::fromLatin1("X11: Cannot open display %1.").arg(QString::fromLocal8Bit(m_displayVariable)); + return false; + } + + m_oldErrorHandler = XSetErrorHandler(xErrorHandler); + return true; +} + +QString X11_WindowManager::waitForTopLevelWindowImpl(unsigned count, Q_PID, int timeOutMS, QString *errorMessage) +{ + const Window w = waitForTopLevelMapped(m_display, count, timeOutMS, errorMessage); + if (w == 0) + return QString(); + return QLatin1String("0x") + QString::number(w, 16); +} + + bool X11_WindowManager::sendCloseEventImpl(const QString &winId, Q_PID, QString *errorMessage) + { + // Get win id + bool ok; + const Window window = winId.toULong(&ok, 16); + if (!ok) { + *errorMessage = QString::fromLatin1("Invalid win id %1.").arg(winId); + return false; + } + // Send a window manager close event + XEvent ev; + memset(&ev, 0, sizeof (ev)); + ev.xclient.type = ClientMessage; + ev.xclient.window = window; + ev.xclient.message_type = XInternAtom(m_display, "WM_PROTOCOLS", true); + ev.xclient.format = 32; + ev.xclient.data.l[0] = XInternAtom(m_display, "WM_DELETE_WINDOW", false); + ev.xclient.data.l[1] = CurrentTime; + // Window disappeared or some error triggered? + unsigned errorCount = x11ErrorCount; + currentX11Function = "XSendEvent"; + XSendEvent(m_display, window, False, NoEventMask, &ev); + if (x11ErrorCount > errorCount) { + *errorMessage = QString::fromLatin1("Error sending event to win id %1.").arg(winId); + return false; + } + currentX11Function = "XSync"; + errorCount = x11ErrorCount; + XSync(m_display, False); + if (x11ErrorCount > errorCount) { + *errorMessage = QString::fromLatin1("Error sending event to win id %1 (XSync).").arg(winId); + return false; + } + return true; + } + +#endif + +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +// Windows + + QString winErrorMessage(unsigned long error) +{ + QString rc = QString::fromLatin1("#%1: ").arg(error); + ushort *lpMsgBuf; + + const int len = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error, 0, (LPTSTR)&lpMsgBuf, 0, NULL); + if (len) { + rc = QString::fromUtf16(lpMsgBuf, len); + LocalFree(lpMsgBuf); + } else { + rc += QString::fromLatin1("<unknown error>"); + } + return rc; +} + + class Win_WindowManager : public WindowManager + { + public: + Win_WindowManager() {} + + protected: + virtual bool isDisplayOpenImpl() const; + virtual bool openDisplayImpl(QString *errorMessage); + virtual QString waitForTopLevelWindowImpl(unsigned count, Q_PID, int timeOutMS, QString *errorMessage); + virtual bool sendCloseEventImpl(const QString &winId, Q_PID pid, QString *errorMessage); + + private: + }; + +bool Win_WindowManager::isDisplayOpenImpl() const +{ + return true; +} + +bool Win_WindowManager::openDisplayImpl(QString *) +{ + return true; +} + +// Enumerate window looking for toplevel of process id +struct FindProcessWindowEnumContext { + FindProcessWindowEnumContext(DWORD pid) : window(0),processId(pid) {} + + HWND window; + DWORD processId; +}; + +/* Check for the active main window of the Application + * of class QWidget. */ +static inline bool isQtMainWindow(HWND hwnd) +{ + static char buffer[MAX_PATH]; + if (!GetClassNameA(hwnd, buffer, MAX_PATH) || qstrcmp(buffer, "QWidget")) + return false; + WINDOWINFO windowInfo; + if (!GetWindowInfo(hwnd, &windowInfo)) + return false; + if (!(windowInfo.dwWindowStatus & WS_ACTIVECAPTION)) + return false; + // Check the style for a real mainwindow + const DWORD excluded = WS_DISABLED | WS_POPUP; + const DWORD required = WS_CAPTION | WS_SYSMENU | WS_VISIBLE; + return (windowInfo.dwStyle & excluded) == 0 + && (windowInfo.dwStyle & required) == required; +} + +static BOOL CALLBACK findProcessWindowEnumWindowProc(HWND hwnd, LPARAM lParam) +{ + DWORD processId = 0; + FindProcessWindowEnumContext *context= reinterpret_cast<FindProcessWindowEnumContext *>(lParam); + GetWindowThreadProcessId(hwnd, &processId); + if (context->processId == processId && isQtMainWindow(hwnd)) { + context->window = hwnd; + return FALSE; + } + return TRUE; +} + +QString Win_WindowManager::waitForTopLevelWindowImpl(unsigned /* count */, Q_PID pid, int timeOutMS, QString *errorMessage) +{ + QTime elapsed; + elapsed.start(); + // First, wait until the application is up + if (WaitForInputIdle(pid->hProcess, timeOutMS) != 0) { + *errorMessage = QString::fromLatin1("WaitForInputIdle time out after %1ms").arg(timeOutMS); + return QString(); + } + // Try to locate top level app window. App still might be in splash screen or initialization + // phase. + const int remainingMilliSeconds = qMax(timeOutMS - elapsed.elapsed(), 500); + const int attempts = 10; + const int intervalMilliSeconds = remainingMilliSeconds / attempts; + for (int a = 0; a < attempts; a++) { + FindProcessWindowEnumContext context(pid->dwProcessId); + EnumWindows(findProcessWindowEnumWindowProc, reinterpret_cast<LPARAM>(&context)); + if (context.window) + return QLatin1String("0x") + QString::number(reinterpret_cast<quintptr>(context.window), 16); + sleepMS(intervalMilliSeconds); + } + *errorMessage = QString::fromLatin1("Unable to find toplevel of process %1 after %2ms.").arg(pid->dwProcessId).arg(timeOutMS); + return QString(); +} + +bool Win_WindowManager::sendCloseEventImpl(const QString &winId, Q_PID, QString *errorMessage) +{ + // Convert window back. + quintptr winIdIntPtr; + QTextStream str(const_cast<QString*>(&winId), QIODevice::ReadOnly); + str.setIntegerBase(16); + str >> winIdIntPtr; + if (str.status() != QTextStream::Ok) { + *errorMessage = QString::fromLatin1("Invalid win id %1.").arg(winId); + return false; + } + if (!PostMessage(reinterpret_cast<HWND>(winIdIntPtr), WM_CLOSE, 0, 0)) { + *errorMessage = QString::fromLatin1("Cannot send event to 0x%1: %2").arg(winIdIntPtr, 0, 16).arg(winErrorMessage(GetLastError())); + return false; + } + return true; +} +#endif + +// ------- Default implementation + +WindowManager::WindowManager() +{ +} + +WindowManager::~WindowManager() +{ +} + +QSharedPointer<WindowManager> WindowManager::create() +{ +#ifdef Q_WS_X11 + return QSharedPointer<WindowManager>(new X11_WindowManager); +#endif +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + return QSharedPointer<WindowManager>(new Win_WindowManager); +#else + return QSharedPointer<WindowManager>(new WindowManager); +#endif +} + +static inline QString msgNoDisplayOpen() { return QLatin1String("No display opened."); } + +bool WindowManager::openDisplay(QString *errorMessage) +{ + if (isDisplayOpen()) + return true; + return openDisplayImpl(errorMessage); +} + +bool WindowManager::isDisplayOpen() const +{ + return isDisplayOpenImpl(); +} + + + +QString WindowManager::waitForTopLevelWindow(unsigned count, Q_PID pid, int timeOutMS, QString *errorMessage) +{ + if (!isDisplayOpen()) { + *errorMessage = msgNoDisplayOpen(); + return QString(); + } + return waitForTopLevelWindowImpl(count, pid, timeOutMS, errorMessage); +} + +bool WindowManager::sendCloseEvent(const QString &winId, Q_PID pid, QString *errorMessage) +{ + if (!isDisplayOpen()) { + *errorMessage = msgNoDisplayOpen(); + return false; + } + return sendCloseEventImpl(winId, pid, errorMessage); +} + +// Default Implementation +bool WindowManager::openDisplayImpl(QString *errorMessage) +{ + *errorMessage = QLatin1String("Not implemented."); + return false; +} + +bool WindowManager::isDisplayOpenImpl() const +{ + return false; +} + +QString WindowManager::waitForTopLevelWindowImpl(unsigned, Q_PID, int, QString *errorMessage) +{ + *errorMessage = QLatin1String("Not implemented."); + return QString(); +} + +bool WindowManager::sendCloseEventImpl(const QString &, Q_PID, QString *errorMessage) +{ + *errorMessage = QLatin1String("Not implemented."); + return false; +} + +void WindowManager::sleepMS(int milliSeconds) +{ + FriendlySleepyThread::sleepMS(milliSeconds); +} diff --git a/tests/auto/guiapplauncher/windowmanager.h b/tests/auto/guiapplauncher/windowmanager.h new file mode 100644 index 0000000..56e2eb9 --- /dev/null +++ b/tests/auto/guiapplauncher/windowmanager.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOWMANAGER_H +#define WINDOWMANAGER_H + +#include <QtCore/QSharedPointer> +#include <QtCore/QString> +#include <QtCore/QProcess> + +/* WindowManager: Provides functions to retrieve the top level window of + * an application and send it a close event. */ + +class WindowManager +{ + Q_DISABLE_COPY(WindowManager) +public: + static QSharedPointer<WindowManager> create(); + + virtual ~WindowManager(); + + bool openDisplay(QString *errorMessage); + bool isDisplayOpen() const; + + // Count: Number of toplevels, 1 for normal apps, 2 for apps with a splash screen + QString waitForTopLevelWindow(unsigned count, Q_PID pid, int timeOutMS, QString *errorMessage); + bool sendCloseEvent(const QString &winId, Q_PID pid, QString *errorMessage); + + static void sleepMS(int milliSeconds); + +protected: + WindowManager(); + + virtual bool openDisplayImpl(QString *errorMessage); + virtual bool isDisplayOpenImpl() const; + virtual QString waitForTopLevelWindowImpl(unsigned count, Q_PID pid, int timeOutMS, QString *errorMessage); + virtual bool sendCloseEventImpl(const QString &winId, Q_PID pid, QString *errorMessage); +}; + +#endif // WINDOWMANAGER_H diff --git a/tests/auto/uic/baseline/mainwindowbase.ui.h b/tests/auto/uic/baseline/mainwindowbase.ui.h index 46270a7..8472dbb 100644 --- a/tests/auto/uic/baseline/mainwindowbase.ui.h +++ b/tests/auto/uic/baseline/mainwindowbase.ui.h @@ -221,7 +221,6 @@ public: hboxLayout->setSpacing(4); hboxLayout->setContentsMargins(8, 8, 8, 8); hboxLayout->setObjectName(QString::fromUtf8("hboxLayout")); - hboxLayout->setContentsMargins(0, 0, 0, 0); helpview = new QTextEdit(widget); helpview->setObjectName(QString::fromUtf8("helpview")); helpview->setMinimumSize(QSize(200, 0)); diff --git a/tools/assistant/lib/qhelp_global.cpp b/tools/assistant/lib/qhelp_global.cpp index 980de27..749d2c9 100644 --- a/tools/assistant/lib/qhelp_global.cpp +++ b/tools/assistant/lib/qhelp_global.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the Qt Assistant. +** This file is part of the Qt Assistant of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 735e030..8996ee1 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3402,7 +3402,8 @@ void Configure::buildHostTools() QString pwd = QDir::currentPath(); QStringList hostToolsDirs; hostToolsDirs - << "src/tools"; + << "src/tools" + << "tools/linguist/lrelease"; if(dictionary["XQMAKESPEC"].startsWith("wince")) hostToolsDirs << "tools/checksdk"; diff --git a/tools/designer/src/lib/uilib/abstractformbuilder.cpp b/tools/designer/src/lib/uilib/abstractformbuilder.cpp index 24d2c01..eb3dc1c 100644 --- a/tools/designer/src/lib/uilib/abstractformbuilder.cpp +++ b/tools/designer/src/lib/uilib/abstractformbuilder.cpp @@ -285,23 +285,8 @@ void QAbstractFormBuilder::initialize(const DomUI *ui) if (!customWidgets.empty()) { QFormBuilderExtra *formBuilderPrivate = QFormBuilderExtra::instance(this); const DomCustomWidgetList::const_iterator cend = customWidgets.constEnd(); - for (DomCustomWidgetList::const_iterator it = customWidgets.constBegin(); it != cend; ++it) { - const DomCustomWidget *cw = *it; -#ifndef QT_FORMBUILDER_NO_SCRIPT - if (const DomScript *domScript = cw->elementScript()) { - const QString script = domScript->text(); - if (!script.isEmpty()) - formBuilderPrivate->storeCustomWidgetScript(cw->elementClass(), script); - } -#endif - const QString addPageMethod = cw->elementAddPageMethod(); - if (!addPageMethod.isEmpty()) - formBuilderPrivate->storeCustomWidgetAddPageMethod(cw->elementClass(), addPageMethod); - - const QString extends = cw->elementExtends(); - if (!extends.isEmpty()) - formBuilderPrivate->storeCustomWidgetBaseClass(cw->elementClass(), extends); - } + for (DomCustomWidgetList::const_iterator it = customWidgets.constBegin(); it != cend; ++it) + formBuilderPrivate->storeCustomWidgetData((*it)->elementClass(), *it); } } } diff --git a/tools/designer/src/lib/uilib/formbuilder.cpp b/tools/designer/src/lib/uilib/formbuilder.cpp index 0a722ba..2de8388 100644 --- a/tools/designer/src/lib/uilib/formbuilder.cpp +++ b/tools/designer/src/lib/uilib/formbuilder.cpp @@ -123,6 +123,8 @@ QWidget *QFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget) QFormBuilderExtra *fb = QFormBuilderExtra::instance(this); if (!fb->parentWidgetIsSet()) fb->setParentWidget(parentWidget); + // Is this a QLayoutWidget with a margin of 0: Not a known page-based + // container and no method for adding pages registered. fb->setProcessingLayoutWidget(false); if (ui_widget->attributeClass() == QFormBuilderStrings::instance().qWidgetClass && !ui_widget->hasAttributeNative() && parentWidget @@ -147,8 +149,11 @@ QWidget *QFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget) #ifndef QT_NO_DOCKWIDGET && !qobject_cast<QDockWidget *>(parentWidget) #endif - ) - fb->setProcessingLayoutWidget(true); + ) { + const QString parentClassName = QLatin1String(parentWidget->metaObject()->className()); + if (!fb->isCustomWidgetContainer(parentClassName)) + fb->setProcessingLayoutWidget(true); + } return QAbstractFormBuilder::create(ui_widget, parentWidget); } diff --git a/tools/designer/src/lib/uilib/formbuilderextra.cpp b/tools/designer/src/lib/uilib/formbuilderextra.cpp index 0e803fb..ce71d59 100644 --- a/tools/designer/src/lib/uilib/formbuilderextra.cpp +++ b/tools/designer/src/lib/uilib/formbuilderextra.cpp @@ -65,6 +65,23 @@ void uiLibWarning(const QString &message) { qWarning("Designer: %s", qPrintable(message)); } + +QFormBuilderExtra::CustomWidgetData::CustomWidgetData() : + isContainer(false) +{ +} + +QFormBuilderExtra::CustomWidgetData::CustomWidgetData(const DomCustomWidget *dcw) : + addPageMethod(dcw->elementAddPageMethod()), + baseClass(dcw->elementExtends()), + isContainer(dcw->hasElementContainer() && dcw->elementContainer() != 0) +{ +#ifndef QT_FORMBUILDER_NO_SCRIPT + if (const DomScript *domScript = dcw->elementScript()) + script = domScript->text(); +#endif +} + QFormBuilderExtra::QFormBuilderExtra() : m_layoutWidget(false), m_resourceBuilder(0), @@ -85,8 +102,8 @@ void QFormBuilderExtra::clear() m_parentWidgetIsSet = false; #ifndef QT_FORMBUILDER_NO_SCRIPT m_FormScriptRunner.clearErrors(); - m_customWidgetScriptHash.clear(); #endif + m_customWidgetDataHash.clear(); m_buttonGroups.clear(); } @@ -160,45 +177,44 @@ QFormScriptRunner &QFormBuilderExtra::formScriptRunner() return m_FormScriptRunner; } -void QFormBuilderExtra::storeCustomWidgetScript(const QString &className, const QString &script) -{ - m_customWidgetScriptHash.insert(className, script); -} - QString QFormBuilderExtra::customWidgetScript(const QString &className) const { - const CustomWidgetScriptHash::const_iterator it = m_customWidgetScriptHash.constFind(className); - if ( it == m_customWidgetScriptHash.constEnd()) - return QString(); - return it.value(); + const QHash<QString, CustomWidgetData>::const_iterator it = m_customWidgetDataHash.constFind(className); + if (it != m_customWidgetDataHash.constEnd()) + return it.value().script; + return QString(); } #endif -void QFormBuilderExtra::storeCustomWidgetBaseClass(const QString &className, const QString &baseClassName) +void QFormBuilderExtra::storeCustomWidgetData(const QString &className, const DomCustomWidget *d) { - m_customWidgetBaseClassHash.insert(className, baseClassName); + if (d) + m_customWidgetDataHash.insert(className, CustomWidgetData(d)); } QString QFormBuilderExtra::customWidgetBaseClass(const QString &className) const { - const QHash<QString, QString>::const_iterator it = m_customWidgetBaseClassHash.constFind(className); - if (it == m_customWidgetBaseClassHash.constEnd()) - return QString(); - return it.value(); + const QHash<QString, CustomWidgetData>::const_iterator it = m_customWidgetDataHash.constFind(className); + if (it != m_customWidgetDataHash.constEnd()) + return it.value().baseClass; + return QString(); } -void QFormBuilderExtra::storeCustomWidgetAddPageMethod(const QString &className, const QString &ct) +QString QFormBuilderExtra::customWidgetAddPageMethod(const QString &className) const { - m_customWidgetAddPageMethodHash.insert(className, ct); + const QHash<QString, CustomWidgetData>::const_iterator it = m_customWidgetDataHash.constFind(className); + if (it != m_customWidgetDataHash.constEnd()) + return it.value().addPageMethod; + return QString(); } -QString QFormBuilderExtra::customWidgetAddPageMethod(const QString &className) const +bool QFormBuilderExtra::isCustomWidgetContainer(const QString &className) const { - const QHash<QString, QString>::const_iterator it = m_customWidgetAddPageMethodHash.constFind(className); - if (it == m_customWidgetAddPageMethodHash.constEnd()) - return QString(); - return it.value(); + const QHash<QString, CustomWidgetData>::const_iterator it = m_customWidgetDataHash.constFind(className); + if (it != m_customWidgetDataHash.constEnd()) + return it.value().isContainer; + return false; } namespace { diff --git a/tools/designer/src/lib/uilib/formbuilderextra_p.h b/tools/designer/src/lib/uilib/formbuilderextra_p.h index ce4d25b..3bcd1eb 100644 --- a/tools/designer/src/lib/uilib/formbuilderextra_p.h +++ b/tools/designer/src/lib/uilib/formbuilderextra_p.h @@ -82,6 +82,7 @@ namespace QFormInternal class DomButtonGroups; class DomButtonGroup; +class DomCustomWidget; class QAbstractFormBuilder; class QResourceBuilder; @@ -92,6 +93,16 @@ class QDESIGNER_UILIB_EXPORT QFormBuilderExtra QFormBuilderExtra(); ~QFormBuilderExtra(); public: + struct CustomWidgetData { + CustomWidgetData(); + explicit CustomWidgetData(const DomCustomWidget *dc); + + QString addPageMethod; + QString script; + QString baseClass; + bool isContainer; + }; + void clear(); bool applyPropertyInternally(QObject *o, const QString &propertyName, const QVariant &value); @@ -107,7 +118,6 @@ public: #ifndef QT_FORMBUILDER_NO_SCRIPT QFormScriptRunner &formScriptRunner(); - void storeCustomWidgetScript(const QString &className, const QString &script); QString customWidgetScript(const QString &className) const; #endif @@ -123,11 +133,10 @@ public: static QFormBuilderExtra *instance(const QAbstractFormBuilder *afb); static void removeInstance(const QAbstractFormBuilder *afb); - void storeCustomWidgetAddPageMethod(const QString &className, const QString &ct); + void storeCustomWidgetData(const QString &className, const DomCustomWidget *d); QString customWidgetAddPageMethod(const QString &className) const; - - void storeCustomWidgetBaseClass(const QString &className, const QString &baseClassName); QString customWidgetBaseClass(const QString &className) const; + bool isCustomWidgetContainer(const QString &className) const; // --- Hash used in creating button groups on demand. Store a map of name and pair of dom group and real group void registerButtonGroups(const DomButtonGroups *groups); @@ -169,13 +178,9 @@ private: #ifndef QT_FORMBUILDER_NO_SCRIPT QFormScriptRunner m_FormScriptRunner; - - typedef QHash<QString, QString> CustomWidgetScriptHash; - CustomWidgetScriptHash m_customWidgetScriptHash; #endif - QHash<QString, QString> m_customWidgetAddPageMethodHash; - QHash<QString, QString> m_customWidgetBaseClassHash; + QHash<QString, CustomWidgetData> m_customWidgetDataHash; ButtonGroupHash m_buttonGroups; diff --git a/tools/linguist/lrelease/lrelease.pro b/tools/linguist/lrelease/lrelease.pro index 01091b3..28a741d 100644 --- a/tools/linguist/lrelease/lrelease.pro +++ b/tools/linguist/lrelease/lrelease.pro @@ -2,19 +2,10 @@ TEMPLATE = app TARGET = lrelease DESTDIR = ../../../bin -QT -= gui - -CONFIG += qt warn_on console -CONFIG -= app_bundle - -build_all:!build_pass { - CONFIG -= build_all - CONFIG += release -} - DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII SOURCES += main.cpp +include(../../../src/tools/bootstrap/bootstrap.pri) include(../shared/formats.pri) include(../shared/proparser.pri) diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index 742c2e6..c45459a 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -42,7 +42,10 @@ #include "translator.h" #include "proreader.h" +#ifndef QT_BOOTSTRAPPED #include <QtCore/QCoreApplication> +#include <QtCore/QTranslator> +#endif #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QFile> @@ -51,7 +54,14 @@ #include <QtCore/QString> #include <QtCore/QStringList> #include <QtCore/QTextStream> -#include <QtCore/QTranslator> + +#ifdef QT_BOOTSTRAPPED +static void initBinaryDir( +#ifndef Q_OS_WIN + const char *argv0 +#endif + ); +#endif static void printOut(const QString & out) { @@ -157,11 +167,18 @@ static bool releaseTsFile(const QString& tsFileName, int main(int argc, char **argv) { +#ifdef QT_BOOTSTRAPPED + initBinaryDir( +#ifndef Q_OS_WIN + argv[0] +#endif + ); +#else QCoreApplication app(argc, argv); - QStringList args = app.arguments(); QTranslator translator; if (translator.load(QLatin1String("lrelease_") + QLocale::system().name())) app.installTranslator(&translator); +#endif ConversionData cd; cd.m_verbose = true; // the default is true starting with Qt 4.2 @@ -171,50 +188,50 @@ int main(int argc, char **argv) QString outputFile; for (int i = 1; i < argc; ++i) { - if (args[i] == QLatin1String("-compress")) { + if (!strcmp(argv[i], "-compress")) { cd.m_saveMode = SaveStripped; continue; - } else if (args[i] == QLatin1String("-idbased")) { + } else if (!strcmp(argv[i], "-idbased")) { cd.m_idBased = true; continue; - } else if (args[i] == QLatin1String("-nocompress")) { + } else if (!strcmp(argv[i], "-nocompress")) { cd.m_saveMode = SaveEverything; continue; - } else if (args[i] == QLatin1String("-removeidentical")) { + } else if (!strcmp(argv[i], "-removeidentical")) { removeIdentical = true; continue; - } else if (args[i] == QLatin1String("-nounfinished")) { + } else if (!strcmp(argv[i], "-nounfinished")) { cd.m_ignoreUnfinished = true; continue; - } else if (args[i] == QLatin1String("-markuntranslated")) { + } else if (!strcmp(argv[i], "-markuntranslated")) { if (i == argc - 1) { printUsage(); return 1; } - cd.m_unTrPrefix = args[++i]; - } else if (args[i] == QLatin1String("-silent")) { + cd.m_unTrPrefix = QString::fromLocal8Bit(argv[++i]); + } else if (!strcmp(argv[i], "-silent")) { cd.m_verbose = false; continue; - } else if (args[i] == QLatin1String("-verbose")) { + } else if (!strcmp(argv[i], "-verbose")) { cd.m_verbose = true; continue; - } else if (args[i] == QLatin1String("-version")) { + } else if (!strcmp(argv[i], "-version")) { printOut(QCoreApplication::tr( "lrelease version %1\n").arg(QLatin1String(QT_VERSION_STR)) ); return 0; - } else if (args[i] == QLatin1String("-qm")) { + } else if (!strcmp(argv[i], "-qm")) { if (i == argc - 1) { printUsage(); return 1; } - outputFile = args[++i]; - } else if (args[i] == QLatin1String("-help")) { + outputFile = QString::fromLocal8Bit(argv[++i]); + } else if (!strcmp(argv[i], "-help")) { printUsage(); return 0; - } else if (args[i].startsWith(QLatin1Char('-'))) { + } else if (argv[i][0] == '-') { printUsage(); return 1; } else { - inputFiles << args[i]; + inputFiles << QString::fromLocal8Bit(argv[i]); } } @@ -261,3 +278,79 @@ int main(int argc, char **argv) return 0; } + +#ifdef QT_BOOTSTRAPPED + +#ifdef Q_OS_WIN +# include <windows.h> +#endif + +static QString binDir; + +static void initBinaryDir( +#ifndef Q_OS_WIN + const char *_argv0 +#endif + ) +{ +#ifdef Q_OS_WIN + wchar_t module_name[MAX_PATH]; + GetModuleFileName(0, module_name, MAX_PATH); + QFileInfo filePath = QString::fromWCharArray(module_name); + binDir = filePath.filePath(); +#else + QString argv0 = QFile::decodeName(QByteArray(_argv0)); + QString absPath; + + if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) { + /* + If argv0 starts with a slash, it is already an absolute + file path. + */ + absPath = argv0; + } else if (argv0.contains(QLatin1Char('/'))) { + /* + If argv0 contains one or more slashes, it is a file path + relative to the current directory. + */ + absPath = QDir::current().absoluteFilePath(argv0); + } else { + /* + Otherwise, the file path has to be determined using the + PATH environment variable. + */ + QByteArray pEnv = qgetenv("PATH"); + QDir currentDir = QDir::current(); + QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1String(":")); + for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) { + if ((*p).isEmpty()) + continue; + QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0); + QFileInfo candidate_fi(candidate); + if (candidate_fi.exists() && !candidate_fi.isDir()) { + binDir = candidate_fi.canonicalPath(); + return; + } + } + return; + } + + QFileInfo fi(absPath); + if (fi.exists()) + binDir = fi.canonicalPath(); +#endif +} + +QT_BEGIN_NAMESPACE + +// The name is hard-coded in QLibraryInfo +QString qmake_libraryInfoFile() +{ + if (binDir.isEmpty()) + return QString(); + return QDir(binDir).filePath(QString::fromLatin1("qt.conf")); +} + +QT_END_NAMESPACE + +#endif // QT_BOOTSTRAPPED diff --git a/tools/linguist/shared/proparserutils.h b/tools/linguist/shared/proparserutils.h index 9a83733..1ed3d6c 100644 --- a/tools/linguist/shared/proparserutils.h +++ b/tools/linguist/shared/proparserutils.h @@ -43,10 +43,35 @@ #define PROPARSERUTILS_H #include <QtCore/QDir> +#ifndef QT_BOOTSTRAPPED #include <QtCore/QLibraryInfo> +#endif QT_BEGIN_NAMESPACE +#ifdef QT_BOOTSTRAPPED +// this is a stripped down version of the one found in QtCore +class QLibraryInfo +{ +public: + enum LibraryLocation + { + PrefixPath, + DocumentationPath, + HeadersPath, + LibrariesPath, + BinariesPath, + PluginsPath, + DataPath, + TranslationsPath, + SettingsPath, + DemosPath, + ExamplesPath + }; + static QString location(LibraryLocation); +}; +#endif + // Pre- and postcondition macros #define PRE(cond) do {if (!(cond))qt_assert(#cond,__FILE__,__LINE__);} while (0) #define POST(cond) do {if (!(cond))qt_assert(#cond,__FILE__,__LINE__);} while (0) diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index 99aedef..e4c26bc 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -41,7 +41,9 @@ #include "translator.h" +#ifndef QT_BOOTSTRAPPED #include <QtCore/QCoreApplication> +#endif #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QFile> diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp index bc27daf..05fc6e5 100644 --- a/tools/linguist/shared/translator.cpp +++ b/tools/linguist/shared/translator.cpp @@ -56,6 +56,16 @@ QT_BEGIN_NAMESPACE +#ifdef QT_BOOTSTRAPPED +QString QObject::tr(const char *sourceText, const char *, int n) +{ + QString ret = QString::fromLatin1(sourceText); + if (n >= 0) + ret.replace(QLatin1String("%n"), QString::number(n)); + return ret; +} +#endif + Translator::Translator() : m_codecName("ISO-8859-1"), m_locationsType(AbsoluteLocations) diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index eec704a..f29317b 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -54,6 +54,18 @@ QT_BEGIN_NAMESPACE +#ifdef QT_BOOTSTRAPPED +struct QObject { + static QString tr(const char *sourceText, const char * = 0, int n = -1); +}; +struct QCoreApplication : public QObject { + enum Encoding { CodecForTr }; + static QString translate(const char *, const char *sourceText, const char * = 0, + Encoding = CodecForTr, int n = -1) + { return tr(sourceText, 0, n); } +}; +#endif + class QIODevice; // A struct of "interesting" data passed to and from the load and save routines diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index f0ddade..957f04f 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -2300,7 +2300,8 @@ void HtmlGenerator::generateCompactList(const Node *relative, << " </b>"; } out() << "</td>\n"; - + + out() << "<td>"; if ((currentParagraphNo[i] < NumParagraphs) && !paragraphName[currentParagraphNo[i]].isEmpty()) { NodeMap::Iterator it; @@ -2308,7 +2309,6 @@ void HtmlGenerator::generateCompactList(const Node *relative, for (j = 0; j < currentOffsetInParagraph[i]; j++) ++it; - out() << "<td>"; // Previously, we used generateFullName() for this, but we // require some special formatting. out() << "<a href=\"" @@ -2322,8 +2322,8 @@ void HtmlGenerator::generateCompactList(const Node *relative, generateFullName(it.value()->parent(), relative, marker); out() << ")"; } - out() << "</td>\n"; - } + } + out() << "</td>\n"; currentOffset[i]++; currentOffsetInParagraph[i]++; diff --git a/tools/qtestlib/wince/cetest/bootstrapped.pri b/tools/qtestlib/wince/cetest/bootstrapped.pri index b9c4b2b..07d86fd 100644 --- a/tools/qtestlib/wince/cetest/bootstrapped.pri +++ b/tools/qtestlib/wince/cetest/bootstrapped.pri @@ -14,6 +14,7 @@ SOURCES += \ $$QT_SOURCE_TREE/src/corelib/io/qdiriterator.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qiodevice.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qbuffer.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qdatastream.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qtextstream.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qurl.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qsettings.cpp \ diff --git a/translations/translations.pri b/translations/translations.pri index c77876a..c423809 100644 --- a/translations/translations.pri +++ b/translations/translations.pri @@ -8,13 +8,8 @@ defineReplace(prependAll) { return ($$result) } -defineReplace(fixPath) { - win32:1 ~= s|/|\\| - return ($$1) -} - -LUPDATE = $$fixPath($$QT_BUILD_TREE/bin/lupdate) -locations relative -no-ui-lines -LRELEASE = $$fixPath($$QT_BUILD_TREE/bin/lrelease) +LUPDATE = $$QT_BUILD_TREE/bin/lupdate -locations relative -no-ui-lines +win32:LUPDATE ~= s|/|\\|g ###### Qt Libraries @@ -41,27 +36,18 @@ ts-qt.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ -ts $$prependAll($$QT_SOURCE_TREE/translations/qt_,$$QT_TS,.ts)) ts-qt.depends = sub-tools -qm-qt.commands = $$LRELEASE $$prependAll($$QT_SOURCE_TREE/translations/qt_,$$QT_TS,.ts) -qm-qt.depends = sub-tools - ###### Designer ts-designer.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/designer/translations/translations.pro) ts-designer.depends = sub-tools -qm-designer.commands = $$LRELEASE $$QT_SOURCE_TREE/tools/designer/translations/translations.pro -qm-designer.depends = sub-tools - ###### Linguist ts-linguist.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/linguist/linguist/linguist.pro) ts-linguist.depends = sub-tools -qm-linguist.commands = $$LRELEASE $$QT_SOURCE_TREE/tools/linguist/linguist/linguist.pro -qm-linguist.depends = sub-tools - ###### Assistant ts-assistant.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ @@ -72,36 +58,21 @@ ts-assistant.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/assistant/translations/translations_adp.pro) ts-assistant.depends = sub-tools -qm-assistant.commands = ($$LRELEASE $$QT_SOURCE_TREE/tools/assistant/translations/translations.pro \ - && $$LRELEASE \ - $$QT_SOURCE_TREE/tools/assistant/translations/qt_help.pro \ - && $$LRELEASE \ - $$QT_SOURCE_TREE/tools/assistant/translations/translations_adp.pro) -qm-assistant.depends = sub-tools - ###### Qtconfig ts-qtconfig.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/qtconfig/translations/translations.pro) ts-qtconfig.depends = sub-tools -qm-qtconfig.commands = $$LRELEASE $$QT_SOURCE_TREE/tools/qtconfig/translations/translations.pro -qm-qtconfig.depends = sub-tools - ###### Qvfp ts-qvfb.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/qvfb/translations/translations.pro) ts-qvfb.depends = sub-tools -qm-qvfb.commands = $$LRELEASE $$QT_SOURCE_TREE/tools/qvfb/translations/translations.pro -qm-qvfb.depends = sub-tools - ###### Overall Rules ts.depends = ts-qt ts-designer ts-linguist ts-assistant ts-qtconfig ts-qvfb -qm.depends = qm-qt qm-designer qm-linguist qm-assistant qm-qtconfig qm-qvfb QMAKE_EXTRA_TARGETS += ts-qt ts-designer ts-linguist ts-assistant ts-qtconfig ts-qvfb \ - qm-qt qm-designer qm-linguist qm-assistant qm-qtconfig qm-qvfb \ - ts qm + ts diff --git a/translations/translations.pro b/translations/translations.pro new file mode 100644 index 0000000..22f0ace --- /dev/null +++ b/translations/translations.pro @@ -0,0 +1,42 @@ +TRANSLATIONS = $$files(*.ts) + +LRELEASE = $$QT_BUILD_TREE/bin/lrelease +win32:LRELEASE ~= s|/|\\|g + +contains(TEMPLATE_PREFIX, vc):vcproj = 1 + +TEMPLATE = app +TARGET = qm_phony_target +CONFIG -= qt separate_debug_info +QT = +LIBS = + +updateqm.input = TRANSLATIONS +updateqm.output = ${QMAKE_FILE_BASE}.qm +isEmpty(vcproj):updateqm.variable_out = PRE_TARGETDEPS +updateqm.commands = @echo lrelease ${QMAKE_FILE_IN}; $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +updateqm.name = LRELEASE ${QMAKE_FILE_IN} +updateqm.CONFIG += no_link +QMAKE_EXTRA_COMPILERS += updateqm + +isEmpty(vcproj) { + QMAKE_LINK = @: IGNORE THIS LINE + OBJECTS_DIR = + win32:CONFIG -= embed_manifest_exe +} else { + CONFIG += console + PHONY_DEPS = . + phony_src.input = PHONY_DEPS + phony_src.output = phony.c + phony_src.variable_out = GENERATED_SOURCES + phony_src.commands = echo int main() { return 0; } > phony.c + phony_src.name = CREATE phony.c + phony_src.CONFIG += combine + QMAKE_EXTRA_COMPILERS += phony_src +} + +translations.path = $$[QT_INSTALL_TRANSLATIONS] +translations.files = $$TRANSLATIONS +translations.files ~= s,\\.ts$,.qm,g +translations.CONFIG += no_check_exist +INSTALLS += translations |