diff options
author | Frans Englich <frans.englich@nokia.com> | 2009-11-20 12:19:09 (GMT) |
---|---|---|
committer | Frans Englich <frans.englich@nokia.com> | 2009-11-20 12:19:09 (GMT) |
commit | b5294497836db44261c97cfeab28d0ac4f8402f1 (patch) | |
tree | c4331314445b41166ce2cd22a80c9fb9f46b5023 /tests | |
parent | 2473ab1cf217a989849190cbfa47fe312698adb9 (diff) | |
parent | 1b8d5bec5763708c66e7bd586aee3df7f94b5cb5 (diff) | |
download | Qt-b5294497836db44261c97cfeab28d0ac4f8402f1.zip Qt-b5294497836db44261c97cfeab28d0ac4f8402f1.tar.gz Qt-b5294497836db44261c97cfeab28d0ac4f8402f1.tar.bz2 |
Merge branch '4.6' into mmfphonon
Conflicts:
demos/qmediaplayer/mediaplayer.cpp
Diffstat (limited to 'tests')
42 files changed, 2795 insertions, 155 deletions
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/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index d4f2ff4..36d25fe 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -77,7 +77,7 @@ private: tst_Headers::tst_Headers() : copyrightPattern("\\*\\* Copyright \\(C\\) 20[0-9][0-9] Nokia Corporation and/or its subsidiary\\(-ies\\)."), - licensePattern("\\*\\* \\$QT_BEGIN_LICENSE:(LGPL|BSD|3RDPARTY)\\$"), + licensePattern("\\*\\* \\$QT_BEGIN_LICENSE:(LGPL|BSD|3RDPARTY|LGPL-ONLY)\\$"), moduleTest(QLatin1String("\\*\\* This file is part of the .+ of the Qt Toolkit.")) { } diff --git a/tests/auto/networkselftest/tst_networkselftest.cpp b/tests/auto/networkselftest/tst_networkselftest.cpp index a09d998..f13bcad 100644 --- a/tests/auto/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/networkselftest/tst_networkselftest.cpp @@ -80,6 +80,9 @@ private slots: void httpProxyNtlmAuth(); void socks5Proxy(); void socks5ProxyAuth(); + + // ssl supported test + void supportsSsl(); }; class Chat @@ -717,5 +720,14 @@ void tst_NetworkSelfTest::socks5ProxyAuth() ); } +void tst_NetworkSelfTest::supportsSsl() +{ +#ifdef QT_NO_OPENSSL + QFAIL("SSL not compiled in"); +#else + QVERIFY(QSslSocket::supportsSsl()); +#endif +} + QTEST_MAIN(tst_NetworkSelfTest) #include "tst_networkselftest.moc" diff --git a/tests/auto/qalgorithms/tst_qalgorithms.cpp b/tests/auto/qalgorithms/tst_qalgorithms.cpp index 176a451..1e24efe 100644 --- a/tests/auto/qalgorithms/tst_qalgorithms.cpp +++ b/tests/auto/qalgorithms/tst_qalgorithms.cpp @@ -620,8 +620,8 @@ void tst_QAlgorithms::test_qBinaryFind() //-42 means not found if (resultValue == -42) { - QVERIFY(qBinaryFind(data.constBegin(), data.constEnd(), resultValue) == data.end()); - QVERIFY(qBinaryFind(data, resultValue) == data.end()); + QVERIFY(qBinaryFind(data.constBegin(), data.constEnd(), resultValue) == data.constEnd()); + QVERIFY(qBinaryFind(data, resultValue) == data.constEnd()); QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue) == data.end()); QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue, qLess<int>()) == data.end()); return; diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index e903ab5..af71961 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -2290,11 +2290,8 @@ void tst_QComboBox::setItemDelegate() QComboBox comboBox; QStyledItemDelegate *itemDelegate = new QStyledItemDelegate; comboBox.setItemDelegate(itemDelegate); -#ifdef Q_CC_MWERKS + // the cast is a workaround for the XLC and Metrowerks compilers QCOMPARE(static_cast<QStyledItemDelegate *>(comboBox.itemDelegate()), itemDelegate); -#else - QCOMPARE(comboBox.itemDelegate(), itemDelegate); -#endif } void tst_QComboBox::task253944_itemDelegateIsReset() @@ -2303,19 +2300,13 @@ void tst_QComboBox::task253944_itemDelegateIsReset() QStyledItemDelegate *itemDelegate = new QStyledItemDelegate; comboBox.setItemDelegate(itemDelegate); + // the casts are workarounds for the XLC and Metrowerks compilers + comboBox.setEditable(true); -#ifdef Q_CC_MWERKS QCOMPARE(static_cast<QStyledItemDelegate *>(comboBox.itemDelegate()), itemDelegate); -#else - QCOMPARE(comboBox.itemDelegate(), itemDelegate); -#endif comboBox.setStyleSheet("QComboBox { border: 1px solid gray; }"); -#ifdef Q_CC_MWERKS QCOMPARE(static_cast<QStyledItemDelegate *>(comboBox.itemDelegate()), itemDelegate); -#else - QCOMPARE(comboBox.itemDelegate(), itemDelegate); -#endif } diff --git a/tests/auto/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/tests/auto/qcommandlinkbutton/tst_qcommandlinkbutton.cpp index 33226bf..f833196 100644 --- a/tests/auto/qcommandlinkbutton/tst_qcommandlinkbutton.cpp +++ b/tests/auto/qcommandlinkbutton/tst_qcommandlinkbutton.cpp @@ -51,6 +51,7 @@ #include <qtimer.h> #include <QDialog> #include <QGridLayout> +#include <QPainter> Q_DECLARE_METATYPE(QCommandLinkButton*) @@ -83,7 +84,8 @@ private slots: void clicked(); void toggled(); void defaultAndAutoDefault(); - void setAutoRepeat(); + void setAutoRepeat(); + void heightForWithWithIcon(); protected slots: void resetCounters(); @@ -106,17 +108,17 @@ private: void tst_QCommandLinkButton::getSetCheck() { QCommandLinkButton obj1; - + QString text("mytext"); QVERIFY(obj1.description().isEmpty()); obj1.setDescription(text); QVERIFY(obj1.description() == text); - + QVERIFY(obj1.text().isEmpty()); obj1.setText(text); QVERIFY(obj1.text() == text); - - + + QMenu *var1 = new QMenu; obj1.setMenu(var1); QCOMPARE(var1, obj1.menu()); @@ -393,8 +395,8 @@ void tst_QCommandLinkButton::setAccel() QTest::qWait(100); } - QVERIFY(testWidget->isActiveWindow()); - + QVERIFY(testWidget->isActiveWindow()); + QTest::keyClick( testWidget, 'A', Qt::AltModifier ); QTest::qWait( 500 ); QVERIFY( click_count == 1 ); @@ -556,5 +558,33 @@ void tst_QCommandLinkButton::defaultAndAutoDefault() } } +void tst_QCommandLinkButton::heightForWithWithIcon() +{ + QWidget mainWin; + + QPixmap pixmap(64, 64); + { + pixmap.fill(Qt::white); + QPainter painter(&pixmap); + painter.setBrush(Qt::black); + painter.drawEllipse(0, 0, 63, 63); + } + + QCommandLinkButton *largeIconButton = new QCommandLinkButton(QString("Large Icon"), + QString("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris nibh lectus, adipiscing eu."), + &mainWin); + largeIconButton->setIconSize(QSize(64, 64)); + largeIconButton->setIcon(pixmap); + + QVBoxLayout *layout = new QVBoxLayout(); + layout->addWidget(largeIconButton); + layout->addStretch(); + mainWin.setLayout(layout); + mainWin.showMaximized(); + QTest::qWaitForWindowShown(&mainWin); + QVERIFY(largeIconButton->height() > 68); //enough room for the icon + +} + QTEST_MAIN(tst_QCommandLinkButton) #include "tst_qcommandlinkbutton.moc" diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index 91050f5..a2c4758 100644 --- a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -133,7 +133,7 @@ tst_QDBusAbstractInterface::tst_QDBusAbstractInterface() void tst_QDBusAbstractInterface::initTestCase() { // enable debugging temporarily: - putenv("QDBUS_DEBUG=1"); + //putenv("QDBUS_DEBUG=1"); // register the object QDBusConnection con = QDBusConnection::sessionBus(); @@ -465,6 +465,7 @@ void tst_QDBusAbstractInterface::followSignal() QDBusConnectionInterface::DontAllowReplacement); QVERIFY(r.isValid() && r.value() == QDBusConnectionInterface::ServiceRegistered); QVERIFY(con.interface()->isServiceRegistered(serviceToFollow)); + QCoreApplication::instance()->processEvents(); // emit the signal again: emit targetObj.voidSignal(); diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index 62d6342..bcd5bd9 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -234,6 +234,7 @@ void tst_QDBusInterface::notValid() void tst_QDBusInterface::invalidAfterServiceOwnerChanged() { + // this test is technically the same as tst_QDBusAbstractInterface::followSignal QDBusConnection conn = QDBusConnection::sessionBus(); QDBusConnectionInterface *connIface = conn.interface(); @@ -249,7 +250,7 @@ void tst_QDBusInterface::invalidAfterServiceOwnerChanged() QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(!invalidInterface.isValid()); + QVERIFY(invalidInterface.isValid()); } void tst_QDBusInterface::introspect() diff --git a/tests/auto/qdbusperformance/tst_qdbusperformance.cpp b/tests/auto/qdbusperformance/tst_qdbusperformance.cpp index 7227d5d..066b5b2 100644 --- a/tests/auto/qdbusperformance/tst_qdbusperformance.cpp +++ b/tests/auto/qdbusperformance/tst_qdbusperformance.cpp @@ -80,6 +80,14 @@ Q_DECLARE_METATYPE(QVariant) void tst_QDBusPerformance::initTestCase() { + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, + QDBusServiceWatcher::WatchForRegistration); + connect(&watcher, SIGNAL(serviceRegistered(QString)), + &QTestEventLoop::instance(), SLOT(exitLoop())); + #ifdef Q_OS_WIN proc.start("server"); #else @@ -87,19 +95,7 @@ void tst_QDBusPerformance::initTestCase() #endif QVERIFY(proc.waitForStarted()); - QDBusConnection con = QDBusConnection::sessionBus(); - QVERIFY(con.isConnected()); - - connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), - &QTestEventLoop::instance(), SLOT(exitLoop())); - QTime timer; - timer.start(); - - while (timer.elapsed() < 5000) { - QTestEventLoop::instance().enterLoop(5); - if (con.interface()->isServiceRegistered(serviceName)) - break; - } + QTestEventLoop::instance().enterLoop(5); QVERIFY(con.interface()->isServiceRegistered(serviceName)); remote = new QDBusInterface(serviceName, "/", "com.trolltech.autotests.Performance", con, this); diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index b3d6fd9..cf46ce1 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -210,6 +210,7 @@ private slots: void task167217(); void openDirectory(); + void writeNothing(); public: // disabled this test for the moment... it hangs @@ -750,6 +751,7 @@ void tst_QFile::readAllStdin() QProcess process; process.start("stdinprocess/stdinprocess all"); + QVERIFY( process.waitForStarted() ); for (int i = 0; i < 5; ++i) { QTest::qWait(1000); process.write(lotsOfData); @@ -2489,13 +2491,13 @@ void tst_QFile::readEof() } QByteArray ret = file.read(10); - QVERIFY(ret.isNull()); + QVERIFY(ret.isEmpty()); QVERIFY(file.error() == QFile::NoError); QVERIFY(file.atEnd()); // Do it again to ensure that we get the same result ret = file.read(10); - QVERIFY(ret.isNull()); + QVERIFY(ret.isEmpty()); QVERIFY(file.error() == QFile::NoError); QVERIFY(file.atEnd()); } @@ -2840,5 +2842,16 @@ void tst_QFile::openStandardStreams() } } +void tst_QFile::writeNothing() +{ + for (int i = 0; i < 3; ++i) { + QFile file("file.txt"); + QVERIFY( openFile(file, QIODevice::WriteOnly | QIODevice::Unbuffered, FileType(i)) ); + QVERIFY( 0 == file.write((char *)0, 0) ); + QCOMPARE( file.error(), QFile::NoError ); + closeFile(file); + } +} + QTEST_MAIN(tst_QFile) #include "tst_qfile.moc" diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index e80f8e0..efb1b56 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -72,6 +72,7 @@ private slots: void veryNarrowElidedText(); void averageCharWidth(); void elidedMultiLength(); + void elidedMultiLengthF(); void bearingIncludedInBoundingRect(); }; @@ -218,13 +219,13 @@ void tst_QFontMetrics::averageCharWidth() QVERIFY(fmf.averageCharWidth() != 0); } -void tst_QFontMetrics::elidedMultiLength() +template<class FontMetrics> void elidedMultiLength_helper() { QString text1 = "Long Text 1\x9cShorter\x9csmall"; QString text1_long = "Long Text 1"; QString text1_short = "Shorter"; QString text1_small = "small"; - QFontMetrics fm = QFontMetrics(QFont()); + FontMetrics fm = FontMetrics(QFont()); int width_long = fm.size(0, text1_long).width(); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, 8000), text1_long); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long + 1), text1_long); @@ -238,7 +239,16 @@ void tst_QFontMetrics::elidedMultiLength() QString text1_el = QString::fromLatin1("s") + ellipsisChar; int width_small = fm.width(text1_el); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_small + 1), text1_el); +} +void tst_QFontMetrics::elidedMultiLength() +{ + elidedMultiLength_helper<QFontMetrics>(); +} + +void tst_QFontMetrics::elidedMultiLengthF() +{ + elidedMultiLength_helper<QFontMetricsF>(); } void tst_QFontMetrics::bearingIncludedInBoundingRect() diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index bca59c3..baa1ba1 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -167,7 +167,7 @@ public: { setContentsMargins( 0,0,0,0 ); if (name.isEmpty()) - setData(0, QString::fromAscii("w%1").arg(int(this))); + setData(0, QString::fromAscii("w%1").arg(quintptr(this))); else setData(0, name); } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 27c6809..db80db6 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4078,8 +4078,11 @@ void tst_QGraphicsItem::defaultItemTest_QGraphicsTextItem() QCOMPARE(text->pos(), QPointF(10, 10)); + text->setTextInteractionFlags(Qt::NoTextInteraction); + QVERIFY(!(text->flags() & QGraphicsItem::ItemAcceptsInputMethod)); text->setTextInteractionFlags(Qt::TextEditorInteraction); QCOMPARE(text->textInteractionFlags(), Qt::TextInteractionFlags(Qt::TextEditorInteraction)); + QVERIFY(text->flags() & QGraphicsItem::ItemAcceptsInputMethod); { QGraphicsSceneMouseEvent event2(QEvent::GraphicsSceneMouseMove); diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 9269164..36ee22c 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -1286,8 +1286,9 @@ void tst_QGraphicsProxyWidget::paintEvent() QGraphicsScene scene; QGraphicsView view(&scene); view.show(); + QApplication::setActiveWindow(&view); QTest::qWaitForWindowShown(&view); - QTest::qWait(70); + QTRY_VERIFY(view.isActiveWindow()); SubQGraphicsProxyWidget proxy; @@ -1298,14 +1299,14 @@ void tst_QGraphicsProxyWidget::paintEvent() w->show(); QTest::qWaitForWindowShown(w); QApplication::processEvents(); - QTest::qWait(100); + QTest::qWait(30); proxy.setWidget(w); scene.addItem(&proxy); //make sure we flush all the paint events - QTest::qWait(70); + QTest::qWait(30); QTRY_VERIFY(proxy.paintCount > 1); - QTest::qWait(110); + QTest::qWait(30); proxy.paintCount = 0; w->update(); @@ -2573,20 +2574,22 @@ void tst_QGraphicsProxyWidget::changingCursor_basic() proxy->setWidget(widget); proxy->show(); scene.addItem(proxy); + QApplication::setActiveWindow(&view); QTest::qWaitForWindowShown(&view); QApplication::processEvents(); + QTRY_VERIFY(view.isActiveWindow()); // in QTest::mouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()))); sendMouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()))); - QTest::qWait(125); - QCOMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor); + QTest::qWait(12); + QTRY_COMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor); // out QTest::mouseMove(view.viewport(), QPoint(1, 1)); sendMouseMove(view.viewport(), QPoint(1, 1)); - QTest::qWait(125); - QCOMPARE(view.viewport()->cursor().shape(), Qt::ArrowCursor); + QTest::qWait(12); + QTRY_COMPARE(view.viewport()->cursor().shape(), Qt::ArrowCursor); #endif } @@ -2746,10 +2749,12 @@ void tst_QGraphicsProxyWidget::windowOpacity() widget->resize(100, 100); QGraphicsProxyWidget *proxy = scene.addWidget(widget); proxy->setCacheMode(QGraphicsItem::ItemCoordinateCache); + + QApplication::setActiveWindow(&view); view.show(); QTest::qWaitForWindowShown(&view); QApplication::sendPostedEvents(); - QTest::qWait(150); + QTRY_VERIFY(view.isActiveWindow()); qRegisterMetaType<QList<QRectF> >("QList<QRectF>"); QSignalSpy signalSpy(&scene, SIGNAL(changed(const QList<QRectF> &))); diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 9a561eb..20d9eb8 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -276,6 +276,7 @@ private slots: void task176178_itemIndexMethodBreaksSceneRect(); void task160653_selectionChanged(); void task250680_childClip(); + void taskQTBUG_5904_crashWithDeviceCoordinateCache(); }; void tst_QGraphicsScene::initTestCase() @@ -3983,20 +3984,28 @@ void tst_QGraphicsScene::isActive() QVERIFY(!scene1.isActive()); //it is hidden; QVERIFY(scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(scene2.hasFocus()); view1->show(); QVERIFY(scene1.isActive()); QVERIFY(scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(scene2.hasFocus()); view2->hide(); QVERIFY(scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); toplevel1.hide(); - QTest::qWait(12); + QTest::qWait(50); QTRY_VERIFY(!scene1.isActive()); QTRY_VERIFY(!scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); toplevel1.show(); QApplication::setActiveWindow(&toplevel1); @@ -4005,14 +4014,21 @@ void tst_QGraphicsScene::isActive() QTRY_VERIFY(scene1.isActive()); QTRY_VERIFY(!scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); view2->show(); QVERIFY(scene1.isActive()); QVERIFY(scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); } QVERIFY(!scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); + { QWidget toplevel2; @@ -4025,6 +4041,8 @@ void tst_QGraphicsScene::isActive() QVERIFY(!scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); toplevel2.show(); QApplication::setActiveWindow(&toplevel2); @@ -4033,66 +4051,89 @@ void tst_QGraphicsScene::isActive() QVERIFY(scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); view2->setScene(&scene2); QVERIFY(scene1.isActive()); QVERIFY(scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); view1->setScene(&scene2); QVERIFY(!scene1.isActive()); QVERIFY(scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(scene2.hasFocus()); view1->hide(); QVERIFY(!scene1.isActive()); QVERIFY(scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(scene2.hasFocus()); view1->setScene(&scene1); QVERIFY(!scene1.isActive()); QVERIFY(scene2.isActive()); - - view1->show(); + QVERIFY(!scene1.hasFocus()); + QVERIFY(scene2.hasFocus()); view1->show(); QVERIFY(scene1.isActive()); QVERIFY(scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(scene2.hasFocus()); view2->hide(); QVERIFY(scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); QGraphicsView topLevelView; topLevelView.show(); QApplication::setActiveWindow(&topLevelView); + topLevelView.setFocus(); QTest::qWaitForWindowShown(&topLevelView); QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&topLevelView)); QVERIFY(!scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); topLevelView.setScene(&scene1); QVERIFY(scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); view2->show(); QVERIFY(scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); view1->hide(); QVERIFY(scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); QApplication::setActiveWindow(&toplevel2); QTRY_COMPARE(QApplication::activeWindow(), &toplevel2); QVERIFY(!scene1.isActive()); QVERIFY(scene2.isActive()); - - + QVERIFY(!scene1.hasFocus()); + QVERIFY(scene2.hasFocus()); } QVERIFY(!scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); { QWidget toplevel3; @@ -4104,6 +4145,9 @@ void tst_QGraphicsScene::isActive() QVERIFY(!scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); + toplevel3.show(); QApplication::setActiveWindow(&toplevel3); @@ -4112,23 +4156,45 @@ void tst_QGraphicsScene::isActive() QVERIFY(scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); layout->addWidget(view2); QApplication::processEvents(); QVERIFY(scene1.isActive()); QVERIFY(scene2.isActive()); + QVERIFY(scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); view1->setParent(0); QVERIFY(!scene1.isActive()); QVERIFY(scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(scene2.hasFocus()); delete view1; } QVERIFY(!scene1.isActive()); QVERIFY(!scene2.isActive()); + QVERIFY(!scene1.hasFocus()); + QVERIFY(!scene2.hasFocus()); } +void tst_QGraphicsScene::taskQTBUG_5904_crashWithDeviceCoordinateCache() +{ + QGraphicsScene scene; + QGraphicsRectItem *rectItem = scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green)); + + rectItem->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + + QPixmap pixmap(100,200); + QPainter painter(&pixmap); + painter.setRenderHint(QPainter::Antialiasing); + scene.render(&painter); + painter.end(); + // No crash, then it passed! +} QTEST_MAIN(tst_QGraphicsScene) #include "tst_qgraphicsscene.moc" diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index f07453c..1ff06c2 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3600,6 +3600,7 @@ void tst_QGraphicsView::inputMethodSensitivity() item->setFlag(QGraphicsItem::ItemIsFocusable); scene.addItem(item); scene.setFocusItem(item); + QCOMPARE(scene.focusItem(), item); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); item->setFlag(QGraphicsItem::ItemAcceptsInputMethod, false); @@ -3614,27 +3615,35 @@ void tst_QGraphicsView::inputMethodSensitivity() scene.addItem(item2); scene.setFocusItem(item2); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + QCOMPARE(scene.focusItem(), item2); scene.setFocusItem(item); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + QCOMPARE(scene.focusItem(), item); view.setScene(0); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + QCOMPARE(scene.focusItem(), item); view.setScene(&scene); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + QCOMPARE(scene.focusItem(), item); scene.setFocusItem(item2); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + QCOMPARE(scene.focusItem(), item2); view.setScene(0); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + QCOMPARE(scene.focusItem(), item2); scene.setFocusItem(item); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + QCOMPARE(scene.focusItem(), item); view.setScene(&scene); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + QCOMPARE(scene.focusItem(), item); } class InputContextTester : public QInputContext diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 829e55c..3b98c2f 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -161,6 +161,7 @@ private slots: void respectHFW(); void addChildInpolishEvent(); void polishEvent(); + void polishEvent2(); // Task fixes void task236127_bspTreeIndexFails(); @@ -2796,6 +2797,29 @@ void tst_QGraphicsWidget::polishEvent() QCOMPARE(widget->events.at(0), QEvent::Polish); } +void tst_QGraphicsWidget::polishEvent2() +{ + class MyGraphicsWidget : public QGraphicsWidget + { public: + void polishEvent() + { events << QEvent::Polish; } + QList<QEvent::Type> events; + }; + + QGraphicsScene scene; + + MyGraphicsWidget *widget = new MyGraphicsWidget; + widget->hide(); + scene.addItem(widget); + + widget->events.clear(); + + QApplication::processEvents(); + + // Make sure the item got polish event. + QVERIFY(widget->events.contains(QEvent::Polish)); +} + QTEST_MAIN(tst_QGraphicsWidget) #include "tst_qgraphicswidget.moc" diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 1c8fecf..605b3e3 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -122,6 +122,7 @@ private slots: void taskQTBUG_633_changeModelData(); void taskQTBUG_435_deselectOnViewportClick(); void taskQTBUG_2678_spacingAndWrappedText(); + void taskQTBUG_5877_skippingItemInPageDownUp(); }; // Testing get/set functions @@ -509,9 +510,7 @@ void tst_QListView::moveCursor2() QModelIndex idx = vu.moveCursor(QMoveCursorListView::MoveHome, Qt::NoModifier); QCOMPARE(idx, model.index(0,0)); idx = vu.moveCursor(QMoveCursorListView::MoveDown, Qt::NoModifier); - QModelIndex p = model.index(8,0); QCOMPARE(idx, model.index(8,0)); - } void tst_QListView::moveCursor3() @@ -605,7 +604,6 @@ void tst_QListView::indexAt() QVERIFY(view2.m_index.isValid()); QVERIFY(view2.m_index.row() != 0); - } void tst_QListView::clicked() @@ -703,7 +701,6 @@ void tst_QListView::modelColumn() view.setModel(&model); - // // Set and get with a valid model // @@ -743,7 +740,6 @@ void tst_QListView::modelColumn() } } - void tst_QListView::hideFirstRow() { QStringList items; @@ -814,7 +810,6 @@ void tst_QListView::batchedMode() ba.setBit(idx.row(), true); } QCOMPARE(ba.size(), 3); - } void tst_QListView::setCurrentIndex() @@ -1146,7 +1141,6 @@ void tst_QListView::selection() for (int i = 0; i < selected.count(); ++i) { QVERIFY(expectedItems.contains(selected.at(i).row())); } - } void tst_QListView::scrollTo() @@ -1251,7 +1245,6 @@ void tst_QListView::scrollTo() QTest::keyClick(lv.viewport(), Qt::Key_Up, Qt::NoModifier); QCOMPARE(lv.visualRect(index).y(), 0); - } @@ -1772,7 +1765,6 @@ void tst_QListView::clickOnViewportClearsSelection() QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, point); //now the selection should be cleared QVERIFY(!view.selectionModel()->hasSelection()); - } void tst_QListView::task262152_setModelColumnNavigate() @@ -1795,7 +1787,6 @@ void tst_QListView::task262152_setModelColumnNavigate() QTest::keyClick(&view, Qt::Key_Down); QTest::qWait(30); QTRY_COMPARE(view.currentIndex(), model.index(2,1)); - } void tst_QListView::taskQTBUG_2233_scrollHiddenItems_data() @@ -1891,5 +1882,38 @@ void tst_QListView::taskQTBUG_2678_spacingAndWrappedText() QCOMPARE(w.horizontalScrollBar()->minimum(), w.horizontalScrollBar()->maximum()); } +void tst_QListView::taskQTBUG_5877_skippingItemInPageDownUp() +{ + QList<int> currentItemIndexes; + QtTestModel model(0); + model.colCount = 1; + model.rCount = 100; + + currentItemIndexes << 0 << 6 << 16 << 25 << 34 << 42 << 57 << 68 << 77 + << 83 << 91 << 94; + QMoveCursorListView vu; + vu.setModel(&model); + vu.show(); + + QTest::qWaitForWindowShown(&vu); + + int itemHeight = vu.visualRect(model.index(0, 0)).height(); + int visibleRowCount = vu.height() / itemHeight; + int scrolledRowCount = visibleRowCount - 1; + + for (int i = 0; i < currentItemIndexes.size(); ++i) { + vu.selectionModel()->setCurrentIndex(model.index(currentItemIndexes[i], 0), + QItemSelectionModel::SelectCurrent); + + QModelIndex idx = vu.moveCursor(QMoveCursorListView::MovePageDown, Qt::NoModifier); + int newCurrent = qMin(currentItemIndexes[i] + scrolledRowCount, 99); + QCOMPARE(idx, model.index(newCurrent, 0)); + + idx = vu.moveCursor(QMoveCursorListView::MovePageUp, Qt::NoModifier); + newCurrent = qMax(currentItemIndexes[i] - scrolledRowCount, 0); + QCOMPARE(idx, model.index(newCurrent, 0)); + } +} + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index f12fa92..7cdfe46 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -87,6 +87,7 @@ private slots: void widgetActionFocus(); void mouseActivation(); void tearOff(); + void layoutDirection(); #if defined(QT3_SUPPORT) void indexBasedInsertion_data(); @@ -101,11 +102,13 @@ private slots: void menuSizeHint(); void task258920_mouseBorder(); void setFixedWidth(); + void deleteActionInTriggered(); protected slots: void onActivated(QAction*); void onHighlighted(QAction*); void onStatusMessageChanged(const QString &); void onStatusTipTimer(); + void deleteAction(QAction *a) { delete a; } private: void createActions(); QMenu *menus[2], *lastMenu; @@ -594,6 +597,31 @@ void tst_QMenu::tearOff() QVERIFY(!torn->isVisible()); } +void tst_QMenu::layoutDirection() +{ + QMainWindow win; + win.setLayoutDirection(Qt::RightToLeft); + + QMenu menu(&win); + menu.show(); + QTest::qWaitForWindowShown(&menu); + QCOMPARE(menu.layoutDirection(), Qt::RightToLeft); + menu.close(); + + menu.setParent(0); + menu.show(); + QTest::qWaitForWindowShown(&menu); + QCOMPARE(menu.layoutDirection(), QApplication::layoutDirection()); + menu.close(); + + //now the menubar + QAction *action = win.menuBar()->addMenu(&menu); + win.menuBar()->setActiveAction(action); + QTest::qWaitForWindowShown(&menu); + QCOMPARE(menu.layoutDirection(), Qt::RightToLeft); +} + + #if defined(QT3_SUPPORT) void tst_QMenu::indexBasedInsertion_data() @@ -858,6 +886,17 @@ void tst_QMenu::setFixedWidth() QCOMPARE(menu.sizeHint().width(), menu.minimumWidth()); } +void tst_QMenu::deleteActionInTriggered() +{ + // should not crash + QMenu m; + QObject::connect(&m, SIGNAL(triggered(QAction*)), this, SLOT(deleteAction(QAction*))); + QWeakPointer<QAction> a = m.addAction("action"); + a.data()->trigger(); + QVERIFY(!a); +} + + QTEST_MAIN(tst_QMenu) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 0b61dcd..bd83c47 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -225,6 +225,9 @@ private Q_SLOTS: void ioPostToHttpUploadProgress(); void ioPostToHttpEmtpyUploadProgress(); + void lastModifiedHeaderForFile(); + void lastModifiedHeaderForHttp(); + void rateControl_data(); void rateControl(); @@ -2619,12 +2622,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocket() QSignalSpy authenticationRequiredSpy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); QSignalSpy proxyAuthenticationRequiredSpy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); -#ifdef Q_OS_SYMBIAN QTestEventLoop::instance().enterLoop(6); -#else - QTestEventLoop::instance().enterLoop(3); -#endif - disconnect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), @@ -2969,6 +2967,41 @@ void tst_QNetworkReply::ioPostToHttpEmtpyUploadProgress() server.close(); } +void tst_QNetworkReply::lastModifiedHeaderForFile() +{ + QFileInfo fileInfo(SRCDIR "./bigfile"); + QUrl url = QUrl::fromLocalFile(fileInfo.filePath()); + + QNetworkRequest request(url); + QNetworkReplyPtr reply = manager.head(request); + QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QDateTime header = reply->header(QNetworkRequest::LastModifiedHeader).toDateTime(); + QCOMPARE(header, fileInfo.lastModified()); +} + +void tst_QNetworkReply::lastModifiedHeaderForHttp() +{ + // Tue, 22 May 2007 12:04:57 GMT according to webserver + QUrl url = "http://" + QtNetworkSettings::serverName() + "/gif/fluke.gif"; + + QNetworkRequest request(url); + QNetworkReplyPtr reply = manager.head(request); + QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QDateTime header = reply->header(QNetworkRequest::LastModifiedHeader).toDateTime(); + QDateTime realDate = QDateTime::fromString("2007-05-22T12:04:57", Qt::ISODate); + realDate.setTimeSpec(Qt::UTC); + + QCOMPARE(header, realDate); +} + void tst_QNetworkReply::rateControl_data() { QTest::addColumn<int>("rate"); diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index d7f042e..0effd01 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -47,6 +47,7 @@ #include <qmatrix.h> #include <qdesktopwidget.h> #include <qpaintengine.h> +#include <qsplashscreen.h> #include <private/qpixmapdata_p.h> @@ -169,6 +170,7 @@ private slots: void loadFromDataNullValues(); void preserveDepth(); + void splash_crash(); }; static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) @@ -1421,6 +1423,17 @@ void tst_QPixmap::fromImage_crash() delete img; } +//This is testing QPixmapData::createCompatiblePixmapData - see QTBUG-5977 +void tst_QPixmap::splash_crash() +{ + QPixmap pix; + pix = QPixmap(":/images/designer.png"); + QSplashScreen splash(pix); + splash.show(); + QCoreApplication::processEvents(); + splash.close(); +} + void tst_QPixmap::fromData() { unsigned char bits[] = { 0xaa, 0x55 }; diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index fd39515..a13bb0d 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -209,6 +209,7 @@ private slots: void task260403_clonedSignals(); void postEventFromOtherThread(); void eventFilterForApplication(); + void eventClassesExported(); }; tst_QStateMachine::tst_QStateMachine() @@ -4307,5 +4308,12 @@ void tst_QStateMachine::eventFilterForApplication() QVERIFY(machine.configuration().contains(s2)); } +void tst_QStateMachine::eventClassesExported() +{ + // make sure this links + QStateMachine::WrappedEvent *wrappedEvent = new QStateMachine::WrappedEvent(0, 0); + QStateMachine::SignalEvent *signalEvent = new QStateMachine::SignalEvent(0, 0, QList<QVariant>()); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" diff --git a/tests/auto/qstatusbar/tst_qstatusbar.cpp b/tests/auto/qstatusbar/tst_qstatusbar.cpp index 9774559..92d9185 100644 --- a/tests/auto/qstatusbar/tst_qstatusbar.cpp +++ b/tests/auto/qstatusbar/tst_qstatusbar.cpp @@ -77,6 +77,7 @@ private slots: void insertPermanentWidget(); void setSizeGripEnabled(); void task194017_hiddenWidget(); + void QTBUG4334_hiddenOnMaximizedWindow(); private: QStatusBar *testWidget; @@ -257,6 +258,19 @@ void tst_QStatusBar::task194017_hiddenWidget() QVERIFY(!label->isVisible()); } +void tst_QStatusBar::QTBUG4334_hiddenOnMaximizedWindow() +{ + QMainWindow main; + QStatusBar statusbar; + statusbar.setSizeGripEnabled(true); + main.setStatusBar(&statusbar); + main.showMaximized(); + QTest::qWaitForWindowShown(&main); + QVERIFY(!statusbar.findChild<QSizeGrip*>()->isVisible()); + main.showNormal(); + QTest::qWaitForWindowShown(&main); + QVERIFY(statusbar.findChild<QSizeGrip*>()->isVisible()); +} QTEST_MAIN(tst_QStatusBar) #include "tst_qstatusbar.moc" diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index f571e8a..46c3fb6 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -198,6 +198,7 @@ private slots: void task191545_dragSelectRows(); void taskQTBUG_5062_spansInconsistency(); void taskQTBUG_4516_clickOnRichTextLabel(); + void taskQTBUG_5237_wheelEventOnHeader(); void mouseWheel_data(); void mouseWheel(); @@ -3613,17 +3614,9 @@ void tst_QTableView::mouseWheel_data() QTest::newRow("scroll down per item") << int(QAbstractItemView::ScrollPerItem) << -120 << 10 + qApp->wheelScrollLines() << 10 + qApp->wheelScrollLines(); -#ifdef Q_WS_MAC - // On Mac, we always scroll one pixel per 120 delta (rather than multiplying with - // singleStep) since wheel events are accelerated by the OS. - QTest::newRow("scroll down per pixel") - << int(QAbstractItemView::ScrollPerPixel) << -120 - << 10 + qApp->wheelScrollLines() << 10 + qApp->wheelScrollLines(); -#else QTest::newRow("scroll down per pixel") << int(QAbstractItemView::ScrollPerPixel) << -120 << 10 + qApp->wheelScrollLines() * 89 << 10 + qApp->wheelScrollLines() * 28; -#endif } void tst_QTableView::mouseWheel() @@ -3913,7 +3906,7 @@ void tst_QTableView::changeHeaderData() QTest::qWaitForWindowShown(&view); QString text = "long long long text"; - const int textWidth = view.fontMetrics().width(text); + const int textWidth = view.verticalHeader()->fontMetrics().width(text); QVERIFY(view.verticalHeader()->width() < textWidth); model.setHeaderData(2, Qt::Vertical, text); @@ -3922,6 +3915,22 @@ void tst_QTableView::changeHeaderData() QVERIFY(view.verticalHeader()->width() > textWidth); } +void tst_QTableView::taskQTBUG_5237_wheelEventOnHeader() +{ + QTableView view; + QStandardItemModel model(500,5); + view.setModel(&model); + view.show(); + QTest::qWaitForWindowShown(&view); + + int sbValueBefore = view.verticalScrollBar()->value(); + QHeaderView *header = view.verticalHeader(); + QTest::mouseMove(header); + QWheelEvent wheelEvent(header->geometry().center(), -720, 0, 0); + QApplication::sendEvent(header->viewport(), &wheelEvent); + int sbValueAfter = view.verticalScrollBar()->value(); + QVERIFY(sbValueBefore != sbValueAfter); +} QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" diff --git a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp index 5577903..4ed9fca 100644 --- a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp @@ -192,6 +192,8 @@ private slots: void connectToMultiIP(); void moveToThread0(); void increaseReadBufferSize(); + void taskQtBug5799ConnectionErrorWaitForConnected(); + void taskQtBug5799ConnectionErrorEventLoop(); #ifdef TEST_QNETWORK_PROXY void invalidProxy_data(); void invalidProxy(); @@ -2214,6 +2216,47 @@ void tst_QTcpSocket::increaseReadBufferSize() delete active; } +void tst_QTcpSocket::taskQtBug5799ConnectionErrorWaitForConnected() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + // check that we get a proper error connecting to port 12346 + // use waitForConnected, e.g. this should use a synchronous select() on the OS level + + QTcpSocket socket; + socket.connectToHost(QtNetworkSettings::serverName(), 12346); + QTime timer; + timer.start(); + socket.waitForConnected(10000); + QVERIFY2(timer.elapsed() < 9900, "Connection to closed port timed out instead of refusing, something is wrong"); + QVERIFY2(socket.state() == QAbstractSocket::UnconnectedState, "Socket connected unexpectedly!"); + QVERIFY2(socket.error() == QAbstractSocket::ConnectionRefusedError, + QString("Could not reach server: %1").arg(socket.errorString()).toLocal8Bit()); +} + +void tst_QTcpSocket::taskQtBug5799ConnectionErrorEventLoop() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + // check that we get a proper error connecting to port 12346 + // This testcase uses an event loop + QTcpSocket socket; + connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), &QTestEventLoop::instance(), SLOT(exitLoop())); + socket.connectToHost(QtNetworkSettings::serverName(), 12346); + + QTestEventLoop::instance().enterLoop(10); + QVERIFY2(!QTestEventLoop::instance().timeout(), "Connection to closed port timed out instead of refusing, something is wrong"); + QVERIFY2(socket.state() == QAbstractSocket::UnconnectedState, "Socket connected unexpectedly!"); + QVERIFY2(socket.error() == QAbstractSocket::ConnectionRefusedError, + QString("Could not reach server: %1").arg(socket.errorString()).toLocal8Bit()); +} + + + #ifdef TEST_QNETWORK_PROXY void tst_QTcpSocket::invalidProxy_data() { diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp index 1d54409..11e32b0 100644 --- a/tests/auto/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp @@ -2615,6 +2615,17 @@ void tst_QTextDocument::testUndoCommandAdded() cf.setFontItalic(true); cursor.mergeCharFormat(cf); QCOMPARE(spy.count(), 1); + + spy.clear(); + doc->undo(); + QCOMPARE(spy.count(), 0); + doc->undo(); + QCOMPARE(spy.count(), 0); + spy.clear(); + doc->redo(); + QCOMPARE(spy.count(), 0); + doc->redo(); + QCOMPARE(spy.count(), 0); } void tst_QTextDocument::testUndoBlocks() diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp index 7c3f4f2..1df26b8 100644 --- a/tests/auto/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp @@ -1115,14 +1115,14 @@ void tst_QTextLayout::testTabDPIScale() QTextOption option = layout.textOption(); QList<QTextOption::Tab> tabs; QTextOption::Tab tab; - tab.position = 200; + tab.position = 300; tabs.append(tab); - tab.position = 400; + tab.position = 600; tab.type = QTextOption::RightTab; tabs.append(tab); - tab.position = 600; + tab.position = 800; tab.type = QTextOption::CenterTab; tabs.append(tab); option.setTabs(tabs); diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index 58f059b..4fc6dd3 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -3653,7 +3653,9 @@ void tst_QTreeView::doubleClickedWithSpans() view.setModel(&model); view.setFirstColumnSpanned(0, QModelIndex(), true); view.show(); + QApplication::setActiveWindow(&view); QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(view.isActiveWindow()); QPoint p(10, 10); QCOMPARE(view.indexAt(p), model.index(0, 0)); diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index c8fe4e5..03e77aa 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -3713,7 +3713,7 @@ void tst_QUrl::fromUserInput_data() QTest::newRow("add scheme-0") << "example.org" << QUrl("http://example.org"); QTest::newRow("add scheme-1") << "www.example.org" << QUrl("http://www.example.org"); QTest::newRow("add scheme-2") << "ftp.example.org" << QUrl("ftp://ftp.example.org"); - QTest::newRow("add scheme-3") << "webkit" << QUrl("webkit"); + QTest::newRow("add scheme-3") << "hostname" << QUrl("http://hostname"); // QUrl's tolerant parser should already handle this QTest::newRow("not-encoded-0") << "http://example.org/test page.html" << QUrl::fromEncoded("http://example.org/test%20page.html"); @@ -3723,6 +3723,9 @@ void tst_QUrl::fromUserInput_data() portUrl.setPort(80); QTest::newRow("port-0") << "example.org:80" << portUrl; QTest::newRow("port-1") << "http://example.org:80" << portUrl; + portUrl.setPath("path"); + QTest::newRow("port-1") << "example.org:80/path" << portUrl; + QTest::newRow("port-1") << "http://example.org:80/path" << portUrl; // mailto doesn't have a ://, but is valid QUrl mailto("ben@example.net"); @@ -3730,10 +3733,11 @@ void tst_QUrl::fromUserInput_data() QTest::newRow("mailto") << "mailto:ben@example.net" << mailto; // misc - QTest::newRow("localhost-0") << "localhost" << QUrl("http://localhost"); QTest::newRow("localhost-1") << "localhost:80" << QUrl("http://localhost:80"); QTest::newRow("spaces-0") << " http://example.org/test page.html " << QUrl("http://example.org/test%20page.html"); QTest::newRow("trash-0") << "example.org/test?someData=42%&someOtherData=abcde#anchor" << QUrl::fromEncoded("http://example.org/test?someData=42%25&someOtherData=abcde#anchor"); + QTest::newRow("other-scheme-0") << "spotify:track:0hO542doVbfGDAGQULMORT" << QUrl("spotify:track:0hO542doVbfGDAGQULMORT"); + QTest::newRow("other-scheme-1") << "weirdscheme:80:otherstuff" << QUrl("weirdscheme:80:otherstuff"); // FYI: The scheme in the resulting url user QUrl authUrl("user:pass@domain.com"); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index e027dd1..9692c6e 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -388,6 +388,8 @@ private slots: void cbaVisibility(); #endif + void focusProxyAndInputMethods(); + private: bool ensureScreenSize(int width, int height); QWidget *testWidget; @@ -9619,5 +9621,62 @@ void tst_QWidget::cbaVisibility() } #endif +class InputContextTester : public QInputContext +{ + Q_OBJECT +public: + QString identifierName() { return QString(); } + bool isComposing() const { return false; } + QString language() { return QString(); } + void reset() { ++resets; } + int resets; +}; + +void tst_QWidget::focusProxyAndInputMethods() +{ + InputContextTester *inputContext = new InputContextTester; + QWidget *toplevel = new QWidget(0, Qt::X11BypassWindowManagerHint); + toplevel->setAttribute(Qt::WA_InputMethodEnabled, true); + toplevel->setInputContext(inputContext); // ownership is transferred + + QWidget *child = new QWidget(toplevel); + child->setFocusProxy(toplevel); + child->setAttribute(Qt::WA_InputMethodEnabled, true); + + toplevel->setFocusPolicy(Qt::WheelFocus); + child->setFocusPolicy(Qt::WheelFocus); + + QVERIFY(!child->hasFocus()); + QVERIFY(!toplevel->hasFocus()); + + toplevel->show(); + QTest::qWaitForWindowShown(toplevel); + QApplication::setActiveWindow(toplevel); + QVERIFY(toplevel->hasFocus()); + QVERIFY(child->hasFocus()); + + // verify that toggling input methods on the child widget + // correctly propagate to the focus proxy's input method + // and that the input method gets the focus proxy passed + // as the focus widget instead of the child widget. + // otherwise input method queries go to the wrong widget + + QCOMPARE(inputContext->focusWidget(), toplevel); + + child->setAttribute(Qt::WA_InputMethodEnabled, false); + QVERIFY(!inputContext->focusWidget()); + + child->setAttribute(Qt::WA_InputMethodEnabled, true); + QCOMPARE(inputContext->focusWidget(), toplevel); + + child->setEnabled(false); + QVERIFY(!inputContext->focusWidget()); + + child->setEnabled(true); + QCOMPARE(inputContext->focusWidget(), toplevel); + + delete toplevel; +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" 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/tests/auto/xmlpatterns/stderrBaselines/Anunboundexternalvariable.txt b/tests/auto/xmlpatterns/stderrBaselines/Anunboundexternalvariable.txt index a7945f0..b620e05 100644 --- a/tests/auto/xmlpatterns/stderrBaselines/Anunboundexternalvariable.txt +++ b/tests/auto/xmlpatterns/stderrBaselines/Anunboundexternalvariable.txt @@ -1 +1 @@ -Error XPST0008 in file:///home/fenglich/dev/qt-xslt/tests/auto/xmlpatterns/queries/externalVariable.xq, at line 1, column 69: No variable by name externalVariable exists +Error XPST0008 in file:///home/fenglich/dev/qt-xslt/tests/auto/xmlpatterns/queries/externalVariable.xq, at line 1, column 69: No variable with name externalVariable exists diff --git a/tests/auto/xmlpatterns/tst_xmlpatterns.cpp b/tests/auto/xmlpatterns/tst_xmlpatterns.cpp index 22f6693..ff7c8c0 100644 --- a/tests/auto/xmlpatterns/tst_xmlpatterns.cpp +++ b/tests/auto/xmlpatterns/tst_xmlpatterns.cpp @@ -160,7 +160,9 @@ void tst_XmlPatterns::xquerySupport() QCOMPARE(process.exitCode(), expectedExitCode); const QByteArray rawProducedStderr((process.readAllStandardError())); - const QString fixedStderr(QString::fromLocal8Bit(rawProducedStderr).remove(m_filenameInStderr)); + QString fixedStderr(QString::fromLocal8Bit(rawProducedStderr).remove(m_filenameInStderr)); + // convert Windows line endings to Unix ones + fixedStderr.replace("\r\n", "\n"); const QString errorFileName(inputFile(QLatin1String(SRCDIR "stderrBaselines/") + QString::fromUtf8(QTest::currentDataTag()).remove(m_normalizeTestName) + diff --git a/tests/manual/keypadnavigation/keypadnavigation.ui b/tests/manual/keypadnavigation/keypadnavigation.ui index 039889b..8b456d9 100644 --- a/tests/manual/keypadnavigation/keypadnavigation.ui +++ b/tests/manual/keypadnavigation/keypadnavigation.ui @@ -1060,75 +1060,100 @@ As a reward you can try out the QDial, below.</string> </widget> <widget class="QWidget" name="m_pageDialogs"> <layout class="QVBoxLayout" name="verticalLayout_13"> + <property name="margin"> + <number>0</number> + </property> <item> - <widget class="QPushButton" name="m_buttonGetOpenFileName"> - <property name="text"> - <string>getOpenFileName()</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="m_buttonGetSaveFileName"> - <property name="text"> - <string>getSaveFileName()</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="m_buttonGetExistingDirectory"> - <property name="text"> - <string>getExistingDirectory()</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="m_buttonGetColor"> - <property name="text"> - <string>getColor()</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="m_buttonGetFont"> - <property name="text"> - <string>getFont()</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="m_buttonQuestion"> - <property name="text"> - <string>question()</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="m_buttonAboutQt"> - <property name="text"> - <string>aboutQt()</string> + <widget class="QScrollArea" name="scrollArea_5"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="m_buttonGetItem"> - <property name="text"> - <string>getItem()</string> + <property name="widgetResizable"> + <bool>true</bool> </property> + <widget class="QWidget" name="scrollAreaWidgetContents_5"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>264</width> + <height>356</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_14"> + <item> + <widget class="QPushButton" name="m_buttonGetOpenFileName"> + <property name="text"> + <string>getOpenFileName()</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="m_buttonGetSaveFileName"> + <property name="text"> + <string>getSaveFileName()</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="m_buttonGetExistingDirectory"> + <property name="text"> + <string>getExistingDirectory()</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="m_buttonGetColor"> + <property name="text"> + <string>getColor()</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="m_buttonGetFont"> + <property name="text"> + <string>getFont()</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="m_buttonQuestion"> + <property name="text"> + <string>question()</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="m_buttonAboutQt"> + <property name="text"> + <string>aboutQt()</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="m_buttonGetItem"> + <property name="text"> + <string>getItem()</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>103</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> </widget> </item> - <item> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>104</height> - </size> - </property> - </spacer> - </item> </layout> </widget> </widget> @@ -1155,7 +1180,7 @@ As a reward you can try out the QDial, below.</string> <addaction name="m_actionLayoutChaos"/> <addaction name="m_actionLayoutDialogs"/> </widget> - <widget class="QMenu" name="menuNavigation_mode"> + <widget class="QMenu" name="m_menuNavigation_mode"> <property name="title"> <string>Navigation mode</string> </property> @@ -1166,7 +1191,7 @@ As a reward you can try out the QDial, below.</string> <addaction name="m_actionModeCursorForceVisible"/> </widget> <addaction name="menuUi_layout"/> - <addaction name="menuNavigation_mode"/> + <addaction name="m_menuNavigation_mode"/> </widget> <action name="m_actionLayoutVerticalSimple"> <property name="text"> diff --git a/tests/manual/keypadnavigation/main.cpp b/tests/manual/keypadnavigation/main.cpp index d1cc8a7..84b3d78 100644 --- a/tests/manual/keypadnavigation/main.cpp +++ b/tests/manual/keypadnavigation/main.cpp @@ -70,6 +70,7 @@ public: } connect(&m_layoutSignalMapper, SIGNAL(mapped(QWidget*)), ui->m_stackWidget, SLOT(setCurrentWidget(QWidget*))); +#ifdef QT_KEYPAD_NAVIGATION const struct { QObject *action; Qt::NavigationMode mode; @@ -85,6 +86,9 @@ public: m_modeSignalMapper.setMapping(modeMappings[i].action, int(modeMappings[i].mode)); } connect(&m_modeSignalMapper, SIGNAL(mapped(int)), SLOT(setNavigationMode(int))); +#else // QT_KEYPAD_NAVIGATION + ui->m_menuNavigation_mode->deleteLater(); +#endif // QT_KEYPAD_NAVIGATION const struct { QObject *button; @@ -112,10 +116,12 @@ public: } protected slots: +#ifdef QT_KEYPAD_NAVIGATION void setNavigationMode(int mode) { QApplication::setNavigationMode(Qt::NavigationMode(mode)); } +#endif // QT_KEYPAD_NAVIGATION void openDialog(int dialog) { @@ -163,7 +169,9 @@ private: Ui_KeypadNavigation *ui; QSignalMapper m_layoutSignalMapper; +#ifdef QT_KEYPAD_NAVIGATION QSignalMapper m_modeSignalMapper; +#endif // QT_KEYPAD_NAVIGATION QSignalMapper m_dialogSignalMapper; }; |