summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/auto.pro5
-rw-r--r--tests/auto/declarative/animations/animations.pro5
-rw-r--r--tests/auto/declarative/animations/data/badproperty1.qml22
-rw-r--r--tests/auto/declarative/animations/data/badtype1.qml10
-rw-r--r--tests/auto/declarative/animations/data/badtype2.qml10
-rw-r--r--tests/auto/declarative/animations/data/badtype3.qml10
-rw-r--r--tests/auto/declarative/animations/data/badtype4.qml23
-rw-r--r--tests/auto/declarative/animations/data/color.qml10
-rw-r--r--tests/auto/declarative/animations/data/dotproperty.qml22
-rw-r--r--tests/auto/declarative/animations/data/mixedtype1.qml22
-rw-r--r--tests/auto/declarative/animations/data/mixedtype2.qml22
-rw-r--r--tests/auto/declarative/animations/data/number.qml10
-rw-r--r--tests/auto/declarative/animations/tst_animations.cpp97
-rw-r--r--tests/auto/declarative/qfxtextedit/data/cursorTest.qml6
-rw-r--r--tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp171
-rw-r--r--tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro1
-rw-r--r--tests/auto/declarative/visual/bindinganimation/bindinganimation.qml12
-rw-r--r--tests/auto/declarative/visual/colorAnimation/colorAnimation.qml10
-rw-r--r--tests/auto/declarative/visual/easing/easing.qml12
-rw-r--r--tests/auto/declarative/visual/flipable/flipable.xml10
-rw-r--r--tests/auto/declarative/visual/pauseAnimation/pauseAnimation.qml4
-rw-r--r--tests/auto/gestures/customgesturerecognizer.cpp167
-rw-r--r--tests/auto/gestures/customgesturerecognizer.h187
-rw-r--r--tests/auto/gestures/gestures.pro3
-rw-r--r--tests/auto/gestures/tst_gestures.cpp949
-rw-r--r--tests/auto/linguist/lconvert/data/codec-cp1252.ts28
-rw-r--r--tests/auto/linguist/lconvert/data/codec-utf8.ts28
-rw-r--r--tests/auto/linguist/lconvert/data/dual-encoding.ts11
-rw-r--r--tests/auto/linguist/lconvert/data/endless-po-loop.ts16
-rwxr-xr-xtests/auto/linguist/lconvert/data/makeplurals.sh43
-rw-r--r--tests/auto/linguist/lconvert/data/msgid.ts27
-rw-r--r--tests/auto/linguist/lconvert/data/plurals-cn.ts17
-rw-r--r--tests/auto/linguist/lconvert/data/plurals-de.ts18
-rw-r--r--tests/auto/linguist/lconvert/data/relative.ts74
-rw-r--r--tests/auto/linguist/lconvert/data/singular.po42
-rw-r--r--tests/auto/linguist/lconvert/data/test-broken-utf8.po9
-rw-r--r--tests/auto/linguist/lconvert/data/test-broken-utf8.po.out9
-rw-r--r--tests/auto/linguist/lconvert/data/test-developer-comment.po23
-rw-r--r--tests/auto/linguist/lconvert/data/test-empty-comment.po24
-rw-r--r--tests/auto/linguist/lconvert/data/test-escapes.po11
-rw-r--r--tests/auto/linguist/lconvert/data/test-escapes.po.out13
-rw-r--r--tests/auto/linguist/lconvert/data/test-kde-ctxt.po25
-rw-r--r--tests/auto/linguist/lconvert/data/test-kde-fuzzy.po31
-rw-r--r--tests/auto/linguist/lconvert/data/test-kde-multiline.po32
-rw-r--r--tests/auto/linguist/lconvert/data/test-kde-plurals.po27
-rw-r--r--tests/auto/linguist/lconvert/data/test-slurp.po19
-rw-r--r--tests/auto/linguist/lconvert/data/test-slurp.po.out19
-rw-r--r--tests/auto/linguist/lconvert/data/test-translator-comment.po41
-rw-r--r--tests/auto/linguist/lconvert/data/test1-cn.po67
-rw-r--r--tests/auto/linguist/lconvert/data/test1-de.po75
-rw-r--r--tests/auto/linguist/lconvert/data/test11.ts32
-rw-r--r--tests/auto/linguist/lconvert/data/test20.ts150
-rw-r--r--tests/auto/linguist/lconvert/data/variants.ts24
-rw-r--r--tests/auto/linguist/lconvert/data/wrapping.po58
-rw-r--r--tests/auto/linguist/lconvert/lconvert.pro8
-rw-r--r--tests/auto/linguist/lconvert/tst_lconvert.cpp300
-rw-r--r--tests/auto/linguist/linguist.pro2
-rw-r--r--tests/auto/linguist/lrelease/lrelease.pro5
-rw-r--r--tests/auto/linguist/lrelease/testdata/compressed.ts46
-rw-r--r--tests/auto/linguist/lrelease/testdata/dupes.errors4
-rw-r--r--tests/auto/linguist/lrelease/testdata/dupes.ts25
-rw-r--r--tests/auto/linguist/lrelease/testdata/mixedcodecs-ts11.ts18
-rw-r--r--tests/auto/linguist/lrelease/testdata/mixedcodecs-ts20.ts18
-rw-r--r--tests/auto/linguist/lrelease/testdata/translate.ts136
-rw-r--r--tests/auto/linguist/lrelease/tst_lrelease.cpp163
-rw-r--r--tests/auto/linguist/lupdate/lupdate.pro7
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/backslashes/lupdatecmd3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/backslashes/project.pro19
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/backslashes/project.ts.result13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/backslashes/src/main.cpp15
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecforsrc/main.cpp18
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.pro20
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.ts.result20
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr/main.cpp24
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr/project.pro19
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr/project.ts.result13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr1/main.cpp20
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.pro15
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.ts.result28
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr2/main.cpp20
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.pro16
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.ts.result28
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt8
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/lacksqobject/main.cpp47
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.ts.result40
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp28
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/lupdatecmd5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.pro14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.before74
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.result82
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_versions/project.pro14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.before14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.result15
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ui44
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_whitespace/main.cpp23
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.pro14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.before70
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.result71
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp25
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp/project.pro14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.before48
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.result49
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/finddialog.cpp123
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/lupdatecmd5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.pro14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.before31
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.result27
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/finddialog.cpp146
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.pro14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.before26
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.result31
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui/project.pro14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before22
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.result23
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui/project.ui47
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.pro14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.before16
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result22
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui26
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/multiple_locations/finddialog.cpp7
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/multiple_locations/main.cpp13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.pro13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.ts.result17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/namespaces/main.cpp97
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/namespaces/project.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/namespaces/project.ts.result82
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parse_special_chars/main.cpp18
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.ts.result17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp229
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result192
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/finddialog.cpp156
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp158
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/project.pro13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result271
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt7
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp24
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main2.cpp28
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main3.cpp42
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejava/main.java54
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejava/project.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsejava/project.ts.result115
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseui/project.pro13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseui/project.ts.result17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parseui/project.ui44
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/prefix/project.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result23
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/preprocess/main.cpp37
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/preprocess/project.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/preprocess/project.ts.result35
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/main.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/main_mac.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/main_unix.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/main_win.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/project.pro40
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/project.ts.result64
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/vpaths/dependpath/main_dependpath.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/main1.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/mainfile.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard1.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard99.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/a4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/a.cpp4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/b4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/b.cpp4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/e4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/f/g.cpp4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/files-cc.txt1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/project.pro42
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/project.ts.result62
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/spaces/z4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/variable_with_spaces4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/with4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/x/d4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsing2/x/variable4
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/common.pri1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.pri5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/mac.pri5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/main_mac.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.pro16
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.ts.result37
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.pri3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub/sub.pri1
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub2/sub2.pri2
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/main_unix.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/unix.pri5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/main_win.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/win.pri5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.pro3
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.ts.result13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/main.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/sub1.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/common.pro5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/main.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/mac.pro5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/main_mac.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.pro7
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.ts.result31
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/main_unix.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/unix.pro5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/main_win.cpp10
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/win.pro5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.pro14
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.before16
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result22
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui26
-rw-r--r--tests/auto/linguist/lupdate/testdata/output_ts/lupdatecmd5
-rw-r--r--tests/auto/linguist/lupdate/testdata/output_ts/project.ts.result12
-rw-r--r--tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/main.cpp9
-rw-r--r--tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/tools.pro12
-rw-r--r--tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/translations/readme.txt2
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/bar.ts.result27
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/foo.ts.result115
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/main.cpp22
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/project.ui44
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.c++8
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cpp8
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cxx8
-rw-r--r--tests/auto/linguist/lupdate/testdata/recursivescan/sub/finddialog.cpp143
-rw-r--r--tests/auto/linguist/lupdate/testlupdate.cpp116
-rw-r--r--tests/auto/linguist/lupdate/testlupdate.h46
-rw-r--r--tests/auto/linguist/lupdate/tst_lupdate.cpp277
-rw-r--r--tests/auto/mediaobject/dummy/README1
-rw-r--r--tests/auto/mediaobject/dummy/audiooutput.cpp53
-rw-r--r--tests/auto/mediaobject/dummy/audiooutput.h41
-rw-r--r--tests/auto/mediaobject/dummy/backend.cpp149
-rw-r--r--tests/auto/mediaobject/dummy/backend.h55
-rw-r--r--tests/auto/mediaobject/dummy/dummy.pro23
-rw-r--r--tests/auto/mediaobject/dummy/mediaobject.cpp397
-rw-r--r--tests/auto/mediaobject/dummy/mediaobject.h169
-rw-r--r--tests/auto/mediaobject/dummy/videowidget.cpp205
-rw-r--r--tests/auto/mediaobject/dummy/videowidget.h70
-rw-r--r--tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp38
-rw-r--r--tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp2
-rw-r--r--tests/auto/qabstractitemview/tst_qabstractitemview.cpp19
-rw-r--r--tests/auto/qaccessibility/tst_qaccessibility.cpp6
-rw-r--r--tests/auto/qapplication/tst_qapplication.cpp149
-rw-r--r--tests/auto/qboxlayout/tst_qboxlayout.cpp79
-rw-r--r--tests/auto/qbytearray/tst_qbytearray.cpp4
-rw-r--r--tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp2
-rw-r--r--tests/auto/qfile/tst_qfile.cpp91
-rw-r--r--tests/auto/qfileinfo/tst_qfileinfo.cpp31
-rw-r--r--tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp121
-rw-r--r--tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp11
-rw-r--r--tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp93
-rw-r--r--tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp29
-rw-r--r--tests/auto/qgroupbox/tst_qgroupbox.cpp11
-rw-r--r--tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro2
-rw-r--r--tests/auto/qitemmodel/qitemmodel.pro3
-rw-r--r--tests/auto/qitemview/tst_qitemview.cpp2
-rw-r--r--tests/auto/qlocale/tst_qlocale.cpp31
-rw-r--r--tests/auto/qmainwindow/tst_qmainwindow.cpp5
-rw-r--r--tests/auto/qmake/testcompiler.cpp2
-rw-r--r--tests/auto/qmenu/tst_qmenu.cpp54
-rw-r--r--tests/auto/qmenubar/tst_qmenubar.cpp69
-rw-r--r--tests/auto/qmetaobject/tst_qmetaobject.cpp39
-rw-r--r--tests/auto/qnetworkaccessmanager_and_qprogressdialog/qnetworkaccessmanager_and_qprogressdialog.pro5
-rw-r--r--tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp130
-rw-r--r--tests/auto/qpixmap/tst_qpixmap.cpp7
-rw-r--r--tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp57
-rw-r--r--tests/auto/qpushbutton/tst_qpushbutton.cpp76
-rw-r--r--tests/auto/qrect/tst_qrect.cpp2
-rw-r--r--tests/auto/qscriptengine/qscriptengine.pro1
-rw-r--r--tests/auto/qscriptengine/tst_qscriptengine.cpp30
-rw-r--r--tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro1
-rw-r--r--tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp2
-rw-r--r--tests/auto/qscriptqobject/tst_qscriptqobject.cpp21
-rw-r--r--tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro1
-rw-r--r--tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp2
-rw-r--r--tests/auto/qsettings/tst_qsettings.cpp6
-rw-r--r--tests/auto/qsharedmemory/src/qsystemlock_win.cpp26
-rw-r--r--tests/auto/qsharedpointer/tst_qsharedpointer.cpp16
-rw-r--r--tests/auto/qspinbox/tst_qspinbox.cpp44
-rw-r--r--tests/auto/qsqldatabase/tst_databases.h71
-rw-r--r--tests/auto/qsqldatabase/tst_qsqldatabase.cpp10
-rw-r--r--tests/auto/qsqldriver/tst_qsqldriver.cpp12
-rw-r--r--tests/auto/qsqlquery/tst_qsqlquery.cpp75
-rw-r--r--tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp48
-rw-r--r--tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp2
-rw-r--r--tests/auto/qstatemachine/tst_qstatemachine.cpp118
-rw-r--r--tests/auto/qstring/tst_qstring.cpp8
-rw-r--r--tests/auto/qstyle/qstyle.pro3
-rw-r--r--tests/auto/qstyle/tst_qstyle.cpp5
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp124
-rw-r--r--tests/auto/qtcpserver/tst_qtcpserver.cpp120
-rw-r--r--tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp33
-rw-r--r--tests/auto/qtimer/tst_qtimer.cpp2
-rw-r--r--tests/auto/qtouchevent/qtouchevent.pro3
-rw-r--r--tests/auto/qtouchevent/tst_qtouchevent.cpp798
-rw-r--r--tests/auto/qurl/tst_qurl.cpp27
-rw-r--r--tests/auto/qvariant/tst_qvariant.cpp17
-rw-r--r--tests/auto/qwebhistory/.gitignore1
-rw-r--r--tests/auto/qwebhistory/dummy.cpp44
-rw-r--r--tests/auto/qwebhistory/qwebhistory.pro14
-rw-r--r--tests/auto/qwidget/tst_qwidget.cpp37
-rw-r--r--tests/auto/qwineventnotifier/tst_qwineventnotifier.cpp7
-rw-r--r--tests/auto/qwizard/tst_qwizard.cpp22
-rw-r--r--tests/auto/qxmlquery/tst_qxmlquery.cpp52
-rw-r--r--tests/auto/qxmlstream/tst_qxmlstream.cpp52
-rw-r--r--tests/auto/tests.xml6
-rw-r--r--tests/auto/windowsmobile/test/tst_windowsmobile.cpp2
308 files changed, 12059 insertions, 624 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index b59706c..a5babc7 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -12,6 +12,7 @@ SUBDIRS += _networkselftest \
compilerwarnings \
dynamicobject \
exceptionsafety \
+ linguist \
macgui \
macplist \
mediaobject \
@@ -218,6 +219,7 @@ SUBDIRS += _networkselftest \
qnetworkproxy \
qnetworkrequest \
qnetworkreply \
+ qnetworkaccessmanager_and_qprogressdialog \
qnumeric \
qobject \
qobjectrace \
@@ -450,7 +452,8 @@ contains(QT_CONFIG, webkit): SUBDIRS += \
qwebframe \
qwebpage \
qwebhistoryinterface \
- qwebelement
+ qwebelement \
+ qwebhistory
SUBDIRS += math3d
diff --git a/tests/auto/declarative/animations/animations.pro b/tests/auto/declarative/animations/animations.pro
new file mode 100644
index 0000000..419da4e
--- /dev/null
+++ b/tests/auto/declarative/animations/animations.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative
+SOURCES += tst_animations.cpp
+
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/auto/declarative/animations/data/badproperty1.qml b/tests/auto/declarative/animations/data/badproperty1.qml
new file mode 100644
index 0000000..dc35775
--- /dev/null
+++ b/tests/auto/declarative/animations/data/badproperty1.qml
@@ -0,0 +1,22 @@
+Rect {
+ id: Wrapper
+ width: 240
+ height: 320
+ Rect {
+ id: MyRect
+ color: "red"
+ width: 50; height: 50
+ x: 100; y: 100
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: if (Wrapper.state == "state1") Wrapper.state = ""; else Wrapper.state = "state1";
+ }
+ }
+ states: State {
+ name: "state1"
+ SetProperties { target: MyRect; pen.color: "blue" }
+ }
+ transitions: Transition {
+ ColorAnimation { target: MyRect; to: "red"; properties: "pen.colr"; duration: 1000 }
+ }
+}
diff --git a/tests/auto/declarative/animations/data/badtype1.qml b/tests/auto/declarative/animations/data/badtype1.qml
new file mode 100644
index 0000000..691d2b3
--- /dev/null
+++ b/tests/auto/declarative/animations/data/badtype1.qml
@@ -0,0 +1,10 @@
+Rect {
+ width: 240
+ height: 320
+ Rect {
+ color: "red"
+ width: 50; height: 50
+ x: 100; y: 100
+ x: PropertyAnimation { from: "blue"; to: "green"; running: true; }
+ }
+}
diff --git a/tests/auto/declarative/animations/data/badtype2.qml b/tests/auto/declarative/animations/data/badtype2.qml
new file mode 100644
index 0000000..aa248a6
--- /dev/null
+++ b/tests/auto/declarative/animations/data/badtype2.qml
@@ -0,0 +1,10 @@
+Rect {
+ width: 240
+ height: 320
+ Rect {
+ color: "red"
+ width: 50; height: 50
+ x: 100; y: 100
+ x: NumberAnimation { from: "blue"; to: "green"; running: true; }
+ }
+}
diff --git a/tests/auto/declarative/animations/data/badtype3.qml b/tests/auto/declarative/animations/data/badtype3.qml
new file mode 100644
index 0000000..f1a89b6
--- /dev/null
+++ b/tests/auto/declarative/animations/data/badtype3.qml
@@ -0,0 +1,10 @@
+Rect {
+ width: 240
+ height: 320
+ Rect {
+ color: "red"
+ color: ColorAnimation { from: 10; to: 15; running: true; }
+ width: 50; height: 50
+ x: 100; y: 100
+ }
+}
diff --git a/tests/auto/declarative/animations/data/badtype4.qml b/tests/auto/declarative/animations/data/badtype4.qml
new file mode 100644
index 0000000..fa4eebe
--- /dev/null
+++ b/tests/auto/declarative/animations/data/badtype4.qml
@@ -0,0 +1,23 @@
+Rect {
+ id: Wrapper
+ width: 240
+ height: 320
+ Rect {
+ id: MyRect
+ color: "red"
+ width: 50; height: 50
+ x: 100; y: 100
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: if (Wrapper.state == "state1") Wrapper.state = ""; else Wrapper.state = "state1";
+ }
+ }
+ states: State {
+ name: "state1"
+ SetProperties { target: MyRect; x: 200; color: "blue" }
+ }
+ transitions: Transition {
+ ColorAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color
+ //NumberAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color
+ }
+}
diff --git a/tests/auto/declarative/animations/data/color.qml b/tests/auto/declarative/animations/data/color.qml
new file mode 100644
index 0000000..051e0e1
--- /dev/null
+++ b/tests/auto/declarative/animations/data/color.qml
@@ -0,0 +1,10 @@
+Rect {
+ width: 240
+ height: 320
+ Rect {
+ color: "red"
+ color: PropertyAnimation { to: "green"; running: true }
+ width: 50; height: 50
+ x: 100; y: 100
+ }
+}
diff --git a/tests/auto/declarative/animations/data/dotproperty.qml b/tests/auto/declarative/animations/data/dotproperty.qml
new file mode 100644
index 0000000..2cfcefe
--- /dev/null
+++ b/tests/auto/declarative/animations/data/dotproperty.qml
@@ -0,0 +1,22 @@
+Rect {
+ id: Wrapper
+ width: 240
+ height: 320
+ Rect {
+ id: MyRect
+ color: "red"
+ width: 50; height: 50
+ x: 100; y: 100
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: if (Wrapper.state == "state1") Wrapper.state = ""; else Wrapper.state = "state1";
+ }
+ }
+ states: State {
+ name: "state1"
+ SetProperties { target: MyRect; pen.color: "blue" }
+ }
+ transitions: Transition {
+ ColorAnimation { properties: "pen.color"; duration: 1000 }
+ }
+}
diff --git a/tests/auto/declarative/animations/data/mixedtype1.qml b/tests/auto/declarative/animations/data/mixedtype1.qml
new file mode 100644
index 0000000..415bbfb
--- /dev/null
+++ b/tests/auto/declarative/animations/data/mixedtype1.qml
@@ -0,0 +1,22 @@
+Rect {
+ id: Wrapper
+ width: 240
+ height: 320
+ Rect {
+ id: MyRect
+ color: "red"
+ width: 50; height: 50
+ x: 100; y: 100
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: if (Wrapper.state == "state1") Wrapper.state = ""; else Wrapper.state = "state1";
+ }
+ }
+ states: State {
+ name: "state1"
+ SetProperties { target: MyRect; x: 200; width: 40 }
+ }
+ transitions: Transition {
+ PropertyAnimation { properties: "x,width"; duration: 1000 } //x is real, width is int
+ }
+}
diff --git a/tests/auto/declarative/animations/data/mixedtype2.qml b/tests/auto/declarative/animations/data/mixedtype2.qml
new file mode 100644
index 0000000..0e9fb8d
--- /dev/null
+++ b/tests/auto/declarative/animations/data/mixedtype2.qml
@@ -0,0 +1,22 @@
+Rect {
+ id: Wrapper
+ width: 240
+ height: 320
+ Rect {
+ id: MyRect
+ color: "red"
+ width: 50; height: 50
+ x: 100; y: 100
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: if (Wrapper.state == "state1") Wrapper.state = ""; else Wrapper.state = "state1";
+ }
+ }
+ states: State {
+ name: "state1"
+ SetProperties { target: MyRect; x: 200; color: "blue" }
+ }
+ transitions: Transition {
+ PropertyAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color
+ }
+}
diff --git a/tests/auto/declarative/animations/data/number.qml b/tests/auto/declarative/animations/data/number.qml
new file mode 100644
index 0000000..feb551b
--- /dev/null
+++ b/tests/auto/declarative/animations/data/number.qml
@@ -0,0 +1,10 @@
+Rect {
+ width: 240
+ height: 320
+ Rect {
+ color: "red"
+ width: 50; height: 50
+ x: 100; y: 100
+ x: PropertyAnimation { from: 0; to: 200; duration: 1000; running: true }
+ }
+}
diff --git a/tests/auto/declarative/animations/tst_animations.cpp b/tests/auto/declarative/animations/tst_animations.cpp
new file mode 100644
index 0000000..a493454
--- /dev/null
+++ b/tests/auto/declarative/animations/tst_animations.cpp
@@ -0,0 +1,97 @@
+#include <qtest.h>
+#include <QtDeclarative/qmlengine.h>
+#include <QtDeclarative/qmlcomponent.h>
+#include <QtDeclarative/qfxview.h>
+#include <QtDeclarative/qfxrect.h>
+
+class tst_animations : public QObject
+{
+ Q_OBJECT
+public:
+ tst_animations() {}
+
+private slots:
+ void badTypes();
+ void badProperties();
+ //void mixedTypes();
+};
+
+void tst_animations::badTypes()
+{
+ //don't crash
+ {
+ QFxView *view = new QFxView;
+ view->setUrl(QUrl("file://" SRCDIR "/data/badtype1.qml"));
+
+ view->execute();
+ qApp->processEvents();
+
+ delete view;
+ }
+
+ //make sure we get a compiler error
+ {
+ QmlEngine engine;
+ QmlComponent c(&engine, QUrl("file://" SRCDIR "/data/badtype2.qml"));
+ QTest::ignoreMessage(QtWarningMsg, "QmlComponent: Component is not ready");
+ c.create();
+
+ QVERIFY(c.errors().count() == 1);
+ QCOMPARE(c.errors().at(0).description(), QLatin1String("Cannot convert value \"blue\" to double number"));
+ }
+
+ //make sure we get a compiler error
+ {
+ QmlEngine engine;
+ QmlComponent c(&engine, QUrl("file://" SRCDIR "/data/badtype3.qml"));
+ QTest::ignoreMessage(QtWarningMsg, "QmlComponent: Component is not ready");
+ c.create();
+
+ QVERIFY(c.errors().count() == 1);
+ QCOMPARE(c.errors().at(0).description(), QLatin1String("Cannot convert value \"10\" to color"));
+ }
+}
+
+void tst_animations::badProperties()
+{
+ //don't crash (should be runtime error)
+ {
+ QFxView *view = new QFxView;
+ view->setUrl(QUrl("file://" SRCDIR "/data/badproperty1.qml"));
+
+ view->execute();
+ qApp->processEvents();
+
+ delete view;
+ }
+}
+
+/*//test animating mixed types with property animation
+ //for example, int + real; color + real; etc
+void tst_animations::mixedTypes()
+{
+ //### this one isn't real robust because width will likely change to real as well
+ {
+ QFxView *view = new QFxView;
+ view->setUrl(QUrl("file://" SRCDIR "/data/mixedtype1.qml"));
+
+ view->execute();
+ qApp->processEvents();
+
+ delete view;
+ }
+
+ {
+ QFxView *view = new QFxView;
+ view->setUrl(QUrl("file://" SRCDIR "/data/mixedtype2.qml"));
+
+ view->execute();
+ qApp->processEvents();
+
+ delete view;
+ }
+}*/
+
+QTEST_MAIN(tst_animations)
+
+#include "tst_animations.moc"
diff --git a/tests/auto/declarative/qfxtextedit/data/cursorTest.qml b/tests/auto/declarative/qfxtextedit/data/cursorTest.qml
new file mode 100644
index 0000000..10ac2fd
--- /dev/null
+++ b/tests/auto/declarative/qfxtextedit/data/cursorTest.qml
@@ -0,0 +1,6 @@
+Rect { width: 300; height: 300; color: "white"
+ TextEdit { text: "Hello world!"; focusable: true; id: textEditObject
+ resources: [ Component { id:cursor; Item { id:cursorInstance } } ]
+ cursorDelegate: cursor
+ }
+}
diff --git a/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp b/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp
index 7be5b50..241dbad 100644
--- a/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp
+++ b/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp
@@ -1,6 +1,8 @@
#include <qtest.h>
#include <QTextDocument>
#include <QtDeclarative/qmlengine.h>
+#include <QtDeclarative/qmlcontext.h>
+#include <QtDeclarative/qmlexpression.h>
#include <QtDeclarative/qmlcomponent.h>
#include <QtDeclarative/qfxtextedit.h>
#include <QFontMetrics>
@@ -22,6 +24,9 @@ private slots:
void vAlign();
void font();
void color();
+ void selection();
+
+ void cursorDelegate();
private:
QStringList standard;
@@ -84,7 +89,7 @@ tst_qfxtextedit::tst_qfxtextedit()
void tst_qfxtextedit::text()
{
{
- QmlComponent texteditComponent(&engine, "TextEdit { text: \"\" }");
+ QmlComponent texteditComponent(&engine, "TextEdit { text: \"\" }", QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
QVERIFY(textEditObject != 0);
@@ -94,7 +99,7 @@ void tst_qfxtextedit::text()
for (int i = 0; i < standard.size(); i++)
{
QString componentStr = "TextEdit { text: \"" + standard.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
QVERIFY(textEditObject != 0);
@@ -104,7 +109,7 @@ void tst_qfxtextedit::text()
for (int i = 0; i < richText.size(); i++)
{
QString componentStr = "TextEdit { text: \"" + richText.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
QVERIFY(textEditObject != 0);
@@ -121,9 +126,10 @@ void tst_qfxtextedit::width()
{
// uses Font metrics to find the width for standard and document to find the width for rich
{
- QmlComponent texteditComponent(&engine, "TextEdit { text: \"\" }");
+ QmlComponent texteditComponent(&engine, "TextEdit { text: \"\" }", QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->width(), 0.);
}
@@ -134,9 +140,10 @@ void tst_qfxtextedit::width()
int metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width();
QString componentStr = "TextEdit { text: \"" + standard.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->width(), qreal(metricWidth));
}
@@ -149,9 +156,10 @@ void tst_qfxtextedit::width()
int documentWidth = document.idealWidth();
QString componentStr = "TextEdit { text: \"" + richText.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->width(), qreal(documentWidth));
}
}
@@ -160,27 +168,30 @@ void tst_qfxtextedit::wrap()
{
// for specified width and wrap set true
{
- QmlComponent texteditComponent(&engine, "TextEdit { text: \"\"; wrap: true; width: 300 }");
+ QmlComponent texteditComponent(&engine, "TextEdit { text: \"\"; wrap: true; width: 300 }", QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->width(), 300.);
}
for (int i = 0; i < standard.size(); i++)
{
QString componentStr = "TextEdit { wrap: true; width: 300; text: \"" + standard.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->width(), 300.);
}
for (int i = 0; i < richText.size(); i++)
{
QString componentStr = "TextEdit { wrap: true; width: 300; text: \"" + richText.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->width(), 300.);
}
@@ -196,9 +207,10 @@ void tst_qfxtextedit::hAlign()
for (int j=0; j < hAlignmentStrings.size(); j++)
{
QString componentStr = "TextEdit { hAlign: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
}
}
@@ -208,9 +220,10 @@ void tst_qfxtextedit::hAlign()
for (int j=0; j < hAlignmentStrings.size(); j++)
{
QString componentStr = "TextEdit { hAlign: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
}
}
@@ -226,9 +239,10 @@ void tst_qfxtextedit::vAlign()
for (int j=0; j < vAlignmentStrings.size(); j++)
{
QString componentStr = "TextEdit { vAlign: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
}
}
@@ -238,9 +252,10 @@ void tst_qfxtextedit::vAlign()
for (int j=0; j < vAlignmentStrings.size(); j++)
{
QString componentStr = "TextEdit { vAlign: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
}
}
@@ -252,9 +267,10 @@ void tst_qfxtextedit::font()
//test size, then bold, then italic, then family
{
QString componentStr = "TextEdit { font.size: 40; text: \"Hello World\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->font()->size(), qreal(40));
QCOMPARE(textEditObject->font()->bold(), false);
QCOMPARE(textEditObject->font()->italic(), false);
@@ -262,27 +278,30 @@ void tst_qfxtextedit::font()
{
QString componentStr = "TextEdit { font.bold: true; text: \"Hello World\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->font()->bold(), true);
QCOMPARE(textEditObject->font()->italic(), false);
}
{
QString componentStr = "TextEdit { font.italic: true; text: \"Hello World\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->font()->italic(), true);
QCOMPARE(textEditObject->font()->bold(), false);
}
{
QString componentStr = "TextEdit { font.family: \"Helvetica\"; text: \"Hello World\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->font()->family(), QString("Helvetica"));
QCOMPARE(textEditObject->font()->bold(), false);
QCOMPARE(textEditObject->font()->italic(), false);
@@ -290,9 +309,10 @@ void tst_qfxtextedit::font()
{
QString componentStr = "TextEdit { font.family: \"\"; text: \"Hello World\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->font()->family(), QString(""));
}
}
@@ -303,9 +323,10 @@ void tst_qfxtextedit::color()
for (int i = 0; i < colorStrings.size(); i++)
{
QString componentStr = "TextEdit { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
//qDebug() << "textEditObject: " << textEditObject->color() << "vs. " << QColor(colorStrings.at(i));
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->color(), QColor(colorStrings.at(i)));
}
@@ -315,12 +336,122 @@ void tst_qfxtextedit::color()
testColor.setAlpha(170);
QString componentStr = "TextEdit { color: \"" + colorStr + "\"; text: \"Hello World\" }";
- QmlComponent texteditComponent(&engine, componentStr.toLatin1());
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
QCOMPARE(textEditObject->color(), testColor);
}
}
+
+void tst_qfxtextedit::selection()
+{
+ QString testStr = standard[0];//TODO: What should happen for multiline/rich text?
+ QString componentStr = "TextEdit { text: \""+ testStr +"\"; }";
+ QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create());
+ QVERIFY(textEditObject != 0);
+
+
+ //Test selection follows cursor
+ for(int i=0; i<= testStr.size(); i++) {
+ textEditObject->setCursorPosition(i);
+ QCOMPARE(textEditObject->cursorPosition(), i);
+ QCOMPARE(textEditObject->selectionStart(), i);
+ QCOMPARE(textEditObject->selectionEnd(), i);
+ QVERIFY(textEditObject->selectedText().isNull());
+ }
+
+ textEditObject->setCursorPosition(0);
+ QVERIFY(textEditObject->cursorPosition() == 0);
+ QVERIFY(textEditObject->selectionStart() == 0);
+ QVERIFY(textEditObject->selectionEnd() == 0);
+ QVERIFY(textEditObject->selectedText().isNull());
+
+ //Test selection
+ for(int i=0; i<= testStr.size(); i++) {
+ textEditObject->setSelectionEnd(i);
+ QCOMPARE(testStr.mid(0,i), textEditObject->selectedText());
+ }
+ for(int i=0; i<= testStr.size(); i++) {
+ textEditObject->setSelectionStart(i);
+ QCOMPARE(testStr.mid(i,testStr.size()-i), textEditObject->selectedText());
+ }
+
+ textEditObject->setCursorPosition(0);
+ QVERIFY(textEditObject->cursorPosition() == 0);
+ QVERIFY(textEditObject->selectionStart() == 0);
+ QVERIFY(textEditObject->selectionEnd() == 0);
+ QVERIFY(textEditObject->selectedText().isNull());
+
+ for(int i=0; i< testStr.size(); i++) {
+ textEditObject->setSelectionStart(i);
+ QCOMPARE(textEditObject->selectionEnd(), i);
+ QCOMPARE(testStr.mid(i,0), textEditObject->selectedText());
+ textEditObject->setSelectionEnd(i+1);
+ QCOMPARE(textEditObject->selectionStart(), i);
+ QCOMPARE(testStr.mid(i,1), textEditObject->selectedText());
+ }
+
+ for(int i= testStr.size() - 1; i>0; i--) {
+ textEditObject->setSelectionEnd(i);
+ QCOMPARE(testStr.mid(i,0), textEditObject->selectedText());
+ textEditObject->setSelectionStart(i-1);
+ QCOMPARE(testStr.mid(i-1,1), textEditObject->selectedText());
+ }
+
+ //Test Error Ignoring behaviour
+ textEditObject->setCursorPosition(0);
+ QVERIFY(textEditObject->selectedText().isNull());
+ textEditObject->setSelectionStart(-10);
+ QVERIFY(textEditObject->selectedText().isNull());
+ textEditObject->setSelectionStart(100);
+ QVERIFY(textEditObject->selectedText().isNull());
+ textEditObject->setSelectionEnd(-10);
+ QVERIFY(textEditObject->selectedText().isNull());
+ textEditObject->setSelectionEnd(100);
+ QVERIFY(textEditObject->selectedText().isNull());
+ textEditObject->setSelectionStart(0);
+ textEditObject->setSelectionEnd(10);
+ QVERIFY(textEditObject->selectedText().size() == 10);
+ textEditObject->setSelectionStart(-10);
+ QVERIFY(textEditObject->selectedText().size() == 10);
+ textEditObject->setSelectionStart(100);
+ QVERIFY(textEditObject->selectedText().size() == 10);
+ textEditObject->setSelectionEnd(-10);
+ QVERIFY(textEditObject->selectedText().size() == 10);
+ textEditObject->setSelectionEnd(100);
+ QVERIFY(textEditObject->selectedText().size() == 10);
+}
+
+#include <QFxView>
+void tst_qfxtextedit::cursorDelegate()
+{
+ QFxView* view = new QFxView(0);
+ view->show();
+ view->setUrl(QUrl("data/cursorTest.qml"));
+ view->execute();
+ QFxTextEdit *textEditObject = view->root()->findChild<QFxTextEdit*>("textEditObject");
+ QVERIFY(textEditObject != 0);
+ QVERIFY(textEditObject->findChild<QFxItem*>("cursorInstance"));
+ //Test Delegate gets created
+ textEditObject->setFocus(true);
+ QFxItem* delegateObject = textEditObject->findChild<QFxItem*>("cursorInstance");
+ QVERIFY(delegateObject);
+ //Test Delegate gets moved
+ for(int i=0; i<= textEditObject->text().length(); i++){
+ textEditObject->setCursorPosition(i);
+ QCOMPARE(textEditObject->cursorRect().x(), qRound(delegateObject->x()));
+ QCOMPARE(textEditObject->cursorRect().y(), qRound(delegateObject->y()));
+ }
+ textEditObject->setCursorPosition(0);
+ QCOMPARE(textEditObject->cursorRect().x(), qRound(delegateObject->x()));
+ QCOMPARE(textEditObject->cursorRect().y(), qRound(delegateObject->y()));
+ //Test Delegate gets deleted
+ textEditObject->setCursorDelegate(0);
+ QVERIFY(!textEditObject->findChild<QFxItem*>("cursorInstance"));
+}
+
QTEST_MAIN(tst_qfxtextedit)
#include "tst_qfxtextedit.moc"
diff --git a/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro b/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro
index 114be8e..f4aea32 100644
--- a/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro
+++ b/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro
@@ -1,5 +1,6 @@
load(qttest_p4)
contains(QT_CONFIG,declarative): QT += declarative
+contains(QT_CONFIG, opengles2)|contains(QT_CONFIG, opengles1): QT += opengl
SOURCES += tst_simplecanvasitem.cpp
# Define SRCDIR equal to test's source directory
diff --git a/tests/auto/declarative/visual/bindinganimation/bindinganimation.qml b/tests/auto/declarative/visual/bindinganimation/bindinganimation.qml
index 61cedc2..69c5d81 100644
--- a/tests/auto/declarative/visual/bindinganimation/bindinganimation.qml
+++ b/tests/auto/declarative/visual/bindinganimation/bindinganimation.qml
@@ -13,21 +13,19 @@ Rect {
states: [
State {
name: "hello"
- SetProperty {
+ SetProperties {
target: MyRect
- property: "x"
- binding: 100
+ x: 100
}
- SetProperty {
+ SetProperties {
target: MyMouseRegion
- property: "onClicked"
- value: "Page.currentState = ''"
+ onClicked: "Page.currentState = ''"
}
}
]
transitions: [
Transition {
- NumericAnimation {
+ NumberAnimation {
properties: "x"
}
}
diff --git a/tests/auto/declarative/visual/colorAnimation/colorAnimation.qml b/tests/auto/declarative/visual/colorAnimation/colorAnimation.qml
index d351b8c..cb631d4 100644
--- a/tests/auto/declarative/visual/colorAnimation/colorAnimation.qml
+++ b/tests/auto/declarative/visual/colorAnimation/colorAnimation.qml
@@ -5,18 +5,16 @@ Rect {
states: [
State {
name: "first"
- SetProperty {
+ SetProperties {
target: mainrect
- property: "color"
- value: "red"
+ color: "red"
}
},
State {
name: "second"
- SetProperty {
+ SetProperties {
target: mainrect
- property: "color"
- value: "blue"
+ color: "blue"
}
}
]
diff --git a/tests/auto/declarative/visual/easing/easing.qml b/tests/auto/declarative/visual/easing/easing.qml
index 4a0ed14..7a58276 100644
--- a/tests/auto/declarative/visual/easing/easing.qml
+++ b/tests/auto/declarative/visual/easing/easing.qml
@@ -148,19 +148,17 @@ Rect {
State {
name: "from"
when: !mouse.pressed
- SetProperty {
+ SetProperties {
target: text
- property: "x"
- value: 0
+ x: 0
}
},
State {
name: "to"
when: mouse.pressed
- SetProperty {
+ SetProperties {
target: text
- property: "x"
- value: item.width-100
+ x: item.width-100
}
}
]
@@ -169,7 +167,7 @@ Rect {
fromState: "*"
toState: "to"
reversible: true
- NumericAnimation {
+ NumberAnimation {
properties: "x"
easing: type
}
diff --git a/tests/auto/declarative/visual/flipable/flipable.xml b/tests/auto/declarative/visual/flipable/flipable.xml
index d769e55..9288acc 100644
--- a/tests/auto/declarative/visual/flipable/flipable.xml
+++ b/tests/auto/declarative/visual/flipable/flipable.xml
@@ -104,17 +104,17 @@
</states>
<transitions>
<Transition fromState="*" toState="*">
- <NumericAnimation property="r" duration="500" />
+ <NumberAnimation property="r" duration="500" />
<SerialAnimation>
<SetPropertyAction target="{MeRect}" property="moveToParent" value="{Bounce}" />
<ParallelAnimation>
- <NumericAnimation target="{MeRect}" properties="x" to="0" duration="250" />
- <NumericAnimation target="{MeRect}" properties="y" to="0" easing="easeInQuad" duration="250"/>
+ <NumberAnimation target="{MeRect}" properties="x" to="0" duration="250" />
+ <NumberAnimation target="{MeRect}" properties="y" to="0" easing="easeInQuad" duration="250"/>
</ParallelAnimation>
<SetPropertyAction target="{MeRect}" property="moveToParent" />
<ParallelAnimation>
- <NumericAnimation target="{MeRect}" properties="x" to="0" duration="250"/>
- <NumericAnimation target="{MeRect}" properties="y" to="0" easing="easeOutQuad" duration="250"/>
+ <NumberAnimation target="{MeRect}" properties="x" to="0" duration="250"/>
+ <NumberAnimation target="{MeRect}" properties="y" to="0" easing="easeOutQuad" duration="250"/>
</ParallelAnimation>
</SerialAnimation>
</Transition>
diff --git a/tests/auto/declarative/visual/pauseAnimation/pauseAnimation.qml b/tests/auto/declarative/visual/pauseAnimation/pauseAnimation.qml
index 5c00f58..e0880f0 100644
--- a/tests/auto/declarative/visual/pauseAnimation/pauseAnimation.qml
+++ b/tests/auto/declarative/visual/pauseAnimation/pauseAnimation.qml
@@ -11,11 +11,11 @@ Rect {
y: SequentialAnimation {
running: true
repeat: true
- NumericAnimation {
+ NumberAnimation {
to: 0; duration: 500
easing: "easeInOutQuad"
}
- NumericAnimation {
+ NumberAnimation {
to: 200-img.height
easing: "easeOutBounce"
duration: 2000
diff --git a/tests/auto/gestures/customgesturerecognizer.cpp b/tests/auto/gestures/customgesturerecognizer.cpp
new file mode 100644
index 0000000..12d07b1
--- /dev/null
+++ b/tests/auto/gestures/customgesturerecognizer.cpp
@@ -0,0 +1,167 @@
+#include "customgesturerecognizer.h"
+#include "qgesture.h"
+
+const char* SingleshotGestureRecognizer::Name = "SingleshotGesture";
+const char* PinchGestureRecognizer::Name = "PinchGesture";
+const char* SecondFingerGestureRecognizer::Name = "SecondFingerGesture";
+const char* PanGestureRecognizer::Name = "PanGesture";
+
+SingleshotGestureRecognizer::SingleshotGestureRecognizer(QObject *parent)
+ : QGestureRecognizer(QString(SingleshotGestureRecognizer::Name), parent)
+{
+ gesture = new SingleshotGesture(this, SingleshotGestureRecognizer::Name);
+}
+
+QGestureRecognizer::Result SingleshotGestureRecognizer::filterEvent(const QEvent *event)
+{
+ if (event->type() == SingleshotEvent::Type) {
+ gesture->setHotSpot(static_cast<const SingleshotEvent*>(event)->point);
+ return QGestureRecognizer::GestureFinished;
+ }
+ return QGestureRecognizer::NotGesture;
+}
+
+void SingleshotGestureRecognizer::reset()
+{
+ gesture->setHotSpot(QPoint());
+ gesture->offset = QPoint();
+}
+
+PinchGestureRecognizer::PinchGestureRecognizer(QObject *parent)
+ : QGestureRecognizer(PinchGestureRecognizer::Name, parent)
+{
+ gesture = new PinchGesture(this, PinchGestureRecognizer::Name);
+}
+
+QGestureRecognizer::Result PinchGestureRecognizer::filterEvent(const QEvent *event)
+{
+ if (event->type() != TouchEvent::Type)
+ return QGestureRecognizer::Ignore;
+
+ const TouchEvent *e = static_cast<const TouchEvent*>(event);
+ if (e->points[0].state == TouchPoint::Begin)
+ gesture->startPoints[0] = e->points[0];
+ if (e->points[1].state == TouchPoint::Begin)
+ gesture->startPoints[1] = e->points[1];
+ gesture->lastPoints[0] = gesture->points[0];
+ gesture->lastPoints[1] = gesture->points[1];
+ gesture->points[0] = e->points[0];
+ gesture->points[1] = e->points[1];
+ if (((e->points[0].state == TouchPoint::Begin || e->points[0].state == TouchPoint::Update))) {
+ if (e->points[1].state == TouchPoint::End || e->points[1].state == TouchPoint::None)
+ return MaybeGesture;
+ return GestureStarted;
+ } else if (((e->points[1].state == TouchPoint::Begin || e->points[1].state == TouchPoint::Update))) {
+ if (e->points[0].state == TouchPoint::End || e->points[0].state == TouchPoint::None)
+ return MaybeGesture;
+ return GestureStarted;
+ } else if ((e->points[0].state == TouchPoint::End && e->points[1].state == TouchPoint::End) ||
+ (e->points[0].state == TouchPoint::End && e->points[1].state == TouchPoint::None) ||
+ (e->points[0].state == TouchPoint::None && e->points[1].state == TouchPoint::End)) {
+ return QGestureRecognizer::NotGesture;
+ }
+ return QGestureRecognizer::NotGesture;
+}
+
+void PinchGestureRecognizer::reset()
+{
+ gesture->startPoints[0] = TouchPoint();
+ gesture->startPoints[1] = TouchPoint();
+ gesture->lastPoints[0] = TouchPoint();
+ gesture->lastPoints[1] = TouchPoint();
+ gesture->points[0] = TouchPoint();
+ gesture->points[1] = TouchPoint();
+ gesture->offset = QPoint();
+}
+
+SecondFingerGestureRecognizer::SecondFingerGestureRecognizer(QObject *parent)
+ : QGestureRecognizer(SecondFingerGestureRecognizer::Name, parent)
+{
+ gesture = new SecondFingerGesture(this, SecondFingerGestureRecognizer::Name);
+}
+
+QGestureRecognizer::Result SecondFingerGestureRecognizer::filterEvent(const QEvent *event)
+{
+ if (event->type() != TouchEvent::Type)
+ return QGestureRecognizer::Ignore;
+
+ const TouchEvent *e = static_cast<const TouchEvent*>(event);
+ if (e->points[1].state != TouchPoint::None) {
+ if (e->points[1].state == TouchPoint::Begin)
+ gesture->startPoint = e->points[1];
+ gesture->lastPoint = gesture->point;
+ gesture->point = e->points[1];
+ if (e->points[1].state == TouchPoint::End)
+ return QGestureRecognizer::GestureFinished;
+ else if (e->points[1].state != TouchPoint::None)
+ return QGestureRecognizer::GestureStarted;
+ }
+ return QGestureRecognizer::NotGesture;
+}
+
+void SecondFingerGestureRecognizer::reset()
+{
+ gesture->startPoint = TouchPoint();
+ gesture->lastPoint = TouchPoint();
+ gesture->point = TouchPoint();
+ gesture->offset = QPoint();
+}
+
+PanGestureRecognizer::PanGestureRecognizer(QObject *parent)
+ : QGestureRecognizer(PanGestureRecognizer::Name, parent)
+{
+ gesture = new PanGesture(this, PanGestureRecognizer::Name);
+}
+
+QGestureRecognizer::Result PanGestureRecognizer::filterEvent(const QEvent *event)
+{
+ if (event->type() != QEvent::TouchBegin &&
+ event->type() != QEvent::TouchUpdate &&
+ event->type() != QEvent::TouchEnd)
+ return QGestureRecognizer::Ignore;
+
+ const QTouchEvent *e = static_cast<const QTouchEvent*>(event);
+ const QList<QTouchEvent::TouchPoint> &points = e->touchPoints();
+
+ if (points.size() >= 1) {
+ gesture->lastPoints[0] = gesture->points[0];
+ gesture->points[0].id = points.at(0).id();
+ gesture->points[0].pt = points.at(0).startPos().toPoint();
+ gesture->points[0].state = (TouchPoint::State)points.at(0).state();
+ if (points.at(0).state() == Qt::TouchPointPressed) {
+ gesture->startPoints[0] = gesture->points[0];
+ gesture->lastPoints[0] = gesture->points[0];
+ }
+ }
+ if (points.size() >= 2) {
+ gesture->lastPoints[1] = gesture->points[1];
+ gesture->points[1].id = points.at(1).id();
+ gesture->points[1].pt = points.at(1).startPos().toPoint();
+ gesture->points[1].state = (TouchPoint::State)points.at(1).state();
+ if (points.at(1).state() == Qt::TouchPointPressed) {
+ gesture->startPoints[1] = gesture->points[1];
+ gesture->lastPoints[1] = gesture->points[1];
+ }
+ }
+
+ if (points.size() == 2)
+ return QGestureRecognizer::GestureStarted;
+ if (points.size() > 2)
+ return QGestureRecognizer::MaybeGesture;
+ if (points.at(0).state() == Qt::TouchPointPressed)
+ return QGestureRecognizer::MaybeGesture;
+ if (points.at(0).state() == Qt::TouchPointReleased)
+ return QGestureRecognizer::GestureFinished;
+ return QGestureRecognizer::GestureStarted;
+}
+
+void PanGestureRecognizer::reset()
+{
+ gesture->startPoints[0] = TouchPoint();
+ gesture->startPoints[1] = TouchPoint();
+ gesture->lastPoints[0] = TouchPoint();
+ gesture->lastPoints[1] = TouchPoint();
+ gesture->points[0] = TouchPoint();
+ gesture->points[1] = TouchPoint();
+ gesture->offset = QPoint();
+}
diff --git a/tests/auto/gestures/customgesturerecognizer.h b/tests/auto/gestures/customgesturerecognizer.h
new file mode 100644
index 0000000..519aba8
--- /dev/null
+++ b/tests/auto/gestures/customgesturerecognizer.h
@@ -0,0 +1,187 @@
+#ifndef CUSTOMGESTURERECOGNIZER_H
+#define CUSTOMGESTURERECOGNIZER_H
+
+#include "qgesturerecognizer.h"
+#include "qgesture.h"
+#include "qevent.h"
+
+class SingleshotEvent : public QEvent
+{
+public:
+ static const int Type = QEvent::User + 1;
+
+ QPoint point;
+
+ explicit SingleshotEvent(int x = 0, int y = 0)
+ : QEvent(QEvent::Type(Type)), point(x, y) { }
+};
+
+class SingleshotGesture : public QGesture
+{
+ Q_OBJECT
+public:
+ SingleshotGesture(QObject *parent, const QString &type)
+ : QGesture(parent, type) { }
+
+ QPoint offset;
+
+protected:
+ void translate(const QPoint &pt)
+ {
+ offset += pt;
+ }
+};
+
+class SingleshotGestureRecognizer : public QGestureRecognizer
+{
+ Q_OBJECT
+public:
+ static const char *Name;
+
+ SingleshotGestureRecognizer(QObject *parent = 0);
+
+ QGestureRecognizer::Result filterEvent(const QEvent *event);
+ QGesture* getGesture() { return gesture; }
+ void reset();
+
+private:
+ SingleshotGesture *gesture;
+};
+
+struct TouchPoint {
+ enum State
+ {
+ None = 0,
+ Begin = Qt::TouchPointPressed,
+ Update = Qt::TouchPointMoved,
+ End = Qt::TouchPointReleased
+ };
+ int id;
+ QPoint pt;
+ State state;
+ TouchPoint() : id(0), state(None) { }
+ TouchPoint(int id_, int x_, int y_, State state_) : id(id_), pt(x_, y_), state(state_) { }
+};
+
+class TouchEvent : public QEvent
+{
+public:
+ static const int Type = QEvent::User + 2;
+
+ TouchEvent()
+ : QEvent(QEvent::Type(Type))
+ {
+ }
+
+ TouchPoint points[2];
+};
+
+class PinchGesture : public QGesture
+{
+ Q_OBJECT
+public:
+ PinchGesture(QObject *parent, const QString &type)
+ : QGesture(parent, type) { }
+
+ TouchPoint startPoints[2];
+ TouchPoint lastPoints[2];
+ TouchPoint points[2];
+
+ QPoint offset;
+
+protected:
+ void translate(const QPoint &pt)
+ {
+ offset += pt;
+ }
+};
+
+class PinchGestureRecognizer : public QGestureRecognizer
+{
+ Q_OBJECT
+public:
+ static const char *Name;
+
+ PinchGestureRecognizer(QObject *parent = 0);
+
+ QGestureRecognizer::Result filterEvent(const QEvent *event);
+ QGesture* getGesture() { return gesture; }
+ void reset();
+
+private:
+ PinchGesture *gesture;
+};
+
+class SecondFingerGesture : public QGesture
+{
+ Q_OBJECT
+public:
+ SecondFingerGesture(QObject *parent, const QString &type)
+ : QGesture(parent, type) { }
+
+ TouchPoint startPoint;
+ TouchPoint lastPoint;
+ TouchPoint point;
+
+ QPoint offset;
+
+protected:
+ void translate(const QPoint &pt)
+ {
+ offset += pt;
+ }
+};
+
+class SecondFingerGestureRecognizer : public QGestureRecognizer
+{
+ Q_OBJECT
+public:
+ static const char *Name;
+
+ SecondFingerGestureRecognizer(QObject *parent = 0);
+
+ QGestureRecognizer::Result filterEvent(const QEvent *event);
+ QGesture* getGesture() { return gesture; }
+ void reset();
+
+private:
+ SecondFingerGesture *gesture;
+};
+
+class PanGesture : public QGesture
+{
+ Q_OBJECT
+public:
+ PanGesture(QObject *parent, const QString &type)
+ : QGesture(parent, type) { }
+
+ TouchPoint startPoints[2];
+ TouchPoint lastPoints[2];
+ TouchPoint points[2];
+
+ QPoint offset;
+
+protected:
+ void translate(const QPoint &pt)
+ {
+ offset += pt;
+ }
+};
+
+class PanGestureRecognizer : public QGestureRecognizer
+{
+ Q_OBJECT
+public:
+ static const char *Name;
+
+ PanGestureRecognizer(QObject *parent = 0);
+
+ QGestureRecognizer::Result filterEvent(const QEvent *event);
+ QGesture* getGesture() { return gesture; }
+ void reset();
+
+private:
+ PanGesture *gesture;
+};
+
+#endif
diff --git a/tests/auto/gestures/gestures.pro b/tests/auto/gestures/gestures.pro
new file mode 100644
index 0000000..ac99b19
--- /dev/null
+++ b/tests/auto/gestures/gestures.pro
@@ -0,0 +1,3 @@
+load(qttest_p4)
+SOURCES += tst_gestures.cpp customgesturerecognizer.cpp
+HEADERS += customgesturerecognizer.h
diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp
new file mode 100644
index 0000000..6d3bc0a
--- /dev/null
+++ b/tests/auto/gestures/tst_gestures.cpp
@@ -0,0 +1,949 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtGui>
+
+#include <QtTest/QtTest>
+
+#include "customgesturerecognizer.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+// color generator for syntax highlighting from QQ-26 by Helder Correia
+QVector<QColor> highlight(const QColor &bg, const
+ QColor &fg, int noColors)
+{
+ QVector<QColor> colors;
+ const int HUE_BASE = (bg.hue() == -1) ? 90 : bg.hue();
+ int h, s, v;
+ for (int i = 0; i < noColors; i++) {
+ h = int(HUE_BASE + (360.0 / noColors * i)) % 360;
+ s = 240;
+ v = int(qMax(bg.value(), fg.value()) * 0.85);
+
+ const int M = 35;
+ if ((h < bg.hue() + M && h > bg.hue() - M)
+ || (h < fg.hue() + M && h > fg.hue() - M))
+ {
+ h = ((bg.hue() + fg.hue()) / (i+1)) % 360;
+ s = ((bg.saturation() + fg.saturation() + 2*i)
+ / 2) % 256;
+ v = ((bg.value() + fg.value() + 2*i) / 2)
+ % 256;
+ }
+ colors.append(QColor::fromHsv(h, s, v));
+ }
+ return colors;
+}
+
+
+// a hack to mark an event as spontaneous.
+class QETWidget
+{
+public:
+ static void setSpont(QEvent *event, bool spont) { event->spont = spont; }
+};
+
+struct GestureState
+{
+ int seenGestureEvent;
+ struct LastGestureEvent
+ {
+ struct SingleshotGesture
+ {
+ bool delivered;
+ QPoint offset;
+ } singleshot;
+ struct PinchGesture
+ {
+ bool delivered;
+ TouchPoint startPoints[2];
+ TouchPoint lastPoints[2];
+ TouchPoint points[2];
+ QPoint offset;
+ } pinch;
+ struct SecondFingerGesture
+ {
+ bool delivered;
+ TouchPoint startPoint;
+ TouchPoint lastPoint;
+ TouchPoint point;
+ QPoint offset;
+ } secondfinger;
+ struct PanGesture
+ {
+ bool delivered;
+ TouchPoint startPoints[2];
+ TouchPoint lastPoints[2];
+ TouchPoint points[2];
+ QPoint offset;
+ } pan;
+ QSet<QString> cancelled;
+ } last;
+
+ GestureState() { reset(); }
+ void reset()
+ {
+ seenGestureEvent = 0;
+ last.singleshot.delivered = false;
+ last.singleshot.offset = QPoint();
+ last.pinch.delivered = false;
+ last.pinch.startPoints[0] = TouchPoint();
+ last.pinch.startPoints[1] = TouchPoint();
+ last.pinch.lastPoints[0] = TouchPoint();
+ last.pinch.lastPoints[1] = TouchPoint();
+ last.pinch.points[0] = TouchPoint();
+ last.pinch.points[1] = TouchPoint();
+ last.pinch.offset = QPoint();
+ last.secondfinger.delivered = false;
+ last.secondfinger.startPoint = TouchPoint();
+ last.secondfinger.lastPoint = TouchPoint();
+ last.secondfinger.point = TouchPoint();
+ last.secondfinger.offset = QPoint();
+ last.cancelled.clear();
+ }
+};
+
+struct TouchState
+{
+ int seenTouchBeginEvent;
+ int seenTouchUpdateEvent;
+ int seenTouchEndEvent;
+
+ TouchState() { reset(); }
+ void reset()
+ {
+ seenTouchBeginEvent = seenTouchUpdateEvent = seenTouchEndEvent = 0;
+ }
+};
+
+class GestureWidget : public QWidget
+{
+ Q_OBJECT
+ static QVector<QColor> colors;
+ static int numberOfWidgets;
+
+public:
+ enum Type { DoNotGrabGestures, GrabAllGestures, GrabSingleshot,
+ GrabPinch, GrabSecondFinger, GrabPan };
+
+ static const int LeftMargin = 10;
+ static const int TopMargin = 20;
+
+ GestureWidget(Type type = GrabAllGestures)
+ {
+ if (colors.isEmpty()) {
+ colors = highlight(palette().color(QPalette::Window), palette().color(QPalette::Text), 5);
+ }
+ QPalette p = palette();
+ p.setColor(QPalette::Window, colors[numberOfWidgets % colors.size()]);
+ setPalette(p);
+ setAutoFillBackground(true);
+ ++numberOfWidgets;
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setSpacing(0);
+ l->setContentsMargins(LeftMargin, TopMargin, LeftMargin, TopMargin);
+
+ singleshotGestureId = -1;
+ pinchGestureId = -1;
+ secondFingerGestureId = -1;
+ panGestureId = -1;
+ if (type == GrabAllGestures || type == GrabSingleshot) {
+ singleshotGestureId = grabGesture(SingleshotGestureRecognizer::Name);
+ }
+ if (type == GrabAllGestures || type == GrabPinch) {
+ pinchGestureId = grabGesture(PinchGestureRecognizer::Name);
+ }
+ if (type == GrabAllGestures || type == GrabSecondFinger) {
+ secondFingerGestureId = grabGesture(SecondFingerGestureRecognizer::Name);
+ }
+ if (type == GrabAllGestures || type == GrabPan) {
+ panGestureId = grabGesture(PanGestureRecognizer::Name);
+ }
+ reset();
+ }
+ ~GestureWidget()
+ {
+ --numberOfWidgets;
+ ungrabGestures();
+ }
+
+ void grabSingleshotGesture()
+ {
+ singleshotGestureId = grabGesture(SingleshotGestureRecognizer::Name);
+ }
+ void grabPinchGesture()
+ {
+ pinchGestureId = grabGesture(PinchGestureRecognizer::Name);
+ }
+ void grabSecondFingerGesture()
+ {
+ secondFingerGestureId = grabGesture(SecondFingerGestureRecognizer::Name);
+ }
+ void grabPanGesture()
+ {
+ panGestureId = grabGesture(PanGestureRecognizer::Name);
+ }
+ void ungrabGestures()
+ {
+ releaseGesture(singleshotGestureId);
+ singleshotGestureId = -1;
+ releaseGesture(pinchGestureId);
+ pinchGestureId = -1;
+ releaseGesture(secondFingerGestureId);
+ secondFingerGestureId = -1;
+ releaseGesture(panGestureId);
+ panGestureId = -1;
+ }
+
+ int singleshotGestureId;
+ int pinchGestureId;
+ int secondFingerGestureId;
+ int panGestureId;
+
+ bool shouldAcceptSingleshotGesture;
+ bool shouldAcceptPinchGesture;
+ bool shouldAcceptSecondFingerGesture;
+ bool shouldAcceptPanGesture;
+
+ GestureState gesture;
+ TouchState touch;
+
+ void reset()
+ {
+ shouldAcceptSingleshotGesture = true;
+ shouldAcceptPinchGesture = true;
+ shouldAcceptSecondFingerGesture = true;
+ shouldAcceptPanGesture = true;
+ gesture.reset();
+ touch.reset();
+ }
+protected:
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::TouchBegin) {
+ event->accept();
+ ++touch.seenTouchBeginEvent;
+ return true;
+ } else if (event->type() == QEvent::TouchUpdate) {
+ ++touch.seenTouchUpdateEvent;
+ } else if (event->type() == QEvent::TouchEnd) {
+ ++touch.seenTouchEndEvent;
+ } else if (event->type() == QEvent::Gesture) {
+ QGestureEvent *e = static_cast<QGestureEvent*>(event);
+ ++gesture.seenGestureEvent;
+ if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) {
+ gesture.last.singleshot.delivered = true;
+ gesture.last.singleshot.offset = g->offset;
+ if (shouldAcceptSingleshotGesture)
+ g->accept();
+ }
+ if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) {
+ gesture.last.pinch.delivered = true;
+ gesture.last.pinch.startPoints[0] = g->startPoints[0];
+ gesture.last.pinch.startPoints[1] = g->startPoints[1];
+ gesture.last.pinch.lastPoints[0] = g->lastPoints[0];
+ gesture.last.pinch.lastPoints[1] = g->lastPoints[1];
+ gesture.last.pinch.points[0] = g->points[0];
+ gesture.last.pinch.points[1] = g->points[1];
+ gesture.last.pinch.offset = g->offset;
+ if (shouldAcceptPinchGesture)
+ g->accept();
+ }
+ if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) {
+ gesture.last.secondfinger.delivered = true;
+ gesture.last.secondfinger.startPoint = g->startPoint;
+ gesture.last.secondfinger.lastPoint = g->lastPoint;
+ gesture.last.secondfinger.point = g->point;
+ gesture.last.secondfinger.offset = g->offset;
+ if (shouldAcceptSecondFingerGesture)
+ g->accept();
+ }
+ if (PanGesture *g = (PanGesture*)e->gesture(PanGestureRecognizer::Name)) {
+ gesture.last.pan.delivered = true;
+ gesture.last.pan.startPoints[0] = g->startPoints[0];
+ gesture.last.pan.startPoints[1] = g->startPoints[1];
+ gesture.last.pan.lastPoints[0] = g->lastPoints[0];
+ gesture.last.pan.lastPoints[1] = g->lastPoints[1];
+ gesture.last.pan.points[0] = g->points[0];
+ gesture.last.pan.points[1] = g->points[1];
+ gesture.last.pan.offset = g->offset;
+ if (shouldAcceptPanGesture)
+ g->accept();
+ }
+ gesture.last.cancelled = e->cancelledGestures();
+ return true;
+ }
+ return QWidget::event(event);
+ }
+};
+QVector<QColor> GestureWidget::colors;
+int GestureWidget::numberOfWidgets = 0;
+
+class GraphicsScene : public QGraphicsScene
+{
+public:
+ GraphicsScene()
+ {
+ reset();
+ }
+ bool shouldAcceptSingleshotGesture;
+ bool shouldAcceptPinchGesture;
+ bool shouldAcceptSecondFingerGesture;
+ GestureState gesture;
+
+ void reset()
+ {
+ shouldAcceptSingleshotGesture = false;
+ shouldAcceptPinchGesture = false;
+ shouldAcceptSecondFingerGesture = false;
+ gesture.reset();
+ }
+protected:
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::GraphicsSceneGesture) {
+ QGraphicsSceneGestureEvent *e = static_cast<QGraphicsSceneGestureEvent*>(event);
+ ++gesture.seenGestureEvent;
+ QGraphicsScene::event(event);
+ if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) {
+ gesture.last.singleshot.delivered = true;
+ gesture.last.singleshot.offset = g->offset;
+ if (shouldAcceptSingleshotGesture)
+ g->accept();
+ }
+ if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) {
+ gesture.last.pinch.delivered = true;
+ gesture.last.pinch.startPoints[0] = g->startPoints[0];
+ gesture.last.pinch.startPoints[1] = g->startPoints[1];
+ gesture.last.pinch.lastPoints[0] = g->lastPoints[0];
+ gesture.last.pinch.lastPoints[1] = g->lastPoints[1];
+ gesture.last.pinch.points[0] = g->points[0];
+ gesture.last.pinch.points[1] = g->points[1];
+ gesture.last.pinch.offset = g->offset;
+ if (shouldAcceptPinchGesture)
+ g->accept();
+ }
+ if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) {
+ gesture.last.secondfinger.delivered = true;
+ gesture.last.secondfinger.startPoint = g->startPoint;
+ gesture.last.secondfinger.lastPoint = g->lastPoint;
+ gesture.last.secondfinger.point = g->point;
+ gesture.last.secondfinger.offset = g->offset;
+ if (shouldAcceptSecondFingerGesture)
+ g->accept();
+ }
+ gesture.last.cancelled = e->cancelledGestures();
+ return true;
+ }
+ return QGraphicsScene::event(event);
+ }
+};
+
+class GraphicsItem : public QGraphicsItem
+{
+public:
+ GraphicsItem(int w = 100, int h = 100)
+ : width(w), height(h)
+ {
+ reset();
+ }
+
+ QRectF boundingRect() const
+ {
+ return QRectF(0, 0, width, height);
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*)
+ {
+ painter->setBrush(Qt::green);
+ painter->drawRect(0, 0, width, height);
+ }
+
+ void grabSingleshotGesture()
+ {
+ singleshotGestureId = grabGesture(SingleshotGestureRecognizer::Name);
+ }
+ void grabPinchGesture()
+ {
+ pinchGestureId = grabGesture(PinchGestureRecognizer::Name);
+ }
+ void grabSecondFingerGesture()
+ {
+ secondFingerGestureId = grabGesture(SecondFingerGestureRecognizer::Name);
+ }
+ void ungrabGestures()
+ {
+ releaseGesture(singleshotGestureId);
+ singleshotGestureId = -1;
+ releaseGesture(pinchGestureId);
+ pinchGestureId = -1;
+ releaseGesture(secondFingerGestureId);
+ secondFingerGestureId = -1;
+ }
+
+ int width;
+ int height;
+
+ int singleshotGestureId;
+ int pinchGestureId;
+ int secondFingerGestureId;
+
+ bool shouldAcceptSingleshotGesture;
+ bool shouldAcceptPinchGesture;
+ bool shouldAcceptSecondFingerGesture;
+ GestureState gesture;
+
+ TouchState touch;
+
+ void reset()
+ {
+ shouldAcceptSingleshotGesture = true;
+ shouldAcceptPinchGesture = true;
+ shouldAcceptSecondFingerGesture = true;
+ gesture.reset();
+ }
+protected:
+ bool sceneEvent(QEvent *event)
+ {
+ if (event->type() == QEvent::TouchBegin) {
+ event->accept();
+ ++touch.seenTouchBeginEvent;
+ return true;
+ } else if (event->type() == QEvent::TouchUpdate) {
+ ++touch.seenTouchUpdateEvent;
+ } else if (event->type() == QEvent::TouchEnd) {
+ ++touch.seenTouchEndEvent;
+ } else if (event->type() == QEvent::GraphicsSceneGesture) {
+ QGraphicsSceneGestureEvent *e = static_cast<QGraphicsSceneGestureEvent*>(event);
+ ++gesture.seenGestureEvent;
+ if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) {
+ gesture.last.singleshot.delivered = true;
+ gesture.last.singleshot.offset = g->offset;
+ if (shouldAcceptSingleshotGesture)
+ g->accept();
+ }
+ if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) {
+ gesture.last.pinch.delivered = true;
+ gesture.last.pinch.startPoints[0] = g->startPoints[0];
+ gesture.last.pinch.startPoints[1] = g->startPoints[1];
+ gesture.last.pinch.lastPoints[0] = g->lastPoints[0];
+ gesture.last.pinch.lastPoints[1] = g->lastPoints[1];
+ gesture.last.pinch.points[0] = g->points[0];
+ gesture.last.pinch.points[1] = g->points[1];
+ gesture.last.pinch.offset = g->offset;
+ if (shouldAcceptPinchGesture)
+ g->accept();
+ }
+ if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) {
+ gesture.last.secondfinger.delivered = true;
+ gesture.last.secondfinger.startPoint = g->startPoint;
+ gesture.last.secondfinger.lastPoint = g->lastPoint;
+ gesture.last.secondfinger.point = g->point;
+ gesture.last.secondfinger.offset = g->offset;
+ if (shouldAcceptSecondFingerGesture)
+ g->accept();
+ }
+ gesture.last.cancelled = e->cancelledGestures();
+ return true;
+ }
+ return QGraphicsItem::sceneEvent(event);
+ }
+};
+
+class tst_Gestures : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_Gestures();
+ virtual ~tst_Gestures();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void singleshotGesture();
+ void pinchGesture();
+
+ void simplePropagation();
+ void simplePropagation2();
+ void acceptedGesturePropagation();
+
+ void simpleGraphicsView();
+ void simpleGraphicsItem();
+ void overlappingGraphicsItems();
+
+ void touch_widget();
+ void touch_graphicsView();
+
+ void panOnWidgets();
+
+private:
+ SingleshotGestureRecognizer *singleshotRecognizer;
+ PinchGestureRecognizer *pinchRecognizer;
+ SecondFingerGestureRecognizer *secondFingerRecognizer;
+ PanGestureRecognizer *panGestureRecognizer;
+ GestureWidget *mainWidget;
+
+ void sendPinchEvents(QWidget *receiver, const QPoint &fromFinger1, const QPoint &fromFinger2);
+};
+
+tst_Gestures::tst_Gestures()
+{
+ singleshotRecognizer = new SingleshotGestureRecognizer;
+ pinchRecognizer = new PinchGestureRecognizer;
+ secondFingerRecognizer = new SecondFingerGestureRecognizer;
+ panGestureRecognizer = new PanGestureRecognizer;
+ qApp->addGestureRecognizer(singleshotRecognizer);
+ qApp->addGestureRecognizer(pinchRecognizer);
+ qApp->addGestureRecognizer(secondFingerRecognizer);
+ qApp->addGestureRecognizer(panGestureRecognizer);
+}
+
+tst_Gestures::~tst_Gestures()
+{
+}
+
+
+void tst_Gestures::initTestCase()
+{
+ mainWidget = new GestureWidget(GestureWidget::DoNotGrabGestures);
+ mainWidget->setObjectName("MainGestureWidget");
+ mainWidget->resize(500, 600);
+ mainWidget->show();
+}
+
+void tst_Gestures::cleanupTestCase()
+{
+ delete mainWidget; mainWidget = 0;
+}
+
+void tst_Gestures::init()
+{
+ // TODO: Add initialization code here.
+ // This will be executed immediately before each test is run.
+ mainWidget->reset();
+}
+
+void tst_Gestures::cleanup()
+{
+}
+
+bool sendSpontaneousEvent(QWidget *receiver, QEvent *event)
+{
+ QETWidget::setSpont(event, true);
+ return qApp->notify(receiver, event);
+}
+
+void tst_Gestures::singleshotGesture()
+{
+ mainWidget->grabSingleshotGesture();
+ SingleshotEvent event;
+ sendSpontaneousEvent(mainWidget, &event);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(mainWidget->gesture.last.cancelled.isEmpty());
+}
+
+void tst_Gestures::sendPinchEvents(QWidget *receiver, const QPoint &fromFinger1, const QPoint &fromFinger2)
+{
+ int x1 = fromFinger1.x();
+ int y1 = fromFinger1.x();
+ int x2 = fromFinger2.x();
+ int y2 = fromFinger2.x();
+
+ TouchEvent event;
+ event.points[0] = TouchPoint(0,x1,y1, TouchPoint::Begin);
+ event.points[1] = TouchPoint();
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint(0, x1+=2,y1+=2, TouchPoint::Update);
+ event.points[1] = TouchPoint();
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint(0, x1,y1, TouchPoint::Update);
+ event.points[1] = TouchPoint(1, x2,y2, TouchPoint::Begin);
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint(0, x1+=5,y1+=10, TouchPoint::End);
+ event.points[1] = TouchPoint(1, x2+=3,y2+=6, TouchPoint::Update);
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint();
+ event.points[1] = TouchPoint(1, x2+=10,y2+=15, TouchPoint::Update);
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint();
+ event.points[1] = TouchPoint(1, x2,y2, TouchPoint::End);
+ sendSpontaneousEvent(receiver, &event);
+}
+
+void tst_Gestures::pinchGesture()
+{
+ mainWidget->grabPinchGesture();
+ sendPinchEvents(mainWidget, QPoint(10,10), QPoint(20,20));
+
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(mainWidget->gesture.last.cancelled.isEmpty());
+ QVERIFY(mainWidget->gesture.last.pinch.delivered);
+ QCOMPARE(mainWidget->gesture.last.pinch.startPoints[0].pt, QPoint(10,10));
+ QCOMPARE(mainWidget->gesture.last.pinch.startPoints[1].pt, QPoint(20,20));
+ QCOMPARE(mainWidget->gesture.last.pinch.offset, QPoint(0,0));
+}
+
+void tst_Gestures::simplePropagation()
+{
+ mainWidget->grabSingleshotGesture();
+ GestureWidget offsetWidget(GestureWidget::DoNotGrabGestures);
+ offsetWidget.setFixedSize(30, 30);
+ mainWidget->layout()->addWidget(&offsetWidget);
+ GestureWidget nonGestureWidget(GestureWidget::DoNotGrabGestures);
+ mainWidget->layout()->addWidget(&nonGestureWidget);
+ QApplication::processEvents();
+
+ SingleshotEvent event;
+ sendSpontaneousEvent(&nonGestureWidget, &event);
+ QVERIFY(!offsetWidget.gesture.seenGestureEvent);
+ QVERIFY(!nonGestureWidget.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.last.cancelled.isEmpty());
+ QVERIFY(mainWidget->gesture.last.singleshot.delivered);
+ QCOMPARE(mainWidget->gesture.last.singleshot.offset, QPoint(GestureWidget::LeftMargin, 30 + GestureWidget::TopMargin));
+}
+
+void tst_Gestures::simplePropagation2()
+{
+ mainWidget->grabSingleshotGesture();
+ mainWidget->grabPinchGesture();
+ GestureWidget nonGestureMiddleWidget(GestureWidget::DoNotGrabGestures);
+ GestureWidget secondGestureWidget(GestureWidget::GrabPinch);
+ nonGestureMiddleWidget.layout()->addWidget(&secondGestureWidget);
+ mainWidget->layout()->addWidget(&nonGestureMiddleWidget);
+ QApplication::processEvents();
+
+ SingleshotEvent event;
+ sendSpontaneousEvent(&secondGestureWidget, &event);
+ QVERIFY(!secondGestureWidget.gesture.seenGestureEvent);
+ QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(mainWidget->gesture.last.cancelled.isEmpty());
+ QCOMPARE(mainWidget->gesture.last.singleshot.offset, QPoint(GestureWidget::LeftMargin*2,GestureWidget::TopMargin*2));
+
+ mainWidget->reset();
+ nonGestureMiddleWidget.reset();
+ secondGestureWidget.reset();
+
+ sendPinchEvents(&secondGestureWidget, QPoint(10,10), QPoint(20,20));
+ QVERIFY(secondGestureWidget.gesture.seenGestureEvent);
+ QVERIFY(!secondGestureWidget.gesture.last.singleshot.delivered);
+ QVERIFY(secondGestureWidget.gesture.last.pinch.delivered);
+ QCOMPARE(secondGestureWidget.gesture.last.pinch.startPoints[0].pt, QPoint(10,10));
+ QCOMPARE(secondGestureWidget.gesture.last.pinch.startPoints[1].pt, QPoint(20,20));
+ QCOMPARE(secondGestureWidget.gesture.last.pinch.offset, QPoint(0,0));
+ QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.seenGestureEvent);
+}
+
+void tst_Gestures::acceptedGesturePropagation()
+{
+ mainWidget->grabSingleshotGesture();
+ mainWidget->grabPinchGesture();
+ mainWidget->grabSecondFingerGesture();
+ GestureWidget nonGestureMiddleWidget(GestureWidget::DoNotGrabGestures);
+ nonGestureMiddleWidget.setObjectName("nonGestureMiddleWidget");
+ GestureWidget secondGestureWidget(GestureWidget::GrabSecondFinger);
+ secondGestureWidget.setObjectName("secondGestureWidget");
+ nonGestureMiddleWidget.layout()->addWidget(&secondGestureWidget);
+ mainWidget->layout()->addWidget(&nonGestureMiddleWidget);
+ QApplication::processEvents();
+
+ sendPinchEvents(&secondGestureWidget, QPoint(10, 10), QPoint(40, 40));
+ QVERIFY(secondGestureWidget.gesture.seenGestureEvent);
+ QVERIFY(!secondGestureWidget.gesture.last.singleshot.delivered);
+ QVERIFY(!secondGestureWidget.gesture.last.pinch.delivered);
+ QVERIFY(secondGestureWidget.gesture.last.secondfinger.delivered);
+ QCOMPARE(secondGestureWidget.gesture.last.secondfinger.startPoint.pt, QPoint(40,40));
+ QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(!mainWidget->gesture.last.secondfinger.delivered);
+ QVERIFY(mainWidget->gesture.last.pinch.delivered);
+ QCOMPARE(mainWidget->gesture.last.pinch.startPoints[0].pt, QPoint(10,10));
+ QCOMPARE(mainWidget->gesture.last.pinch.startPoints[1].pt, QPoint(40,40));
+
+ mainWidget->reset();
+ nonGestureMiddleWidget.reset();
+ secondGestureWidget.reset();
+
+ // don't accept it and make sure it propagates to parent
+ secondGestureWidget.shouldAcceptSecondFingerGesture = false;
+ sendPinchEvents(&secondGestureWidget, QPoint(10, 10), QPoint(40, 40));
+ QVERIFY(secondGestureWidget.gesture.seenGestureEvent);
+ QVERIFY(secondGestureWidget.gesture.last.secondfinger.delivered);
+ QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(mainWidget->gesture.last.secondfinger.delivered);
+ QVERIFY(mainWidget->gesture.last.pinch.delivered);
+}
+
+void tst_Gestures::simpleGraphicsView()
+{
+ mainWidget->grabSingleshotGesture();
+ GraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.grabGesture(SingleshotGestureRecognizer::Name);
+ mainWidget->layout()->addWidget(&view);
+ QApplication::processEvents();
+
+ scene.shouldAcceptSingleshotGesture = true;
+
+ SingleshotEvent event;
+ sendSpontaneousEvent(&view, &event);
+ QVERIFY(!mainWidget->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.last.singleshot.delivered);
+ QVERIFY(scene.gesture.last.cancelled.isEmpty());
+}
+
+void tst_Gestures::simpleGraphicsItem()
+{
+ mainWidget->grabSingleshotGesture();
+ GraphicsScene scene;
+ QGraphicsView view(&scene);
+ mainWidget->layout()->addWidget(&view);
+ GraphicsItem *item = new GraphicsItem;
+ item->grabSingleshotGesture();
+ item->setPos(30, 50);
+ scene.addItem(item);
+ QApplication::processEvents();
+
+ SingleshotEvent event(50, 80);
+ sendSpontaneousEvent(&view, &event);
+ QVERIFY(item->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.seenGestureEvent);
+
+ item->reset();
+ scene.reset();
+ mainWidget->reset();
+
+ item->shouldAcceptSingleshotGesture = false;
+ SingleshotEvent event2(20, 40);
+ sendSpontaneousEvent(&view, &event2);
+ QVERIFY(!item->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+}
+
+void tst_Gestures::overlappingGraphicsItems()
+{
+ mainWidget->grabSingleshotGesture();
+ GraphicsScene scene;
+ QGraphicsView view(&scene);
+ mainWidget->layout()->addWidget(&view);
+
+ GraphicsItem *item = new GraphicsItem(300, 100);
+ item->setPos(30, 50);
+ scene.addItem(item);
+ GraphicsItem *subitem1 = new GraphicsItem(50, 70);
+ subitem1->setPos(70, 70);
+ scene.addItem(subitem1);
+ GraphicsItem *subitem2 = new GraphicsItem(50, 70);
+ subitem2->setPos(250, 70);
+ scene.addItem(subitem2);
+ QApplication::processEvents();
+
+ item->grabSingleshotGesture();
+ item->grabPinchGesture();
+ item->grabSecondFingerGesture();
+ subitem1->grabSingleshotGesture();
+ subitem2->grabSecondFingerGesture();
+
+ SingleshotEvent event(100, 100);
+ sendSpontaneousEvent(&view, &event);
+ QVERIFY(subitem1->gesture.seenGestureEvent);
+ QVERIFY(!subitem2->gesture.seenGestureEvent);
+ QVERIFY(!item->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.seenGestureEvent);
+ QVERIFY(subitem1->gesture.last.singleshot.delivered);
+
+ item->reset();
+ subitem1->reset();
+ subitem2->reset();
+ scene.reset();
+ mainWidget->reset();
+
+ subitem1->shouldAcceptSingleshotGesture = false;
+ SingleshotEvent event2(100, 100);
+ sendSpontaneousEvent(&view, &event2);
+ QVERIFY(subitem1->gesture.seenGestureEvent);
+ QVERIFY(!subitem2->gesture.seenGestureEvent);
+ QVERIFY(item->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.seenGestureEvent);
+ QVERIFY(subitem1->gesture.last.singleshot.delivered);
+ QVERIFY(item->gesture.last.singleshot.delivered);
+}
+
+void tst_Gestures::touch_widget()
+{
+ GestureWidget leftWidget(GestureWidget::DoNotGrabGestures);
+ leftWidget.setObjectName("leftWidget");
+ leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ GestureWidget rightWidget(GestureWidget::DoNotGrabGestures);
+ rightWidget.setObjectName("rightWidget");
+ rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ delete mainWidget->layout();
+ (void)new QHBoxLayout(mainWidget);
+ mainWidget->layout()->addWidget(&leftWidget);
+ mainWidget->layout()->addWidget(&rightWidget);
+ QApplication::processEvents();
+
+ QTest::touchEvent()
+ .press(0, QPoint(10, 10), &leftWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(12, 30), &leftWidget);
+ QTest::touchEvent()
+ .stationary(0)
+ .press(1, QPoint(15, 15), &rightWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(10, 35), &leftWidget)
+ .press(1, QPoint(15, 15), &rightWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(10, 40), &leftWidget)
+ .move(1, QPoint(20, 50), &rightWidget);
+ QTest::touchEvent()
+ .release(0, QPoint(10, 40), &leftWidget)
+ .release(1, QPoint(20, 50), &rightWidget);
+ QVERIFY(!mainWidget->touch.seenTouchBeginEvent);
+ QVERIFY(leftWidget.touch.seenTouchBeginEvent);
+ QVERIFY(leftWidget.touch.seenTouchUpdateEvent);
+ QVERIFY(leftWidget.touch.seenTouchEndEvent);
+ QVERIFY(rightWidget.touch.seenTouchBeginEvent);
+ QVERIFY(rightWidget.touch.seenTouchUpdateEvent);
+ QVERIFY(rightWidget.touch.seenTouchEndEvent);
+}
+
+void tst_Gestures::touch_graphicsView()
+{
+ mainWidget->setAttribute(Qt::WA_AcceptTouchEvents);
+ GraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
+ mainWidget->layout()->addWidget(&view);
+
+ GraphicsItem *item = new GraphicsItem(300, 100);
+ item->setAcceptTouchEvents(true);
+ item->setPos(30, 50);
+ scene.addItem(item);
+ GraphicsItem *subitem1 = new GraphicsItem(50, 70);
+ subitem1->setAcceptTouchEvents(true);
+ subitem1->setPos(70, 70);
+ scene.addItem(subitem1);
+ GraphicsItem *subitem2 = new GraphicsItem(50, 70);
+ subitem2->setAcceptTouchEvents(true);
+ subitem2->setPos(250, 70);
+ scene.addItem(subitem2);
+ QApplication::processEvents();
+
+ QRect itemRect = view.mapFromScene(item->mapRectToScene(item->boundingRect())).boundingRect();
+ QPoint pt = itemRect.center();
+ QTest::touchEvent(view.viewport())
+ .press(0, pt)
+ .press(1, pt);
+ QTest::touchEvent(view.viewport())
+ .move(0, pt + QPoint(20, 30))
+ .move(1, QPoint(300, 300));
+ QTest::touchEvent(view.viewport())
+ .stationary(0)
+ .move(1, QPoint(330, 330));
+ QTest::touchEvent(view.viewport())
+ .release(0, QPoint(120, 120))
+ .release(1, QPoint(300, 300));
+
+ QVERIFY(item->touch.seenTouchBeginEvent);
+ QVERIFY(item->touch.seenTouchUpdateEvent);
+ QVERIFY(item->touch.seenTouchEndEvent);
+}
+
+void tst_Gestures::panOnWidgets()
+{
+ GestureWidget leftWidget(GestureWidget::GrabPan);
+ leftWidget.setObjectName("leftWidget");
+ leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ GestureWidget rightWidget(GestureWidget::GrabPan);
+ rightWidget.setObjectName("rightWidget");
+ rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ delete mainWidget->layout();
+ (void)new QHBoxLayout(mainWidget);
+ mainWidget->layout()->addWidget(&leftWidget);
+ mainWidget->layout()->addWidget(&rightWidget);
+ QApplication::processEvents();
+
+ QTest::touchEvent()
+ .press(0, QPoint(10, 10), &leftWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(12, 30), &leftWidget);
+ QTest::touchEvent()
+ .stationary(0)
+ .press(1, QPoint(15, 15), &rightWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(10, 35), &leftWidget)
+ .press(1, QPoint(15, 15), &rightWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(10, 40), &leftWidget)
+ .move(1, QPoint(20, 50), &rightWidget);
+ QTest::touchEvent()
+ .release(0, QPoint(10, 40), &leftWidget)
+ .release(1, QPoint(20, 50), &rightWidget);
+
+ QVERIFY(leftWidget.gesture.last.pan.delivered);
+ QVERIFY(rightWidget.gesture.last.pan.delivered);
+}
+
+QTEST_MAIN(tst_Gestures)
+#include "tst_gestures.moc"
diff --git a/tests/auto/linguist/lconvert/data/codec-cp1252.ts b/tests/auto/linguist/lconvert/data/codec-cp1252.ts
new file mode 100644
index 0000000..5ffa2f3
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/codec-cp1252.ts
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>windows-1252</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="10"/>
+ <source>random ascii only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut Ì &amp;uuml;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="12"/>
+ <source>random ascii only in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message utf8="true">
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut Ì &amp;uuml; in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/codec-utf8.ts b/tests/auto/linguist/lconvert/data/codec-utf8.ts
new file mode 100644
index 0000000..0ebdbfd
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/codec-utf8.ts
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="10"/>
+ <source>random ascii only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut Ì &amp;uuml;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="12"/>
+ <source>random ascii only in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut Ì &amp;uuml; in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/dual-encoding.ts b/tests/auto/linguist/lconvert/data/dual-encoding.ts
new file mode 100644
index 0000000..5023a04
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/dual-encoding.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message utf8="both">
+ <source>MÃŒhsam</source>
+ <translation>tedious</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/endless-po-loop.ts b/tests/auto/linguist/lconvert/data/endless-po-loop.ts
new file mode 100644
index 0000000..6212fbd
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/endless-po-loop.ts
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de">
+<context>
+ <name>Assistant</name>
+ <message>
+ <source>This is some text which introduces the DonauDampfSchifffahrtsKapitaensMuetzeMitKomischenUltraViolettenFransenUndEinemKnopf</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="this/is/a/really/really/absurdly/no,/grotesquely/long/path/supposed/to/blow/up.cpp" line="20"/>
+ <source>%n document(s) found.</source>
+ <translation></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/makeplurals.sh b/tests/auto/linguist/lconvert/data/makeplurals.sh
new file mode 100755
index 0000000..2e0f375
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/makeplurals.sh
@@ -0,0 +1,43 @@
+#! /bin/bash
+
+function makeit2()
+{
+ for ((i = 0; i < (1 << $1); i++)); do
+ echo
+ test -n "$3" && echo "$3"
+ echo "msgid \"singular $2 $i\""
+ echo "msgid_plural \"plural $2 $i\""
+ for ((j = 0; j < $1; j++)); do
+ tr=
+ if test $((i & (1 << j))) = 0; then
+ tr="translated $2 $i $j"
+ fi
+ echo "msgstr[$j] \"$tr\""
+ done
+ done
+}
+
+function makeit()
+{
+ {
+ cat <<EOF
+msgid ""
+msgstr ""
+"X-FooBar: yup\n"
+"X-Language: $2\n"
+EOF
+ makeit2 $1 one ""
+ makeit2 $1 two "#, fuzzy
+#| msgid \"old untranslated one\""
+ makeit2 $1 three "#, fuzzy
+#| msgid \"old untranslated two\"
+#| msgid_plural \"old untranslated plural two\""
+ makeit2 $1 four "#, fuzzy
+#| msgid_plural \"old untranslated only plural three\""
+ } > ${OUTDIR}plural-$1.po
+}
+
+OUTDIR=$1
+makeit 1 zh_CN
+makeit 2 de_DE
+makeit 3 pl_PL
diff --git a/tests/auto/linguist/lconvert/data/msgid.ts b/tests/auto/linguist/lconvert/data/msgid.ts
new file mode 100644
index 0000000..ab65845
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/msgid.ts
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" sourcelanguage="en">
+<context>
+ <name>Dialog2</name>
+ <message numerus="yes">
+ <source>%n files</source>
+ <translation>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message id="this_is_some_id" numerus="yes">
+ <source>%n cars</source>
+ <translation>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Age: %1</source>
+ <translation></translation>
+ </message>
+ <message id="this_is_another_id">
+ <source>func3</source>
+ <translation></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/plurals-cn.ts b/tests/auto/linguist/lconvert/data/plurals-cn.ts
new file mode 100644
index 0000000..966ec77
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/plurals-cn.ts
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="cn">
+<context>
+ <name>Assistant</name>
+ <message>
+ <source>Source</source>
+ <translation>Translation</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n document(s) found.</source>
+ <translation>
+ <numerusform>1 Dokument gefunden.</numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/plurals-de.ts b/tests/auto/linguist/lconvert/data/plurals-de.ts
new file mode 100644
index 0000000..6cbadff
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/plurals-de.ts
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de">
+<context>
+ <name>Assistant</name>
+ <message>
+ <source>Not plural</source>
+ <translation>Kein plural</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n document(s) found.</source>
+ <translation>
+ <numerusform>1 Dokument gefunden.</numerusform>
+ <numerusform>%n Dokumente gefunden.</numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/relative.ts b/tests/auto/linguist/lconvert/data/relative.ts
new file mode 100644
index 0000000..b8eaaca
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/relative.ts
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="foo.cpp" line="+13"/>
+ <source>This is the first entry.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>And a second one on the same line.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>This tr is new.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location line="+16"/>
+ <source>This one moved in from another file.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="-2"/>
+ <source>Just as this one.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location filename="bar.cpp" line="+100"/>
+ <source>Another alien.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>They are coming!</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>They are everywhere!</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="bar.cpp" line="+20"/>
+ <source>An earthling again.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="-5"/>
+ <source>This is from the bottom, too.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Third string from the bottom.</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Fourth one!</source>
+ <translation></translation>
+ </message>
+ <message>
+ <location line="-9"/>
+ <source>This string did move from the bottom.</source>
+ <translation></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/singular.po b/tests/auto/linguist/lconvert/data/singular.po
new file mode 100644
index 0000000..a0d4019
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/singular.po
@@ -0,0 +1,42 @@
+msgid ""
+msgstr ""
+
+msgid "untranslated one"
+msgstr "translated"
+
+#, fuzzy
+#| msgid "old untranslated"
+msgid "untranslated two"
+msgstr "translated"
+
+#, fuzzy
+#| msgid "old untranslated"
+msgid "untranslated two b"
+msgstr ""
+
+#, fuzzy
+#| msgid "old untranslated"
+#| msgid_plural "old untranslated plural"
+msgid "untranslated three"
+msgstr "translated"
+
+#, fuzzy
+#| msgid "old untranslated"
+#| msgid_plural "old untranslated plural"
+msgid "untranslated three b"
+msgstr ""
+
+#, fuzzy
+#| msgid_plural "old untranslated only plural"
+msgid "untranslated four"
+msgstr "translated"
+
+#, fuzzy
+#| msgid_plural "old untranslated only plural"
+msgid "untranslated four b"
+msgstr ""
+
+#, fuzzy
+#| msgctxt "old context"
+msgid "untranslated five"
+msgstr "translated"
diff --git a/tests/auto/linguist/lconvert/data/test-broken-utf8.po b/tests/auto/linguist/lconvert/data/test-broken-utf8.po
new file mode 100644
index 0000000..20b58a0
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-broken-utf8.po
@@ -0,0 +1,9 @@
+# no comment
+msgid ""
+msgstr ""
+
+msgid "this works"
+msgstr "das geht: À"
+
+msgid "this is broken"
+msgstr "das ist kaputt: Ãi"
diff --git a/tests/auto/linguist/lconvert/data/test-broken-utf8.po.out b/tests/auto/linguist/lconvert/data/test-broken-utf8.po.out
new file mode 100644
index 0000000..c00fd19
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-broken-utf8.po.out
@@ -0,0 +1,9 @@
+# no comment
+msgid ""
+msgstr ""
+
+msgid "this works"
+msgstr "das geht: À"
+
+msgid "this is broken"
+msgstr "das ist kaputt: i"
diff --git a/tests/auto/linguist/lconvert/data/test-developer-comment.po b/tests/auto/linguist/lconvert/data/test-developer-comment.po
new file mode 100644
index 0000000..787f312
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-developer-comment.po
@@ -0,0 +1,23 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. I'm a clever developer. Right? Uhm ...
+msgid "User %u will log in in %t"
+msgstr "甚户 %u 将圚 %t 秒后登圕"
diff --git a/tests/auto/linguist/lconvert/data/test-empty-comment.po b/tests/auto/linguist/lconvert/data/test-empty-comment.po
new file mode 100644
index 0000000..ce74c46
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-empty-comment.po
@@ -0,0 +1,24 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#
+#: themer/kdmlabel.cpp:236
+msgid "User %u will log in in %t"
+msgstr "甚户 %u 将圚 %t 秒后登圕"
diff --git a/tests/auto/linguist/lconvert/data/test-escapes.po b/tests/auto/linguist/lconvert/data/test-escapes.po
new file mode 100644
index 0000000..059dc58
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-escapes.po
@@ -0,0 +1,11 @@
+msgid ""
+msgstr ""
+
+msgid "this comes\non a new line"
+msgstr "yup"
+
+msgid "come to \"quote\" me"
+msgstr "sure?"
+
+msgid "\x1a\45\r\t\v\a\b"
+msgstr "yup"
diff --git a/tests/auto/linguist/lconvert/data/test-escapes.po.out b/tests/auto/linguist/lconvert/data/test-escapes.po.out
new file mode 100644
index 0000000..10eefb2
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-escapes.po.out
@@ -0,0 +1,13 @@
+msgid ""
+msgstr ""
+
+msgid ""
+"this comes\n"
+"on a new line"
+msgstr "yup"
+
+msgid "come to \"quote\" me"
+msgstr "sure?"
+
+msgid "\x1a%\r\t\v\a\b"
+msgstr "yup"
diff --git a/tests/auto/linguist/lconvert/data/test-kde-ctxt.po b/tests/auto/linguist/lconvert/data/test-kde-ctxt.po
new file mode 100644
index 0000000..b510538
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-kde-ctxt.po
@@ -0,0 +1,25 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: kgdialog.cpp:231
+#, kde-format
+msgctxt "session (location)"
+msgid "%1 (%2)"
+msgstr "%1(%2)"
diff --git a/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po b/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po
new file mode 100644
index 0000000..b3f6e03
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-kde-fuzzy.po
@@ -0,0 +1,31 @@
+# translation of kdmgreet.po to German
+# Übersetzung von kdmgreet.po ins Deutsche
+# Copyright (C)
+# Thomas Diehl <thd@kde.org>, 2002, 2003, 2004.
+# Stephan Johach <hunsum@gmx.de>, 2005.
+# Thomas Reitelbach <tr@erdfunkstelle.de>, 2005, 2006, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2007-12-06 20:50+0100\n"
+"Last-Translator: Thomas Reitelbach <tr@erdfunkstelle.de>\n"
+"Language-Team: German <kde-i18n-de@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KAider 0.1\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: kgverify.cpp:459
+#, fuzzy, kde-format
+#| msgid ""
+#| "Logging in %1 ...\n"
+#| "\n"
+msgid ""
+"Logging in %1...\n"
+"\n"
+msgstr ""
+"%1 wird angemeldet ...\n"
+"\n"
diff --git a/tests/auto/linguist/lconvert/data/test-kde-multiline.po b/tests/auto/linguist/lconvert/data/test-kde-multiline.po
new file mode 100644
index 0000000..0ca714c
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-kde-multiline.po
@@ -0,0 +1,32 @@
+# translation of kdmgreet.po to German
+# Übersetzung von kdmgreet.po ins Deutsche
+# Copyright (C)
+# Thomas Diehl <thd@kde.org>, 2002, 2003, 2004.
+# Stephan Johach <hunsum@gmx.de>, 2005.
+# Thomas Reitelbach <tr@erdfunkstelle.de>, 2005, 2006, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2007-12-06 20:50+0100\n"
+"Last-Translator: Thomas Reitelbach <tr@erdfunkstelle.de>\n"
+"Language-Team: German <kde-i18n-de@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KAider 0.1\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: kdmshutdown.cpp:706
+#, kde-format
+msgid ""
+"Owner: %1\n"
+"Type: %2%5\n"
+"Start: %3\n"
+"Timeout: %4"
+msgstr ""
+"EigentÃŒmer: %1\n"
+"Typ: %2%5\n"
+"Start: %3\n"
+"Zeitlimit: %4"
diff --git a/tests/auto/linguist/lconvert/data/test-kde-plurals.po b/tests/auto/linguist/lconvert/data/test-kde-plurals.po
new file mode 100644
index 0000000..6c85d74
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-kde-plurals.po
@@ -0,0 +1,27 @@
+# translation of kdmgreet.po to German
+# Übersetzung von kdmgreet.po ins Deutsche
+# Copyright (C)
+# Thomas Diehl <thd@kde.org>, 2002, 2003, 2004.
+# Stephan Johach <hunsum@gmx.de>, 2005.
+# Thomas Reitelbach <tr@erdfunkstelle.de>, 2005, 2006, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2007-12-06 20:50+0100\n"
+"Last-Translator: Thomas Reitelbach <tr@erdfunkstelle.de>\n"
+"Language-Team: German <kde-i18n-de@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KAider 0.1\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Language: de_DE\n"
+
+#: kgverify.cpp:505
+#, kde-format
+msgid "Your account expires tomorrow."
+msgid_plural "Your account expires in %1 days."
+msgstr[0] "Ihre Zugangsberechtigung lÀuft morgen ab."
+msgstr[1] "Ihre Zugangsberechtigung lÀuft in %1 Tagen ab."
diff --git a/tests/auto/linguist/lconvert/data/test-slurp.po b/tests/auto/linguist/lconvert/data/test-slurp.po
new file mode 100644
index 0000000..67bc239
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-slurp.po
@@ -0,0 +1,19 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+
+msgid "just a line"
+msgstr "indeed"
+
+msgid ""
+"another "
+"line"
+msgstr "certainly"
+
+msgid "a somewhat longer line that will certainly require re-wrapping, and will be re-wrapped if our algorithm is not completely broken.\n"
+"this comes on a new line.\n"
+msgstr "whatever ..."
+
+msgid "bi-""segmented"
+msgstr "aye"
diff --git a/tests/auto/linguist/lconvert/data/test-slurp.po.out b/tests/auto/linguist/lconvert/data/test-slurp.po.out
new file mode 100644
index 0000000..8859a70
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-slurp.po.out
@@ -0,0 +1,19 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+
+msgid "just a line"
+msgstr "indeed"
+
+msgid "another line"
+msgstr "certainly"
+
+msgid ""
+"a somewhat longer line that will certainly require re-wrapping, and will be "
+"re-wrapped if our algorithm is not completely broken.\n"
+"this comes on a new line.\n"
+msgstr "whatever ..."
+
+msgid "bi-segmented"
+msgstr "aye"
diff --git a/tests/auto/linguist/lconvert/data/test-translator-comment.po b/tests/auto/linguist/lconvert/data/test-translator-comment.po
new file mode 100644
index 0000000..bc4df5c
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test-translator-comment.po
@@ -0,0 +1,41 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgid "no comment"
+msgstr "indeed"
+
+#
+msgid "just empty"
+msgstr "indeed"
+
+#
+# This is some comment.
+#
+# This is another comment.
+#
+msgid "User %u will log in in %t"
+msgstr "甚户 %u 将圚 %t 秒后登圕"
+
+# A fooish bar.
+# Hey-ho, sucker.
+#
+# Babbling gully.
+msgid "Foo"
+msgstr "Bar"
diff --git a/tests/auto/linguist/lconvert/data/test1-cn.po b/tests/auto/linguist/lconvert/data/test1-cn.po
new file mode 100644
index 0000000..529eca3
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test1-cn.po
@@ -0,0 +1,67 @@
+# translation of kdmgreet.po to zh_CN
+# Simp. Chinese Translation for kdmgreet.
+# Copyright (C) 2001,2003 Free Software Foundation, Inc.
+# Gou Zhuang <gouzhuang@bigfoot.com>, 2001.
+# Xiong Jiang <jxiong@offtopic.org>, 2003.
+# Yan Shuangchun <yahzee@d3eye.com>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2008-04-22 16:56+0800\n"
+"Last-Translator: Lie_Ex <lilith.ex@gmail.com>\n"
+"Language-Team: zh_CN <kde-china@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Language: zh_CN\n"
+
+#: kdmconfig.cpp:147
+msgid "[fix kdmrc]"
+msgstr "[修倍 kdmrc]"
+
+#: krootimage.cpp:39
+msgid "Fancy desktop background for kdm"
+msgstr "kdm 的梊幻桌面背景"
+
+#: kgreeter.cpp:558
+#, kde-format
+msgid ""
+"Your saved session type '%1' is not valid any more.\n"
+"Please select a new one, otherwise 'default' will be used."
+msgstr ""
+"䜠保存的“%1”䌚话类型䞍再有效。\n"
+"请选择䞀䞪新的类型吊则将䜿甚“默讀”。"
+
+#: kgdialog.cpp:231
+#, kde-format
+msgctxt "session (location)"
+msgid "%1 (%2)"
+msgstr "%1(%2)"
+
+#: kgverify.cpp:505
+#, kde-format
+msgid "Your account expires tomorrow."
+msgid_plural "Your account expires in %1 days."
+msgstr[0] "悚的莊户将于 %1 倩后过期。"
+
+#: kdmshutdown.cpp:510
+#, kde-format
+msgctxt "current option in boot loader"
+msgid "%1 (current)"
+msgstr "%1 (圓前)"
+
+#: themer/kdmlabel.cpp:285
+#, no-c-format
+msgctxt "date format"
+msgid "%a %d %B"
+msgstr "%B月%d日%a"
+
+#~ msgid "_Suspend"
+#~ msgstr "挂起(_S)"
+
+#~ msgid "Confi_gure"
+#~ msgstr "配眮(_G)"
diff --git a/tests/auto/linguist/lconvert/data/test1-de.po b/tests/auto/linguist/lconvert/data/test1-de.po
new file mode 100644
index 0000000..256b8e9
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test1-de.po
@@ -0,0 +1,75 @@
+# translation of kdmgreet.po to German
+# translation of kdmgreet.po to
+# Übersetzung von kdmgreet.po ins Deutsche
+# Copyright (C)
+# Thomas Diehl <thd@kde.org>, 2002, 2003, 2004.
+# Stephan Johach <hunsum@gmx.de>, 2005.
+# Thomas Reitelbach <tr@erdfunkstelle.de>, 2005, 2006, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: kdmgreet\n"
+"Report-Msgid-Bugs-To: http://bugs.kde.org\n"
+"POT-Creation-Date: 2008-04-28 18:47+0200\n"
+"PO-Revision-Date: 2007-12-06 20:50+0100\n"
+"Last-Translator: Thomas Reitelbach <tr@erdfunkstelle.de>\n"
+"Language-Team: German <kde-i18n-de@kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KAider 0.1\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Language: de_DE\n"
+
+#: lib/acl.c:107 lib/acl.c:121 lib/acl.c:138 lib/acl.c:165 lib/acl.c:174
+#: src/copy.c:695 src/copy.c:2017
+#, c-format
+msgid "preserving permissions for %s"
+msgstr "a preservar as permissões de %s"
+
+#: kdmconfig.cpp:147
+msgid "[fix kdmrc]"
+msgstr "[fix kdmrc]"
+
+#: krootimage.cpp:39
+msgid "Fancy desktop background for kdm"
+msgstr "Schicker ArbeitsflÀchenhintergrund fÌr KDM"
+
+#: kgreeter.cpp:558
+#, kde-format
+msgid ""
+"Your saved session type '%1' is not valid any more.\n"
+"Please select a new one, otherwise 'default' will be used."
+msgstr ""
+"Der gespeicherte Sitzungstyp „%1“ ist nicht mehr gÃŒltig.\n"
+"Bitte wÀhlen Sie einen neuen. Sonst wird die Voreinstellung verwendet."
+
+#: kgdialog.cpp:231
+#, kde-format
+msgctxt "session (location)"
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+#: kgverify.cpp:505
+#, kde-format
+msgid "Your account expires tomorrow."
+msgid_plural "Your account expires in %1 days."
+msgstr[0] "Ihre Zugangsberechtigung lÀuft morgen ab."
+msgstr[1] "Ihre Zugangsberechtigung lÀuft in %1 Tagen ab."
+
+#: kdmshutdown.cpp:510
+#, kde-format
+msgctxt "current option in boot loader"
+msgid "%1 (current)"
+msgstr "%1 (Aktuelle)"
+
+#: themer/kdmlabel.cpp:285
+#, no-c-format
+msgctxt "date format"
+msgid "%a %d %B"
+msgstr "%a %d %B"
+
+#~ msgid "_Suspend"
+#~ msgstr "_Ruhezustand"
+
+#~ msgid "Confi_gure"
+#~ msgstr "Ein_richten"
diff --git a/tests/auto/linguist/lconvert/data/test11.ts b/tests/auto/linguist/lconvert/data/test11.ts
new file mode 100644
index 0000000..aeb46af
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test11.ts
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="1.1" language="de_DE">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="57"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="107"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="122"/>
+ <source>Should be obsolete</source>
+ <translation type="unfinished">SHOULD BE OBSOLETE</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/test20.ts b/tests/auto/linguist/lconvert/data/test20.ts
new file mode 100644
index 0000000..542cdee
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/test20.ts
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Dialog2</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="29"/>
+ <source>%n files</source>
+ <comment>plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="30"/>
+ <source>%n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="31"/>
+ <source>&amp;Find %n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="32"/>
+ <source>Search in %n items?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="33"/>
+ <source>%1. Search in %n items?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="34"/>
+ <source>Age: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="35"/>
+ <source>There are %n house(s)</source>
+ <comment>Plurals and function call</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="53"/>
+ <source>QTranslator</source>
+ <comment>Simple</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="54"/>
+ <source>QTranslator</source>
+ <comment>Simple with comment</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="55"/>
+ <source>QTranslator</source>
+ <comment>Plural without comment</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="57"/>
+ <source>QTranslator</source>
+ <comment>Plural with comment</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="102"/>
+ <source>func3</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="main.cpp" line="13"/>
+ <source>QT_LAYOUT_DIRECTION</source>
+ <comment>Translate this string to the string &apos;LTR&apos; in left-to-right languages or to &apos;RTL&apos; in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QCoreApplication</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="40"/>
+ <source>Plurals, QCoreApplication</source>
+ <comment>%n house(s)</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="41"/>
+ <source>Plurals, QCoreApplication</source>
+ <comment>%n car(s)</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="42"/>
+ <source>Plurals, QCoreApplication</source>
+ <comment>%n horse(s)</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>TestClass</name>
+ <message>
+ <location filename="main.cpp" line="116"/>
+ <source>inline function</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="120"/>
+ <source>inline function 2</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="124"/>
+ <source>static inline function</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/variants.ts b/tests/auto/linguist/lconvert/data/variants.ts
new file mode 100644
index 0000000..52bb2d4
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/variants.ts
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de">
+<context>
+ <name>Assistant</name>
+ <message>
+ <source>Source</source>
+ <translation variants="yes">
+ <lengthvariant>A really very long translation</lengthvariant>
+ <lengthvariant>Short translation</lengthvariant>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n document(s) found.</source>
+ <translation>
+ <numerusform>1 Dokument gefunden.</numerusform>
+ <numerusform variants="yes">
+ <lengthvariant>%n Dokumente gefunden.</lengthvariant>
+ <lengthvariant>%n Dok. gefunden.</lengthvariant>
+ </numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lconvert/data/wrapping.po b/tests/auto/linguist/lconvert/data/wrapping.po
new file mode 100644
index 0000000..39b7fbe
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/wrapping.po
@@ -0,0 +1,58 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-05-14 14:01+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, no-wrap
+msgid "one two three four five six seven eight nine ten eleven twelve thirteen a 12 foo bar\n"
+msgstr ""
+
+#, no-wrap
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve thirteen a 13 foo bar\n"
+"second line"
+msgstr ""
+
+#: gettxt.c:3
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve thirteen a 14 "
+"foo bar\n"
+msgstr ""
+
+#: gettxt.c:4
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve thirteen a "
+"15\n"
+msgstr ""
+
+#: gettxt.c:5
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve thirteen a "
+"123 foo bar\n"
+msgstr ""
+
+#: gettxt.c:6
+msgid "one two three four five six seven eight nine ten eleven twelve thirteen"
+msgstr ""
+
+#: gettxt.c:7
+msgid ""
+"one two three four five six seven eight nine ten eleven twelve th1rt33n\n"
+msgstr ""
+
+#: gettxt.c:8
+msgid "one two three four five six\n"
+msgstr ""
diff --git a/tests/auto/linguist/lconvert/lconvert.pro b/tests/auto/linguist/lconvert/lconvert.pro
new file mode 100644
index 0000000..517dacd
--- /dev/null
+++ b/tests/auto/linguist/lconvert/lconvert.pro
@@ -0,0 +1,8 @@
+CONFIG += qttest_p4
+
+TARGET = tst_lconvert
+
+#HEADERS += testlupdate.h
+SOURCES += tst_lconvert.cpp
+# testlupdate.cpp
+
diff --git a/tests/auto/linguist/lconvert/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp
new file mode 100644
index 0000000..3df2a19
--- /dev/null
+++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp
@@ -0,0 +1,300 @@
+#include <QtTest/QtTest>
+#include <QtCore/QFile>
+
+class tst_lconvert : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_lconvert() : dataDir("data/") {}
+
+private slots:
+ void initTestCase();
+ void readverifies_data();
+ void readverifies();
+ void converts_data();
+ void converts();
+ void roundtrips_data();
+ void roundtrips();
+#if 0
+ void chains_data();
+ void chains();
+#endif
+
+private:
+ void doWait(QProcess *cvt, int stage);
+ void doCompare(QIODevice *actual, const QString &expectedFn);
+ void verifyReadFail(const QString &fn);
+ // args can be empty or have one element less than stations
+ void convertChain(const QString &inFileName, const QString &outFileName,
+ const QStringList &stations, const QList<QStringList> &args);
+ void convertRoundtrip(const QString &fileName, const QStringList &stations,
+ const QList<QStringList> &args);
+
+ QString dataDir;
+};
+
+void tst_lconvert::initTestCase()
+{
+ if (!QFile::exists(QLatin1String("data/plural-1.po")))
+ QProcess::execute(QLatin1String("data/makeplurals.sh"), QStringList() << QLatin1String("data/"));
+ QVERIFY(QFile::exists(QLatin1String("data/plural-1.po")));
+}
+
+void tst_lconvert::doWait(QProcess *cvt, int stage)
+{
+ if (QTest::currentTestFailed()) {
+ cvt->kill();
+ cvt->waitForFinished();
+ } else {
+ QVERIFY2(cvt->waitForFinished(3000),
+ qPrintable(QString("Process %1 hung").arg(stage)));
+ QVERIFY2(cvt->exitStatus() == QProcess::NormalExit,
+ qPrintable(QString("Process %1 crashed").arg(stage)));
+ QVERIFY2(cvt->exitCode() == 0,
+ qPrintable(QString("Process %1 exited with status %2. Errors:\n%3")
+ .arg(stage).arg(cvt->exitCode())
+ .arg(QString::fromUtf8(cvt->readAllStandardError()))));
+ }
+}
+
+void tst_lconvert::doCompare(QIODevice *actualDev, const QString &expectedFn)
+{
+ QList<QByteArray> actual = actualDev->readAll().split('\n');
+
+ QFile file(expectedFn);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QList<QByteArray> expected = file.readAll().split('\n');
+
+ int i = 0, ei = expected.size(), gi = actual.size();
+ for (; ; i++) {
+ if (i == gi) {
+ if (i == ei)
+ return;
+ gi = 0;
+ break;
+ } else if (i == ei) {
+ ei = 0;
+ break;
+ } else if (actual.at(i) != expected.at(i)) {
+ while ((ei - 1) >= i && (gi - 1) >= i && actual.at(gi - 1) == expected.at(ei - 1))
+ ei--, gi--;
+ break;
+ }
+ }
+ QByteArray diff;
+ for (int j = qMax(0, i - 3); j < i; j++)
+ diff += expected.at(j) + '\n';
+ diff += "<<<<<<< got\n";
+ for (int j = i; j < gi; j++) {
+ diff += actual.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += "=========\n";
+ for (int j = i; j < ei; j++) {
+ diff += expected.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += ">>>>>>> expected\n";
+ for (int j = ei; j < qMin(ei + 3, expected.size()); j++)
+ diff += expected.at(j) + '\n';
+ QFAIL(qPrintable("Output for " + expectedFn + " does not meet expectations:\n" + diff));
+}
+
+void tst_lconvert::verifyReadFail(const QString &fn)
+{
+ QProcess cvt;
+ cvt.start("lconvert", QStringList() << (dataDir + fn));
+ QVERIFY(cvt.waitForFinished(1000));
+ QVERIFY(cvt.exitStatus() == QProcess::NormalExit);
+ QVERIFY2(cvt.exitCode() == 2, "Accepted invalid input");
+}
+
+void tst_lconvert::convertChain(const QString &_inFileName, const QString &_outFileName,
+ const QStringList &stations, const QList<QStringList> &argList)
+{
+ QList<QProcess *> cvts;
+
+ QString fileName = dataDir + _inFileName;
+ QString outFileName = dataDir + _outFileName;
+
+ for (int i = 0; i < stations.size() - 1; i++) {
+ QProcess *cvt = new QProcess(this);
+ if (cvts.isEmpty())
+ cvt->setStandardInputFile(fileName);
+ else
+ cvts.last()->setStandardOutputProcess(cvt);
+ cvts.append(cvt);
+ }
+ for (int i = 0; i < stations.size() - 1; i++) {
+ QStringList args;
+ if (!argList.isEmpty())
+ args += argList[i];
+ args << "-if" << stations[i] << "-i" << "-" << "-of" << stations[i + 1];
+ cvts.at(i)->start("lconvert", args);
+ }
+ int st = 0;
+ foreach (QProcess *cvt, cvts)
+ doWait(cvt, ++st);
+
+ if (!QTest::currentTestFailed())
+ doCompare(cvts.last(), outFileName);
+
+ qDeleteAll(cvts);
+}
+
+void tst_lconvert::convertRoundtrip(const QString &_fileName, const QStringList &stations,
+ const QList<QStringList> &argList)
+{
+ convertChain(_fileName, _fileName, stations, argList);
+}
+
+void tst_lconvert::readverifies_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("format");
+
+ QTest::newRow("empty comment") << "test-empty-comment.po" << "po";
+ QTest::newRow("translator comment") << "test-translator-comment.po" << "po";
+ QTest::newRow("developer comment") << "test-developer-comment.po" << "po";
+ QTest::newRow("kde context") << "test-kde-ctxt.po" << "po";
+ QTest::newRow("kde fuzzy") << "test-kde-fuzzy.po" << "po";
+ QTest::newRow("kde plurals") << "test-kde-plurals.po" << "po";
+ QTest::newRow("kde multiline") << "test-kde-multiline.po" << "po";
+ QTest::newRow("po linewrapping") << "wrapping.po" << "po";
+ QTest::newRow("relative locations") << "relative.ts" << "ts";
+ QTest::newRow("message ids") << "msgid.ts" << "ts";
+ QTest::newRow("length variants") << "variants.ts" << "ts";
+}
+
+void tst_lconvert::readverifies()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QString, format);
+
+ convertRoundtrip(fileName, QStringList() << format << format, QList<QStringList>());
+}
+
+void tst_lconvert::converts_data()
+{
+ QTest::addColumn<QString>("inFileName");
+ QTest::addColumn<QString>("outFileName");
+ QTest::addColumn<QString>("format");
+
+ QTest::newRow("broken utf8") << "test-broken-utf8.po" << "test-broken-utf8.po.out" << "po";
+ QTest::newRow("line joins") << "test-slurp.po" << "test-slurp.po.out" << "po";
+ QTest::newRow("escapes") << "test-escapes.po" << "test-escapes.po.out" << "po";
+}
+
+void tst_lconvert::converts()
+{
+ QFETCH(QString, inFileName);
+ QFETCH(QString, outFileName);
+ QFETCH(QString, format);
+
+ QString outFileNameFq = dataDir + outFileName;
+
+ QProcess cvt;
+ cvt.start("lconvert", QStringList() << "-i" << (dataDir + inFileName) << "-of" << format);
+ doWait(&cvt, 0);
+ if (QTest::currentTestFailed())
+ return;
+
+ doCompare(&cvt, outFileNameFq);
+}
+
+Q_DECLARE_METATYPE(QList<QStringList>);
+
+#if 0
+void tst_lconvert::chains_data()
+{
+ QTest::addColumn<QString>("inFileName");
+ QTest::addColumn<QString>("outFileName");
+ QTest::addColumn<QStringList>("stations");
+ QTest::addColumn<QList<QStringList> >("args");
+
+}
+
+void tst_lconvert::chains()
+{
+ QFETCH(QString, inFileName);
+ QFETCH(QString, outFileName);
+ QFETCH(QStringList, stations);
+ QFETCH(QList<QStringList>, args);
+
+ convertChain(inFileName, outFileName, stations, args);
+}
+#endif
+
+void tst_lconvert::roundtrips_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QStringList>("stations");
+ QTest::addColumn<QList<QStringList> >("args");
+
+ QStringList poTsPo; poTsPo << "po" << "ts" << "po";
+ QStringList poXlfPo; poXlfPo << "po" << "xlf" << "po";
+ QStringList tsTs11Ts; tsTs11Ts << "ts" << "ts11" << "ts";
+ QStringList tsPoTs; tsPoTs << "ts" << "po" << "ts";
+ QStringList ts11PoTs11; ts11PoTs11 << "ts11" << "po" << "ts11";
+ QStringList tsXlfTs; tsXlfTs << "ts" << "xlf" << "ts";
+ QStringList tsQmTs; tsQmTs << "ts" << "qm" << "ts";
+
+ QList<QStringList> noArgs;
+ QList<QStringList> filterPoArgs; filterPoArgs << QStringList() << (QStringList() << "-drop-tag" << "po:*");
+ QList<QStringList> outDeArgs; outDeArgs << QStringList() << (QStringList() << "-target-language" << "de");
+ QList<QStringList> outCnArgs; outCnArgs << QStringList() << (QStringList() << "-target-language" << "cn");
+
+ QTest::newRow("po-ts-po (translator comment)") << "test-translator-comment.po" << poTsPo << noArgs;
+ QTest::newRow("po-xliff-po (translator comment)") << "test-translator-comment.po" << poXlfPo << noArgs;
+ QTest::newRow("po-ts-po (developer comment)") << "test-developer-comment.po" << poTsPo << noArgs;
+ QTest::newRow("po-xliff-po (developer comment)") << "test-developer-comment.po" << poXlfPo << noArgs;
+
+ QTest::newRow("ts11-po-ts11") << "test11.ts" << ts11PoTs11 << filterPoArgs;
+ QTest::newRow("ts20-po-ts20") << "test20.ts" << tsPoTs << filterPoArgs;
+ QTest::newRow("po-ts-po (de)") << "test1-de.po" << poTsPo << noArgs;
+ QTest::newRow("po-ts-po (cn)") << "test1-cn.po" << poTsPo << noArgs;
+ QTest::newRow("po-xliff-po (de)") << "test1-de.po" << poXlfPo << noArgs;
+ QTest::newRow("po-xliff-po (cn)") << "test1-cn.po" << poXlfPo << noArgs;
+
+ QTest::newRow("po-ts-po (singular)") << "singular.po" << poTsPo << noArgs;
+ QTest::newRow("po-ts-po (plural-1)") << "plural-1.po" << poTsPo << noArgs;
+ QTest::newRow("po-ts-po (plural-2)") << "plural-2.po" << poTsPo << noArgs;
+ QTest::newRow("po-ts-po (plural-3)") << "plural-3.po" << poTsPo << noArgs;
+ QTest::newRow("po-xliff-po (singular)") << "singular.po" << poXlfPo << noArgs;
+ QTest::newRow("po-xliff-po (plural-1)") << "plural-1.po" << poXlfPo << noArgs;
+ QTest::newRow("po-xliff-po (plural-2)") << "plural-2.po" << poXlfPo << noArgs;
+ QTest::newRow("po-xliff-po (plural-3)") << "plural-3.po" << poXlfPo << noArgs;
+
+ QTest::newRow("ts20-ts11-ts20 (utf8)") << "codec-utf8.ts" << tsTs11Ts << noArgs;
+ QTest::newRow("ts20-ts11-ts20 (cp1252)") << "codec-cp1252.ts" << tsTs11Ts << noArgs;
+ QTest::newRow("ts20-ts11-ts20 (dual-encoding)") << "dual-encoding.ts" << tsTs11Ts << noArgs;
+
+ QTest::newRow("ts-qm-ts (dual-encoding)") << "dual-encoding.ts" << tsQmTs << noArgs;
+ QTest::newRow("ts-qm-ts (plurals-de)") << "plurals-de.ts" << tsQmTs << outDeArgs;
+ QTest::newRow("ts-qm-ts (plurals-cn)") << "plurals-cn.ts" << tsQmTs << outCnArgs;
+ QTest::newRow("ts-qm-ts (variants)") << "variants.ts" << tsQmTs << outDeArgs;
+ QTest::newRow("ts-po-ts (msgid)") << "msgid.ts" << tsPoTs << noArgs;
+ QTest::newRow("ts-xliff-ts (msgid)") << "msgid.ts" << tsXlfTs << noArgs;
+
+ QTest::newRow("ts-po-ts (endless loop)") << "endless-po-loop.ts" << tsPoTs << noArgs;
+}
+
+void tst_lconvert::roundtrips()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QStringList, stations);
+ QFETCH(QList<QStringList>, args);
+
+ convertRoundtrip(fileName, stations, args);
+}
+
+QTEST_APPLESS_MAIN(tst_lconvert)
+
+#include "tst_lconvert.moc"
diff --git a/tests/auto/linguist/linguist.pro b/tests/auto/linguist/linguist.pro
new file mode 100644
index 0000000..90e2d36
--- /dev/null
+++ b/tests/auto/linguist/linguist.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = lrelease lconvert lupdate
diff --git a/tests/auto/linguist/lrelease/lrelease.pro b/tests/auto/linguist/lrelease/lrelease.pro
new file mode 100644
index 0000000..8006042
--- /dev/null
+++ b/tests/auto/linguist/lrelease/lrelease.pro
@@ -0,0 +1,5 @@
+CONFIG += qttest_p4
+CONFIG -= gui
+TARGET = tst_lrelease
+
+SOURCES += tst_lrelease.cpp
diff --git a/tests/auto/linguist/lrelease/testdata/compressed.ts b/tests/auto/linguist/lrelease/testdata/compressed.ts
new file mode 100644
index 0000000..9579269
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/compressed.ts
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Context1</name>
+ <message>
+ <source>Foo</source>
+ <translation>in first context</translation>
+ </message>
+</context>
+<context>
+ <name>Context2</name>
+ <message>
+ <source>Bar</source>
+ <translation>in second context</translation>
+ </message>
+</context>
+<context>
+ <name>Action1</name>
+ <message>
+ <location filename="main.cpp" line="14"/>
+ <source>Component Name</source>
+ <translation>translation in first context</translation>
+ </message>
+ <message>
+ <source>Fooish bar</source>
+ <translation>the bar is fooish</translation>
+ </message>
+</context>
+<context>
+ <name>Action2</name>
+ <message>
+ <location filename="main.cpp" line="20"/>
+ <source>Component Name</source>
+ <translation>translation in second context</translation>
+ </message>
+</context>
+<context>
+ <name>Action3</name>
+ <message>
+ <location filename="main.cpp" line="26"/>
+ <source>Component Name</source>
+ <translation>translation in third context</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/testdata/dupes.errors b/tests/auto/linguist/lrelease/testdata/dupes.errors
new file mode 100644
index 0000000..74fcbbb
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/dupes.errors
@@ -0,0 +1,4 @@
+Warning: dropping duplicate messages in 'testdata/dupes\.qm':
+
+\* Context: FindDialog
+\* Source: Text not found
diff --git a/tests/auto/linguist/lrelease/testdata/dupes.ts b/tests/auto/linguist/lrelease/testdata/dupes.ts
new file mode 100644
index 0000000..ec368c3
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/dupes.ts
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS>
+<TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message utf8="true">
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Text not found</source>
+ <translation type="obsolete"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts11.ts b/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts11.ts
new file mode 100644
index 0000000..991f354
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts11.ts
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="1.1">
+<defaultcodec>windows-1252</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut &#xfc; &amp;uuml;</source>
+ <translation>random stuff with umlaut</translation>
+ </message>
+ <message encoding="UTF-8">
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut Ì &amp;uuml; in utf8</source>
+ <translation>more random stuff with umlaut</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts20.ts b/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts20.ts
new file mode 100644
index 0000000..8bb56d4
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/mixedcodecs-ts20.ts
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>windows-1252</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut Ì &amp;uuml;</source>
+ <translation>random stuff with umlaut</translation>
+ </message>
+ <message utf8="true">
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut Ì &amp;uuml; in utf8</source>
+ <translation>more random stuff with umlaut</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/testdata/translate.ts b/tests/auto/linguist/lrelease/testdata/translate.ts
new file mode 100644
index 0000000..ad3015d
--- /dev/null
+++ b/tests/auto/linguist/lrelease/testdata/translate.ts
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="1.1" language="en">
+<context>
+ <name></name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="32"/>
+ <source>Test</source>
+ <translation>AAAA</translation>
+ <comment>Empty context</comment>
+ </message>
+</context>
+<context>
+ <name>CubeForm</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="31"/>
+ <source>Test</source>
+ <translation>BBBB</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="22"/>
+ <source>
+newline at the start</source>
+ <translation>
+NEWLINE AT THE START</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="23"/>
+ <source>newline at the end
+</source>
+ <translation>NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="24"/>
+ <source>newline and space at the end
+ </source>
+ <translation>NEWLINE AND SPACE AT THE END
+ </translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="25"/>
+ <source>space and newline at the end
+</source>
+ <translation>SPACE AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="26"/>
+ <source><byte value="x9"/>tab at the start and newline at the end
+</source>
+ <translation><byte value="x9"/>TAB AT THE START AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="27"/>
+ <source>
+<byte value="x9"/>newline and tab at the start</source>
+ <translation>
+<byte value="x9"/>NEWLINE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="28"/>
+ <source> <byte value="x9"/>space and tab at the start</source>
+ <translation> <byte value="x9"/>SPACE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="29"/>
+ <source> space first</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="tst_lrelease.cpp" line="29"/>
+ <source> string that does not exist</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Plurals</name>
+ <message numerus="yes">
+ <location filename="tst_lrelease.cpp" line="35"/>
+ <source>There are %n houses</source>
+ <translation>
+ <numerusform>There is %n house</numerusform>
+ <numerusform>There are %n houses</numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>tst_lrelease</name>
+ <message numerus="yes">
+ <location filename="tst_lrelease.cpp" line="43"/>
+ <source>There are %n cars</source>
+ <comment>More Plurals</comment>
+ <translation>
+ <numerusform>There is %n car</numerusform>
+ <numerusform>There are %n cars</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Completely random string</source>
+ <translation variants="yes">
+ <lengthvariant>Super-lange Uebersetzung mit Schikanen</lengthvariant>
+ <lengthvariant>Mittlere Uebersetung</lengthvariant>
+ <lengthvariant>Kurze Uebers.</lengthvariant>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>no_en</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="49"/>
+ <source>Kj&#xf8;r K&#xe5;re, kj&#xe6;re</source>
+ <translation>Drive K&#xe5;re, dear</translation>
+ </message>
+</context>
+<context>
+ <name>en_no</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="50"/>
+ <source>Drive K&#xe5;re, dear</source>
+ <translation>Kj&#xf8;r K&#xe5;re, kj&#xe6;re</translation>
+ </message>
+</context>
+<context>
+ <name>en_ch</name>
+ <message>
+ <location filename="tst_lrelease.cpp" line="51"/>
+ <source>Chinese symbol:</source>
+ <translation>Chinese symbol:&#x7c1f;</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp
new file mode 100644
index 0000000..6f65dbc
--- /dev/null
+++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp
@@ -0,0 +1,163 @@
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QByteArray>
+
+#include <QtTest/QtTest>
+
+class tst_lrelease : public QObject
+{
+ Q_OBJECT
+private:
+
+private slots:
+ void translate();
+ void mixedcodecs();
+ void compressed();
+ void dupes();
+
+private:
+ void doCompare(const QStringList &actual, const QString &expectedFn);
+};
+
+void tst_lrelease::doCompare(const QStringList &actual, const QString &expectedFn)
+{
+ QFile file(expectedFn);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QStringList expected = QString(file.readAll()).trimmed().remove('\r').split('\n');
+
+ int i = 0, ei = expected.size(), gi = actual.size();
+ for (; ; i++) {
+ if (i == gi) {
+ if (i == ei)
+ return;
+ gi = 0;
+ break;
+ } else if (i == ei) {
+ ei = 0;
+ break;
+ } else if (!QRegExp(expected.at(i)).exactMatch(actual.at(i))) {
+ while ((ei - 1) >= i && (gi - 1) >= i &&
+ (QRegExp(expected.at(ei - 1)).exactMatch(actual.at(gi - 1))))
+ ei--, gi--;
+ break;
+ }
+ }
+ QByteArray diff;
+ for (int j = qMax(0, i - 3); j < i; j++)
+ diff += expected.at(j) + '\n';
+ diff += "<<<<<<< got\n";
+ for (int j = i; j < gi; j++) {
+ diff += actual.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += "=========\n";
+ for (int j = i; j < ei; j++) {
+ diff += expected.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += ">>>>>>> expected\n";
+ for (int j = ei; j < qMin(ei + 3, expected.size()); j++)
+ diff += expected.at(j) + '\n';
+ QFAIL(qPrintable("Output for " + expectedFn + " does not meet expectations:\n" + diff));
+}
+
+void tst_lrelease::translate()
+{
+ QVERIFY(!QProcess::execute("lrelease testdata/translate.ts"));
+
+ QTranslator translator;
+ QVERIFY(translator.load("testdata/translate.qm"));
+ qApp->installTranslator(&translator);
+
+ QCOMPARE(QObject::tr("\nnewline at the start"), QString("\nNEWLINE AT THE START"));
+ QCOMPARE(QObject::tr("newline at the end\n"), QString("NEWLINE AT THE END\n"));
+ QCOMPARE(QObject::tr("newline and space at the end\n "), QString("NEWLINE AND SPACE AT THE END\n "));
+ QCOMPARE(QObject::tr("space and newline at the end \n"), QString("SPACE AND NEWLINE AT THE END \n"));
+ QCOMPARE(QObject::tr("\ttab at the start and newline at the end\n"), QString("\tTAB AT THE START AND NEWLINE AT THE END\n"));
+ QCOMPARE(QObject::tr("\n\tnewline and tab at the start"), QString("\n\tNEWLINE AND TAB AT THE START"));
+ QCOMPARE(QObject::tr(" \tspace and tab at the start"), QString(" \tSPACE AND TAB AT THE START"));
+ QCOMPARE(QObject::tr(" string that does not exist"), QString(" string that does not exist"));
+
+ QCOMPARE(QCoreApplication::translate("CubeForm", "Test"), QString::fromAscii("BBBB"));
+ QCOMPARE(QCoreApplication::translate("", "Test", "Empty context"), QString("AAAA"));
+
+ // Test plurals
+ QString txed = QCoreApplication::translate("Plurals", "There are %n houses", 0, QCoreApplication::UnicodeUTF8, 0);
+ QCOMPARE(QString::fromAscii("[%1]").arg(txed), QString("[There are 0 houses]"));
+ QCOMPARE(QCoreApplication::translate("Plurals", "There are %n houses", 0, QCoreApplication::UnicodeUTF8, 1), QString("There is 1 house"));
+ QCOMPARE(QCoreApplication::translate("Plurals", "There are %n houses", 0, QCoreApplication::UnicodeUTF8, 2), QString("There are 2 houses"));
+ QCOMPARE(QCoreApplication::translate("Plurals", "There are %n houses", 0, QCoreApplication::UnicodeUTF8, 3), QString("There are 3 houses"));
+
+
+ // More plurals
+ QCOMPARE(tr("There are %n cars", "More Plurals", 0) , QString("There are 0 cars"));
+ QCOMPARE(tr("There are %n cars", "More Plurals", 1) , QString("There is 1 car"));
+ QCOMPARE(tr("There are %n cars", "More Plurals", 2) , QString("There are 2 cars"));
+ QCOMPARE(tr("There are %n cars", "More Plurals", 3) , QString("There are 3 cars"));
+
+
+ QCOMPARE(QCoreApplication::translate("no_en", "Kj\370r K\345re, kj\346re"), QString::fromAscii("Drive K\345re, dear"));
+ QCOMPARE(QCoreApplication::translate("en_no", "Drive K\345re, dear"), QString::fromAscii("Kj\370r K\345re, kj\346re"));
+ QCOMPARE(QCoreApplication::translate("en_ch", "Chinese symbol:"), QString::fromAscii("Chinese symbol:%1").arg(QChar(0x7c1f)));
+
+// printf("halo\r\nhallo");
+ // QCOMPARE(tr("This\r\nwill fail"), QString("THIS\nWILL FAIL")); // \r\n = 0d 0a
+
+ QCOMPARE(tr("Completely random string"),
+ QString::fromLatin1("Super-lange Uebersetzung mit Schikanen\x9c"
+ "Mittlere Uebersetung\x9c"
+ "Kurze Uebers."));
+
+ qApp->removeTranslator(&translator);
+}
+
+void tst_lrelease::mixedcodecs()
+{
+ QVERIFY(!QProcess::execute("lrelease testdata/mixedcodecs-ts11.ts"));
+ QVERIFY(!QProcess::execute("lrelease testdata/mixedcodecs-ts20.ts"));
+ QVERIFY(!QProcess::execute("cmp testdata/mixedcodecs-ts11.qm testdata/mixedcodecs-ts20.qm"));
+ QTranslator translator;
+ QVERIFY(translator.load("testdata/mixedcodecs-ts11.qm"));
+ qApp->installTranslator(&translator);
+
+ QCOMPARE(QCoreApplication::translate("FooBar", "this contains an umlaut \xfc &uuml;"),
+ QString::fromAscii("random stuff with umlaut"));
+ QCOMPARE(QCoreApplication::translate("FooBar", "umlaut \xc3\xbc &uuml; in utf8"),
+ QString::fromAscii("more random stuff with umlaut"));
+}
+
+void tst_lrelease::compressed()
+{
+ QVERIFY(!QProcess::execute("lrelease -compress testdata/compressed.ts"));
+
+ QTranslator translator;
+ QVERIFY(translator.load("testdata/compressed.qm"));
+ qApp->installTranslator(&translator);
+
+ QCOMPARE(QCoreApplication::translate("Context1", "Foo"), QString::fromAscii("in first context"));
+ QCOMPARE(QCoreApplication::translate("Context2", "Bar"), QString::fromAscii("in second context"));
+
+ QCOMPARE(QCoreApplication::translate("Action1", "Component Name"), QString::fromAscii("translation in first context"));
+ QCOMPARE(QCoreApplication::translate("Action2", "Component Name"), QString::fromAscii("translation in second context"));
+ QCOMPARE(QCoreApplication::translate("Action3", "Component Name"), QString::fromAscii("translation in third context"));
+
+}
+
+void tst_lrelease::dupes()
+{
+ QProcess proc;
+ proc.start("lrelease testdata/dupes.ts");
+ QVERIFY(proc.waitForFinished());
+ QVERIFY(proc.exitStatus() == QProcess::NormalExit);
+ doCompare(QString(proc.readAllStandardError()).trimmed().remove('\r').split('\n'), "testdata/dupes.errors");
+}
+
+QTEST_MAIN(tst_lrelease)
+#include "tst_lrelease.moc"
diff --git a/tests/auto/linguist/lupdate/lupdate.pro b/tests/auto/linguist/lupdate/lupdate.pro
new file mode 100644
index 0000000..19259dc
--- /dev/null
+++ b/tests/auto/linguist/lupdate/lupdate.pro
@@ -0,0 +1,7 @@
+CONFIG += qttest_p4
+
+TARGET = tst_lupdate
+
+HEADERS += testlupdate.h
+SOURCES += tst_lupdate.cpp testlupdate.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/backslashes/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/backslashes/lupdatecmd
new file mode 100644
index 0000000..9b83a04
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/backslashes/lupdatecmd
@@ -0,0 +1,3 @@
+# Add the command that lupdate should run here. If it can't find anything it will default to
+TRANSLATION: ts\project.ts
+lupdate -silent project.pro
diff --git a/tests/auto/linguist/lupdate/testdata/good/backslashes/project.pro b/tests/auto/linguist/lupdate/testdata/good/backslashes/project.pro
new file mode 100644
index 0000000..3584c89
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/backslashes/project.pro
@@ -0,0 +1,19 @@
+######################################################################
+# Automatically generated by qmake (2.01a) ma 22. jan 10:10:16 2007
+######################################################################
+
+TEMPLATE = app
+TARGET =
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += src\main.cpp
+
+TRANSLATIONS = ts\project.ts
+
+
+!exists(ts) {
+ win32: system(md ts)
+ else: system(mkdir ts)
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/backslashes/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/backslashes/project.ts.result
new file mode 100644
index 0000000..151a18e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/backslashes/project.ts.result
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="1.1">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="../src/main.cpp" line="13"/>
+ <source>QT_LAYOUT_DIRECTION</source>
+ <comment>Translate this string to the string &apos;LTR&apos; in left-to-right languages or to &apos;RTL&apos; in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/backslashes/src/main.cpp b/tests/auto/linguist/lupdate/testdata/good/backslashes/src/main.cpp
new file mode 100644
index 0000000..348a6be
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/backslashes/src/main.cpp
@@ -0,0 +1,15 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+//
+//
+//
+//
+
+QString qt_detectRTLLanguage()
+{
+ return QApplication::tr("QT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right"
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew"
+ " and Arabic) to get proper widget layout.") == QLatin1String("RTL");
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecforsrc/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/main.cpp
new file mode 100644
index 0000000..2573fbb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/main.cpp
@@ -0,0 +1,18 @@
+#include <QApplication>
+#include <QtGui>
+#include <QtCore>
+#include <QTextCodec>
+
+int main(int argc, char **argv)
+{
+ QApplication a(argc, argv);
+ QWidget w;
+ QLabel label1(QObject::tr("abc", "ascii"), &w);
+ QLabel label2(QObject::tr("ÊÞå", "utf-8"), &w);
+
+// I would expect the following to work !?
+// QLabel label3(QObject::trUtf8("F\374r \310lise", "trUtf8"), &w);
+
+ w.show();
+ return a.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.pro
new file mode 100644
index 0000000..848ebda
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+TARGET +=
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += main.cpp
+
+TRANSLATIONS = project.ts
+CONFIG+= console
+
+CODECFORTR = utf-8
+CODECFORSRC = utf-8
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.ts.result
new file mode 100644
index 0000000..e746c7e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecforsrc/project.ts.result
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="10"/>
+ <source>abc</source>
+ <comment>ascii</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>ÊÞå</source>
+ <comment>utf-8</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecfortr/main.cpp
new file mode 100644
index 0000000..79b0503
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr/main.cpp
@@ -0,0 +1,24 @@
+#include <QApplication>
+#include <QtGui>
+#include <QtCore>
+#include <QTextCodec>
+
+int main(int argc, char **argv)
+{
+ QApplication a(argc, argv);
+ QTranslator trans(0);
+
+ trans.load("t1_en", ".");
+
+ a.installTranslator(&trans);
+ QWidget w;
+/*
+ QLabel label1(QObject::tr("\33"), &w);
+ QLabel label2(QObject::tr("\32"), &w);
+ QLabel label3(QObject::tr("\176"), &w);
+*/
+ QLabel label4(QObject::tr("\301"), &w);
+
+ w.show();
+ return a.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.pro
new file mode 100644
index 0000000..81273ee
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+TARGET +=
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += main.cpp
+
+TRANSLATIONS = project.ts
+CONFIG+= console
+
+CODECFORTR = CP1251
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.ts.result
new file mode 100644
index 0000000..9a082ef
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr/project.ts.result
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>windows-1251</defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="20"/>
+ <source>Á</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr1/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/main.cpp
new file mode 100644
index 0000000..91af165
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/main.cpp
@@ -0,0 +1,20 @@
+#include <QtCore>
+
+class FooBar : QObject
+{
+ Q_OBJECT
+
+public:
+ void doFoo()
+ {
+ tr("random ascii only");
+ tr("this contains an umlaut ü &uuml;");
+ trUtf8("random ascii only in utf8");
+ trUtf8("umlaut \xfc &uuml; in utf8");
+ }
+};
+
+int main(int argc, char **argv)
+{
+ return 0;
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.pro
new file mode 100644
index 0000000..1d5b071
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.pro
@@ -0,0 +1,15 @@
+TEMPLATE = app
+
+SOURCES += main.cpp
+
+TRANSLATIONS = project.ts
+CONFIG += console
+
+CODECFORTR = CP1252
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.ts.result
new file mode 100644
index 0000000..5ffa2f3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr1/project.ts.result
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>windows-1252</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="10"/>
+ <source>random ascii only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut Ì &amp;uuml;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="12"/>
+ <source>random ascii only in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message utf8="true">
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut Ì &amp;uuml; in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr2/main.cpp b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/main.cpp
new file mode 100644
index 0000000..91af165
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/main.cpp
@@ -0,0 +1,20 @@
+#include <QtCore>
+
+class FooBar : QObject
+{
+ Q_OBJECT
+
+public:
+ void doFoo()
+ {
+ tr("random ascii only");
+ tr("this contains an umlaut ü &uuml;");
+ trUtf8("random ascii only in utf8");
+ trUtf8("umlaut \xfc &uuml; in utf8");
+ }
+};
+
+int main(int argc, char **argv)
+{
+ return 0;
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.pro b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.pro
new file mode 100644
index 0000000..f4975f2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+
+SOURCES += main.cpp
+
+TRANSLATIONS = project.ts
+CONFIG += console
+
+CODECFORSRC = CP1252
+CODECFORTR = UTF-8
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.ts.result
new file mode 100644
index 0000000..0ebdbfd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/codecfortr2/project.ts.result
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>FooBar</name>
+ <message>
+ <location filename="main.cpp" line="10"/>
+ <source>random ascii only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>this contains an umlaut Ì &amp;uuml;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="12"/>
+ <source>random ascii only in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="13"/>
+ <source>umlaut Ì &amp;uuml; in utf8</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt
new file mode 100644
index 0000000..1a6cfeb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt
@@ -0,0 +1,8 @@
+.*/lupdate/testdata/good/lacksqobject/main.cpp:17: Class 'B' lacks Q_OBJECT macro
+
+.*/lupdate/testdata/good/lacksqobject/main.cpp:24: Class 'C' lacks Q_OBJECT macro
+
+.*/lupdate/testdata/good/lacksqobject/main.cpp:37: Class 'nsB::B' lacks Q_OBJECT macro
+
+.*/lupdate/testdata/good/lacksqobject/main.cpp:43: Class 'nsB::C' lacks Q_OBJECT macro
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/main.cpp b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/main.cpp
new file mode 100644
index 0000000..05fcd79
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/main.cpp
@@ -0,0 +1,47 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+#include <QtCore>
+
+
+//
+// Test 'lacks Q_OBJECT' reporting on namespace scopes
+//
+
+class B : public QObject {
+ //Q_OBJECT
+ void foo();
+};
+
+void B::foo() {
+ tr("Bla", "::B");
+}
+
+
+class C : public QObject {
+ //Q_OBJECT
+ void foo() {
+ tr("Bla", "::C");
+ }
+};
+
+
+namespace nsB {
+
+ class B : public QObject {
+ //Q_OBJECT
+ void foo();
+ };
+
+ void B::foo() {
+ tr("Bla", "nsB::B");
+ }
+
+ class C : public QObject {
+ //Q_OBJECT
+ void foo() {
+ tr("Bla", "nsB::C");
+ }
+ };
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.pro b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.pro
new file mode 100644
index 0000000..7547a8d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES = main.cpp
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.ts.result
new file mode 100644
index 0000000..bab0881
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/project.ts.result
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>B</name>
+ <message>
+ <location filename="main.cpp" line="17"/>
+ <source>Bla</source>
+ <comment>::B</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>C</name>
+ <message>
+ <location filename="main.cpp" line="24"/>
+ <source>Bla</source>
+ <comment>::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>nsB::B</name>
+ <message>
+ <location filename="main.cpp" line="37"/>
+ <source>Bla</source>
+ <comment>nsB::B</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>nsB::C</name>
+ <message>
+ <location filename="main.cpp" line="43"/>
+ <source>Bla</source>
+ <comment>nsB::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp
new file mode 100644
index 0000000..af8534d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp
@@ -0,0 +1,28 @@
+
+// The first line in this file should always be empty, its part of the test!!
+class Foo : public QObject
+{
+ Q_OBJECT
+public:
+ Foo();
+};
+
+Foo::Foo(MainWindow *parent)
+ : QObject(parent)
+{
+ tr("This is the first entry.");
+ tr("A second message."); tr("And a second one on the same line.");
+ tr("This string did move from the bottom.");
+ tr("This tr is new.");
+ tr("This one moved in from another file.");
+ tr("Now again one which is just where it was.");
+
+ tr("Just as this one.");
+ tr("Another alien.");
+ tr("This is from the bottom, too.");
+ tr("Third string from the bottom.");
+ tr("Fourth one!");
+ tr("They are coming!");
+ tr("They are everywhere!");
+ tr("An earthling again.");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/lupdatecmd
new file mode 100644
index 0000000..91a4800
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/lupdatecmd
@@ -0,0 +1,5 @@
+# Add the command that lupdate should run here. If it can't find anything it will default to
+# 'lupdate project.pro -ts project.ts'
+
+# lupdate project.pro
+lupdate -silent -locations relative project.pro
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.pro b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.pro
new file mode 100644
index 0000000..e79456f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += foo.cpp
+
+TRANSLATIONS = project.ts
+
+# Copy the ts to a temp file because:
+# 1. The depot file is usually read-only
+# 2. We don't want to modify the original file, since then it won't be possible to run the test twice
+# without reverting the original file again.
+
+win32: system(copy /Y project.ts.before $$TRANSLATIONS)
+unix: system(cp -f project.ts.before $$TRANSLATIONS && chmod a+w $$TRANSLATIONS)
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.before
new file mode 100644
index 0000000..d70193f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.before
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="2.0">
+<context>
+ <name>Bar</name>
+ <message>
+ <location filename="bar1.cpp" line="13"/>
+ <source>Another alien.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="bar1.cpp" line="14"/>
+ <source>They are coming!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="bar1.cpp" line="16"/>
+ <source>They are everywhere!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="bar1.cpp" line="18"/>
+ <source>This one moved in from another file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="foo1.cpp" line="13"/>
+ <source>This is the first entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="14"/>
+ <source>A second message.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="15"/>
+ <source>Now again one which is just where it was.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="16"/>
+ <source>Just as this one.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="17"/>
+ <source>An earthling again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="18"/>
+ <source>This is from the bottom, too.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="19"/>
+ <source>Third string from the bottom.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="20"/>
+ <source>Fourth one!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="foo1.cpp" line="21"/>
+ <source>This string did move from the bottom.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.result
new file mode 100644
index 0000000..2027efd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_ordering/project.ts.result
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="foo.cpp" line="+13"/>
+ <source>This is the first entry.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>A second message.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>And a second one on the same line.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>This tr is new.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>This one moved in from another file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Now again one which is just where it was.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Just as this one.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Another alien.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>They are coming!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>They are everywhere!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>An earthling again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-5"/>
+ <source>This is from the bottom, too.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Third string from the bottom.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Fourth one!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-9"/>
+ <source>This string did move from the bottom.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.pro b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.pro
new file mode 100644
index 0000000..6c704c2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
+
+# Copy the ts to a temp file because:
+# 1. The depot file is usually read-only
+# 2. We don't want to modify the original file, since then it won't be possible to run the test twice
+# without reverting the original file again.
+
+win32: system(copy /Y project.ts.before $$TRANSLATIONS)
+unix: system(cp -f project.ts.before $$TRANSLATIONS && chmod a+w $$TRANSLATIONS)
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.before
new file mode 100644
index 0000000..fdc2a99
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.before
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Qt Assistant - Finn text</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Finn tekst</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.result
new file mode 100644
index 0000000..f9d26df
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ts.result
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Qt Assistant - Finn text</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Finn tekst</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ui b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ui
new file mode 100644
index 0000000..7adb650
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_versions/project.ui
@@ -0,0 +1,44 @@
+<ui version="4.0" >
+ <author></author>
+ <comment>*********************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+*********************************************************************</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Qt Assistant - Finn text</string><!-- changed to uppercase -->
+ </property>
+ <property name="height" >
+ <string>Finn tekst</string>
+ </property>
+ </widget>
+ <tabstops>
+ <tabstop>comboFind</tabstop>
+ <tabstop>checkWords</tabstop>
+ <tabstop>checkCase</tabstop>
+ <tabstop>radioForward</tabstop>
+ <tabstop>radioBackward</tabstop>
+ <tabstop>findButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/main.cpp b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/main.cpp
new file mode 100644
index 0000000..e058da0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/main.cpp
@@ -0,0 +1,23 @@
+#include <QApplication>
+#include <QDebug>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QTranslator translator;
+ translator.load("whitespace");
+ app.installTranslator(&translator);
+
+ QObject::tr("\nnewline at the start");
+ QObject::tr("newline at the end\n");
+ QObject::tr("newline and space at the end\n ");
+ QObject::tr("space and newline at the end \n");
+ QObject::tr("\tTab at the start and newline at the end\n");
+ QObject::tr("\n\tnewline and tab at the start");
+ QObject::tr(" \tspace and tab at the start");
+ QObject::tr(" space_first");
+ QObject::tr("space_last ");
+ QObject::tr("carriage return and line feed last\r\n");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.pro b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.pro
new file mode 100644
index 0000000..f4faf2f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES = main.cpp
+
+TRANSLATIONS = project.ts
+
+# Copy the ts to a temp file because:
+# 1. The depot file is usually read-only
+# 2. We don't want to modify the original file, since then it won't be possible to run the test twice
+# without reverting the original file again.
+
+win32: system(copy /Y project.ts.before $$TRANSLATIONS)
+unix: system(cp -f project.ts.before $$TRANSLATIONS && chmod a+w $$TRANSLATIONS)
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.before
new file mode 100644
index 0000000..3acae3e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.before
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="7"/>
+ <source>
+newline at the start</source>
+ <translation>
+NEWLINE AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="8"/>
+ <source>newline at the end
+</source>
+ <translation>NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="9"/>
+ <source>newline and space at the end
+ </source>
+ <translation>NEWLINE AND SPACE AT THE END
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="10"/>
+ <source>space and newline at the end
+</source>
+ <translation>SPACE AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source><byte value="x9"/>Tab at the start and newline at the end
+</source>
+ <translation><byte value="x9"/>TAB AT THE START AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="12"/>
+ <source>
+<byte value="x9"/>newline and tab at the start</source>
+ <translation>
+<byte value="x9"/>NEWLINE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="13"/>
+ <source> <byte value="x9"/>space and tab at the start</source>
+ <translation> <byte value="x9"/>SPACE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="14"/>
+ <source> space_first</source>
+ <translation> SPACE_FIRST</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="15"/>
+ <source>space_last </source>
+ <translation>SPACE_LAST </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="21"/>
+ <source>carriage return and line feed last<byte value="xd"/>
+</source>
+ <translation type="unfinished">CARRIAGE RETURN AND LINE FEED LAST<byte value="xd"/>
+</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.result
new file mode 100644
index 0000000..6d6b469
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/merge_whitespace/project.ts.result
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="12"/>
+ <source>
+newline at the start</source>
+ <translation>
+NEWLINE AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="13"/>
+ <source>newline at the end
+</source>
+ <translation>NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="14"/>
+ <source>newline and space at the end
+ </source>
+ <translation>NEWLINE AND SPACE AT THE END
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="15"/>
+ <source>space and newline at the end
+</source>
+ <translation>SPACE AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="16"/>
+ <source> Tab at the start and newline at the end
+</source>
+ <translation> TAB AT THE START AND NEWLINE AT THE END
+</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="17"/>
+ <source>
+ newline and tab at the start</source>
+ <translation>
+ NEWLINE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="18"/>
+ <source> space and tab at the start</source>
+ <translation> SPACE AND TAB AT THE START</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="19"/>
+ <source> space_first</source>
+ <translation> SPACE_FIRST</translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="20"/>
+ <source>space_last </source>
+ <translation>SPACE_LAST </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="21"/>
+ <source>carriage return and line feed last
+</source>
+ <translation type="unfinished">CARRIAGE RETURN AND LINE FEED LAST
+</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp
new file mode 100644
index 0000000..7edb923
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp
@@ -0,0 +1,25 @@
+
+// The first line in this file should always be empty, its part of the test!!
+class FindDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ FindDialog(MainWindow *parent);
+ void reset();
+};
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ QString trans = tr("Enter the text you want to find.");
+ trans = tr("Search reached end of the document");
+ trans = tr("Search reached start of the document");
+ trans = tr( "Text not found" );
+}
+
+void FindDialog::reset()
+{
+ tr("%n item(s)", "merge from singular to plural form", 4);
+ tr("%n item(s)", "merge from a finished singular form to an unfinished plural form", 4);
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.pro
new file mode 100644
index 0000000..e988c0a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += finddialog.cpp
+
+TRANSLATIONS = project.ts
+
+# Copy the ts to a temp file because:
+# 1. The depot file is usually read-only
+# 2. We don't want to modify the original file, since then it won't be possible to run the test twice
+# without reverting the original file again.
+
+win32: system(copy /Y project.ts.before $$TRANSLATIONS)
+unix: system(cp -f project.ts.before $$TRANSLATIONS && chmod a+w $$TRANSLATIONS)
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.before
new file mode 100644
index 0000000..474444f
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.before
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1" language="zh_CN">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source></source>
+ <comment>magic context comment</comment>
+ <translatorcomment>random translator comment</translatorcomment>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="14"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="15"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="16"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="17"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="finddialog.cpp" line="22"/>
+ <source>%n item(s)</source>
+ <comment>merge from singular to plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="finddialog.cpp" line="23"/>
+ <source>%n item(s)</source>
+ <comment>merge from a finished singular form to an unfinished plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.result
new file mode 100644
index 0000000..152b568
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp/project.ts.result
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="zh_CN">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source></source>
+ <comment>magic context comment</comment>
+ <translatorcomment>random translator comment</translatorcomment>
+ <translation></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="14"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="15"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="16"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="17"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="finddialog.cpp" line="22"/>
+ <source>%n item(s)</source>
+ <comment>merge from singular to plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="finddialog.cpp" line="23"/>
+ <source>%n item(s)</source>
+ <comment>merge from a finished singular form to an unfinished plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/finddialog.cpp
new file mode 100644
index 0000000..f587618
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/finddialog.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "finddialog.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpwindow.h"
+
+#include <QTextBrowser>
+#include <QTextCursor>
+#include <QStatusBar>
+#include <QLineEdit>
+#include <QDateTime>
+#include <QGridLayout>
+
+CaseSensitiveModel::CaseSensitiveModel(int rows, int columns, QObject *parent)
+ : QStandardItemModel(rows, columns, parent)
+{}
+QModelIndexList CaseSensitiveModel::match(const QModelIndex &start, int role, const QVariant &value,
+ int hits, Qt::MatchFlags flags) const
+{
+ if (flags == Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap))
+ flags |= Qt::MatchCaseSensitive;
+
+ return QStandardItemModel::match(start, role, value, hits, flags);
+}
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ contentsWidget = new QWidget(this);
+ ui.setupUi(contentsWidget);
+ ui.comboFind->setModel(new CaseSensitiveModel(0, 1, ui.comboFind));
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+ l->addWidget(contentsWidget);
+
+ lastBrowser = 0;
+ onceFound = false;
+ findExpr.clear();
+
+ sb = new QStatusBar(this);
+ l->addWidget(sb);
+
+ sb->showMessage(tr("Enter the text you want to find."));
+
+ connect(ui.findButton, SIGNAL(clicked()), this, SLOT(findButtonClicked()));
+ connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+FindDialog::~FindDialog()
+{
+}
+
+void FindDialog::findButtonClicked()
+{
+ doFind(ui.radioForward->isChecked());
+}
+
+void FindDialog::doFind(bool forward)
+{
+ QTextBrowser *browser = static_cast<QTextBrowser*>(mainWindow()->browsers()->currentBrowser());
+ sb->clearMessage();
+
+ if (ui.comboFind->currentText() != findExpr || lastBrowser != browser)
+ onceFound = false;
+ findExpr = ui.comboFind->currentText();
+
+ QTextDocument::FindFlags flags = 0;
+
+ if (ui.checkCase->isChecked())
+ flags |= QTextDocument::FindCaseSensitively;
+
+ if (ui.checkWords->isChecked())
+ flags |= QTextDocument::FindWholeWords;
+
+ QTextCursor c = browser->textCursor();
+ if (!c.hasSelection()) {
+ if (forward)
+ c.movePosition(QTextCursor::Start);
+ else
+ c.movePosition(QTextCursor::End);
+
+ browser->setTextCursor(c);
+ }
+
+ QTextDocument::FindFlags options;
+ if (forward == false)
+ flags |= QTextDocument::FindBackward;
+
+ QTextCursor found = browser->document()->find(findExpr, c, flags);
+ if (found.isNull()) {
+ if (onceFound) {
+ if (forward)
+ statusMessage(tr("Search reached end of the document"));
+ else
+ statusMessage(tr("Search reached start of the document"));
+ } else {
+ statusMessage(tr( "Text not found" ));
+ }
+ } else {
+ browser->setTextCursor(found);
+ }
+ onceFound |= !found.isNull();
+ lastBrowser = browser;
+}
+
+bool FindDialog::hasFindExpression() const
+{
+ // statusMessage(tr( "Should be obsolete" ));
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/lupdatecmd
new file mode 100644
index 0000000..d200143
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/lupdatecmd
@@ -0,0 +1,5 @@
+# Add the command that lupdate should run here. If it can't find anything it will default to
+# 'lupdate project.pro -ts project.ts'
+
+# lupdate project.pro
+lupdate -silent -noobsolete project.pro
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.pro
new file mode 100644
index 0000000..e988c0a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += finddialog.cpp
+
+TRANSLATIONS = project.ts
+
+# Copy the ts to a temp file because:
+# 1. The depot file is usually read-only
+# 2. We don't want to modify the original file, since then it won't be possible to run the test twice
+# without reverting the original file again.
+
+win32: system(copy /Y project.ts.before $$TRANSLATIONS)
+unix: system(cp -f project.ts.before $$TRANSLATIONS && chmod a+w $$TRANSLATIONS)
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.before
new file mode 100644
index 0000000..12e30b5
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.before
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="57"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="107"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="122"/>
+ <source>Should be obsolete</source>
+ <translation type="unfinished">SHOULD BE OBSOLETE</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.result
new file mode 100644
index 0000000..21d1ca0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_noobsolete/project.ts.result
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="57"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="107"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/finddialog.cpp
new file mode 100644
index 0000000..e23d129
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/finddialog.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "finddialog.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpwindow.h"
+
+#include <QTextBrowser>
+#include <QTextCursor>
+#include <QStatusBar>
+#include <QLineEdit>
+#include <QDateTime>
+#include <QGridLayout>
+
+CaseSensitiveModel::CaseSensitiveModel(int rows, int columns, QObject *parent)
+ : QStandardItemModel(rows, columns, parent)
+{}
+QModelIndexList CaseSensitiveModel::match(const QModelIndex &start, int role, const QVariant &value,
+ int hits, Qt::MatchFlags flags) const
+{
+ if (flags == Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap))
+ flags |= Qt::MatchCaseSensitive;
+
+ return QStandardItemModel::match(start, role, value, hits, flags);
+}
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ contentsWidget = new QWidget(this);
+ ui.setupUi(contentsWidget);
+ ui.comboFind->setModel(new CaseSensitiveModel(0, 1, ui.comboFind));
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+ l->addWidget(contentsWidget);
+
+ lastBrowser = 0;
+ onceFound = false;
+ findExpr.clear();
+
+ sb = new QStatusBar(this);
+ l->addWidget(sb);
+
+
+ // Move it to another line and change the text,
+ // then lupdate should add this one as a new one, and mark the old one as obsolete.
+ sb->showMessage(tr("Enter the text you want to find."));
+
+ connect(ui.findButton, SIGNAL(clicked()), this, SLOT(findButtonClicked()));
+ connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+FindDialog::~FindDialog()
+{
+}
+
+void FindDialog::findButtonClicked()
+{
+ doFind(ui.radioForward->isChecked());
+}
+
+void FindDialog::doFind(bool forward)
+{
+ QTextBrowser *browser = static_cast<QTextBrowser*>(mainWindow()->browsers()->currentBrowser());
+ sb->clearMessage();
+
+ if (ui.comboFind->currentText() != findExpr || lastBrowser != browser)
+ onceFound = false;
+ findExpr = ui.comboFind->currentText();
+
+ QTextDocument::FindFlags flags = 0;
+
+ if (ui.checkCase->isChecked())
+ flags |= QTextDocument::FindCaseSensitively;
+
+ if (ui.checkWords->isChecked())
+ flags |= QTextDocument::FindWholeWords;
+
+ QTextCursor c = browser->textCursor();
+ if (!c.hasSelection()) {
+ if (forward)
+ c.movePosition(QTextCursor::Start);
+ else
+ c.movePosition(QTextCursor::End);
+
+ browser->setTextCursor(c);
+ }
+
+ QTextDocument::FindFlags options;
+ if (forward == false)
+ flags |= QTextDocument::FindBackward;
+
+ QTextCursor found = browser->document()->find(findExpr, c, flags);
+ if (found.isNull()) {
+ if (onceFound) {
+ if (forward)
+ statusMessage(tr("Search reached end of the document"));
+ else
+ statusMessage(tr("Search reached start of the document"));
+ } else {
+ statusMessage(tr( "Text not found" ));
+ }
+ } else {
+ browser->setTextCursor(found);
+ }
+ onceFound |= !found.isNull();
+ lastBrowser = browser;
+}
+
+bool FindDialog::hasFindExpression() const
+{
+ return !findExpr.isEmpty();
+}
+
+void FindDialog::statusMessage(const QString &message)
+{
+ if (isVisible())
+ sb->showMessage(message);
+ else
+ static_cast<MainWindow*>(parent())->statusBar()->showMessage(message, 2000);
+}
+
+MainWindow *FindDialog::mainWindow() const
+{
+ return static_cast<MainWindow*>(parentWidget());
+}
+
+void FindDialog::reset()
+{
+ ui.comboFind->setFocus();
+ ui.comboFind->lineEdit()->setSelection(
+ 0, ui.comboFind->lineEdit()->text().length());
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.pro
new file mode 100644
index 0000000..e988c0a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += finddialog.cpp
+
+TRANSLATIONS = project.ts
+
+# Copy the ts to a temp file because:
+# 1. The depot file is usually read-only
+# 2. We don't want to modify the original file, since then it won't be possible to run the test twice
+# without reverting the original file again.
+
+win32: system(copy /Y project.ts.before $$TRANSLATIONS)
+unix: system(cp -f project.ts.before $$TRANSLATIONS && chmod a+w $$TRANSLATIONS)
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.before
new file mode 100644
index 0000000..271cc39
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.before
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="57"/>
+ <source>Enter the text you are looking for.</source>
+ <translation type="unfinished">Skriv inn teksten du soker etter</translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="107"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.result
new file mode 100644
index 0000000..b7074fe
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergecpp_obsolete/project.ts.result
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Enter the text you are looking for.</source>
+ <translation type="obsolete">Skriv inn teksten du soker etter</translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="60"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="110"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="112"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="114"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.pro
new file mode 100644
index 0000000..28ba291
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
+
+# Copy the ts to a temp file because:
+# 1. The depot file is usually read-only
+# 2. We don't want to modify the original file, since then it won't be possible to run the test twice
+# without reverting the original file again.
+
+win32: system(copy /Y project.ts.before $$TRANSLATIONS)
+unix: system(cp -f project.ts.before $$TRANSLATIONS && chmod a+w $$TRANSLATIONS)
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before
new file mode 100644
index 0000000..e297784
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="27"/>
+ <source>Qt Assistant - Find text</source>
+ <!--should be changed to unfinished, since we are changing the sourcetext in the ui file-->
+ <translation>Qt Assistant - Finn tekst</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="30"/>
+ <source>300px</source>
+ <translation>300px</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="33"/>
+ <source>400px</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.result
new file mode 100644
index 0000000..b21f583
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.result
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="27"/>
+ <source>Qt Assistant - Find Text</source>
+ <oldsource>Qt Assistant - Find text</oldsource>
+ <translation type="unfinished">Qt Assistant - Finn tekst</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="30"/>
+ <source>300px</source>
+ <translation>300px</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="33"/>
+ <source>401 pixels</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ui b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ui
new file mode 100644
index 0000000..c10545d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ui
@@ -0,0 +1,47 @@
+<ui version="4.0" >
+ <author></author>
+ <comment>*********************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+*********************************************************************</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Qt Assistant - Find Text</string><!-- changed to uppercase, marked as finished -->
+ </property>
+ <property name="height" >
+ <string>300px</string>
+ </property>
+ <property name="width" >
+ <string>401 pixels</string><!-- Changed from 400px to 401 pixels, but this is marked as unfinished -->
+ </property>
+ </widget>
+ <tabstops>
+ <tabstop>comboFind</tabstop>
+ <tabstop>checkWords</tabstop>
+ <tabstop>checkCase</tabstop>
+ <tabstop>radioForward</tabstop>
+ <tabstop>radioBackward</tabstop>
+ <tabstop>findButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.pro b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.pro
new file mode 100644
index 0000000..28ba291
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
+
+# Copy the ts to a temp file because:
+# 1. The depot file is usually read-only
+# 2. We don't want to modify the original file, since then it won't be possible to run the test twice
+# without reverting the original file again.
+
+win32: system(copy /Y project.ts.before $$TRANSLATIONS)
+unix: system(cp -f project.ts.before $$TRANSLATIONS && chmod a+w $$TRANSLATIONS)
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.before
new file mode 100644
index 0000000..f06c22c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.before
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="20"/>
+ <source>Test similarity</source>
+ <translation type="unfinished">Test likhet (test1)</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="23"/>
+ <source>Similarity should have kicked in here!</source>
+ <translation type="unfinished">Test likhet (test2)</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result
new file mode 100644
index 0000000..d65110a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Test similarity</source>
+ <translation type="obsolete">Test likhet (test1)</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="20"/>
+ <source>This should not be considered to be more or less equal to the corresponding one in the ts file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="23"/>
+ <source>Here, similarity should kick in!</source>
+ <oldsource>Similarity should have kicked in here!</oldsource>
+ <translation type="unfinished">Test likhet (test2)</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui
new file mode 100644
index 0000000..0d0defd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui
@@ -0,0 +1,26 @@
+<ui version="4.0" >
+ <author></author>
+ <comment><!--
+*********************************************************************
+**
+** Do not change the location (linenumber) of the <string> elements in this file!
+** That will make the test break!
+**
+** If you need to add some tests, please add them to the end of the file!
+**
+**
+*********************************************************************
+-->
+</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="test1">
+ <!-- If the sourcetext is not similar to the vernacular sourcetext, mark the old one as obsolete and the new one as unfinished -->
+ <string>This should not be considered to be more or less equal to the corresponding one in the ts file.</string>
+ </property>
+ <property name="test2">
+ <string>Here, similarity should kick in!</string>
+ </property>
+ </widget>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/good/multiple_locations/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/finddialog.cpp
new file mode 100644
index 0000000..c3881d3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/finddialog.cpp
@@ -0,0 +1,7 @@
+
+QT_TRANSLATE_NOOP("context", "just a message")
+
+
+
+//: This is one comment
+QT_TRANSLATE_NOOP("context", "just a message")
diff --git a/tests/auto/linguist/lupdate/testdata/good/multiple_locations/main.cpp b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/main.cpp
new file mode 100644
index 0000000..71d9085
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/main.cpp
@@ -0,0 +1,13 @@
+
+
+
+
+//: This is a comment, too.
+QT_TRANSLATE_NOOP("context", "just a message")
+
+
+
+
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.pro b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.pro
new file mode 100644
index 0000000..4582705
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main.cpp
+SOURCES += finddialog.cpp
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.ts.result
new file mode 100644
index 0000000..dd013fa
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/multiple_locations/project.ts.result
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>context</name>
+ <message>
+ <location filename="finddialog.cpp" line="2"/>
+ <location filename="finddialog.cpp" line="7"/>
+ <location filename="main.cpp" line="6"/>
+ <source>just a message</source>
+ <extracomment>This is one comment
+----------
+This is a comment, too.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/namespaces/main.cpp b/tests/auto/linguist/lupdate/testdata/good/namespaces/main.cpp
new file mode 100644
index 0000000..9f5a98c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/namespaces/main.cpp
@@ -0,0 +1,97 @@
+#include <QtCore>
+
+class Class : public QObject
+{
+ Q_OBJECT
+
+ class SubClass
+ {
+ void f()
+ {
+ tr("nested class context");
+ }
+ };
+
+ void f()
+ {
+ tr("just class context");
+ }
+};
+
+namespace Outer {
+
+class Class : public QObject { Q_OBJECT };
+
+namespace Middle1 {
+
+class Class : public QObject { Q_OBJECT };
+
+namespace Inner1 {
+
+class Class : public QObject { Q_OBJECT };
+
+}
+
+namespace I = Inner1;
+
+class Something;
+class Different;
+
+}
+
+namespace Middle2 {
+
+class Class : public QObject { Q_OBJECT };
+
+namespace Inner2 {
+
+class Class : public QObject { Q_OBJECT };
+
+namespace IO = Middle2;
+
+}
+
+namespace I = Inner2;
+
+}
+
+namespace MI = Middle1::Inner1;
+
+namespace O = ::Outer;
+
+class Middle1::Different : QObject {
+Q_OBJECT
+ void f() {
+ tr("different namespaced class def");
+ }
+};
+
+}
+
+namespace O = Outer;
+namespace OM = Outer::Middle1;
+namespace OMI = Outer::Middle1::I;
+
+int main()
+{
+ Class::tr("outestmost class");
+ Outer::Class::tr("outer class");
+ Outer::MI::Class::tr("innermost one");
+ OMI::Class::tr("innermost two");
+ O::Middle1::I::Class::tr("innermost three");
+ O::Middle2::I::Class::tr("innermost three b");
+ OM::I::Class::tr("innermost four");
+ return 0;
+}
+
+class OM::Something : QObject {
+Q_OBJECT
+ void f() {
+ tr("namespaced class def");
+ }
+ void g() {
+ tr("namespaced class def 2");
+ }
+};
+
+#include "main.moc"
diff --git a/tests/auto/linguist/lupdate/testdata/good/namespaces/project.pro b/tests/auto/linguist/lupdate/testdata/good/namespaces/project.pro
new file mode 100644
index 0000000..56d472c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/namespaces/project.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main.cpp
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/namespaces/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/namespaces/project.ts.result
new file mode 100644
index 0000000..d1193d3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/namespaces/project.ts.result
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Class</name>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>nested class context</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="17"/>
+ <source>just class context</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="77"/>
+ <source>outestmost class</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Class</name>
+ <message>
+ <location filename="main.cpp" line="78"/>
+ <source>outer class</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Middle1::Different</name>
+ <message>
+ <location filename="main.cpp" line="65"/>
+ <source>different namespaced class def</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Middle1::Inner1::Class</name>
+ <message>
+ <location filename="main.cpp" line="79"/>
+ <source>innermost one</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="80"/>
+ <source>innermost two</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="81"/>
+ <source>innermost three</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="83"/>
+ <source>innermost four</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Middle1::Something</name>
+ <message>
+ <location filename="main.cpp" line="90"/>
+ <source>namespaced class def</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="93"/>
+ <source>namespaced class def 2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Outer::Middle2::Inner2::Class</name>
+ <message>
+ <location filename="main.cpp" line="82"/>
+ <source>innermost three b</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/main.cpp
new file mode 100644
index 0000000..72a1590
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/main.cpp
@@ -0,0 +1,18 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+class Dialog2 : public QDialog
+{
+ Q_OBJECT
+ void func();
+
+};
+
+void Dialog2::func()
+{
+ tr("cat\351gorie");
+
+ tr("F\374r \310lise")
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.pro b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.pro
new file mode 100644
index 0000000..cb18ea4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main.cpp
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.ts.result
new file mode 100644
index 0000000..a49b47a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parse_special_chars/project.ts.result
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Dialog2</name>
+ <message>
+ <location filename="main.cpp" line="13"/>
+ <source>catégorie</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="15"/>
+ <source>FÃŒr Èlise</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp
new file mode 100644
index 0000000..65eeed5
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/main.cpp
@@ -0,0 +1,229 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+#include <QtCore>
+#include <QtGui>
+
+//
+// Test namespace scoping
+//
+
+class D : public QObject {
+ Q_OBJECT
+ public:
+ QString foo() {
+ return tr("test", "D");
+ }
+
+};
+
+namespace A {
+
+ class C : public QObject {
+ Q_OBJECT
+ public:
+ void foo();
+ };
+
+ void C::foo() {
+ tr("Bla", "A::C");
+ }
+
+ void goo() {
+ C::tr("Bla", "A::C"); // Is identical to the previous tr(), (same context, sourcetext and comment,
+ // so it should not add another entry to the list of messages)
+ }
+
+ void goo2() {
+ C::tr("Bla 2", "A::C"); //Should be in the same namespace as the previous tr()
+ }
+
+}
+
+
+namespace X {
+
+ class D : public QObject {
+ Q_OBJECT
+ public:
+
+ };
+
+ class E : public QObject {
+ Q_OBJECT
+ public:
+ void foo() { D::tr("foo", "D"); } // Note that this is X::D from 440 on
+ };
+
+
+ namespace Y {
+ class E : public QObject {
+ Q_OBJECT
+
+ };
+
+ class C : public QObject {
+ Q_OBJECT
+ void foo();
+ };
+
+ void C::foo() {
+ tr("Bla", "X::Y::C");
+ }
+
+ void goo() {
+ D::tr("Bla", "X::D"); //This should be assigned to the X::D context
+ }
+
+ void goo2() {
+ E::tr("Bla", "X::Y::E"); //This should be assigned to the X::Y::E context
+ Y::E::tr("Bla", "X::Y::E"); //This should be assigned to the X::Y::E context
+ }
+
+ }; // namespace Y
+
+ class F : public QObject {
+ Q_OBJECT
+ inline void inlinefunc() {
+ tr("inline function", "X::F");
+ }
+ };
+} // namespace X
+
+namespace ico {
+ namespace foo {
+ class A : public QObject {
+ A();
+ };
+
+ A::A() {
+ tr("myfoo", "ico::foo::A");
+ QObject::tr("task 161186", "QObject");
+ }
+ }
+}
+
+namespace AA {
+class C {};
+}
+
+/**
+ * the context of a message should not be affected by any inherited classes
+ *
+ * Keep this disabled for now, but at a long-term range it should work.
+ */
+namespace Gui {
+ class MainWindow : public QMainWindow,
+ public AA::C
+ {
+ Q_OBJECT
+public:
+ MainWindow()
+ {
+ tr("More bla", "Gui::MainWindow");
+ }
+
+ };
+} //namespace Gui
+
+
+namespace A1 {
+ class AB : public QObject {
+ Q_OBJECT
+ public:
+
+ friend class OtherClass;
+
+ QString inlineFuncAfterFriendDeclaration() const {
+ return tr("inlineFuncAfterFriendDeclaration", "A1::AB");
+ }
+ };
+ class B : AB {
+ Q_OBJECT
+ public:
+ QString foo() const { return tr("foo", "A1::B"); }
+ };
+
+ // This is valid C++ too....
+ class V : virtual AB {
+ Q_OBJECT
+ public:
+ QString bar() const { return tr("bar", "A1::V"); }
+ };
+
+ class W : virtual public AB {
+ Q_OBJECT
+ public:
+ QString baz() const { return tr("baz", "A1::W"); }
+ };
+}
+
+class ForwardDecl;
+
+
+class B1 : public QObject {
+};
+
+class C1 : public QObject {
+};
+
+namespace A1 {
+
+class B2 : public QObject {
+};
+
+}
+
+void func1()
+{
+ B1::tr("test TRANSLATOR comment (1)", "B1");
+
+}
+
+using namespace A1;
+/*
+ TRANSLATOR A1::B2
+*/
+void func2()
+{
+ B2::tr("test TRANSLATOR comment (2)", "A1::B2");
+ C1::tr("test TRANSLATOR comment (3)", "C1");
+}
+
+void func3()
+{
+ B2::tr("test TRANSLATOR comment (4)", "A1::B2");
+}
+
+/*
+ TRANSLATOR B2
+ This is a comment to the translator.
+*/
+void func4()
+{
+ B2::tr("test TRANSLATOR comment (5)", "A1::B2");
+}
+
+namespace A1 {
+namespace B3 {
+class C2 : public QObject {
+QString foo();
+};
+}
+}
+
+namespace D1 = A1::B3;
+using namespace D1;
+
+// TRANSLATOR A1::B3::C2
+QString C2::foo()
+{
+ return tr("test TRANSLATOR comment (6)", "A1::B3::C2"); // 4.4 screws up
+}
+
+
+
+int main(int /*argc*/, char ** /*argv*/) {
+ return 0;
+}
+
+#include "main.moc"
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.pro
new file mode 100644
index 0000000..7547a8d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES = main.cpp
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result
new file mode 100644
index 0000000..04bb3ae
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>A1::AB</name>
+ <message>
+ <location filename="main.cpp" line="137"/>
+ <source>inlineFuncAfterFriendDeclaration</source>
+ <comment>A1::AB</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::B</name>
+ <message>
+ <location filename="main.cpp" line="143"/>
+ <source>foo</source>
+ <comment>A1::B</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::B2</name>
+ <message>
+ <location filename="main.cpp" line="188"/>
+ <source>test TRANSLATOR comment (2)</source>
+ <comment>A1::B2</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="194"/>
+ <source>test TRANSLATOR comment (4)</source>
+ <comment>A1::B2</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="203"/>
+ <source>test TRANSLATOR comment (5)</source>
+ <comment>A1::B2</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::B3::C2</name>
+ <message>
+ <location filename="main.cpp" line="220"/>
+ <source>test TRANSLATOR comment (6)</source>
+ <comment>A1::B3::C2</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::V</name>
+ <message>
+ <location filename="main.cpp" line="150"/>
+ <source>bar</source>
+ <comment>A1::V</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A1::W</name>
+ <message>
+ <location filename="main.cpp" line="156"/>
+ <source>baz</source>
+ <comment>A1::W</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>A::C</name>
+ <message>
+ <location filename="main.cpp" line="28"/>
+ <location filename="main.cpp" line="32"/>
+ <source>Bla</source>
+ <comment>A::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="37"/>
+ <source>Bla 2</source>
+ <comment>A::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>B1</name>
+ <message>
+ <location filename="main.cpp" line="178"/>
+ <source>test TRANSLATOR comment (1)</source>
+ <comment>B1</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>B2</name>
+ <message>
+ <location filename="main.cpp" line="197"/>
+ <source></source>
+ <comment>This is a comment to the translator.</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>C1</name>
+ <message>
+ <location filename="main.cpp" line="189"/>
+ <source>test TRANSLATOR comment (3)</source>
+ <comment>C1</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>D</name>
+ <message>
+ <location filename="main.cpp" line="14"/>
+ <source>test</source>
+ <comment>D</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Gui::MainWindow</name>
+ <message>
+ <location filename="main.cpp" line="122"/>
+ <source>More bla</source>
+ <comment>Gui::MainWindow</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="100"/>
+ <source>task 161186</source>
+ <comment>QObject</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>X::D</name>
+ <message>
+ <location filename="main.cpp" line="54"/>
+ <source>foo</source>
+ <comment>D</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="74"/>
+ <source>Bla</source>
+ <comment>X::D</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>X::F</name>
+ <message>
+ <location filename="main.cpp" line="87"/>
+ <source>inline function</source>
+ <comment>X::F</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>X::Y::C</name>
+ <message>
+ <location filename="main.cpp" line="70"/>
+ <source>Bla</source>
+ <comment>X::Y::C</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>X::Y::E</name>
+ <message>
+ <location filename="main.cpp" line="78"/>
+ <location filename="main.cpp" line="79"/>
+ <source>Bla</source>
+ <comment>X::Y::E</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ico::foo::A</name>
+ <message>
+ <location filename="main.cpp" line="99"/>
+ <source>myfoo</source>
+ <comment>ico::foo::A</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/finddialog.cpp
new file mode 100644
index 0000000..454c173
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/finddialog.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "finddialog.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpwindow.h"
+
+#include <QTextBrowser>
+#include <QTextCursor>
+#include <QStatusBar>
+#include <QLineEdit>
+#include <QDateTime>
+#include <QGridLayout>
+
+CaseSensitiveModel::CaseSensitiveModel(int rows, int columns, QObject *parent)
+ : QStandardItemModel(rows, columns, parent)
+{}
+QModelIndexList CaseSensitiveModel::match(const QModelIndex &start, int role, const QVariant &value,
+ int hits, Qt::MatchFlags flags) const
+{
+ if (flags == Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap))
+ flags |= Qt::MatchCaseSensitive;
+
+ return QStandardItemModel::match(start, role, value, hits, flags);
+}
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ contentsWidget = new QWidget(this);
+ ui.setupUi(contentsWidget);
+ ui.comboFind->setModel(new CaseSensitiveModel(0, 1, ui.comboFind));
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+ l->addWidget(contentsWidget);
+
+ lastBrowser = 0;
+ onceFound = false;
+ findExpr.clear();
+
+ sb = new QStatusBar(this);
+ l->addWidget(sb);
+
+ sb->showMessage(tr("Enter the text you are looking for."));
+
+ connect(ui.findButton, SIGNAL(clicked()), this, SLOT(findButtonClicked()));
+ connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+FindDialog::~FindDialog()
+{
+}
+
+void FindDialog::findButtonClicked()
+{
+ doFind(ui.radioForward->isChecked());
+}
+
+void FindDialog::doFind(bool forward)
+{
+ QTextBrowser *browser = static_cast<QTextBrowser*>(mainWindow()->browsers()->currentBrowser());
+ sb->clearMessage();
+
+ if (ui.comboFind->currentText() != findExpr || lastBrowser != browser)
+ onceFound = false;
+ findExpr = ui.comboFind->currentText();
+
+ QTextDocument::FindFlags flags = 0;
+
+ if (ui.checkCase->isChecked())
+ flags |= QTextDocument::FindCaseSensitively;
+
+ if (ui.checkWords->isChecked())
+ flags |= QTextDocument::FindWholeWords;
+
+ QTextCursor c = browser->textCursor();
+ if (!c.hasSelection()) {
+ if (forward)
+ c.movePosition(QTextCursor::Start);
+ else
+ c.movePosition(QTextCursor::End);
+
+ browser->setTextCursor(c);
+ }
+
+ QTextDocument::FindFlags options;
+ if (forward == false)
+ flags |= QTextDocument::FindBackward;
+
+ QTextCursor found = browser->document()->find(findExpr, c, flags);
+ if (found.isNull()) {
+ if (onceFound) {
+ if (forward)
+ statusMessage(tr("Search reached end of the document"));
+ else
+ statusMessage(tr("Search reached start of the document"));
+ } else {
+ statusMessage(tr( "Text not found" ));
+ }
+ } else {
+ browser->setTextCursor(found);
+ }
+ onceFound |= !found.isNull();
+ lastBrowser = browser;
+}
+
+bool FindDialog::hasFindExpression() const
+{
+ return !findExpr.isEmpty();
+}
+
+void FindDialog::statusMessage(const QString &message)
+{
+ if (isVisible())
+ sb->showMessage(message);
+ else
+ static_cast<MainWindow*>(parent())->statusBar()->showMessage(message, 2000);
+}
+
+MainWindow *FindDialog::mainWindow() const
+{
+ return static_cast<MainWindow*>(parentWidget());
+}
+
+void FindDialog::reset()
+{
+ ui.comboFind->setFocus();
+ ui.comboFind->lineEdit()->setSelection(
+ 0, ui.comboFind->lineEdit()->text().length());
+
+ QString s = QApplication::translate("QCoreApplication", "with comment", "comment");
+ QString s = QApplication::translate("QCoreApplication", "empty comment", "");
+ QString s = QApplication::translate("QCoreApplication", "null comment", 0);
+ QString s = tr("null comment");
+
+ QString s = QApplication::translate("QCoreApplication", "encoding, using QCoreApplication", 0, QCoreApplication::UnicodeUTF8);
+ QString s = QApplication::translate("QCoreApplication", "encoding, using QApplication", 0, QApplication::UnicodeUTF8);
+
+ QString s = QApplication::translate("KÃ¥ntekst", "encoding, using QApplication", 0, QApplication::UnicodeUTF8);
+
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
new file mode 100644
index 0000000..df75baf
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
@@ -0,0 +1,158 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+int main(char **argv, int argc)
+{
+ Size size = QSize(1,1);
+}
+
+QString qt_detectRTLLanguage()
+{
+ return QApplication::tr("QT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right"
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew"
+ " and Arabic) to get proper widget layout.") == QLatin1String("RTL");
+}
+
+
+class Dialog2 : public QDialog
+{
+ Q_OBJECT
+ void func();
+ void func3();
+ int getCount() const { return 2; }
+
+};
+
+void Dialog2::func()
+{
+ int n = getCount();
+ tr("%n files", "plural form", n);
+ tr("%n cars", 0, n);
+ tr("&Find %n cars", 0, n);
+ tr("Search in %n items?", 0, n);
+ tr("%1. Search in %n items?", 0, n);
+ tr("Age: %1");
+ tr("There are %n house(s)", "Plurals and function call", getCount());
+
+
+
+
+ QCoreApplication::translate("Plurals, QCoreApplication", "%n house(s)", "Plurals and identifier", QCoreApplication::UnicodeUTF8, n);
+ QCoreApplication::translate("Plurals, QCoreApplication", "%n car(s)", "Plurals and literal number", QCoreApplication::UnicodeUTF8, 1);
+ QCoreApplication::translate("Plurals, QCoreApplication", "%n horse(s)", "Plurals and function call", QCoreApplication::UnicodeUTF8, getCount());
+
+
+
+
+
+
+
+
+ QTranslator trans;
+ trans.translate("QTranslator", "Simple");
+ trans.translate("QTranslator", "Simple", 0);
+ trans.translate("QTranslator", "Simple with comment", "with comment");
+ trans.translate("QTranslator", "Plural without comment", 0, 1);
+ trans.translate("QTranslator", "Plural with comment", "comment 1", n);
+ trans.translate("QTranslator", "Plural with comment", "comment 2", getCount());
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+
+
+
+/* This is actually a test of how many alternative ways a struct/class can be found in a source file.
+ * Due to the simple parser in lupdate, it will actually not treat the remaining lines in the define
+ * as a macro, which is a case the 'Tok_Class' parser block might not consider, and it might loop infinite
+ * if it just tries to fetch the next token until it gets a '{' or a ';'. Another pitfall is that the
+ * context of tr("func3") might not be parsed, it won't resume normal evaluation until the '{' after the function
+ * signature.
+ *
+ */
+typedef struct S_
+{
+int a;
+} S, *SPtr;
+class ForwardDecl;
+
+
+#define FT_DEFINE_SERVICE( name ) \
+ typedef struct FT_Service_ ## name ## Rec_ \
+ FT_Service_ ## name ## Rec ; \
+ typedef struct FT_Service_ ## name ## Rec_ \
+ const * FT_Service_ ## name ; \
+ struct FT_Service_ ## name ## Rec_
+
+
+/* removing this comment will break this test */
+
+void Dialog2::func3()
+{
+ tr("func3");
+}
+
+
+
+
+namespace Gui { class BaseClass {}; }
+
+
+class TestClass : QObject {
+ Q_OBJECT
+
+
+ inline QString inlineFunc1() {
+ return tr("inline function", "TestClass");
+ }
+
+ QString inlineFunc2() {
+ return tr("inline function 2", "TestClass");
+ }
+
+ static inline QString staticInlineFunc() {
+ return tr("static inline function", "TestClass");
+ }
+
+ class NoQObject : public Gui::BaseClass {
+ public:
+ inline QString hello() { return QString("hello"); }
+
+ };
+
+};
+
+
+class Testing : QObject {
+ Q_OBJECT
+
+ inline QString f1() {
+ //: this is an extra comment for the translator
+ return tr("extra-commented string");
+ return tr("not extra-commented string");
+ /*: another extra-comment */
+ return tr("another extra-commented string");
+ /*: blah! */
+ return QApplication::translate("scope", "works in translate, too", "blabb", 0);
+ }
+
+};
+
+//: extra comment for NOOP
+//: which spans multiple lines
+QT_TRANSLATE_NOOP("scope", "string") // 4.4 says the line of this is at the next statement
+//: extra comment for NOOP3
+QT_TRANSLATE_NOOP3_UTF8("scope", "string", "comment") // 4.4 doesn't see this
+
+QT_TRANSLATE_NOOP("scope", "string " // this is an interleaved comment
+ "continuation on next line")
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.pro
new file mode 100644
index 0000000..4582705
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main.cpp
+SOURCES += finddialog.cpp
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
new file mode 100644
index 0000000..9386c19
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Dialog2</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="29"/>
+ <source>%n files</source>
+ <comment>plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="30"/>
+ <source>%n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="31"/>
+ <source>&amp;Find %n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="32"/>
+ <source>Search in %n items?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="33"/>
+ <source>%1. Search in %n items?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="34"/>
+ <source>Age: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="35"/>
+ <source>There are %n house(s)</source>
+ <comment>Plurals and function call</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="102"/>
+ <source>func3</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="finddialog.cpp" line="57"/>
+ <source>Enter the text you are looking for.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="107"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="147"/>
+ <source>null comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>KÃ¥ntekst</name>
+ <message utf8="true">
+ <location filename="finddialog.cpp" line="152"/>
+ <source>encoding, using QApplication</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Plurals, QCoreApplication</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="40"/>
+ <source>%n house(s)</source>
+ <comment>Plurals and identifier</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="41"/>
+ <source>%n car(s)</source>
+ <comment>Plurals and literal number</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="42"/>
+ <source>%n horse(s)</source>
+ <comment>Plurals and function call</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="main.cpp" line="10"/>
+ <source>QT_LAYOUT_DIRECTION</source>
+ <comment>Translate this string to the string &apos;LTR&apos; in left-to-right languages or to &apos;RTL&apos; in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QCoreApplication</name>
+ <message>
+ <location filename="finddialog.cpp" line="144"/>
+ <source>with comment</source>
+ <comment>comment</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="145"/>
+ <source>empty comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="146"/>
+ <source>null comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="149"/>
+ <source>encoding, using QCoreApplication</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="finddialog.cpp" line="150"/>
+ <source>encoding, using QApplication</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QTranslator</name>
+ <message>
+ <location filename="main.cpp" line="52"/>
+ <location filename="main.cpp" line="53"/>
+ <source>Simple</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="54"/>
+ <source>Simple with comment</source>
+ <comment>with comment</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="55"/>
+ <source>Plural without comment</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="56"/>
+ <source>Plural with comment</source>
+ <comment>comment 1</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.cpp" line="57"/>
+ <source>Plural with comment</source>
+ <comment>comment 2</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>TestClass</name>
+ <message>
+ <location filename="main.cpp" line="116"/>
+ <source>inline function</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="120"/>
+ <source>inline function 2</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="124"/>
+ <source>static inline function</source>
+ <comment>TestClass</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>Testing</name>
+ <message>
+ <location filename="main.cpp" line="141"/>
+ <source>extra-commented string</source>
+ <extracomment>this is an extra comment for the translator</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="142"/>
+ <source>not extra-commented string</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="144"/>
+ <source>another extra-commented string</source>
+ <extracomment>another extra-comment</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>scope</name>
+ <message numerus="yes">
+ <location filename="main.cpp" line="146"/>
+ <source>works in translate, too</source>
+ <comment>blabb</comment>
+ <extracomment>blah!</extracomment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="153"/>
+ <source>string</source>
+ <extracomment>extra comment for NOOP which spans multiple lines</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="155"/>
+ <source>string</source>
+ <comment>comment</comment>
+ <extracomment>extra comment for NOOP3</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="157"/>
+ <source>string continuation on next line</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt
new file mode 100644
index 0000000..e3f7926
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt
@@ -0,0 +1,7 @@
+.*/lupdate/testdata/good/parsecpp2/main.cpp:10: Excess closing brace .*
+
+.*/lupdate/testdata/good/parsecpp2/main.cpp:14: Excess closing brace .*
+
+.*/lupdate/testdata/good/parsecpp2/main.cpp:20: Excess closing brace .*
+
+.*/lupdate/testdata/good/parsecpp2/main.cpp:24: Excess closing brace .*
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
new file mode 100644
index 0000000..eb4a09b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
@@ -0,0 +1,24 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+// nothing here
+
+// sickness: multi-\
+line c++ comment } (with brace)
+
+#define This is a closing brace } which was ignored
+} // complain here
+
+#define This is another \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another /* comment in } define */\
+ something /* comment )
+ spanning {multiple} lines */ \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another // comment in } define \
+ something } comment
+} // complain here
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main2.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main2.cpp
new file mode 100644
index 0000000..1c72ac2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main2.cpp
@@ -0,0 +1,28 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+// nothing here
+
+// sickness: multi-\
+line c++ comment } (with brace)
+
+#define This is a closing brace } which was ignored
+} // complain here
+
+#define This is another \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another /* comment in } define */\
+ something /* comment )
+ spanning {multiple} lines */ \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another // comment in } define \
+ something } comment
+} // complain here
+
+char somestring[] = "\
+ continued\n\
+ here and \"quoted\" to activate\n";
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main3.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main3.cpp
new file mode 100644
index 0000000..731d5cdf
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main3.cpp
@@ -0,0 +1,42 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+// nothing here
+
+// sickness: multi-\
+line c++ comment } (with brace)
+
+#define This is a closing brace } which was ignored
+} // complain here
+
+#define This is another \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another /* comment in } define */\
+ something /* comment )
+ spanning {multiple} lines */ \
+ closing brace } which was ignored
+} // complain here
+
+#define This is another // comment in } define \
+ something } comment
+} // complain here
+
+char somestring[] = "\
+ continued\n\
+ here and \"quoted\" to activate\n";
+
+ NSString *scriptSource = @"\
+ on SetupNewMail(theRecipientAddress, theSubject, theContent, theAttachmentPath)\n\
+ tell application \"Mail\" to activate\n\
+ tell application \"Mail\"\n\
+ set theMessage to make new outgoing message with properties {visible:true, subject:theSubject, content:theContent}\n\
+ tell theMessage\n\
+ make new to recipient at end of to recipients with properties {address:theRecipientAddress}\n\
+ end tell\n\
+ tell content of theMessage\n\
+ make new attachment with properties {file name:theAttachmentPath} at after last paragraph\n\
+ end tell\n\
+ end tell\n\
+ end SetupNewMail\n";
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.pro
new file mode 100644
index 0000000..7547a8d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES = main.cpp
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
new file mode 100644
index 0000000..07a7469
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejava/main.java b/tests/auto/linguist/lupdate/testdata/good/parsejava/main.java
new file mode 100644
index 0000000..07681d2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejava/main.java
@@ -0,0 +1,54 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+package com.trolltech.examples;
+
+public class I18N extends QDialog {
+
+ private class MainWindow extends QMainWindow {
+ private String foo = tr("pack class class");
+
+ //: extra comment for t-tor
+ private String bar = tr("pack class class extra");
+
+ public MainWindow(QWidget parent) {
+ super(parent);
+
+ listWidget = new QListWidget();
+ listWidget.addItem(tr("pack class class method"));
+
+ }
+ }
+
+ public I18N(QWidget parent) {
+ super(parent, new Qt.WindowFlags(Qt.WindowType.WindowStaysOnTopHint));
+
+ tr("pack class method");
+
+ tr("QT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right" +
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew" +
+ " and Arabic) to get proper widget layout.");
+
+ tr("%n files", "plural form", n);
+ tr("%n cars", null, n);
+ tr("Age: %1");
+ tr("There are %n house(s)", "Plurals and function call", getCount());
+
+ QTranslator trans;
+ trans.translate("QTranslator", "Simple");
+ trans.translate("QTranslator", "Simple", null);
+ trans.translate("QTranslator", "Simple with comment", "with comment");
+ trans.translate("QTranslator", "Plural without comment", null, 1);
+ trans.translate("QTranslator", "Plural with comment", "comment 1", n);
+ trans.translate("QTranslator", "Plural with comment", "comment 2", getCount());
+
+ /*: with extra comment! */
+ QCoreApplication.translate("Plurals, QCoreApplication", "%n house(s)", "Plurals and identifier", n);
+
+ // FIXME: This will fail.
+ //QApplication.tr("QT_LAYOUT_DIRECTION", "scoped to qapp");
+
+ }
+
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejava/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsejava/project.pro
new file mode 100644
index 0000000..7e64c80
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejava/project.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = Java
+
+SOURCES += main.java
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejava/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsejava/project.ts.result
new file mode 100644
index 0000000..69c0a00
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsejava/project.ts.result
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Plurals, QCoreApplication</name>
+ <message numerus="yes">
+ <location filename="main.java" line="47"/>
+ <source>%n house(s)</source>
+ <comment>Plurals and identifier</comment>
+ <extracomment>with extra comment!</extracomment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>QTranslator</name>
+ <message>
+ <location filename="main.java" line="39"/>
+ <location filename="main.java" line="40"/>
+ <source>Simple</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.java" line="41"/>
+ <source>Simple with comment</source>
+ <comment>with comment</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="42"/>
+ <source>Plural without comment</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="43"/>
+ <source>Plural with comment</source>
+ <comment>comment 1</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="44"/>
+ <source>Plural with comment</source>
+ <comment>comment 2</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>com.trolltech.examples.I18N</name>
+ <message>
+ <location filename="main.java" line="26"/>
+ <source>pack class method</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.java" line="31"/>
+ <source>QT_LAYOUT_DIRECTION</source>
+ <comment>Translate this string to the string &apos;LTR&apos; in left-to-right languages or to &apos;RTL&apos; in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="33"/>
+ <source>%n files</source>
+ <comment>plural form</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="34"/>
+ <source>%n cars</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="main.java" line="35"/>
+ <source>Age: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="main.java" line="36"/>
+ <source>There are %n house(s)</source>
+ <comment>Plurals and function call</comment>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>com.trolltech.examples.I18N$MainWindow</name>
+ <message>
+ <location filename="main.java" line="9"/>
+ <source>pack class class</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.java" line="12"/>
+ <source>pack class class extra</source>
+ <extracomment>extra comment for t-tor</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.java" line="18"/>
+ <source>pack class class method</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseui/project.pro b/tests/auto/linguist/lupdate/testdata/good/parseui/project.pro
new file mode 100644
index 0000000..bdc06e7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseui/project.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32 : system(del $$TRANSLATIONS)
+ unix : system(rm $$TRANSLATIONS)
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseui/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parseui/project.ts.result
new file mode 100644
index 0000000..ddf58c3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseui/project.ts.result
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="27"/>
+ <source>Qt Assistant - Finn text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message utf8="true">
+ <location filename="project.ui" line="30"/>
+ <source>Finn tekst - Der BjÞrn möchte auch mal.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/parseui/project.ui b/tests/auto/linguist/lupdate/testdata/good/parseui/project.ui
new file mode 100644
index 0000000..19fcaf5
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parseui/project.ui
@@ -0,0 +1,44 @@
+<ui version="4.0" >
+ <author></author>
+ <comment>*********************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+*********************************************************************</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Qt Assistant - Finn text</string>
+ </property>
+ <property name="height" >
+ <string>Finn tekst - Der BjÞrn möchte auch mal.</string>
+ </property>
+ </widget>
+ <tabstops>
+ <tabstop>comboFind</tabstop>
+ <tabstop>checkWords</tabstop>
+ <tabstop>checkCase</tabstop>
+ <tabstop>radioForward</tabstop>
+ <tabstop>radioBackward</tabstop>
+ <tabstop>findButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp b/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp
new file mode 100644
index 0000000..d845853
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/prefix/main.cpp
@@ -0,0 +1,17 @@
+
+
+
+QString foo()
+{
+ QCoreApplication::translate("Foo","XXX","YYY");
+}
+
+Foo::Foo()
+{
+ tr("CTOR");
+}
+
+void Foo::bar()
+{
+ tr("BAR");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/prefix/project.pro b/tests/auto/linguist/lupdate/testdata/good/prefix/project.pro
new file mode 100644
index 0000000..7547a8d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/prefix/project.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES = main.cpp
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result
new file mode 100644
index 0000000..5ced00d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/prefix/project.ts.result
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>Foo</name>
+ <message>
+ <location filename="main.cpp" line="6"/>
+ <source>XXX</source>
+ <comment>YYY</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="11"/>
+ <source>CTOR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="16"/>
+ <source>BAR</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/preprocess/main.cpp b/tests/auto/linguist/lupdate/testdata/good/preprocess/main.cpp
new file mode 100644
index 0000000..9abfa5e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/preprocess/main.cpp
@@ -0,0 +1,37 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
+
+
+void func2() {
+#ifdef Q_OS_WIN
+ QApplication::tr("Kind", "Windows only, see Type");
+#else
+ QApplication::tr("Type", "Not used on windows, see Kind");
+#endif
+
+}
+
+
+
+void stringconcatenation()
+{
+ QApplication::tr("One string,"
+ " three"
+ " lines");
+
+ QApplication::tr("a backslash followed by newline \
+should be ignored \
+and the next line should be syntactically considered to be \
+on the same line");
+
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/preprocess/project.pro b/tests/auto/linguist/lupdate/testdata/good/preprocess/project.pro
new file mode 100644
index 0000000..012c7e0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/preprocess/project.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main.cpp
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm -f $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/preprocess/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/preprocess/project.ts.result
new file mode 100644
index 0000000..3aec045
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/preprocess/project.ts.result
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="main.cpp" line="6"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="14"/>
+ <source>Kind</source>
+ <comment>Windows only, see Type</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="16"/>
+ <source>Type</source>
+ <comment>Not used on windows, see Kind</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="25"/>
+ <source>One string, three lines</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="29"/>
+ <source>a backslash followed by newline should be ignored and the next line should be syntactically considered to be on the same line</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/main.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/main.cpp
new file mode 100644
index 0000000..236bbe7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/main.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/main_mac.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_mac.cpp
new file mode 100644
index 0000000..845aaa6
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_mac.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello macworld", "mac-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/main_unix.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_unix.cpp
new file mode 100644
index 0000000..229e154
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_unix.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello unixworld", "unix-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/main_win.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_win.cpp
new file mode 100644
index 0000000..4eb39f7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/main_win.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello windowsworld", "Windows-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsing/project.pro
new file mode 100644
index 0000000..3078817
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/project.pro
@@ -0,0 +1,40 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+# Try to reference a variable that does not exist:
+MYVAR=$$THIS_VARIABLE_IS_NOT_DEFINED
+
+SOURCES += main.cpp
+
+win32 {
+ SOURCES += main_win.cpp
+}
+
+unix {
+ SOURCES += main_unix.cpp
+}
+
+mac {
+ SOURCES += main_mac.cpp
+}
+
+SOURCES += wildcard/main*.cpp \
+# yadiyada it should also parse the next line
+ wildcard*.cpp
+
+
+DEPENDPATH = vpaths/dependpath
+
+# The purpose of this test is to test expansion of environment variables,
+# and to test if the DEPENDPATH variable is considered correctly.
+if (exists($$member($$(PATH), 0))) {
+ SOURCES += main_dependpath.cpp
+}
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm -f $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsing/project.ts.result
new file mode 100644
index 0000000..ef98596
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/project.ts.result
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="main.cpp" line="6"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main_mac.cpp" line="6"/>
+ <source>Hello macworld</source>
+ <comment>mac-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main_unix.cpp" line="6"/>
+ <source>Hello unixworld</source>
+ <comment>unix-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main_win.cpp" line="6"/>
+ <source>Hello windowsworld</source>
+ <comment>Windows-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="wildcard/main1.cpp" line="6"/>
+ <source>Hello world</source>
+ <comment>wildcard/main1.cpp</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="wildcard/mainfile.cpp" line="6"/>
+ <source>Hello world</source>
+ <comment>wildcard/main2.cpp</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="wildcard1.cpp" line="6"/>
+ <source>Hello world</source>
+ <comment>wildcard1.cpp</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="wildcard99.cpp" line="6"/>
+ <source>Hello world</source>
+ <comment>wildcard99.cpp</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QCoreApplication</name>
+ <message>
+ <location filename="vpaths/dependpath/main_dependpath.cpp" line="7"/>
+ <source>Hello from a DEPENDPATH</source>
+ <comment>See if the DEPENDPATH thing works</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/vpaths/dependpath/main_dependpath.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/vpaths/dependpath/main_dependpath.cpp
new file mode 100644
index 0000000..f019c79
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/vpaths/dependpath/main_dependpath.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+int main(int argc, char **argv)
+{
+ QCoreApplication::tr("Hello from a DEPENDPATH", "See if the DEPENDPATH thing works");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/main1.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/main1.cpp
new file mode 100644
index 0000000..506ae42
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/main1.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "wildcard/main1.cpp");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/mainfile.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/mainfile.cpp
new file mode 100644
index 0000000..f4cd00a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard/mainfile.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "wildcard/main2.cpp");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard1.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard1.cpp
new file mode 100644
index 0000000..c7790c5
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard1.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "wildcard1.cpp");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard99.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard99.cpp
new file mode 100644
index 0000000..93febda
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing/wildcard99.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "wildcard99.cpp");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/a b/tests/auto/linguist/lupdate/testdata/good/proparsing2/a
new file mode 100644
index 0000000..5966392
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/a
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("a");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/a.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing2/a.cpp
new file mode 100644
index 0000000..1d80ed3
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/a.cpp
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("a.cpp");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/b b/tests/auto/linguist/lupdate/testdata/good/proparsing2/b
new file mode 100644
index 0000000..d0fe066
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/b
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("b");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/b.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing2/b.cpp
new file mode 100644
index 0000000..a5c386d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/b.cpp
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("b.cpp");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/e b/tests/auto/linguist/lupdate/testdata/good/proparsing2/e
new file mode 100644
index 0000000..66e89a8
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/e
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("e");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/f/g.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsing2/f/g.cpp
new file mode 100644
index 0000000..d86bee2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/f/g.cpp
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("f/g.cpp");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/files-cc.txt b/tests/auto/linguist/lupdate/testdata/good/proparsing2/files-cc.txt
new file mode 100644
index 0000000..5bd8d03
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/files-cc.txt
@@ -0,0 +1 @@
+a.cpp b.cpp
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.pro
new file mode 100644
index 0000000..1d6895a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.pro
@@ -0,0 +1,42 @@
+# This is to test if quoted elements with spaces are treated as elements (and not splitted up due
+# to the spaces.)
+# It also tries to verify the behaviour of combining quoted and non-quoted elements with literals.
+#
+
+TEMPLATE = app
+LANGUAGE = C++
+
+QUOTED = $$quote(variable with spaces)
+VERSIONAB = "a.b"
+VAB = $$split(VERSIONAB, ".")
+V += $$VAB
+V += $$QUOTED
+
+# this is just to make p4 happy with no spaces in filename
+SOURCES += $$member(V,0,1)
+V2 = $$member(V,2)
+V2S = $$split(V2, " ")
+SOURCES += $$join(V2S,"_")
+message($$SOURCES)
+# SOURCES += [a, b, variable_with_spaces]
+
+LIST = d e f
+L2 = x/$$LIST/g.cpp
+SOURCES += $$L2
+# SOURCES += [x/d, e, f/g.cpp]
+
+QUOTEDEXTRA = x/$$QUOTED/z
+Q3 = $$split(QUOTEDEXTRA, " ")
+SOURCES += $$Q3
+# SOURCES += [x/variable, with, spaces/z]
+
+win32: SOURCES += $$system(type files-cc.txt)
+unix: SOURCES += $$system(cat files-cc.txt)
+
+TRANSLATIONS += project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.ts.result
new file mode 100644
index 0000000..2e60696
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/project.ts.result
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QLineEdit</name>
+ <message>
+ <location filename="a" line="3"/>
+ <source>a</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="a.cpp" line="3"/>
+ <source>a.cpp</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="b" line="3"/>
+ <source>b</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="b.cpp" line="3"/>
+ <source>b.cpp</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="e" line="3"/>
+ <source>e</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="f/g.cpp" line="3"/>
+ <source>f/g.cpp</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="spaces/z" line="3"/>
+ <source>spaces/z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="variable_with_spaces" line="3"/>
+ <source>variable with spaces</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="with" line="3"/>
+ <source>with</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="x/d" line="3"/>
+ <source>x/d</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="x/variable" line="3"/>
+ <source>x/variable</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/spaces/z b/tests/auto/linguist/lupdate/testdata/good/proparsing2/spaces/z
new file mode 100644
index 0000000..34364d6
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/spaces/z
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("spaces/z");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/variable_with_spaces b/tests/auto/linguist/lupdate/testdata/good/proparsing2/variable_with_spaces
new file mode 100644
index 0000000..cf56fc4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/variable_with_spaces
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("variable with spaces");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/with b/tests/auto/linguist/lupdate/testdata/good/proparsing2/with
new file mode 100644
index 0000000..a156ca1
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/with
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("with");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/d b/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/d
new file mode 100644
index 0000000..e2effde
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/d
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("x/d");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/variable b/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/variable
new file mode 100644
index 0000000..a86e387
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsing2/x/variable
@@ -0,0 +1,4 @@
+QString func()
+{
+ return QLineEdit::tr("x/variable");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/common.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/common.pri
new file mode 100644
index 0000000..ba3169d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/common.pri
@@ -0,0 +1 @@
+include(main.pri)
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.cpp
new file mode 100644
index 0000000..236bbe7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.pri
new file mode 100644
index 0000000..a8d4a2b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/common/main.pri
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += $$PWD/main.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/mac.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/mac.pri
new file mode 100644
index 0000000..549eab5
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/mac.pri
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += $$PWD/main_mac.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/main_mac.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/main_mac.cpp
new file mode 100644
index 0000000..845aaa6
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/mac/main_mac.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello macworld", "mac-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.pro
new file mode 100644
index 0000000..3810a02
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+include(win/win.pri)
+include(mac/mac.pri)
+include(unix/unix.pri)
+include (common/common.pri) # Important: keep the space before the '('
+include(relativity/relativity.pri)
+
+message($$SOURCES)
+TRANSLATIONS = project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm $$TRANSLATIONS)
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.ts.result
new file mode 100644
index 0000000..c64ba82
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/project.ts.result
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="common/main.cpp" line="6"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mac/main_mac.cpp" line="6"/>
+ <source>Hello macworld</source>
+ <comment>mac-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="relativity/relativity.cpp" line="6"/>
+ <source>relativity.pri</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="unix/main_unix.cpp" line="6"/>
+ <source>Hello unixworld</source>
+ <comment>unix-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="win/main_win.cpp" line="6"/>
+ <source>Hello windowsworld</source>
+ <comment>Windows-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.cpp
new file mode 100644
index 0000000..83ae7d5
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("relativity.pri", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.pri
new file mode 100644
index 0000000..42658f0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/relativity.pri
@@ -0,0 +1,3 @@
+# Lets test how well the proparser can walk the tree of includes...
+
+include(sub/sub.pri)
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub/sub.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub/sub.pri
new file mode 100644
index 0000000..17055a7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub/sub.pri
@@ -0,0 +1 @@
+include(../sub2/sub2.pri)
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub2/sub2.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub2/sub2.pri
new file mode 100644
index 0000000..e2876b1
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/relativity/sub2/sub2.pri
@@ -0,0 +1,2 @@
+SOURCES += $$PWD/../relativity.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/main_unix.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/main_unix.cpp
new file mode 100644
index 0000000..229e154
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/main_unix.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello unixworld", "unix-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/unix.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/unix.pri
new file mode 100644
index 0000000..99777d7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/unix/unix.pri
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += $$PWD/main_unix.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/main_win.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/main_win.cpp
new file mode 100644
index 0000000..4eb39f7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/main_win.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello windowsworld", "Windows-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/win.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/win.pri
new file mode 100644
index 0000000..742417c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpri/win/win.pri
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += $$PWD/main_win.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.pro
new file mode 100644
index 0000000..4de6622
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.pro
@@ -0,0 +1,3 @@
+TEMPLATE =subdirs
+
+SUBDIRS = sub1
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.ts.result
new file mode 100644
index 0000000..5914d0b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/project.ts.result
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="sub1/main.cpp" line="6"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/main.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/main.cpp
new file mode 100644
index 0000000..236bbe7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/main.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/sub1.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/sub1.pro
new file mode 100644
index 0000000..1d50c2b
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubdirs/sub1/sub1.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main.cpp
+
+TRANSLATIONS += ../project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm -f $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/common.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/common.pro
new file mode 100644
index 0000000..a8b3106
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/common.pro
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/main.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/main.cpp
new file mode 100644
index 0000000..236bbe7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/common/main.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world", "Platform-independent file");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/mac.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/mac.pro
new file mode 100644
index 0000000..87478bf
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/mac.pro
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main_mac.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/main_mac.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/main_mac.cpp
new file mode 100644
index 0000000..845aaa6
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/mac/main_mac.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello macworld", "mac-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.pro
new file mode 100644
index 0000000..668ecf4
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.pro
@@ -0,0 +1,7 @@
+TEMPLATE = subdirs
+SUBDIRS = win mac unix common
+
+exists( project.ts ) {
+ win32: system(del project.ts)
+ unix: system(rm project.ts)
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.ts.result
new file mode 100644
index 0000000..c0352fb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/project.ts.result
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="win/main_win.cpp" line="6"/>
+ <source>Hello windowsworld</source>
+ <comment>Windows-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mac/main_mac.cpp" line="6"/>
+ <source>Hello macworld</source>
+ <comment>mac-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="unix/main_unix.cpp" line="6"/>
+ <source>Hello unixworld</source>
+ <comment>unix-only file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="common/main.cpp" line="6"/>
+ <source>Hello world</source>
+ <comment>Platform-independent file</comment>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/main_unix.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/main_unix.cpp
new file mode 100644
index 0000000..229e154
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/main_unix.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello unixworld", "unix-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/unix.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/unix.pro
new file mode 100644
index 0000000..d0ebec7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/unix/unix.pro
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main_unix.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/main_win.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/main_win.cpp
new file mode 100644
index 0000000..4eb39f7
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/main_win.cpp
@@ -0,0 +1,10 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello windowsworld", "Windows-only file");
+}
+
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/win.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/win.pro
new file mode 100644
index 0000000..a9a9751
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/proparsingsubs/win/win.pro
@@ -0,0 +1,5 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main_win.cpp
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.pro b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.pro
new file mode 100644
index 0000000..28ba291
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+FORMS += project.ui
+
+TRANSLATIONS = project.ts
+
+# Copy the ts to a temp file because:
+# 1. The depot file is usually read-only
+# 2. We don't want to modify the original file, since then it won't be possible to run the test twice
+# without reverting the original file again.
+
+win32: system(copy /Y project.ts.before $$TRANSLATIONS)
+unix: system(cp -f project.ts.before $$TRANSLATIONS && chmod a+w $$TRANSLATIONS)
diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.before
new file mode 100644
index 0000000..f06c22c
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.before
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="20"/>
+ <source>Test similarity</source>
+ <translation type="unfinished">Test likhet (test1)</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="23"/>
+ <source>Similarity should have kicked in here!</source>
+ <translation type="unfinished">Test likhet (test2)</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result
new file mode 100644
index 0000000..d65110a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <source>Test similarity</source>
+ <translation type="obsolete">Test likhet (test1)</translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="20"/>
+ <source>This should not be considered to be more or less equal to the corresponding one in the ts file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="23"/>
+ <source>Here, similarity should kick in!</source>
+ <oldsource>Similarity should have kicked in here!</oldsource>
+ <translation type="unfinished">Test likhet (test2)</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui
new file mode 100644
index 0000000..0d0defd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui
@@ -0,0 +1,26 @@
+<ui version="4.0" >
+ <author></author>
+ <comment><!--
+*********************************************************************
+**
+** Do not change the location (linenumber) of the <string> elements in this file!
+** That will make the test break!
+**
+** If you need to add some tests, please add them to the end of the file!
+**
+**
+*********************************************************************
+-->
+</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="test1">
+ <!-- If the sourcetext is not similar to the vernacular sourcetext, mark the old one as obsolete and the new one as unfinished -->
+ <string>This should not be considered to be more or less equal to the corresponding one in the ts file.</string>
+ </property>
+ <property name="test2">
+ <string>Here, similarity should kick in!</string>
+ </property>
+ </widget>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/output_ts/lupdatecmd b/tests/auto/linguist/lupdate/testdata/output_ts/lupdatecmd
new file mode 100644
index 0000000..80319de
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/output_ts/lupdatecmd
@@ -0,0 +1,5 @@
+# Add the command that lupdate should run here. If it can't find anything it will default to
+# 'lupdate project.pro -ts project.ts'
+
+# lupdate project.pro
+lupdate toplevel/library/tools/tools.pro
diff --git a/tests/auto/linguist/lupdate/testdata/output_ts/project.ts.result b/tests/auto/linguist/lupdate/testdata/output_ts/project.ts.result
new file mode 100644
index 0000000..7fde820
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/output_ts/project.ts.result
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>QApplication</name>
+ <message>
+ <location filename="../main.cpp" line="6"/>
+ <source>Hello world</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/main.cpp b/tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/main.cpp
new file mode 100644
index 0000000..477f5ec
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/main.cpp
@@ -0,0 +1,9 @@
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+
+void func1() {
+ QApplication::tr("Hello world");
+}
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/tools.pro b/tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/tools.pro
new file mode 100644
index 0000000..ec6c01d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/tools.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+LANGUAGE = C++
+
+SOURCES += main.cpp
+
+TRANSLATIONS += translations/project.ts
+
+exists( $$TRANSLATIONS ) {
+ win32: system(del $$TRANSLATIONS)
+ unix: system(rm -f $$TRANSLATIONS)
+}
+
diff --git a/tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/translations/readme.txt b/tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/translations/readme.txt
new file mode 100644
index 0000000..83adcd2
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/output_ts/toplevel/library/tools/translations/readme.txt
@@ -0,0 +1,2 @@
+This is just a dummy file so that GIT creates this folder
+
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/bar.ts.result b/tests/auto/linguist/lupdate/testdata/recursivescan/bar.ts.result
new file mode 100644
index 0000000..e132342
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/bar.ts.result
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="sub/finddialog.cpp" line="57"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="107"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/foo.ts.result b/tests/auto/linguist/lupdate/testdata/recursivescan/foo.ts.result
new file mode 100644
index 0000000..6646014
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/foo.ts.result
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name>FindDialog</name>
+ <message>
+ <location filename="project.ui" line="27"/>
+ <source>Qt Assistant - Finn text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="project.ui" line="30"/>
+ <source>Finn tekst</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="57"/>
+ <source>Enter the text you want to find.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="107"/>
+ <source>Search reached end of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="109"/>
+ <source>Search reached start of the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="sub/finddialog.cpp" line="111"/>
+ <source>Text not found</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="main.cpp" line="12"/>
+ <source>
+newline at the start</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="13"/>
+ <source>newline at the end
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="14"/>
+ <source>newline and space at the end
+ </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="15"/>
+ <source>space and newline at the end
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="16"/>
+ <source> Tab at the start and newline at the end
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="17"/>
+ <source>
+ newline and tab at the start</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="18"/>
+ <source> space and tab at the start</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="19"/>
+ <source> space_first</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="main.cpp" line="20"/>
+ <source>space_last </source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>text/c++</name>
+ <message>
+ <location filename="sub/filetypes/main.c++" line="6"/>
+ <source>test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>text/cpp</name>
+ <message>
+ <location filename="sub/filetypes/main.cpp" line="6"/>
+ <source>test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>text/cxx</name>
+ <message>
+ <location filename="sub/filetypes/main.cxx" line="6"/>
+ <source>test</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/main.cpp b/tests/auto/linguist/lupdate/testdata/recursivescan/main.cpp
new file mode 100644
index 0000000..905cccd
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/main.cpp
@@ -0,0 +1,22 @@
+#include <QApplication>
+#include <QDebug>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QTranslator translator;
+ translator.load("whitespace");
+ app.installTranslator(&translator);
+
+ QObject::tr("\nnewline at the start");
+ QObject::tr("newline at the end\n");
+ QObject::tr("newline and space at the end\n ");
+ QObject::tr("space and newline at the end \n");
+ QObject::tr("\tTab at the start and newline at the end\n");
+ QObject::tr("\n\tnewline and tab at the start");
+ QObject::tr(" \tspace and tab at the start");
+ QObject::tr(" space_first");
+ QObject::tr("space_last ");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/project.ui b/tests/auto/linguist/lupdate/testdata/recursivescan/project.ui
new file mode 100644
index 0000000..e03a66e
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/project.ui
@@ -0,0 +1,44 @@
+<ui version="4.0" >
+ <author></author>
+ <comment>*********************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+*********************************************************************</comment>
+ <exportmacro></exportmacro>
+ <class>FindDialog</class>
+ <widget class="QWidget" name="FindDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>172</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Qt Assistant - Finn text</string>
+ </property>
+ <property name="height" >
+ <string>Finn tekst</string>
+ </property>
+ </widget>
+ <tabstops>
+ <tabstop>comboFind</tabstop>
+ <tabstop>checkWords</tabstop>
+ <tabstop>checkCase</tabstop>
+ <tabstop>radioForward</tabstop>
+ <tabstop>radioBackward</tabstop>
+ <tabstop>findButton</tabstop>
+ <tabstop>closeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.c++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.c++
new file mode 100644
index 0000000..4da3ded
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.c++
@@ -0,0 +1,8 @@
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QApplication::translate("text/c++", "test");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cpp b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cpp
new file mode 100644
index 0000000..9b3207d
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cpp
@@ -0,0 +1,8 @@
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QApplication::translate("text/cpp", "test");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cxx b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cxx
new file mode 100644
index 0000000..b741ff0
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/filetypes/main.cxx
@@ -0,0 +1,8 @@
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QApplication::translate("text/cxx", "test");
+ return app.exec();
+}
diff --git a/tests/auto/linguist/lupdate/testdata/recursivescan/sub/finddialog.cpp b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/finddialog.cpp
new file mode 100644
index 0000000..8e92a2a
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/recursivescan/sub/finddialog.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "finddialog.h"
+#include "mainwindow.h"
+#include "tabbedbrowser.h"
+#include "helpwindow.h"
+
+#include <QTextBrowser>
+#include <QTextCursor>
+#include <QStatusBar>
+#include <QLineEdit>
+#include <QDateTime>
+#include <QGridLayout>
+
+CaseSensitiveModel::CaseSensitiveModel(int rows, int columns, QObject *parent)
+ : QStandardItemModel(rows, columns, parent)
+{}
+QModelIndexList CaseSensitiveModel::match(const QModelIndex &start, int role, const QVariant &value,
+ int hits, Qt::MatchFlags flags) const
+{
+ if (flags == Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap))
+ flags |= Qt::MatchCaseSensitive;
+
+ return QStandardItemModel::match(start, role, value, hits, flags);
+}
+
+FindDialog::FindDialog(MainWindow *parent)
+ : QDialog(parent)
+{
+ contentsWidget = new QWidget(this);
+ ui.setupUi(contentsWidget);
+ ui.comboFind->setModel(new CaseSensitiveModel(0, 1, ui.comboFind));
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+ l->addWidget(contentsWidget);
+
+ lastBrowser = 0;
+ onceFound = false;
+ findExpr.clear();
+
+ sb = new QStatusBar(this);
+ l->addWidget(sb);
+
+ sb->showMessage(tr("Enter the text you want to find."));
+
+ connect(ui.findButton, SIGNAL(clicked()), this, SLOT(findButtonClicked()));
+ connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+FindDialog::~FindDialog()
+{
+}
+
+void FindDialog::findButtonClicked()
+{
+ doFind(ui.radioForward->isChecked());
+}
+
+void FindDialog::doFind(bool forward)
+{
+ QTextBrowser *browser = static_cast<QTextBrowser*>(mainWindow()->browsers()->currentBrowser());
+ sb->clearMessage();
+
+ if (ui.comboFind->currentText() != findExpr || lastBrowser != browser)
+ onceFound = false;
+ findExpr = ui.comboFind->currentText();
+
+ QTextDocument::FindFlags flags = 0;
+
+ if (ui.checkCase->isChecked())
+ flags |= QTextDocument::FindCaseSensitively;
+
+ if (ui.checkWords->isChecked())
+ flags |= QTextDocument::FindWholeWords;
+
+ QTextCursor c = browser->textCursor();
+ if (!c.hasSelection()) {
+ if (forward)
+ c.movePosition(QTextCursor::Start);
+ else
+ c.movePosition(QTextCursor::End);
+
+ browser->setTextCursor(c);
+ }
+
+ QTextDocument::FindFlags options;
+ if (forward == false)
+ flags |= QTextDocument::FindBackward;
+
+ QTextCursor found = browser->document()->find(findExpr, c, flags);
+ if (found.isNull()) {
+ if (onceFound) {
+ if (forward)
+ statusMessage(tr("Search reached end of the document"));
+ else
+ statusMessage(tr("Search reached start of the document"));
+ } else {
+ statusMessage(tr( "Text not found" ));
+ }
+ } else {
+ browser->setTextCursor(found);
+ }
+ onceFound |= !found.isNull();
+ lastBrowser = browser;
+}
+
+bool FindDialog::hasFindExpression() const
+{
+ return !findExpr.isEmpty();
+}
+
+void FindDialog::statusMessage(const QString &message)
+{
+ if (isVisible())
+ sb->showMessage(message);
+ else
+ static_cast<MainWindow*>(parent())->statusBar()->showMessage(message, 2000);
+}
+
+MainWindow *FindDialog::mainWindow() const
+{
+ return static_cast<MainWindow*>(parentWidget());
+}
+
+void FindDialog::reset()
+{
+ ui.comboFind->setFocus();
+ ui.comboFind->lineEdit()->setSelection(
+ 0, ui.comboFind->lineEdit()->text().length());
+}
diff --git a/tests/auto/linguist/lupdate/testlupdate.cpp b/tests/auto/linguist/lupdate/testlupdate.cpp
new file mode 100644
index 0000000..c80dd54
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testlupdate.cpp
@@ -0,0 +1,116 @@
+#include "testlupdate.h"
+#include <stdlib.h>
+#include <QtGui/QApplication>
+#include <QtCore/QProcess>
+#include <QtCore/QTimer>
+#include <QtCore/QDir>
+
+#ifdef Q_OS_WIN32
+# include <windows.h>
+#endif
+
+#include <QtTest/QtTest>
+
+
+TestLUpdate::TestLUpdate()
+{
+ childProc = 0;
+ m_cmdLupdate = QLatin1String("lupdate");
+ m_cmdQMake = QLatin1String("qmake");
+}
+
+TestLUpdate::~TestLUpdate()
+{
+ if (childProc)
+ delete childProc;
+}
+
+void TestLUpdate::setWorkingDirectory(const QString &workDir)
+{
+ m_workDir = workDir;
+ QDir::setCurrent(m_workDir);
+}
+
+void TestLUpdate::addMakeResult( const QString &result )
+{
+ make_result.append( result );
+}
+
+bool TestLUpdate::runChild( bool showOutput, const QString &program, const QStringList &argList)
+{
+ make_result.clear();
+ exit_ok = FALSE;
+ if (childProc)
+ delete childProc;
+
+ child_show = showOutput;
+ if ( showOutput ) {
+ QString S = argList.join(" ");
+ addMakeResult( program + QLatin1String(" ") + S );
+ }
+
+ childProc = new QProcess();
+ Q_ASSERT(childProc);
+
+ childProc->setWorkingDirectory(m_workDir);
+ connect(childProc, SIGNAL(finished(int)), this, SLOT(childReady(int)));
+ childProc->setProcessChannelMode(QProcess::MergedChannels);
+ if (argList.isEmpty()) {
+ childProc->start( program );
+ } else {
+ childProc->start( program, argList );
+ }
+ bool ok;
+
+ ok = childProc->waitForStarted();
+
+ if (ok)
+ ok = childProc->waitForFinished();
+
+ if (!ok)
+ addMakeResult( "Error executing '" + program + "'." );
+
+ childReady(ok ? 0 : -1);
+
+ return ok;
+}
+
+void TestLUpdate::childReady(int /*exitCode*/)
+{
+ if (childProc != 0) {
+ childHasData();
+ exit_ok = childProc->state() == QProcess::NotRunning
+ && childProc->exitStatus() == 0;
+ childProc->deleteLater();
+ }
+ childProc = 0;
+}
+
+void TestLUpdate::childHasData()
+{
+ //QByteArray ba = childProc->readAllStandardError();
+ //qDebug() << "ERROR:" << ba;
+ QString stdoutput = childProc->readAllStandardOutput();
+ stdoutput = stdoutput.replace("\t", " ");
+ if (child_show)
+ addMakeResult(stdoutput);
+}
+
+bool TestLUpdate::run(const QString &commandline)
+{
+ return runChild(true, m_cmdLupdate + QLatin1String(" ") + commandline);
+}
+
+
+bool TestLUpdate::updateProFile(const QString &arguments)
+{
+ QStringList args = arguments.split(QChar(' '));
+ return runChild( true, m_cmdLupdate, args );
+}
+
+bool TestLUpdate::qmake()
+{
+ QStringList args;
+ args << "-r";
+ return runChild(true, m_cmdQMake, args);
+}
diff --git a/tests/auto/linguist/lupdate/testlupdate.h b/tests/auto/linguist/lupdate/testlupdate.h
new file mode 100644
index 0000000..3fd7dcb
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testlupdate.h
@@ -0,0 +1,46 @@
+#ifndef TESTLUPDATE_H
+#define TESTLUPDATE_H
+
+#include <QObject>
+#include <QProcess>
+#include <QStringList>
+
+class TestLUpdate : public QObject
+{
+ Q_OBJECT
+
+public:
+ TestLUpdate();
+ virtual ~TestLUpdate();
+
+ void setWorkingDirectory( const QString &workDir);
+ bool run( const QString &commandline);
+ bool updateProFile( const QString &arguments);
+ bool qmake();
+ QStringList getErrorMessages() {
+ return make_result;
+ }
+ void clearResult() {
+ make_result.clear();
+ }
+private:
+ QString m_cmdLupdate;
+ QString m_cmdQMake;
+ QString m_workDir;
+ QProcess *childProc;
+ QStringList env_list;
+ QStringList make_result;
+
+ bool child_show;
+ bool qws_mode;
+ bool exit_ok;
+
+ bool runChild( bool showOutput, const QString &program, const QStringList &argList = QStringList());
+ void addMakeResult( const QString &result );
+ void childHasData();
+
+private slots:
+ void childReady(int exitCode);
+};
+
+#endif // TESTLUPDATE_H
diff --git a/tests/auto/linguist/lupdate/tst_lupdate.cpp b/tests/auto/linguist/lupdate/tst_lupdate.cpp
new file mode 100644
index 0000000..1beae73
--- /dev/null
+++ b/tests/auto/linguist/lupdate/tst_lupdate.cpp
@@ -0,0 +1,277 @@
+#include "testlupdate.h"
+#if CHECK_SIMTEXTH
+#include "../shared/simtexth.h"
+#endif
+
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QByteArray>
+
+#include <QtTest/QtTest>
+
+class tst_lupdate : public QObject
+{
+ Q_OBJECT
+public:
+ tst_lupdate() { m_basePath = QDir::currentPath() + QLatin1String("/testdata/"); }
+
+private slots:
+ void good_data();
+ void good();
+ void output_ts();
+ void commandline_data();
+ void commandline();
+#if CHECK_SIMTEXTH
+ void simtexth();
+ void simtexth_data();
+#endif
+
+private:
+ TestLUpdate m_lupdate;
+ QString m_basePath;
+
+ void doCompare(const QStringList &actual, const QString &expectedFn, bool err);
+ void doCompare(const QString &actualFn, const QString &expectedFn, bool err);
+};
+
+
+void tst_lupdate::doCompare(const QStringList &actual, const QString &expectedFn, bool err)
+{
+ QFile file(expectedFn);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QStringList expected = QString(file.readAll()).trimmed().remove('\r').split('\n');
+
+ int i = 0, ei = expected.size(), gi = actual.size();
+ for (; ; i++) {
+ if (i == gi) {
+ if (i == ei)
+ return;
+ gi = 0;
+ break;
+ } else if (i == ei) {
+ ei = 0;
+ break;
+ } else if (err ? !QRegExp(expected.at(i)).exactMatch(actual.at(i)) :
+ (actual.at(i) != expected.at(i))) {
+ while ((ei - 1) >= i && (gi - 1) >= i &&
+ (err ? QRegExp(expected.at(ei - 1)).exactMatch(actual.at(gi - 1)) :
+ (actual.at(gi - 1) == expected.at(ei - 1))))
+ ei--, gi--;
+ break;
+ }
+ }
+ QByteArray diff;
+ for (int j = qMax(0, i - 3); j < i; j++)
+ diff += expected.at(j) + '\n';
+ diff += "<<<<<<< got\n";
+ for (int j = i; j < gi; j++) {
+ diff += actual.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += "=========\n";
+ for (int j = i; j < ei; j++) {
+ diff += expected.at(j) + '\n';
+ if (j >= i + 5) {
+ diff += "...\n";
+ break;
+ }
+ }
+ diff += ">>>>>>> expected\n";
+ for (int j = ei; j < qMin(ei + 3, expected.size()); j++)
+ diff += expected.at(j) + '\n';
+ QFAIL(qPrintable((err ? "Output for " : "Result for ") + expectedFn + " does not meet expectations:\n" + diff));
+}
+
+void tst_lupdate::doCompare(const QString &actualFn, const QString &expectedFn, bool err)
+{
+ QFile afile(actualFn);
+ QVERIFY(afile.open(QIODevice::ReadOnly));
+ QStringList actual = QString(afile.readAll()).trimmed().remove('\r').split('\n');
+
+ doCompare(actual, expectedFn, err);
+}
+
+void tst_lupdate::good_data()
+{
+ QTest::addColumn<QString>("directory");
+
+ QDir parsingDir(m_basePath + "good");
+ QStringList dirs = parsingDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
+
+#ifndef Q_OS_WIN
+ dirs.removeAll(QLatin1String("backslashes"));
+#endif
+
+ foreach (const QString &dir, dirs)
+ QTest::newRow(dir.toLocal8Bit()) << dir;
+}
+
+void tst_lupdate::good()
+{
+ QFETCH(QString, directory);
+
+ QString dir = m_basePath + "good/" + directory;
+ QString expectedFile = dir + QLatin1String("/project.ts.result");
+
+ qDebug() << "Checking...";
+
+ // qmake will delete the previous one, to ensure that we don't do any merging....
+ QString generatedtsfile(QLatin1String("project.ts"));
+
+ m_lupdate.setWorkingDirectory(dir);
+ m_lupdate.qmake();
+ // look for a command
+ QString lupdatecmd;
+ QFile file(dir + "/lupdatecmd");
+ if (file.exists()) {
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ while (!file.atEnd()) {
+ QByteArray cmdstring = file.readLine().simplified();
+ if (cmdstring.startsWith('#'))
+ continue;
+ if (cmdstring.startsWith("lupdate")) {
+ cmdstring.remove(0, 8);
+ lupdatecmd.append(cmdstring);
+ break;
+ } else if (cmdstring.startsWith("TRANSLATION:")) {
+ cmdstring.remove(0, 12);
+ generatedtsfile = dir + QLatin1Char('/') + cmdstring.trimmed();
+ }
+ }
+ file.close();
+ }
+
+ if (lupdatecmd.isEmpty()) {
+ lupdatecmd = QLatin1String("project.pro -ts project.ts");
+ }
+ lupdatecmd.prepend("-silent ");
+ m_lupdate.updateProFile(lupdatecmd);
+
+ // If the file expectedoutput.txt exists, compare the
+ // console output with the content of that file
+ QFile outfile(dir + "/expectedoutput.txt");
+ if (outfile.exists()) {
+ QString errs = m_lupdate.getErrorMessages().at(1).trimmed();
+ QStringList errslist = errs.split(QLatin1Char('\n'));
+ doCompare(errslist, outfile.fileName(), true);
+ if (QTest::currentTestFailed())
+ return;
+ }
+
+ doCompare(generatedtsfile, expectedFile, false);
+}
+
+void tst_lupdate::output_ts()
+{
+ QString dir = m_basePath + "output_ts";
+ m_lupdate.setWorkingDirectory(dir);
+
+ // look for a command
+ QString lupdatecmd;
+ QFile file(dir + "/lupdatecmd");
+ if (file.exists()) {
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ while (!file.atEnd()) {
+ QByteArray cmdstring = file.readLine().simplified();
+ if (cmdstring.startsWith('#'))
+ continue;
+ if (cmdstring.startsWith("lupdate")) {
+ cmdstring.remove(0, 8);
+ lupdatecmd.append(cmdstring);
+ break;
+ }
+ }
+ file.close();
+ }
+
+ QDir parsingDir(m_basePath + "output_ts");
+
+ QString generatedtsfile =
+ dir + QLatin1String("/toplevel/library/tools/translations/project.ts");
+
+ QFile::remove(generatedtsfile);
+
+ lupdatecmd.prepend("-silent ");
+ m_lupdate.qmake();
+ m_lupdate.updateProFile(lupdatecmd);
+
+ // If the file expectedoutput.txt exists, compare the
+ // console output with the content of that file
+ QFile outfile(dir + "/expectedoutput.txt");
+ if (outfile.exists()) {
+ QString errs = m_lupdate.getErrorMessages().at(1).trimmed();
+ QStringList errslist = errs.split(QLatin1Char('\n'));
+ doCompare(errslist, outfile.fileName(), true);
+ if (QTest::currentTestFailed())
+ return;
+ }
+
+ doCompare(generatedtsfile, dir + QLatin1String("/project.ts.result"), false);
+}
+
+void tst_lupdate::commandline_data()
+{
+ QTest::addColumn<QString>("currentPath");
+ QTest::addColumn<QString>("commandline");
+ QTest::addColumn<QString>("generatedtsfile");
+ QTest::addColumn<QString>("expectedtsfile");
+
+ QTest::newRow("Recursive scan") << QString("recursivescan")
+ << QString(". -ts foo.ts") << QString("foo.ts") << QString("foo.ts.result");
+ QTest::newRow("Deep path argument") << QString("recursivescan")
+ << QString("sub/finddialog.cpp -ts bar.ts") << QString("bar.ts") << QString("bar.ts.result");
+}
+
+void tst_lupdate::commandline()
+{
+ QFETCH(QString, currentPath);
+ QFETCH(QString, commandline);
+ QFETCH(QString, generatedtsfile);
+ QFETCH(QString, expectedtsfile);
+
+ m_lupdate.setWorkingDirectory(m_basePath + currentPath);
+ QString generated =
+ m_basePath + currentPath + QLatin1Char('/') + generatedtsfile;
+ QFile gen(generated);
+ if (gen.exists())
+ QVERIFY(gen.remove());
+ if (!m_lupdate.run("-silent " + commandline))
+ qDebug() << m_lupdate.getErrorMessages().last();
+
+ doCompare(generated, m_basePath + currentPath + QLatin1Char('/') + expectedtsfile, false);
+}
+
+#if CHECK_SIMTEXTH
+void tst_lupdate::simtexth()
+{
+ QFETCH(QString, one);
+ QFETCH(QString, two);
+ QFETCH(int, expected);
+
+ int measured = getSimilarityScore(one, two.toLatin1());
+ QCOMPARE(measured, expected);
+}
+
+
+void tst_lupdate::simtexth_data()
+{
+ using namespace QTest;
+
+ addColumn<QString>("one");
+ addColumn<QString>("two");
+ addColumn<int>("expected");
+
+ newRow("00") << "" << "" << 1024;
+ newRow("01") << "a" << "a" << 1024;
+ newRow("02") << "ab" << "ab" << 1024;
+ newRow("03") << "abc" << "abc" << 1024;
+ newRow("04") << "abcd" << "abcd" << 1024;
+}
+#endif
+
+QTEST_MAIN(tst_lupdate)
+#include "tst_lupdate.moc"
diff --git a/tests/auto/mediaobject/dummy/README b/tests/auto/mediaobject/dummy/README
new file mode 100644
index 0000000..43f69d9
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/README
@@ -0,0 +1 @@
+This is a dummy backend for phonon, used for testing purposes.
diff --git a/tests/auto/mediaobject/dummy/audiooutput.cpp b/tests/auto/mediaobject/dummy/audiooutput.cpp
new file mode 100644
index 0000000..41b473d
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/audiooutput.cpp
@@ -0,0 +1,53 @@
+#include "audiooutput.h"
+#include "backend.h"
+#include <phonon/audiooutput.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace Dummy
+{
+AudioOutput::AudioOutput(Backend *backend, QObject *parent)
+ : QObject(parent)
+{
+ Q_UNUSED(backend)
+
+ m_volumeLevel = 100;
+}
+
+AudioOutput::~AudioOutput()
+{
+}
+
+qreal AudioOutput::volume() const
+{
+ return m_volumeLevel;
+}
+
+int AudioOutput::outputDevice() const
+{
+ return m_device;
+}
+
+void AudioOutput::setVolume(qreal newVolume)
+{
+ m_volumeLevel = newVolume;
+ emit volumeChanged(newVolume);
+}
+
+bool AudioOutput::setOutputDevice(int newDevice)
+{
+ return (newDevice == 0);
+}
+
+bool AudioOutput::setOutputDevice(const AudioOutputDevice &newDevice)
+{
+ return setOutputDevice(newDevice.index());
+}
+
+}
+} //namespace Phonon::Dummy
+
+QT_END_NAMESPACE
+#include "moc_audiooutput.cpp"
diff --git a/tests/auto/mediaobject/dummy/audiooutput.h b/tests/auto/mediaobject/dummy/audiooutput.h
new file mode 100644
index 0000000..39efb55
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/audiooutput.h
@@ -0,0 +1,41 @@
+#ifndef PHONON_DUMMY_AUDIOOUTPUT_H
+#define PHONON_DUMMY_AUDIOOUTPUT_H
+
+#include "backend.h"
+#include <phonon/audiooutputinterface.h>
+#include <phonon/phononnamespace.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace Dummy
+{
+class AudioOutput : public QObject, public AudioOutputInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::AudioOutputInterface)
+public:
+ AudioOutput(Backend *backend, QObject *parent);
+ ~AudioOutput();
+
+ qreal volume() const;
+ int outputDevice() const;
+ void setVolume(qreal newVolume);
+ bool setOutputDevice(int newDevice);
+ bool setOutputDevice(const AudioOutputDevice &newDevice);
+
+Q_SIGNALS:
+ void volumeChanged(qreal newVolume);
+ void audioDeviceFailed();
+
+private:
+ qreal m_volumeLevel;
+ int m_device;
+};
+}
+} //namespace Phonon::Dummy
+
+QT_END_NAMESPACE
+
+#endif // PHONON_DUMMY_AUDIOOUTPUT_H
diff --git a/tests/auto/mediaobject/dummy/backend.cpp b/tests/auto/mediaobject/dummy/backend.cpp
new file mode 100644
index 0000000..53f3896
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/backend.cpp
@@ -0,0 +1,149 @@
+#include "audiooutput.h"
+#include "mediaobject.h"
+#include "videowidget.h"
+
+#include "backend.h"
+
+#include <QtCore/QSet>
+#include <QtCore/QVariant>
+#include <QtCore/QtPlugin>
+
+QT_BEGIN_NAMESPACE
+
+Q_EXPORT_PLUGIN2(phonon_dummy, Phonon::Dummy::Backend)
+
+namespace Phonon
+{
+namespace Dummy
+{
+
+Backend::Backend(QObject *parent, const QVariantList &)
+ : QObject(parent)
+{
+ qWarning()<<"Using TEST Phonon backend";
+}
+
+Backend::~Backend()
+{
+}
+
+/***
+ * !reimp
+ */
+QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList<QVariant> &args)
+{
+ Q_UNUSED(args)
+
+ switch (c) {
+ case MediaObjectClass:
+ return new MediaObject(this, parent);
+
+ case AudioOutputClass: {
+ AudioOutput *ao = new AudioOutput(this, parent);
+ m_audioOutputs.append(ao);
+ return ao;
+ }
+ case VideoWidgetClass: {
+ QWidget *widget = qobject_cast<QWidget*>(parent);
+ return new VideoWidget(this, widget);
+ }
+ default:
+ qWarning("createObject() : Backend object not available");
+ }
+ return 0;
+}
+
+/***
+ * !reimp
+ */
+QStringList Backend::availableMimeTypes() const
+{
+ QStringList availableMimeTypes;
+ // audio *.wav and *.mp3 files
+ availableMimeTypes << QLatin1String("audio/x-mp3");
+ availableMimeTypes << QLatin1String("audio/x-wav");
+
+ // video *.ogv, *.mp4, *.avi (some)
+
+ availableMimeTypes << QLatin1String("video/mpeg");
+ availableMimeTypes << QLatin1String("video/ogg");
+ availableMimeTypes << QLatin1String("video/mp4");
+
+ return availableMimeTypes;
+}
+
+/***
+ * !reimp
+ */
+QList<int> Backend::objectDescriptionIndexes(ObjectDescriptionType type) const
+{
+ QList<int> list;
+
+ if(type == Phonon::AudioOutputDeviceType)
+ list.append(0);
+
+ return list;
+}
+
+/***
+ * !reimp
+ */
+QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const
+{
+ Q_UNUSED(index);
+ QHash<QByteArray, QVariant> ret;
+
+ if(type == Phonon::AudioOutputDeviceType)
+ ret["name"] = QLatin1String("default audio device");
+
+ return ret;
+}
+
+/***
+ * !reimp
+ */
+bool Backend::startConnectionChange(QSet<QObject *> objects)
+{
+ Q_UNUSED(objects)
+
+ return true;
+}
+
+/***
+ * !reimp
+ */
+bool Backend::connectNodes(QObject *source, QObject *sink)
+{
+ Q_UNUSED(source)
+ Q_UNUSED(sink)
+
+ return true;
+}
+
+/***
+ * !reimp
+ */
+bool Backend::disconnectNodes(QObject *source, QObject *sink)
+{
+ Q_UNUSED(source)
+ Q_UNUSED(sink)
+
+ return true;
+}
+
+/***
+ * !reimp
+ */
+bool Backend::endConnectionChange(QSet<QObject *> objects)
+{
+ Q_UNUSED(objects)
+
+ return true;
+}
+
+}
+}
+
+QT_END_NAMESPACE
+
+#include "moc_backend.cpp"
diff --git a/tests/auto/mediaobject/dummy/backend.h b/tests/auto/mediaobject/dummy/backend.h
new file mode 100644
index 0000000..20af216
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/backend.h
@@ -0,0 +1,55 @@
+#ifndef PHONON_DUMMY_BACKEND_H
+#define PHONON_DUMMY_BACKEND_H
+
+#include <phonon/objectdescription.h>
+#include <phonon/backendinterface.h>
+
+#include <phonon/medianode.h>
+
+#include <QtCore/QList>
+#include <QtCore/QPointer>
+#include <QtCore/QStringList>
+#include <QtCore/QTimer>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace Dummy
+{
+class AudioOutput;
+class MediaObject;
+
+class Backend : public QObject, public BackendInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::BackendInterface)
+
+public:
+ Backend(QObject *parent = 0, const QVariantList & = QVariantList());
+ virtual ~Backend();
+
+ QObject *createObject(BackendInterface::Class, QObject *parent, const QList<QVariant> &args);
+
+ QStringList availableMimeTypes() const;
+
+ QList<int> objectDescriptionIndexes(ObjectDescriptionType type) const;
+ QHash<QByteArray, QVariant> objectDescriptionProperties(ObjectDescriptionType type, int index) const;
+
+ bool startConnectionChange(QSet<QObject *>);
+ bool connectNodes(QObject *, QObject *);
+ bool disconnectNodes(QObject *, QObject *);
+ bool endConnectionChange(QSet<QObject *>);
+
+Q_SIGNALS:
+ void objectDescriptionChanged(ObjectDescriptionType);
+
+private:
+ QList<QPointer<AudioOutput> > m_audioOutputs;
+};
+}
+} // namespace Phonon::Dummy
+
+QT_END_NAMESPACE
+
+#endif // PHONON_DUMMY_BACKEND_H
diff --git a/tests/auto/mediaobject/dummy/dummy.pro b/tests/auto/mediaobject/dummy/dummy.pro
new file mode 100644
index 0000000..b4f6109
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/dummy.pro
@@ -0,0 +1,23 @@
+TEMPLATE = lib
+
+isEmpty(QT_MAJOR_VERSION) {
+ VERSION=4.5.2
+} else {
+ VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
+}
+CONFIG += qt plugin
+
+TARGET = phonon_dummy
+DESTDIR = $$QT_BUILD_TREE/plugins/phonon_backend
+DEPENDPATH += .
+INCLUDEPATH += .
+
+QT += phonon
+
+
+# Input
+HEADERS += backend.h audiooutput.h mediaobject.h videowidget.h
+SOURCES += backend.cpp audiooutput.cpp mediaobject.cpp videowidget.cpp
+
+target.path = $$[QT_INSTALL_PLUGINS]/phonon_backend
+INSTALLS += target
diff --git a/tests/auto/mediaobject/dummy/mediaobject.cpp b/tests/auto/mediaobject/dummy/mediaobject.cpp
new file mode 100644
index 0000000..521e3a6
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/mediaobject.cpp
@@ -0,0 +1,397 @@
+#include "mediaobject.h"
+#include "backend.h"
+
+#include <QtCore>
+#include <QtCore/QTimer>
+#include <QtCore/QVector>
+#include <QtCore/QFile>
+#include <QtCore/QByteRef>
+#include <QtCore/QStringList>
+#include <QtCore/QEvent>
+#include <QApplication>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace Dummy
+{
+
+static const char* riffId = "RIFF";
+
+MediaObject::MediaObject(Backend *backend, QObject *parent)
+ : QObject(parent)
+ , m_resumeState(false)
+ , m_oldState(Phonon::LoadingState)
+ , m_oldPos(0)
+ , currentPos(0)
+{
+ Q_UNUSED(backend)
+
+ m_error = Phonon::NoError;
+ m_tickInterval = 100; // 100ms
+ m_totalTime = 26000; // 26s
+ m_prefinishMark = 0;
+ m_transitionTime = 100; //100ms
+ m_hasVideo = false;
+ m_prefinishMarkReachedNotEmitted = true;
+ m_aboutToFinishEmitted = false;
+ m_pendingState = Phonon::LoadingState;
+ m_state = Phonon::LoadingState;
+ m_pendingState = Phonon::LoadingState;
+ m_tickTimer = new QTimer(this);
+ connect(m_tickTimer, SIGNAL(timeout()), SLOT(emitTick()));
+}
+
+MediaObject::~MediaObject()
+{
+ delete m_tickTimer;
+}
+
+QString stateString(const Phonon::State &state)
+{
+ switch (state) {
+ case Phonon::LoadingState:
+ return QString("LoadingState");
+ case Phonon::StoppedState:
+ return QString("StoppedState");
+ case Phonon::PlayingState:
+ return QString("PlayingState");
+ case Phonon::BufferingState:
+ return QString("BufferingState");
+ case Phonon::PausedState:
+ return QString("PausedState");
+ case Phonon::ErrorState:
+ return QString("ErrorState");
+ }
+ return QString();
+}
+
+void MediaObject::saveState()
+{
+ if (m_resumeState)
+ return;
+
+ if (m_pendingState == Phonon::PlayingState || m_pendingState == Phonon::PausedState) {
+ m_resumeState = true;
+ m_oldState = m_pendingState;
+ m_oldPos = currentPos;
+ }
+}
+
+void MediaObject::resumeState()
+{
+ if (m_resumeState)
+ QMetaObject::invokeMethod(this, "setState", Qt::QueuedConnection, Q_ARG(State, m_oldState));
+}
+
+/**
+ * !reimp
+ */
+State MediaObject::state() const
+{
+ return m_state;
+}
+
+/**
+ * !reimp
+ */
+bool MediaObject::hasVideo() const
+{
+ return m_hasVideo;
+}
+
+/**
+ * !reimp
+ */
+bool MediaObject::isSeekable() const
+{
+ return true;
+}
+
+/**
+ * !reimp
+ */
+qint64 MediaObject::currentTime() const
+{
+ if (m_resumeState)
+ return m_oldPos;
+
+ switch (state()) {
+ case Phonon::PausedState:
+ case Phonon::BufferingState:
+ case Phonon::PlayingState:
+ return currentPos;
+ case Phonon::StoppedState:
+ case Phonon::LoadingState:
+ return 0;
+ case Phonon::ErrorState:
+ break;
+ }
+ return -1;
+}
+
+/**
+ * !reimp
+ */
+qint32 MediaObject::tickInterval() const
+{
+ return m_tickInterval;
+}
+
+/**
+ * !reimp
+ */
+void MediaObject::setTickInterval(qint32 newTickInterval)
+{
+ m_tickInterval = newTickInterval;
+ if (m_tickInterval <= 0) {
+ m_tickTimer->setInterval(100);
+ } else
+ m_tickTimer->setInterval(newTickInterval);
+}
+
+/**
+ * !reimp
+ */
+void MediaObject::play()
+{
+ if(m_state == Phonon::PlayingState)
+ return;
+ if(m_state == Phonon::ErrorState)
+ return;
+
+ if(m_state != Phonon::PausedState)
+ m_tickTimer->stop();
+
+ m_prefinishMarkReachedNotEmitted = true;
+ m_aboutToFinishEmitted = false;
+
+ setState(Phonon::PlayingState);
+ m_resumeState = false;
+ m_tickTimer->start();
+}
+
+/**
+ * !reimp
+ */
+QString MediaObject::errorString() const
+{
+ return m_errorString;
+}
+
+/**
+ * !reimp
+ */
+Phonon::ErrorType MediaObject::errorType() const
+{
+ return m_error;
+}
+
+void MediaObject::setState(State newstate)
+{
+ if (m_state == newstate)
+ return;
+
+ switch (newstate) {
+ case Phonon::PausedState:
+ m_pendingState = Phonon::PausedState;
+ emit stateChanged(newstate, m_state);
+ m_state = newstate;
+ break;
+ case Phonon::StoppedState:
+ m_pendingState = Phonon::StoppedState;
+ emit stateChanged(newstate, m_state);
+ m_state = newstate;
+ break;
+ case Phonon::PlayingState:
+ m_pendingState = Phonon::PlayingState;
+ emit stateChanged(newstate, m_state);
+ m_state = newstate;
+ break;
+ case Phonon::ErrorState:
+ emit stateChanged(newstate, m_state);
+ m_state = newstate;
+ break;
+ case Phonon::BufferingState:
+ case Phonon::LoadingState:
+ emit stateChanged(newstate, m_state);
+ m_state = newstate;
+ break;
+ }
+}
+
+qint64 MediaObject::totalTime() const
+{
+ return m_totalTime;
+}
+
+qint32 MediaObject::prefinishMark() const
+{
+ return m_prefinishMark;
+}
+
+qint32 MediaObject::transitionTime() const
+{
+ return m_transitionTime;
+}
+
+void MediaObject::setTransitionTime(qint32 time)
+{
+ m_transitionTime = time;
+}
+
+qint64 MediaObject::remainingTime() const
+{
+ if(currentTime() > totalTime())
+ return 0;
+
+ return totalTime() - currentTime();
+}
+
+MediaSource MediaObject::source() const
+{
+ return m_source;
+}
+
+void MediaObject::setNextSource(const MediaSource &source)
+{
+ if (source.type() == MediaSource::Invalid &&
+ source.type() == MediaSource::Empty)
+ return;
+ m_nextSource = source;
+}
+
+/*
+ * !reimp
+ */
+void MediaObject::setSource(const MediaSource &source)
+{
+ QMultiMap<QString, QString> ret;
+
+ ret.insert(QLatin1String("ARTIST"), "Nokia Dude");
+ ret.insert(QLatin1String("ALBUM"), "Sound of silence");
+ ret.insert(QLatin1String("DATE"), "2009");
+
+ m_error = Phonon::NoError;
+ setState(Phonon::LoadingState);
+
+ m_source = source;
+ currentPos = 0;
+
+ if((source.fileName().contains(".avi")) ||
+ (source.fileName().contains(".mp4"))) {
+ m_hasVideo = true;
+ emit hasVideoChanged(m_hasVideo);
+ }
+ if(source.fileName().contains(".wav")) {
+ QFile file(source.fileName());
+ if (file.open(QIODevice::ReadOnly)) {
+ int len = file.read((char*)&header, sizeof(CombinedHeader));
+ if(len == sizeof(CombinedHeader)) {
+ if(memcmp(&header.riff.descriptor.id, riffId, 4) != 0) {
+ // Not a valid wav file, to satisfy unit test for mediaobject
+ m_error = Phonon::FatalError;
+ //m_state = Phonon::ErrorState;
+ m_errorString = "Invalid wav file";
+ setState(Phonon::ErrorState);
+ file.close();
+ return;
+ }
+ }
+ file.close();
+ }
+ }
+ emit metaDataChanged(ret);
+ emit currentSourceChanged(source);
+ emit totalTimeChanged(m_totalTime);
+
+ setState(Phonon::StoppedState);
+}
+
+void MediaObject::setPrefinishMark(qint32 newPrefinishMark)
+{
+ m_prefinishMark = newPrefinishMark;
+ if (currentTime() < totalTime() - m_prefinishMark) // not about to finish
+ m_prefinishMarkReachedNotEmitted = true;
+}
+
+void MediaObject::pause()
+{
+ if (state() != Phonon::PausedState)
+ setState(Phonon::PausedState);
+ m_resumeState = false;
+ m_tickTimer->stop();
+}
+
+void MediaObject::stop()
+{
+ if (state() != Phonon::StoppedState) {
+ if(m_state != Phonon::ErrorState) {
+ setState(Phonon::StoppedState);
+ }
+ m_prefinishMarkReachedNotEmitted = true;
+ }
+ m_resumeState = false;
+ m_tickTimer->stop();
+}
+
+void MediaObject::emitTick()
+{
+ if (m_resumeState) {
+ return;
+ }
+ if(m_tickInterval > 0)
+ currentPos += m_tickInterval;
+ else
+ currentPos += 100;
+
+ qint64 currentTime = currentPos;
+ qint64 totalTime = m_totalTime;
+
+ if (m_tickInterval > 0 && currentTime != m_previousTickTime) {
+ emit tick(currentTime);
+ m_previousTickTime = currentTime;
+ }
+ if (m_state == Phonon::PlayingState) {
+ if (currentTime >= totalTime - m_prefinishMark) {
+ if (m_prefinishMarkReachedNotEmitted) {
+ m_prefinishMarkReachedNotEmitted = false;
+ emit prefinishMarkReached(totalTime - currentTime);
+ }
+ }
+ // Prepare load of next source
+ if (currentTime >= totalTime - 500) {
+ if (!m_aboutToFinishEmitted) {
+ m_aboutToFinishEmitted = true; // track is about to finish
+ emit aboutToFinish();
+ }
+ }
+ if(currentTime >= totalTime) {
+ m_tickTimer->stop();
+ if(m_nextSource.type() != MediaSource::Invalid &&
+ m_nextSource.type() != MediaSource::Empty) {
+ setSource(m_nextSource);
+ m_nextSource = MediaSource();
+ m_pendingState = Phonon::PlayingState;
+ } else {
+ setState(Phonon::PausedState);
+ currentPos = 0;
+ emit finished();
+ }
+ }
+ }
+}
+
+void MediaObject::seek(qint64 time)
+{
+ // We will assume no buffering in the object so this is not needed.
+ currentPos = time;
+}
+
+} // ns Dummy
+} // ns Phonon
+
+QT_END_NAMESPACE
+
+#include "moc_mediaobject.cpp"
diff --git a/tests/auto/mediaobject/dummy/mediaobject.h b/tests/auto/mediaobject/dummy/mediaobject.h
new file mode 100644
index 0000000..a87b32f
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/mediaobject.h
@@ -0,0 +1,169 @@
+#ifndef PHONON_DUMMY_MEDIAOBJECT_H
+#define PHONON_DUMMY_MEDIAOBJECT_H
+
+#include "backend.h"
+#include <phonon/mediaobjectinterface.h>
+#include <phonon/addoninterface.h>
+
+#include <QtCore/QHash>
+#include <QtCore/QString>
+#include <QtCore/QVariant>
+#include <QtCore/QObject>
+#include <QtCore/QDate>
+#include <QtCore/QEvent>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+class QTimer;
+typedef QMultiMap<QString, QString> TagMap;
+
+namespace Phonon
+{
+namespace Dummy
+{
+
+class VideoWidget;
+class AudioPath;
+class VideoPath;
+class AudioOutput;
+
+class MediaObject : public QObject, public MediaObjectInterface
+{
+ friend class Stream;
+ Q_OBJECT
+ Q_INTERFACES(Phonon::MediaObjectInterface
+ )
+
+public:
+
+ MediaObject(Backend *backend, QObject *parent);
+ ~MediaObject();
+ Phonon::State state() const;
+
+ bool hasVideo() const;
+ bool isSeekable() const;
+
+ qint64 currentTime() const;
+ qint32 tickInterval() const;
+
+ void setTickInterval(qint32 newTickInterval);
+
+ void play();
+ void pause();
+ void stop();
+ void seek(qint64 time);
+
+ QString errorString() const;
+ Phonon::ErrorType errorType() const;
+
+ QUrl url() const;
+ qint64 totalTime() const;
+
+ qint32 prefinishMark() const;
+ void setPrefinishMark(qint32 newPrefinishMark);
+
+ qint32 transitionTime() const;
+ void setTransitionTime(qint32);
+ qint64 remainingTime() const;
+
+ void setSource(const MediaSource &source);
+ void setNextSource(const MediaSource &source);
+ MediaSource source() const;
+
+ void saveState();
+ void resumeState();
+
+public Q_SLOTS:
+ void setState(State);
+
+Q_SIGNALS:
+ void currentSourceChanged(const MediaSource &newSource);
+ void stateChanged(Phonon::State newstate, Phonon::State oldstate);
+ void tick(qint64 time);
+ void metaDataChanged(QMultiMap<QString, QString>);
+ void seekableChanged(bool);
+ void hasVideoChanged(bool);
+
+ void finished();
+ void prefinishMarkReached(qint32);
+ void aboutToFinish();
+ void totalTimeChanged(qint64 length);
+ void bufferStatus(int percentFilled);
+
+ QMultiMap<QString, QString> metaData();
+ void setMetaData(QMultiMap<QString, QString> newData);
+
+private Q_SLOTS:
+ void emitTick();
+
+private:
+ bool m_resumeState;
+ State m_oldState;
+ quint64 m_oldPos;
+ quint64 currentPos;
+ bool m_hasVideo;
+ qint32 m_tickInterval;
+ QTimer *m_tickTimer;
+ Phonon::ErrorType m_error;
+ QString m_errorString;
+ qint64 m_totalTime;
+ qint32 m_prefinishMark;
+ qint32 m_transitionTime;
+ MediaSource m_source;
+ MediaSource m_nextSource;
+ bool m_prefinishMarkReachedNotEmitted;
+ bool m_aboutToFinishEmitted;
+ int m_previousTickTime;
+
+ State m_state;
+ State m_pendingState;
+
+ struct chunk
+ {
+ char id[4];
+ quint32 size;
+ };
+
+ struct RIFFHeader
+ {
+ chunk descriptor;
+ char type[4];
+ };
+
+ struct WAVEHeader
+ {
+ chunk descriptor;
+ quint16 audioFormat; // PCM = 1
+ quint16 numChannels;
+ quint32 sampleRate;
+ quint32 byteRate;
+ quint16 blockAlign;
+ quint16 bitsPerSample;
+ quint32 xFreq1;
+ chunk fact;
+ quint32 xfact;
+ chunk data;
+ };
+
+ struct DATAHeader
+ {
+ chunk descriptor;
+ quint8 data[];
+ };
+
+ struct CombinedHeader
+ {
+ RIFFHeader riff;
+ WAVEHeader wave;
+ DATAHeader data;
+ };
+
+ CombinedHeader header;
+};
+}
+} //namespace Phonon::Dummy
+
+QT_END_NAMESPACE
+
+#endif // PHONON_DUMMY_MEDIAOBJECT_H
diff --git a/tests/auto/mediaobject/dummy/videowidget.cpp b/tests/auto/mediaobject/dummy/videowidget.cpp
new file mode 100644
index 0000000..890363f
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/videowidget.cpp
@@ -0,0 +1,205 @@
+#include "videowidget.h"
+#include <QtCore/QEvent>
+#include <QtGui/QResizeEvent>
+#include <QtGui/QPalette>
+#include <QtGui/QImage>
+#include <QtGui/QPainter>
+#include <QtGui/QBoxLayout>
+#include <QApplication>
+#include "mediaobject.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace Dummy
+{
+
+VideoWidget::VideoWidget(Backend *backend, QWidget *parent) :
+ QWidget(parent),
+ m_aspectRatio(Phonon::VideoWidget::AspectRatioAuto),
+ m_brightness(0.0),
+ m_hue(0.0),
+ m_contrast(0.0),
+ m_saturation(0.0),
+ m_scaleMode(Phonon::VideoWidget::FitInView)
+{
+ Q_UNUSED(backend)
+
+}
+
+VideoWidget::~VideoWidget()
+{
+}
+
+void VideoWidget::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event)
+}
+
+void VideoWidget::setVisible(bool val)
+{
+ Q_UNUSED(val)
+}
+
+Phonon::VideoWidget::AspectRatio VideoWidget::aspectRatio() const
+{
+ return m_aspectRatio;
+}
+
+QSize VideoWidget::sizeHint() const
+{
+ return QSize(640, 480);
+}
+
+void VideoWidget::setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio)
+{
+ Q_UNUSED(aspectRatio)
+}
+
+Phonon::VideoWidget::ScaleMode VideoWidget::scaleMode() const
+{
+ return m_scaleMode;
+}
+
+QRect VideoWidget::scaleToAspect(QRect srcRect, int w, int h) const
+{
+ float width = srcRect.width();
+ float height = srcRect.width() * (float(h) / float(w));
+ if (height > srcRect.height()) {
+ height = srcRect.height();
+ width = srcRect.height() * (float(w) / float(h));
+ }
+ return QRect(0, 0, (int)width, (int)height);
+}
+
+/***
+ * Calculates the actual rectangle the movie will be presented with
+ **/
+QRect VideoWidget::calculateDrawFrameRect() const
+{
+ QRect widgetRect = rect();
+ QRect drawFrameRect;
+ // Set m_drawFrameRect to be the size of the smallest possible
+ // rect conforming to the aspect and containing the whole frame:
+ switch (aspectRatio()) {
+
+ case Phonon::VideoWidget::AspectRatioWidget:
+ drawFrameRect = widgetRect;
+ // No more calculations needed.
+ return drawFrameRect;
+
+ case Phonon::VideoWidget::AspectRatio4_3:
+ drawFrameRect = scaleToAspect(widgetRect, 4, 3);
+ break;
+
+ case Phonon::VideoWidget::AspectRatio16_9:
+ drawFrameRect = scaleToAspect(widgetRect, 16, 9);
+ break;
+
+ case Phonon::VideoWidget::AspectRatioAuto:
+ default:
+ drawFrameRect = QRect(0, 0, movieSize().width(), movieSize().height());
+ break;
+ }
+
+ // Scale m_drawFrameRect to fill the widget
+ // without breaking aspect:
+ float widgetWidth = widgetRect.width();
+ float widgetHeight = widgetRect.height();
+ float frameWidth = widgetWidth;
+ float frameHeight = drawFrameRect.height() * float(widgetWidth) / float(drawFrameRect.width());
+
+ switch (scaleMode()) {
+ case Phonon::VideoWidget::ScaleAndCrop:
+ if (frameHeight < widgetHeight) {
+ frameWidth *= float(widgetHeight) / float(frameHeight);
+ frameHeight = widgetHeight;
+ }
+ break;
+ case Phonon::VideoWidget::FitInView:
+ default:
+ if (frameHeight > widgetHeight) {
+ frameWidth *= float(widgetHeight) / float(frameHeight);
+ frameHeight = widgetHeight;
+ }
+ break;
+ }
+ drawFrameRect.setSize(QSize(int(frameWidth), int(frameHeight)));
+ drawFrameRect.moveTo(int((widgetWidth - frameWidth) / 2.0f),
+ int((widgetHeight - frameHeight) / 2.0f));
+ return drawFrameRect;
+}
+
+void VideoWidget::setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode)
+{
+ Q_UNUSED(scaleMode)
+}
+
+qreal VideoWidget::brightness() const
+{
+ return m_brightness;
+}
+
+qreal clampedValue(qreal val)
+{
+ if (val > 1.0 )
+ return 1.0;
+ else if (val < -1.0)
+ return -1.0;
+ else return val;
+}
+
+void VideoWidget::setBrightness(qreal newValue)
+{
+ Q_UNUSED(newValue)
+}
+
+qreal VideoWidget::contrast() const
+{
+ return m_contrast;
+}
+
+void VideoWidget::setContrast(qreal newValue)
+{
+ Q_UNUSED(newValue)
+}
+
+qreal VideoWidget::hue() const
+{
+ return m_hue;
+}
+
+void VideoWidget::setHue(qreal newValue)
+{
+ Q_UNUSED(newValue)
+}
+
+qreal VideoWidget::saturation() const
+{
+ return m_saturation;
+}
+
+void VideoWidget::setSaturation(qreal newValue)
+{
+ Q_UNUSED(newValue)
+}
+
+bool VideoWidget::event(QEvent *event)
+{
+ return QWidget::event(event);
+}
+
+void VideoWidget::setMovieSize(const QSize &size)
+{
+ m_movieSize = size;
+ widget()->updateGeometry();
+ widget()->update();
+}
+
+}
+} //namespace Phonon::Dummy
+
+QT_END_NAMESPACE
+
+#include "moc_videowidget.cpp"
diff --git a/tests/auto/mediaobject/dummy/videowidget.h b/tests/auto/mediaobject/dummy/videowidget.h
new file mode 100644
index 0000000..2e5a2b8
--- /dev/null
+++ b/tests/auto/mediaobject/dummy/videowidget.h
@@ -0,0 +1,70 @@
+#ifndef PHONON_DUMMY_VIDEOWIDGET_H
+#define PHONON_DUMMY_VIDEOWIDGET_H
+
+#include <phonon/videowidget.h>
+#include <phonon/videowidgetinterface.h>
+
+#include "backend.h"
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+namespace Phonon
+{
+namespace Dummy
+{
+
+class VideoWidget : public QWidget, public Phonon::VideoWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::VideoWidgetInterface)
+public:
+ VideoWidget(Backend *backend, QWidget *parent = 0);
+ ~VideoWidget();
+
+ void paintEvent(QPaintEvent *event);
+ void setVisible(bool);
+
+ Phonon::VideoWidget::AspectRatio aspectRatio() const;
+ void setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio);
+ Phonon::VideoWidget::ScaleMode scaleMode() const;
+ void setScaleMode(Phonon::VideoWidget::ScaleMode);
+ qreal brightness() const;
+ void setBrightness(qreal);
+ qreal contrast() const;
+ void setContrast(qreal);
+ qreal hue() const;
+ void setHue(qreal);
+ qreal saturation() const;
+ void setSaturation(qreal);
+ void setMovieSize(const QSize &size);
+ QSize sizeHint() const;
+ QRect scaleToAspect(QRect srcRect, int w, int h) const;
+ QRect calculateDrawFrameRect() const;
+
+ QSize movieSize() const {
+ return m_movieSize;
+ }
+
+ bool event(QEvent *);
+
+ QWidget *widget() {
+ return this;
+ }
+
+protected:
+ QSize m_movieSize;
+
+private:
+ Phonon::VideoWidget::AspectRatio m_aspectRatio;
+ qreal m_brightness, m_hue, m_contrast, m_saturation;
+ Phonon::VideoWidget::ScaleMode m_scaleMode;
+};
+
+}
+} //namespace Phonon::Dummy
+
+QT_END_NAMESPACE
+
+#endif // PHONON_DUMMY_VIDEOWIDGET_H
diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
index 74126f8..fa786f1 100644
--- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
+++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
@@ -132,6 +132,12 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase db )
if ( !db.isValid() )
return;
QSqlQuery q( db );
+
+ if (tst_Databases::isSqlServer(db)) {
+ QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON"));
+ QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF"));
+ }
+
// please never ever change this table; otherwise fix all tests ;)
if ( tst_Databases::isMSAccess( db ) ) {
QVERIFY_SQL(q, exec( "create table " + qTableName( "qtest" ) + " ( id int not null, t_varchar varchar(40) not null,"
@@ -301,7 +307,8 @@ void tst_Q3SqlCursor::insert()
// check that primeInsert returns a valid QSqlRecord
QCOMPARE( (int)irec->count(), 4 );
if ( ( irec->field( 0 ).type() != QVariant::Int ) &&
- ( irec->field( 0 ).type() != QVariant::String ) ) {
+ ( irec->field( 0 ).type() != QVariant::String ) &&
+ ( irec->field( 0 ).type() != QVariant::Double ) ) {
QFAIL( QString( "Wrong datatype %1 for field 'ID'"
" (expected Int or String)" ).arg( QVariant::typeToName( irec->field( 0 ).type() ) ) );
}
@@ -533,13 +540,18 @@ void tst_Q3SqlCursor::unicode()
cur.del();
if ( res != utf8str ) {
- int i;
- for ( i = 0; i < (int)res.length(); ++i ) {
- if ( res[ i ] != utf8str[ i ] )
- break;
- }
- QFAIL( QString( "Strings differ at position %1: orig: %2, db: %3" ).arg( i ).arg( utf8str[ i ].unicode(), 0, 16 ).arg( res[ i ].unicode(), 0, 16 ) );
+ int i;
+ for ( i = 0; i < (int)res.length(); ++i ) {
+ if ( res[ i ] != utf8str[ i ] )
+ break;
+ }
+ if(db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QDB2"))
+ qWarning() << "Needs someone with more Unicode knowledge than I have to fix:" << QString( "Strings differ at position %1: orig: %2, db: %3" ).arg( i ).arg( utf8str[ i ].unicode(), 0, 16 ).arg( res[ i ].unicode(), 0, 16 );
+ else
+ QFAIL( QString( "Strings differ at position %1: orig: %2, db: %3" ).arg( i ).arg( utf8str[ i ].unicode(), 0, 16 ).arg( res[ i ].unicode(), 0, 16 ) );
}
+ if(db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QDB2"))
+ QEXPECT_FAIL("", "See above message", Continue);
QVERIFY( res == utf8str );
}
@@ -747,12 +759,12 @@ void tst_Q3SqlCursor::insertFieldNameContainsWS() {
QString tableName = qTableName("qtestws");
QSqlQuery q(db);
- q.exec(QString("DROP TABLE %1").arg(tableName));
+ tst_Databases::safeDropTable(db, tableName);
QString query = QString("CREATE TABLE %1 (id int, \"first Name\" varchar(20), "
- "lastName varchar(20))");
- QVERIFY_SQL(q, exec(query.arg(tableName)));
+ "lastName varchar(20))").arg(tableName);
+ QVERIFY_SQL(q, exec(query));
- Q3SqlCursor cur(QString("%1").arg(tableName), true, db);
+ Q3SqlCursor cur(tableName, true, db);
cur.select();
QSqlRecord *r = cur.primeInsert();
@@ -768,8 +780,8 @@ void tst_Q3SqlCursor::insertFieldNameContainsWS() {
QVERIFY(cur.value(0) == 1);
QCOMPARE(cur.value(1).toString(), QString("Kong"));
QCOMPARE(cur.value(2).toString(), QString("Harald"));
-
- q.exec(QString("DROP TABLE %1").arg(tableName));
+
+ tst_Databases::safeDropTable(db, tableName);
}
diff --git a/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp b/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp
index d026cbf..ec1f805 100644
--- a/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp
+++ b/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp
@@ -114,7 +114,7 @@ void tst_Q3SqlSelectCursor::createTestTables( QSqlDatabase db )
void tst_Q3SqlSelectCursor::dropTestTables( QSqlDatabase db )
{
- tst_Databases::safeDropTables( db, QStringList() << qTableName( "qtest" ) );
+ tst_Databases::safeDropTable( db, qTableName( "qtest" ) );
}
void tst_Q3SqlSelectCursor::populateTestTables( QSqlDatabase db )
diff --git a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp
index c117aa4..0bc459e 100644
--- a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp
@@ -212,6 +212,7 @@ private slots:
void task221955_selectedEditor();
void task250754_fontChange();
+ void task200665_itemEntered();
};
class MyAbstractItemDelegate : public QAbstractItemDelegate
@@ -1199,5 +1200,23 @@ void tst_QAbstractItemView::task250754_fontChange()
qApp->setStyleSheet(app_css);
}
+void tst_QAbstractItemView::task200665_itemEntered()
+{
+ //we test that view will emit entered
+ //when the scrollbar move but not the mouse itself
+ QStandardItemModel model(1000,1);
+ QListView view;
+ view.setModel(&model);
+ view.show();
+ QTest::qWait(200);
+ QRect rect = view.visualRect(model.index(0,0));
+ QCursor::setPos( view.viewport()->mapToGlobal(rect.center()) );
+ QSignalSpy spy(&view, SIGNAL(entered(QModelIndex)));
+ view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum());
+ QCOMPARE(spy.count(), 1);
+
+}
+
+
QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc"
diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp
index a87d02f..8a88b59 100644
--- a/tests/auto/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp
@@ -53,12 +53,12 @@
#include "QtTest/qtestaccessible.h"
#if defined(Q_OS_WINCE)
-extern "C" bool SystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);
+extern "C" bool SystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);
#define SPI_GETPLATFORMTYPE 257
inline bool IsValidCEPlatform() {
wchar_t tszPlatform[64];
- if (SystemParametersInfoW(SPI_GETPLATFORMTYPE, sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0)) {
- QString platform = QString::fromUtf16(tszPlatform);
+ if (SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(tszPlatform) / sizeof(*tszPlatform), tszPlatform, 0)) {
+ QString platform = QString::fromWCharArray(tszPlatform);
if ((platform == QLatin1String("PocketPC")) || (platform == QLatin1String("Smartphone")))
return false;
}
diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp
index a11b159..85494af 100644
--- a/tests/auto/qapplication/tst_qapplication.cpp
+++ b/tests/auto/qapplication/tst_qapplication.cpp
@@ -48,6 +48,7 @@
#include "qabstracteventdispatcher.h"
#include <QtGui>
+#include "private/qapplication_p.h"
#include "private/qstylesheetstyle_p.h"
#ifdef Q_OS_WINCE
#include <windows.h>
@@ -117,6 +118,8 @@ private slots:
void windowsCommandLine_data();
void windowsCommandLine();
+
+ void touchEventPropagation();
};
class MyInputContext : public QInputContext
@@ -752,9 +755,9 @@ void tst_QApplication::libraryPaths()
// current Path. Therefore we need to identify it ourselves
// here for the test.
QFileInfo filePath;
- wchar_t module_name[256];
- GetModuleFileNameW(0, module_name, sizeof(module_name) / sizeof(wchar_t));
- filePath = QString::fromUtf16((ushort *)module_name);
+ wchar_t module_name[MAX_PATH];
+ GetModuleFileName(0, module_name, MAX_PATH);
+ filePath = QString::fromWCharArray(module_name);
QString testDir = filePath.path() + "/test";
#endif
QApplication::setLibraryPaths(QStringList() << testDir);
@@ -1773,6 +1776,146 @@ void tst_QApplication::windowsCommandLine()
#endif
}
+class TouchEventPropagationTestWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ bool seenTouchEvent, acceptTouchEvent, seenMouseEvent, acceptMouseEvent;
+
+ TouchEventPropagationTestWidget(QWidget *parent = 0)
+ : QWidget(parent), seenTouchEvent(false), acceptTouchEvent(false), seenMouseEvent(false), acceptMouseEvent(false)
+ { }
+
+ void reset()
+ {
+ seenTouchEvent = acceptTouchEvent = seenMouseEvent = acceptMouseEvent = false;
+ }
+
+ bool event(QEvent *event)
+ {
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ // qDebug() << objectName() << "seenMouseEvent = true";
+ seenMouseEvent = true;
+ event->setAccepted(acceptMouseEvent);
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ // qDebug() << objectName() << "seenTouchEvent = true";
+ seenTouchEvent = true;
+ event->setAccepted(acceptTouchEvent);
+ break;
+ default:
+ return QWidget::event(event);
+ }
+ return true;
+ }
+};
+
+void tst_QApplication::touchEventPropagation()
+{
+ int argc = 1;
+ QApplication app(argc, &argv0, QApplication::GuiServer);
+ QTouchEvent::TouchPoint touchPoint(0);
+ QTouchEvent touchEvent(QEvent::TouchBegin, Qt::NoModifier, QList<QTouchEvent::TouchPoint *>() << (&touchPoint));
+
+ {
+ // touch event behavior on a window
+ TouchEventPropagationTestWidget window;
+ window.setObjectName("1. window");
+
+ QApplicationPrivate::sendTouchEvent(&window, &touchEvent);
+ QVERIFY(!window.seenTouchEvent);
+ QVERIFY(window.seenMouseEvent);
+
+ window.reset();
+ window.setAttribute(Qt::WA_AcceptsTouchEvents);
+ QApplicationPrivate::sendTouchEvent(&window, &touchEvent);
+ QVERIFY(window.seenTouchEvent);
+ QVERIFY(window.seenMouseEvent);
+
+ window.reset();
+ window.acceptTouchEvent = true;
+ QApplicationPrivate::sendTouchEvent(&window, &touchEvent);
+ QVERIFY(window.seenTouchEvent);
+ QVERIFY(!window.seenMouseEvent);
+ }
+
+ {
+ // touch event behavior on a window with a child widget
+ TouchEventPropagationTestWidget window;
+ window.setObjectName("2. window");
+ TouchEventPropagationTestWidget widget(&window);
+ widget.setObjectName("2. widget");
+
+ QApplicationPrivate::sendTouchEvent(&widget, &touchEvent);
+ QVERIFY(!widget.seenTouchEvent);
+ QVERIFY(widget.seenMouseEvent);
+ QVERIFY(!window.seenTouchEvent);
+ QVERIFY(window.seenMouseEvent);
+
+ window.reset();
+ widget.reset();
+ widget.setAttribute(Qt::WA_AcceptsTouchEvents);
+ QApplicationPrivate::sendTouchEvent(&widget, &touchEvent);
+ QVERIFY(widget.seenTouchEvent);
+ QVERIFY(widget.seenMouseEvent);
+ QVERIFY(!window.seenTouchEvent);
+ QVERIFY(window.seenMouseEvent);
+
+ window.reset();
+ widget.reset();
+ widget.acceptMouseEvent = true;
+ QApplicationPrivate::sendTouchEvent(&widget, &touchEvent);
+ QVERIFY(widget.seenTouchEvent);
+ QVERIFY(widget.seenMouseEvent);
+ QVERIFY(!window.seenTouchEvent);
+ QVERIFY(!window.seenMouseEvent);
+
+ window.reset();
+ widget.reset();
+ widget.acceptTouchEvent = true;
+ QApplicationPrivate::sendTouchEvent(&widget, &touchEvent);
+ QVERIFY(widget.seenTouchEvent);
+ QVERIFY(!widget.seenMouseEvent);
+ QVERIFY(!window.seenTouchEvent);
+ QVERIFY(!window.seenMouseEvent);
+
+ window.reset();
+ widget.reset();
+ widget.setAttribute(Qt::WA_AcceptsTouchEvents, false);
+ window.setAttribute(Qt::WA_AcceptsTouchEvents);
+ QApplicationPrivate::sendTouchEvent(&widget, &touchEvent);
+ QVERIFY(!widget.seenTouchEvent);
+ QVERIFY(widget.seenMouseEvent);
+ QVERIFY(window.seenTouchEvent);
+ QVERIFY(window.seenMouseEvent);
+
+ window.reset();
+ widget.reset();
+ window.acceptTouchEvent = true;
+ QApplicationPrivate::sendTouchEvent(&widget, &touchEvent);
+ QVERIFY(!widget.seenTouchEvent);
+ QVERIFY(!widget.seenMouseEvent);
+ QVERIFY(window.seenTouchEvent);
+ QVERIFY(!window.seenMouseEvent);
+
+ window.reset();
+ widget.reset();
+ widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first
+ window.acceptTouchEvent = true;
+ QApplicationPrivate::sendTouchEvent(&widget, &touchEvent);
+ QVERIFY(!widget.seenTouchEvent);
+ QVERIFY(!widget.seenMouseEvent);
+ QVERIFY(window.seenTouchEvent);
+ QVERIFY(!window.seenMouseEvent);
+ }
+}
+
//QTEST_APPLESS_MAIN(tst_QApplication)
int main(int argc, char *argv[])
{
diff --git a/tests/auto/qboxlayout/tst_qboxlayout.cpp b/tests/auto/qboxlayout/tst_qboxlayout.cpp
index f34fc00..be6f3dd 100644
--- a/tests/auto/qboxlayout/tst_qboxlayout.cpp
+++ b/tests/auto/qboxlayout/tst_qboxlayout.cpp
@@ -65,8 +65,53 @@ private slots:
void sizeHint();
void sizeConstraints();
void setGeometry();
+ void setStyleShouldChangeSpacing();
};
+class CustomLayoutStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ CustomLayoutStyle() : QWindowsStyle()
+ {
+ hspacing = 5;
+ vspacing = 10;
+ }
+
+ virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0,
+ const QWidget * widget = 0 ) const;
+
+ int hspacing;
+ int vspacing;
+};
+
+int CustomLayoutStyle::pixelMetric(PixelMetric metric, const QStyleOption * option /*= 0*/,
+ const QWidget * widget /*= 0*/ ) const
+{
+ switch (metric) {
+ case PM_LayoutLeftMargin:
+ return 0;
+ break;
+ case PM_LayoutTopMargin:
+ return 3;
+ break;
+ case PM_LayoutRightMargin:
+ return 6;
+ break;
+ case PM_LayoutBottomMargin:
+ return 9;
+ break;
+ case PM_LayoutHorizontalSpacing:
+ return hspacing;
+ case PM_LayoutVerticalSpacing:
+ return vspacing;
+ break;
+ default:
+ break;
+ }
+ return QWindowsStyle::pixelMetric(metric, option, widget);
+}
+
tst_QBoxLayout::tst_QBoxLayout()
{
@@ -163,12 +208,44 @@ void tst_QBoxLayout::setGeometry()
lay->addLayout(lay2);
w.setLayout(lay);
w.show();
-
+
QRect newGeom(0, 0, 70, 70);
lay2->setGeometry(newGeom);
QApplication::processEvents();
QVERIFY2(newGeom.contains(dial->geometry()), "dial->geometry() should be smaller and within newGeom");
}
+void tst_QBoxLayout::setStyleShouldChangeSpacing()
+{
+
+ QWidget *window = new QWidget;
+ QHBoxLayout *hbox = new QHBoxLayout(window);
+ QPushButton *pb1 = new QPushButton(tr("The spacing between this"));
+ QPushButton *pb2 = new QPushButton(tr("and this button should depend on the style of the parent widget"));;
+ hbox->addWidget(pb1);
+ hbox->addWidget(pb2);
+ CustomLayoutStyle *style1 = new CustomLayoutStyle;
+ style1->hspacing = 6;
+ window->setStyle(style1);
+ window->show();
+
+ QTest::qWait(100);
+ int spacing = pb2->geometry().left() - pb1->geometry().right() - 1;
+ QCOMPARE(spacing, 6);
+
+ CustomLayoutStyle *style2 = new CustomLayoutStyle();
+ style2->hspacing = 10;
+ window->setStyle(style2);
+ QTest::qWait(100);
+ spacing = pb2->geometry().left() - pb1->geometry().right() - 1;
+ QEXPECT_FAIL("", "Fix for next minor release", Continue);
+ QCOMPARE(spacing, 10);
+
+ delete window;
+ delete style1;
+ delete style2;
+}
+
+
QTEST_MAIN(tst_QBoxLayout)
#include "tst_qboxlayout.moc"
diff --git a/tests/auto/qbytearray/tst_qbytearray.cpp b/tests/auto/qbytearray/tst_qbytearray.cpp
index 0e3df53..78fbf32 100644
--- a/tests/auto/qbytearray/tst_qbytearray.cpp
+++ b/tests/auto/qbytearray/tst_qbytearray.cpp
@@ -239,10 +239,6 @@ void tst_QByteArray::qUncompress()
QTEST(::qUncompress(in), "out");
-#if defined Q_WS_MAC && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4)
- QSKIP("Corrupt data causes this test to lock up on Mac OS X Panther", SkipSingle);
-#endif
-
QTEST(::qUncompress(in + "blah"), "out");
}
#endif
diff --git a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp
index 6c73fd6..ab98d1d 100644
--- a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp
+++ b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp
@@ -102,7 +102,7 @@ Q_DECLARE_METATYPE(QList<int>);
#if defined(Q_OS_WINCE)
bool qt_wince_is_platform(const QString &platformString) {
- TCHAR tszPlatform[64];
+ wchar_t tszPlatform[64];
if (SystemParametersInfo(SPI_GETPLATFORMTYPE,
sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0))
if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform))
diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp
index d7e9dff..8d9c2be 100644
--- a/tests/auto/qfile/tst_qfile.cpp
+++ b/tests/auto/qfile/tst_qfile.cpp
@@ -994,57 +994,32 @@ static QString getWorkingDirectoryForLink(const QString &linkFileName)
{
bool neededCoInit = false;
QString ret;
- QT_WA({
- IShellLink *psl;
- HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
- if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
- neededCoInit = true;
- CoInitialize(NULL);
- hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
- }
- if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
- IPersistFile *ppf;
- hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
- if (SUCCEEDED(hres)) {
- hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ);
- //The original path of the link is retrieved. If the file/folder
- //was moved, the return value still have the old path.
- if(SUCCEEDED(hres)) {
- wchar_t szGotPath[MAX_PATH];
- if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR)
- ret = QString::fromUtf16((ushort*)szGotPath);
- }
- ppf->Release();
- }
- psl->Release();
- }
- },{
- IShellLinkA *psl;
- HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
- if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
- neededCoInit = true;
- CoInitialize(NULL);
- hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
- }
+ IShellLink *psl;
+ HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
+ if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
+ neededCoInit = true;
+ CoInitialize(NULL);
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
+ }
- if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
- IPersistFile *ppf;
- hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
- if (SUCCEEDED(hres)) {
- hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ);
- //The original path of the link is retrieved. If the file/folder
- //was moved, the return value still have the old path.
- if(SUCCEEDED(hres)) {
- char szGotPath[MAX_PATH];
- if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR)
- ret = QString::fromLocal8Bit(szGotPath);
- }
- ppf->Release();
+ if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
+ IPersistFile *ppf;
+ hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
+ if (SUCCEEDED(hres)) {
+ hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ);
+ //The original path of the link is retrieved. If the file/folder
+ //was moved, the return value still have the old path.
+ if(SUCCEEDED(hres)) {
+ wchar_t szGotPath[MAX_PATH];
+ if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR)
+ ret = QString::fromWCharArray(szGotPath);
}
- psl->Release();
+ ppf->Release();
}
- });
+ psl->Release();
+ }
+
if (neededCoInit) {
CoUninitialize();
}
@@ -1538,13 +1513,8 @@ void tst_QFile::largeFileSupport()
qlonglong freespace = qlonglong(0);
#ifdef Q_WS_WIN
_ULARGE_INTEGER free;
- if (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) {
- if (::GetDiskFreeSpaceExW((wchar_t *)QDir::currentPath().utf16(), &free, 0, 0))
- freespace = free.QuadPart;
- } else {
- if (::GetDiskFreeSpaceExA(QDir::currentPath().local8Bit(), &free, 0, 0))
- freespace = free.QuadPart;
- }
+ if (::GetDiskFreeSpaceEx((wchar_t*)QDir::currentPath().utf16(), &free, 0, 0))
+ freespace = free.QuadPart;
if (freespace != 0) {
#elif defined(Q_OS_IRIX)
struct statfs info;
@@ -1662,16 +1632,9 @@ void tst_QFile::longFileName()
}
{
QFile file(fileName);
-#if defined(Q_WS_WIN)
-#if !defined(Q_OS_WINCE)
- QT_WA({ if (false) ; }, {
- QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort);
- QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort);
- });
-#else
- QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort);
- QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort);
-#endif
+#if defined(Q_OS_WINCE)
+ QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort);
+ QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort);
#endif
QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
QTextStream ts(&file);
diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp
index 1a73948..48dc357 100644
--- a/tests/auto/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp
@@ -862,11 +862,6 @@ void tst_QFileInfo::fileTimes()
#if !defined(Q_OS_UNIX) && !defined(Q_OS_WINCE)
QVERIFY(fileInfo.created() < beforeWrite);
#endif
-#ifdef Q_OS_WIN
- if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) {
- QVERIFY(fileInfo.lastRead().addDays(1) > beforeRead);
- } else
-#endif
//In Vista the last-access timestamp is not updated when the file is accessed/touched (by default).
//To enable this the HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate
//is set to 0, in the test machine.
@@ -897,26 +892,14 @@ void tst_QFileInfo::fileTimes_oldFile()
// WriteOnly can create files, ReadOnly cannot.
DWORD creationDisp = OPEN_ALWAYS;
- HANDLE fileHandle;
-
// Create the file handle.
- QT_WA({
- fileHandle = CreateFileW(L"oldfile.txt",
- accessRights,
- shareMode,
- &securityAtts,
- creationDisp,
- flagsAndAtts,
- NULL);
- }, {
- fileHandle = CreateFileA("oldfile.txt",
- accessRights,
- shareMode,
- &securityAtts,
- creationDisp,
- flagsAndAtts,
- NULL);
- });
+ HANDLE fileHandle = CreateFile(L"oldfile.txt",
+ accessRights,
+ shareMode,
+ &securityAtts,
+ creationDisp,
+ flagsAndAtts,
+ NULL);
// Set file times back to 1601.
FILETIME ctime;
diff --git a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
index ce4828a..a548329 100644
--- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
+++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
@@ -153,8 +153,11 @@ void tst_QGraphicsGridLayout::qgraphicsgridlayout()
layout.columnStretchFactor(0);
layout.count();
layout.horizontalSpacing();
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsGridLayout::itemAt: invalid row, column 0, 0");
layout.itemAt(0, 0);
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsGridLayout::itemAt: invalid index 0");
layout.itemAt(0);
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsGridLayout::removeAt: invalid index 0");
layout.removeAt(0);
layout.rowAlignment(0);
layout.rowCount();
@@ -191,7 +194,7 @@ class RectWidget : public QGraphicsWidget
public:
RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent){}
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
@@ -235,11 +238,11 @@ static void populateLayout(QGraphicsGridLayout *gridLayout, int width, int heigh
* |+---|---+|xxxx|
* ||span=2 ||hole|
* |+---|---+|xxxx|
- * +----+----+----+
+ * +----+----+----+
* |xxxx|+---|---+|
* |hole||span=2 ||
* |xxxx|+---|---+|
- * +----+----+----+
+ * +----+----+----+
*/
static void populateLayoutWithSpansAndHoles(QGraphicsGridLayout *gridLayout)
{
@@ -296,7 +299,7 @@ void tst_QGraphicsGridLayout::addItem()
QTest::ignoreMessage(QtWarningMsg, "QGraphicsGridLayout::addItem: invalid row/column: -1");
} else if (rowSpan < 1 || columnSpan < 1) {
char buf[1024];
- ::qsnprintf(buf, sizeof(buf), "QGraphicsGridLayout::addItem: invalid row span/column span: %d",
+ ::qsnprintf(buf, sizeof(buf), "QGraphicsGridLayout::addItem: invalid row span/column span: %d",
rowSpan < 1 ? rowSpan : columnSpan);
QTest::ignoreMessage(QtWarningMsg, buf);
}
@@ -458,7 +461,7 @@ void tst_QGraphicsGridLayout::columnCount()
QCOMPARE(layout->columnCount(), 3);
layout->addItem(new RectWidget(widget), 1, 2);
QCOMPARE(layout->columnCount(), 3);
-
+
// ### Talk with Jasmin. Not sure if removeAt() should adjust columnCount().
widget->setLayout(0);
layout = new QGraphicsGridLayout();
@@ -524,7 +527,7 @@ void tst_QGraphicsGridLayout::columnMinimumWidth()
populateLayout(layout, 3, 2);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
-
+
// should at least be a very large number
QCOMPARE(layout->columnMinimumWidth(0), 0.0);
QCOMPARE(layout->columnMinimumWidth(0), layout->columnMinimumWidth(1));
@@ -559,7 +562,7 @@ void tst_QGraphicsGridLayout::columnPreferredWidth()
populateLayout(layout, 3, 2);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
-
+
// default preferred width ??
QCOMPARE(layout->columnPreferredWidth(0), 0.0);
QCOMPARE(layout->columnPreferredWidth(0), layout->columnPreferredWidth(1));
@@ -594,7 +597,7 @@ void tst_QGraphicsGridLayout::setColumnFixedWidth()
populateLayout(layout, 3, 2);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
-
+
layout->setColumnFixedWidth(0, 20);
layout->setColumnFixedWidth(2, 40);
@@ -626,7 +629,7 @@ void tst_QGraphicsGridLayout::columnSpacing()
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
QCOMPARE(layout->columnSpacing(0), 0.0);
-
+
layout->setColumnSpacing(0, 20);
view.show();
widget->show();
@@ -655,7 +658,7 @@ void tst_QGraphicsGridLayout::columnStretchFactor()
populateLayout(layout, 3, 2);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
-
+
layout->setColumnStretchFactor(0, 1);
layout->setColumnStretchFactor(1, 2);
layout->setColumnStretchFactor(2, 3);
@@ -741,7 +744,7 @@ void tst_QGraphicsGridLayout::contentsMargins()
scene.addItem(widget);
widget->setLayout(layout);
layout->addItem(sublayout,0, 1);
-
+
qreal left, top, right, bottom;
// sublayouts have 0 margin
sublayout->getContentsMargins(&left, &top, &right, &bottom);
@@ -750,7 +753,7 @@ void tst_QGraphicsGridLayout::contentsMargins()
QCOMPARE(right, 0.0);
QCOMPARE(bottom, 0.0);
- // top level layouts have style dependent margins.
+ // top level layouts have style dependent margins.
// we'll just check if its different from 0. (applies to all our styles)
layout->getContentsMargins(&left, &top, &right, &bottom);
QVERIFY(left >= 0.0);
@@ -771,7 +774,7 @@ void tst_QGraphicsGridLayout::itemAt()
scene.addItem(widget);
widget->setLayout(layout);
populateLayoutWithSpansAndHoles(layout);
-
+
//itemAt(int row, int column)
QVERIFY( layout->itemAt(0,0));
QVERIFY( layout->itemAt(0,1));
@@ -874,7 +877,7 @@ void tst_QGraphicsGridLayout::rowAlignment()
QCOMPARE(layout->alignment(layout->itemAt(1,0)), Qt::AlignTop);
QCOMPARE(layout->itemAt(1,0)->geometry(), QRectF(0, 101, 50, 50));
QCOMPARE(layout->rowAlignment(1), Qt::AlignVCenter);
- QCOMPARE(layout->itemAt(1,1)->geometry(), QRectF(101, 126, 50, 50));
+ QCOMPARE(layout->itemAt(1,1)->geometry(), QRectF(101, 126, 50, 50));
QCOMPARE(layout->alignment(layout->itemAt(2,0)), Qt::AlignHCenter);
QCOMPARE(layout->itemAt(2,0)->geometry(), QRectF(25, 202, 50, 50));
QCOMPARE(layout->rowAlignment(2), Qt::AlignTop);
@@ -922,7 +925,7 @@ void tst_QGraphicsGridLayout::rowMaximumHeight()
populateLayout(layout, 2, 3);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
-
+
// should at least be a very large number
QVERIFY(layout->rowMaximumHeight(0) >= 10000);
QCOMPARE(layout->rowMaximumHeight(0), layout->rowMaximumHeight(1));
@@ -957,7 +960,7 @@ void tst_QGraphicsGridLayout::rowMinimumHeight()
populateLayout(layout, 2, 3);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
-
+
// should at least be a very large number
QCOMPARE(layout->rowMinimumHeight(0), 0.0);
QCOMPARE(layout->rowMinimumHeight(0), layout->rowMinimumHeight(1));
@@ -992,7 +995,7 @@ void tst_QGraphicsGridLayout::rowPreferredHeight()
populateLayout(layout, 2, 3);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
-
+
// default preferred height ??
QCOMPARE(layout->rowPreferredHeight(0), 0.0);
QCOMPARE(layout->rowPreferredHeight(0), layout->rowPreferredHeight(1));
@@ -1028,7 +1031,7 @@ void tst_QGraphicsGridLayout::setRowFixedHeight()
populateLayout(layout, 2, 3);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
-
+
layout->setRowFixedHeight(0, 20.);
layout->setRowFixedHeight(2, 40.);
@@ -1060,7 +1063,7 @@ void tst_QGraphicsGridLayout::rowSpacing()
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
QCOMPARE(layout->columnSpacing(0), 0.0);
-
+
layout->setColumnSpacing(0, 20);
view.show();
widget->show();
@@ -1090,7 +1093,7 @@ void tst_QGraphicsGridLayout::rowStretchFactor()
populateLayout(layout, 2, 3);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
-
+
layout->setRowStretchFactor(0, 1);
layout->setRowStretchFactor(1, 2);
layout->setRowStretchFactor(2, 3);
@@ -1121,7 +1124,7 @@ void tst_QGraphicsGridLayout::setColumnSpacing()
{
QFETCH(int, column);
QFETCH(qreal, spacing);
-
+
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
@@ -1175,7 +1178,7 @@ void tst_QGraphicsGridLayout::setRowSpacing()
{
QFETCH(int, row);
QFETCH(qreal, spacing);
-
+
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
@@ -1229,7 +1232,7 @@ void tst_QGraphicsGridLayout::setSpacing()
void tst_QGraphicsGridLayout::sizeHint_data()
{
-
+
/*
QTest::addColumn<Qt::SizeHint>("which");
QTest::addColumn<QSizeF>("constraint");
@@ -1308,7 +1311,7 @@ void tst_QGraphicsGridLayout::layoutDirection()
RectWidget *w4 = new RectWidget;
w4->setMinimumSize(30, 20);
layout->addItem(w4, 1, 1);
-
+
layout->setAlignment(w2, Qt::AlignRight);
layout->setAlignment(w3, Qt::AlignLeft);
@@ -1325,7 +1328,7 @@ void tst_QGraphicsGridLayout::layoutDirection()
QCOMPARE(w3->geometry().right(), 21.0);
QCOMPARE(w4->geometry().left(), 37.0);
QCOMPARE(w4->geometry().right(), 67.0);
-
+
window->setLayoutDirection(Qt::RightToLeft);
QApplication::processEvents();
QCOMPARE(w1->geometry().left(), 39.0);
@@ -1336,7 +1339,7 @@ void tst_QGraphicsGridLayout::layoutDirection()
QCOMPARE(w3->geometry().right(), 69.0);
QCOMPARE(w4->geometry().left(), 3.0);
QCOMPARE(w4->geometry().right(), 33.0);
-
+
delete window;
}
@@ -1437,7 +1440,7 @@ struct ItemDesc
m_sizes[Qt::MaximumSize] = sz;
return (*this);
}
-
+
ItemDesc &alignment(Qt::Alignment alignment) {
m_align = alignment;
return (*this);
@@ -1506,8 +1509,8 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF()
<< (SizeList()
- << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
- << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
+ << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
+ << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
);
QTest::newRow("ignoreitem01") << (ItemList()
@@ -1527,8 +1530,8 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF()
<< (SizeList()
- << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
- << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
+ << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
+ << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
);
QTest::newRow("ignoreitem01_resize120x40") << (ItemList()
@@ -1548,8 +1551,8 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF(120, 40)
<< (SizeList()
- << QSizeF(20,20) << QSizeF(40,20) << QSizeF(60,20)
- << QSizeF(20,20) << QSizeF(40,20) << QSizeF(60,20)
+ << QSizeF(20,20) << QSizeF(40,20) << QSizeF(60,20)
+ << QSizeF(20,20) << QSizeF(40,20) << QSizeF(60,20)
);
QTest::newRow("ignoreitem11_resize120x40") << (ItemList()
@@ -1569,8 +1572,8 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF(120, 60)
<< (SizeList()
- << QSizeF(20,20) << QSizeF(40,20) << QSizeF(60,20)
- << QSizeF(20,40) << QSizeF(40,40) << QSizeF(60,40)
+ << QSizeF(20,20) << QSizeF(40,20) << QSizeF(60,20)
+ << QSizeF(20,40) << QSizeF(40,40) << QSizeF(60,40)
);
QTest::newRow("ignoreitem01_span01_resize70x60") << (ItemList()
@@ -1589,10 +1592,10 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF(70, 60)
<< (SizeList()
- << QSizeF(20,20) << QSizeF(10,60) << QSizeF(40,20)
- << QSizeF(20,40) << QSizeF(40,40)
+ << QSizeF(20,20) << QSizeF(10,60) << QSizeF(40,20)
+ << QSizeF(20,40) << QSizeF(40,40)
);
-
+
QTest::newRow("ignoreitem10_resize40x120") << (ItemList()
<< ItemDesc(0,0)
.preferredSizeHint(QSizeF(10,10))
@@ -1610,11 +1613,11 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF(40, 120)
<< (SizeList()
- << QSizeF(20,20) << QSizeF(20,20)
- << QSizeF(20,40) << QSizeF(20,40)
- << QSizeF(20,60) << QSizeF(20,60)
+ << QSizeF(20,20) << QSizeF(20,20)
+ << QSizeF(20,40) << QSizeF(20,40)
+ << QSizeF(20,60) << QSizeF(20,60)
);
-
+
QTest::newRow("ignoreitem01_span02") << (ItemList()
<< ItemDesc(0,0)
.preferredSizeHint(QSizeF(10,10))
@@ -1631,7 +1634,7 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF()
<< (SizeList()
- << QSizeF(10,10) << QSizeF(0,20) << QSizeF(10,10)
+ << QSizeF(10,10) << QSizeF(0,20) << QSizeF(10,10)
<< QSizeF(10,10) << QSizeF(10,10)
);
@@ -1651,7 +1654,7 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF()
<< (SizeList()
- << QSizeF(10,10) << QSizeF(10,10) << QSizeF(0,20)
+ << QSizeF(10,10) << QSizeF(10,10) << QSizeF(0,20)
<< QSizeF(10,10) << QSizeF(10,10)
);
@@ -1670,7 +1673,7 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF()
<< (SizeList()
- << QSizeF(10,20) << QSizeF(10,10) << QSizeF(0,20)
+ << QSizeF(10,20) << QSizeF(10,10) << QSizeF(0,20)
<< QSizeF(10,10)
);
@@ -1690,7 +1693,7 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF()
<< (SizeList()
- << QSizeF(20,10) << QSizeF(10,10) << QSizeF(10,10)
+ << QSizeF(20,10) << QSizeF(10,10) << QSizeF(10,10)
<< QSizeF(10,10) << QSizeF(10,10)
);
@@ -1710,10 +1713,10 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF()
<< (SizeList()
- << QSizeF(10,10) << QSizeF(20,10) << QSizeF(10,10)
+ << QSizeF(10,10) << QSizeF(20,10) << QSizeF(10,10)
<< QSizeF(10,10) << QSizeF(10,10)
);
-
+
QTest::newRow("ignorecolumn1_resize70x60") << (ItemList()
<< ItemDesc(0,0)
.preferredSizeHint(QSizeF(10,10))
@@ -1732,8 +1735,8 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF(70, 60)
<< (SizeList()
- << QSizeF(20,20) << QSizeF(10,20) << QSizeF(40,20)
- << QSizeF(20,40) << QSizeF(10,40) << QSizeF(40,40)
+ << QSizeF(20,20) << QSizeF(10,20) << QSizeF(40,20)
+ << QSizeF(20,40) << QSizeF(10,40) << QSizeF(40,40)
);
QTest::newRow("ignorerow0") << (ItemList()
@@ -1756,7 +1759,7 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
<< QSizeF()
<< (SizeList()
<< QSizeF(10,0) << QSizeF(10,0) << QSizeF(10,0)
- << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
+ << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
);
QTest::newRow("ignorerow1") << (ItemList()
@@ -1778,10 +1781,10 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
)
<< QSizeF()
<< (SizeList()
- << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
+ << QSizeF(10,10) << QSizeF(10,10) << QSizeF(10,10)
<< QSizeF(10,0) << QSizeF(10,0) << QSizeF(10,0)
);
-
+
QTest::newRow("ignorerow0_resize60x50") << (ItemList()
<< ItemDesc(0,0)
.sizePolicy(QSizePolicy::Ignored)
@@ -1802,9 +1805,9 @@ void tst_QGraphicsGridLayout::defaultStretchFactors_data()
<< QSizeF(60, 50)
<< (SizeList()
<< QSizeF(10,10) << QSizeF(20,10) << QSizeF(30,10)
- << QSizeF(10,40) << QSizeF(20,40) << QSizeF(30,40)
+ << QSizeF(10,40) << QSizeF(20,40) << QSizeF(30,40)
);
-
+
}
void tst_QGraphicsGridLayout::defaultStretchFactors()
@@ -1837,13 +1840,13 @@ void tst_QGraphicsGridLayout::defaultStretchFactors()
view.resize(400,300);
if (newSize.isValid())
widget->resize(newSize);
-
+
QApplication::processEvents();
for (i = 0; i < expectedSizes.count(); ++i) {
QSizeF itemSize = layout->itemAt(i)->geometry().size();
QCOMPARE(itemSize, expectedSizes.at(i));
}
-
+
delete widget;
}
@@ -2024,7 +2027,7 @@ void tst_QGraphicsGridLayout::geometries_data()
<< (RectList()
<< QRectF(0, 0, 50,10) << QRectF(0, 10, 10,10)
);
-
+
QTest::newRow("combine_min_sizes") << (ItemList()
<< ItemDesc(0,0)
.minSize(QSizeF(50,10))
@@ -2035,7 +2038,7 @@ void tst_QGraphicsGridLayout::geometries_data()
<< (RectList()
<< QRectF(0, 0, 60,10) << QRectF(0, 10, 60,10)
);
-
+
}
void tst_QGraphicsGridLayout::geometries()
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
index 981efeb..7552f18 100644
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -173,6 +173,7 @@ private slots:
void sceneBoundingRect();
void childrenBoundingRect();
void childrenBoundingRectTransformed();
+ void childrenBoundingRect2();
void group();
void setGroup();
void nestedGroups();
@@ -2995,6 +2996,16 @@ void tst_QGraphicsItem::childrenBoundingRectTransformed()
QCOMPARE(rect->childrenBoundingRect(), QRectF(-100, 75, 275, 250));
}
+void tst_QGraphicsItem::childrenBoundingRect2()
+{
+ QGraphicsItemGroup box;
+ QGraphicsLineItem l1(0, 0, 100, 0, &box);
+ QGraphicsLineItem l2(100, 0, 100, 100, &box);
+ QGraphicsLineItem l3(0, 0, 0, 100, &box);
+ // Make sure lines (zero with/height) are included in the childrenBoundingRect.
+ QCOMPARE(box.childrenBoundingRect(), QRectF(0, 0, 100, 100));
+}
+
void tst_QGraphicsItem::group()
{
QGraphicsScene scene;
diff --git a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
index b61b2bb..a30e5e5 100644
--- a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
+++ b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
@@ -163,19 +163,19 @@ class RectWidget : public QGraphicsWidget
public:
RectWidget(QGraphicsItem *parent = 0, const QBrush &brush = QBrush()) : QGraphicsWidget(parent){ m_brush = brush;}
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
painter->setBrush(m_brush);
painter->drawRoundRect(rect());
}
-
+
void setSizeHint(Qt::SizeHint which, const QSizeF &size) {
m_sizeHints[which] = size;
updateGeometry();
}
-
+
virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const {
if (m_sizeHints[which].isValid()) {
return m_sizeHints[which];
@@ -210,17 +210,16 @@ void tst_QGraphicsLinearLayout::qgraphicslinearlayout()
layout.setOrientation(Qt::Vertical);
layout.orientation();
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert null item");
- //QCOMPARE(layout.count(), 0);
+ QCOMPARE(layout.count(), 0);
layout.addItem(0);
- //QCOMPARE(layout.count(), 0);
+ QCOMPARE(layout.count(), 0);
layout.addStretch(0);
- //QCOMPARE(layout.count(), 1);
+ QCOMPARE(layout.count(), 0);
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert null item");
layout.insertItem(0, 0);
layout.insertStretch(0, 0);
layout.removeItem(0);
- layout.removeAt(0);
- //QCOMPARE(layout.count(), 1);
+ QCOMPARE(layout.count(), 0);
layout.setSpacing(0);
layout.spacing();
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::setStretchFactor: cannot assign a stretch factor to a null item");
@@ -231,8 +230,7 @@ void tst_QGraphicsLinearLayout::qgraphicslinearlayout()
QCOMPARE(layout.alignment(0), 0);
layout.setGeometry(QRectF());
layout.geometry();
- //QCOMPARE(layout.count(), 1);
- layout.itemAt(0);
+ QCOMPARE(layout.count(), 0);
layout.invalidate();
layout.sizeHint(Qt::MinimumSize, QSizeF());
}
@@ -285,7 +283,7 @@ void tst_QGraphicsLinearLayout::alignment()
int i;
bool addWidget = true;
for (i = 0; i < sizeof(alignmentsToTest)/sizeof(Qt::Alignment); ++i) {
- QGraphicsLayoutItem *loutItem;
+ QGraphicsLayoutItem *loutItem;
Qt::Alignment align = alignmentsToTest[i];
if (!align && i > 0)
addWidget = false;
@@ -537,7 +535,10 @@ void tst_QGraphicsLinearLayout::insertItem()
QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
layout.insertItem(insertItemAt, item);
QCOMPARE(layout.count(), itemCount + layoutCount + 1);
- QCOMPARE(layout.itemAt(insertItemAt), insertItemAt == -1 ? (QGraphicsLayoutItem*)0 : item);
+
+ if (insertItemAt >= 0 && (itemCount + layoutCount >= 0)) {
+ QCOMPARE(layout.itemAt(itemCount + layoutCount), item);
+ }
layout.activate();
QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
@@ -599,8 +600,7 @@ void tst_QGraphicsLinearLayout::insertStretch()
}
widget->setLayout(layout);
layout->insertStretch(insertItemAt, stretch);
- QCOMPARE(layout->itemAt(insertItemAt), (QGraphicsLayoutItem*)0);
- QCOMPARE(layout->count(), itemCount + layoutCount + 1);
+ QCOMPARE(layout->count(), itemCount + layoutCount);
layout->activate();
view.show();
@@ -669,7 +669,6 @@ void tst_QGraphicsLinearLayout::invalidate()
void tst_QGraphicsLinearLayout::itemAt_data()
{
QTest::addColumn<int>("index");
- QTest::newRow("-1") << -1;
QTest::newRow("0") << 0;
QTest::newRow("1") << 1;
QTest::newRow("2") << 2;
@@ -681,7 +680,10 @@ void tst_QGraphicsLinearLayout::itemAt()
// see also the insertItem() etc tests
QFETCH(int, index);
SubQGraphicsLinearLayout layout;
- QCOMPARE(layout.itemAt(index), (QGraphicsLayoutItem*)0);
+ for (int i = 0; i < 3; ++i)
+ layout.addItem(new QGraphicsWidget);
+
+ QVERIFY(layout.itemAt(index) != 0);
}
void tst_QGraphicsLinearLayout::orientation_data()
@@ -695,7 +697,7 @@ void tst_QGraphicsLinearLayout::orientation_data()
void tst_QGraphicsLinearLayout::orientation()
{
QFETCH(Qt::Orientation, orientation);
-
+
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
@@ -721,7 +723,7 @@ void tst_QGraphicsLinearLayout::orientation()
qreal pos;
if (initialOrientation == Qt::Horizontal)
pos = item->pos().x();
- else
+ else
pos = item->pos().y();
positions.append(pos);
@@ -736,7 +738,7 @@ void tst_QGraphicsLinearLayout::orientation()
QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(i));
if (initialOrientation == Qt::Horizontal)
QCOMPARE(item->pos().y(), positions.at(i));
- else
+ else
QCOMPARE(item->pos().x(), positions.at(i));
}
@@ -779,19 +781,18 @@ void tst_QGraphicsLinearLayout::removeAt()
layout.addItem(new SubQGraphicsLinearLayout);
QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
- QGraphicsLayoutItem *w = layout.itemAt(removeItemAt);
- QGraphicsLayoutItem *wParent = 0;
+ QGraphicsLayoutItem *w = 0;
+ if (removeItemAt >= 0 && removeItemAt < layout.count())
+ w = layout.itemAt(removeItemAt);
if (w) {
- wParent = w->parentLayoutItem();
+ QGraphicsLayoutItem *wParent = w->parentLayoutItem();
QCOMPARE(wParent, static_cast<QGraphicsLayoutItem *>(&layout));
- }
- layout.removeAt(removeItemAt);
- if (w) {
+ layout.removeAt(removeItemAt);
wParent = w->parentLayoutItem();
QCOMPARE(wParent, static_cast<QGraphicsLayoutItem *>(0));
+ delete w;
}
- delete w;
- QCOMPARE(layout.count(), itemCount + layoutCount - ((removeItemAt == -1) ? 0 : 1));
+ QCOMPARE(layout.count(), itemCount + layoutCount - (w ? 1 : 0));
layout.activate();
QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
@@ -829,11 +830,15 @@ void tst_QGraphicsLinearLayout::removeItem()
for (int i = 0; i < layoutCount; ++i)
layout.addItem(new SubQGraphicsLinearLayout);
- QGraphicsLayoutItem *w = layout.itemAt(removeItemAt);
+ QGraphicsLayoutItem *w = 0;
+ if (removeItemAt >= 0 && removeItemAt < layout.count())
+ w = layout.itemAt(removeItemAt);
QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
- layout.removeItem(w);
- delete w;
- QCOMPARE(layout.count(), itemCount + layoutCount - ((removeItemAt == -1) ? 0 : 1));
+ if (w) {
+ layout.removeItem(w);
+ delete w;
+ }
+ QCOMPARE(layout.count(), itemCount + layoutCount - (w ? 1 : 0));
layout.activate();
QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
@@ -882,7 +887,7 @@ void tst_QGraphicsLinearLayout::setSpacing_data()
void tst_QGraphicsLinearLayout::setSpacing()
{
QFETCH(qreal, spacing);
-
+
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
@@ -994,7 +999,7 @@ void tst_QGraphicsLinearLayout::itemSpacing()
/**
* The stretch factors are not applied linearly, but they are used together with both the preferred size, maximum size to form the
* internal effective stretch factor.
- * There is only need to apply stretch factors if the size of the layout is different than the layouts preferred size.
+ * There is only need to apply stretch factors if the size of the layout is different than the layouts preferred size.
* (If the size of the layout is the preferred size, then all items should get their preferred sizes.
* However, imagine this use case:
* Layout
@@ -1007,7 +1012,7 @@ void tst_QGraphicsLinearLayout::itemSpacing()
* layout->resize(120, h)
*
* In QLayout, C would become 50, B would become 50 and A would get 20. When scaling a layout this would give a jerky feeling, since
- * the item with the highest stretch factor will first resize. When that has reached its maximum the next candidate for stretch will
+ * the item with the highest stretch factor will first resize. When that has reached its maximum the next candidate for stretch will
* resize, and finally, item with the lowest stretch factor will resize.
* In QGraphicsLinearLayout we try to scale all items so that they all reach their maximum at the same time. This means that
* their relative sizes are not proportional to their stretch factors.
@@ -1059,7 +1064,7 @@ void tst_QGraphicsLinearLayout::setStretchFactor()
view.show();
widget->show();
-
+
qreal firstStretch = -1;
qreal firstExtent = -1.;
qreal sumExtent = 0;
@@ -1073,7 +1078,7 @@ void tst_QGraphicsLinearLayout::setStretchFactor()
QCOMPARE(extent, firstExtent);
else if (stretch > firstStretch)
QVERIFY(extent > firstExtent);
- else
+ else
QVERIFY(extent < firstExtent);
} else {
firstStretch = (qreal)stretch;
@@ -1082,7 +1087,7 @@ void tst_QGraphicsLinearLayout::setStretchFactor()
sumExtent+= extent;
}
QCOMPARE(sumExtent, totalSize);
-
+
delete widget;
}
@@ -1167,7 +1172,7 @@ void tst_QGraphicsLinearLayout::defaultStretchFactors()
QSizePolicy sp = item->sizePolicy();
if (orientation == Qt::Horizontal)
sp.setHorizontalPolicy(QSizePolicy::Policy(sp.horizontalPolicy() | QSizePolicy::IgnoreFlag));
- else
+ else
sp.setVerticalPolicy(QSizePolicy::Policy(sp.verticalPolicy() | QSizePolicy::IgnoreFlag));
item->setSizePolicy(sp);
}
@@ -1180,7 +1185,7 @@ void tst_QGraphicsLinearLayout::defaultStretchFactors()
view.resize(400,300);
if (newSize.isValid())
widget->resize(newSize);
-
+
QApplication::processEvents();
for (i = 0; i < count; ++i) {
QSizeF itemSize = layout->itemAt(i)->geometry().size();
@@ -1189,7 +1194,7 @@ void tst_QGraphicsLinearLayout::defaultStretchFactors()
if (i < expectedSizes.count())
QCOMPARE(itemSize.width(), qreal(expectedSizes.at(i)));
}
-
+
delete widget;
}
@@ -1254,7 +1259,7 @@ void tst_QGraphicsLinearLayout::updateGeometry()
layout->setContentsMargins(0, 0, 0, 0);
QCOMPARE(w1->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout));
QCOMPARE(layout->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(window));
-
+
view.show();
QApplication::processEvents();
QCOMPARE(window->size().toSize(), QSize(100, 50));
@@ -1283,7 +1288,7 @@ void tst_QGraphicsLinearLayout::updateGeometry()
QApplication::processEvents();
w1->setMinimumSize(120, 60);
QApplication::processEvents();
- QCOMPARE(window->size().toSize(), QSize(124, 64));
+ QCOMPARE(window->size().toSize(), QSize(124, 64));
}
{
@@ -1341,7 +1346,7 @@ void tst_QGraphicsLinearLayout::layoutDirection()
w2->setPreferredSize(20, 20);
w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
layout->addItem(w2);
-
+
scene.addItem(window);
window->setLayout(layout);
view.show();
@@ -1359,7 +1364,7 @@ void tst_QGraphicsLinearLayout::layoutDirection()
QCOMPARE(w1->geometry().left(), 29.0);
QCOMPARE(w2->geometry().right(), 23.0);
QCOMPARE(w2->geometry().left(), 3.0);
-
+
delete window;
}
diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
index 6439125..4247cca 100644
--- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -141,7 +141,7 @@ protected:
}
};
-class EventSpy : public QObject
+class EventSpy : public QGraphicsWidget
{
Q_OBJECT
public:
@@ -151,6 +151,13 @@ public:
watched->installEventFilter(this);
}
+ EventSpy(QGraphicsScene *scene, QGraphicsItem *watched, QEvent::Type type)
+ : _count(0), spied(type)
+ {
+ scene->addItem(this);
+ watched->installSceneEventFilter(this);
+ }
+
int count() const { return _count; }
protected:
@@ -162,6 +169,14 @@ protected:
return false;
}
+ bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+ {
+ Q_UNUSED(watched);
+ if (event->type() == spied)
+ ++_count;
+ return false;
+ }
+
int _count;
QEvent::Type spied;
};
@@ -236,6 +251,7 @@ private slots:
void changedSignal();
void stickyFocus_data();
void stickyFocus();
+ void sendEvent();
// task specific tests below me
void task139710_bspTreeCrash();
@@ -3587,5 +3603,16 @@ void tst_QGraphicsScene::stickyFocus()
QCOMPARE(text->hasFocus(), sticky);
}
+void tst_QGraphicsScene::sendEvent()
+{
+ QGraphicsScene scene;
+ QGraphicsTextItem *item = scene.addText(QString());
+ EventSpy *spy = new EventSpy(&scene, item, QEvent::User);
+ QCOMPARE(spy->count(), 0);
+ QEvent event(QEvent::User);
+ scene.sendEvent(item, &event);
+ QCOMPARE(spy->count(), 1);
+}
+
QTEST_MAIN(tst_QGraphicsScene)
#include "tst_qgraphicsscene.moc"
diff --git a/tests/auto/qgroupbox/tst_qgroupbox.cpp b/tests/auto/qgroupbox/tst_qgroupbox.cpp
index 2fa553f..3b94851 100644
--- a/tests/auto/qgroupbox/tst_qgroupbox.cpp
+++ b/tests/auto/qgroupbox/tst_qgroupbox.cpp
@@ -80,6 +80,7 @@ private slots:
void clicked();
void toggledVsClicked();
void childrenAreDisabled();
+ void propagateFocus();
private:
bool checked;
@@ -459,5 +460,15 @@ void tst_QGroupBox::childrenAreDisabled()
}
}
+void tst_QGroupBox::propagateFocus()
+{
+ QGroupBox box;
+ QLineEdit lineEdit(&box);
+ box.show();
+ box.setFocus();
+ QTest::qWait(250);
+ QCOMPARE(qApp->focusWidget(), &lineEdit);
+}
+
QTEST_MAIN(tst_QGroupBox)
#include "tst_qgroupbox.moc"
diff --git a/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro b/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro
index 0755055..2e41fcd 100644
--- a/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro
+++ b/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro
@@ -1,5 +1,5 @@
load(qttest_p4)
SOURCES += tst_qhttpnetworkreply.cpp
-INCLUDEPATH += $$(QTDIR)/src/3rdparty/zlib
+INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/zlib
QT = core network
diff --git a/tests/auto/qitemmodel/qitemmodel.pro b/tests/auto/qitemmodel/qitemmodel.pro
index c51f4c7..38c615b 100644
--- a/tests/auto/qitemmodel/qitemmodel.pro
+++ b/tests/auto/qitemmodel/qitemmodel.pro
@@ -1,6 +1,5 @@
-CONFIG += qtestlib
+load(qttest_p4)
SOURCES += tst_qitemmodel.cpp
-TARGET = tst_qitemmodel
QT += sql
diff --git a/tests/auto/qitemview/tst_qitemview.cpp b/tests/auto/qitemview/tst_qitemview.cpp
index 6bfd1e8..73c08d1 100644
--- a/tests/auto/qitemview/tst_qitemview.cpp
+++ b/tests/auto/qitemview/tst_qitemview.cpp
@@ -55,7 +55,7 @@
#if defined(Q_OS_WINCE)
bool qt_wince_is_platform(const QString &platformString) {
- TCHAR tszPlatform[64];
+ wchar_t tszPlatform[64];
if (SystemParametersInfo(SPI_GETPLATFORMTYPE,
sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0))
if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform))
diff --git a/tests/auto/qlocale/tst_qlocale.cpp b/tests/auto/qlocale/tst_qlocale.cpp
index 8ac6ef0..9ef7f1d 100644
--- a/tests/auto/qlocale/tst_qlocale.cpp
+++ b/tests/auto/qlocale/tst_qlocale.cpp
@@ -1093,12 +1093,7 @@ void tst_QLocale::macDefaultLocale()
static QString getWinLocaleInfo(LCTYPE type)
{
LCID id = GetThreadLocale();
- int cnt = 0;
- QT_WA({
- cnt = GetLocaleInfoW(id, type, 0, 0)*2;
- } , {
- cnt = GetLocaleInfoA(id, type, 0, 0);
- });
+ int cnt = GetLocaleInfo(id, type, 0, 0) * 2;
if (cnt == 0) {
qWarning("QLocale: empty windows locale info (%d)", type);
@@ -1107,38 +1102,20 @@ static QString getWinLocaleInfo(LCTYPE type)
QByteArray buff(cnt, 0);
- QT_WA({
- cnt = GetLocaleInfoW(id, type,
- reinterpret_cast<wchar_t*>(buff.data()),
- buff.size()/2);
- } , {
- cnt = GetLocaleInfoA(id, type,
- buff.data(), buff.size());
- });
+ cnt = GetLocaleInfo(id, type, reinterpret_cast<wchar_t*>(buff.data()), buff.size() / 2);
if (cnt == 0) {
qWarning("QLocale: empty windows locale info (%d)", type);
return QString();
}
- QString result;
- QT_WA({
- result = QString::fromUtf16(reinterpret_cast<ushort*>(buff.data()));
- } , {
- result = QString::fromLocal8Bit(buff.data());
- });
- return result;
+ return QString::fromWCharArray(reinterpret_cast<wchar_t*>(buff.data()));
}
static void setWinLocaleInfo(LCTYPE type, const QString &value)
{
LCID id = GetThreadLocale();
-
- QT_WA({
- SetLocaleInfoW(id, type, reinterpret_cast<const wchar_t*>(value.utf16()));
- } , {
- SetLocaleInfoA(id, type, value.toLocal8Bit());
- });
+ SetLocaleInfo(id, type, reinterpret_cast<const wchar_t*>(value.utf16()));
}
class RestoreLocaleHelper {
diff --git a/tests/auto/qmainwindow/tst_qmainwindow.cpp b/tests/auto/qmainwindow/tst_qmainwindow.cpp
index 80ba198..e46c2e1 100644
--- a/tests/auto/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/qmainwindow/tst_qmainwindow.cpp
@@ -1434,10 +1434,7 @@ void MoveSeparator::apply(QMainWindow *mw) const
}
QVERIFY(!path.isEmpty());
- QVector<QLayoutStruct> cache;
-
- l->layoutState.dockAreaLayout.separatorMove(path, QPoint(0, 0), QPoint(delta, delta), &cache);
-
+ l->layoutState.dockAreaLayout.separatorMove(path, QPoint(0, 0), QPoint(delta, delta));
}
QMap<QString, QRect> dockWidgetGeometries(QMainWindow *mw)
diff --git a/tests/auto/qmake/testcompiler.cpp b/tests/auto/qmake/testcompiler.cpp
index 2f8dae8..38876d0 100644
--- a/tests/auto/qmake/testcompiler.cpp
+++ b/tests/auto/qmake/testcompiler.cpp
@@ -56,7 +56,7 @@ static QString targetName( BuildType buildMode, const QString& target, const QSt
targetName.append(".exe");
break;
case Dll: // dll
- if (!version.empty())
+ if (!version.isEmpty())
targetName.append(version.section(".", 0, 0));
targetName.append(".dll");
break;
diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp
index 2fb9b8b..1d19ffa 100644
--- a/tests/auto/qmenu/tst_qmenu.cpp
+++ b/tests/auto/qmenu/tst_qmenu.cpp
@@ -92,7 +92,9 @@ private slots:
void activeSubMenuPosition();
void task242454_sizeHint();
void task176201_clear();
- void task250673_activeMutliColumnSubMenuPosition();
+ void task250673_activeMultiColumnSubMenuPosition();
+ void task256918_setFont();
+ void menuSizeHint();
protected slots:
void onActivated(QAction*);
void onHighlighted(QAction*);
@@ -679,7 +681,7 @@ void tst_QMenu::task176201_clear()
QTest::mouseClick(&menu, Qt::LeftButton, 0, menu.rect().center());
}
-void tst_QMenu::task250673_activeMutliColumnSubMenuPosition()
+void tst_QMenu::task250673_activeMultiColumnSubMenuPosition()
{
class MyMenu : public QMenu
{
@@ -713,5 +715,53 @@ void tst_QMenu::task250673_activeMutliColumnSubMenuPosition()
const int subMenuOffset = main.style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, &main);
QVERIFY((sub.geometry().left() - subMenuOffset + 5) < main.geometry().right());
}
+
+
+void tst_QMenu::task256918_setFont()
+{
+ QMenu menu;
+ QAction *action = menu.addAction("foo");
+ QFont f;
+ f.setPointSize(30);
+ action->setFont(f);
+ menu.show(); //ensures that the actiongeometry are calculated
+ QVERIFY(menu.actionGeometry(action).height() > f.pointSize());
+}
+
+void tst_QMenu::menuSizeHint()
+{
+ QMenu menu;
+ //this is a list of arbitrary strings so that we check the geometry
+ QStringList list = QStringList() << "trer" << "ezrfgtgvqd" << "sdgzgzerzerzer" << "eerzertz" << "er";
+ foreach(QString str, list)
+ menu.addAction(str);
+
+ int left, top, right, bottom;
+ menu.getContentsMargins(&left, &top, &right, &bottom);
+ const int panelWidth = menu.style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, &menu);
+ const int hmargin = menu.style()->pixelMetric(QStyle::PM_MenuHMargin, 0, &menu),
+ vmargin = menu.style()->pixelMetric(QStyle::PM_MenuVMargin, 0, &menu);
+
+ int maxWidth =0;
+ QRect result;
+ foreach(QAction *action, menu.actions()) {
+ maxWidth = qMax(maxWidth, menu.actionGeometry(action).width());
+ result |= menu.actionGeometry(action);
+ QCOMPARE(result.x(), left + hmargin + panelWidth);
+ QCOMPARE(result.y(), top + vmargin + panelWidth);
+ }
+
+ QStyleOption opt(0);
+ opt.rect = menu.rect();
+ opt.state = QStyle::State_None;
+
+ QSize resSize = QSize(result.x(), result.y()) + result.size() + QSize(hmargin + right + panelWidth, vmargin + top + panelWidth);
+
+ resSize = menu.style()->sizeFromContents(QStyle::CT_Menu, &opt,
+ resSize.expandedTo(QApplication::globalStrut()), &menu);
+
+ QCOMPARE(resSize, menu.sizeHint());
+}
+
QTEST_MAIN(tst_QMenu)
#include "tst_qmenu.moc"
diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp
index 8a38782..500465c 100644
--- a/tests/auto/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/qmenubar/tst_qmenubar.cpp
@@ -48,8 +48,10 @@
#include <q3popupmenu.h>
#endif
#include <qstyle.h>
+#include <qwindowsstyle.h>
#include <qdesktopwidget.h>
#include <qaction.h>
+#include <qstyleoption.h>
#ifdef Q_WS_WIN
#include <windows.h>
@@ -150,6 +152,7 @@ private slots:
void check_menuPosition();
void task223138_triggered();
void task256322_highlight();
+ void menubarSizeHint();
#if defined(QT3_SUPPORT)
void indexBasedInsertion_data();
@@ -1556,6 +1559,72 @@ void tst_QMenuBar::task256322_highlight()
QVERIFY(!win.menuBar()->activeAction());
}
+void tst_QMenuBar::menubarSizeHint()
+{
+ struct MyStyle : public QWindowsStyle
+ {
+ virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0, const QWidget * widget = 0 ) const
+ {
+ // I chose strange values (prime numbers to be more sure that the size of the menubar is correct)
+ switch (metric)
+ {
+ case QStyle::PM_MenuBarItemSpacing:
+ return 7;
+ case PM_MenuBarHMargin:
+ return 13;
+ case PM_MenuBarVMargin:
+ return 11;
+ case PM_MenuBarPanelWidth:
+ return 1;
+ }
+ return QWindowsStyle::pixelMetric(metric, option, widget);
+ }
+ } style;
+
+ QMenuBar mb;
+ mb.setStyle(&style);
+ //this is a list of arbitrary strings so that we check the geometry
+ QStringList list = QStringList() << "trer" << "ezrfgtgvqd" << "sdgzgzerzerzer" << "eerzertz" << "er";
+ foreach(QString str, list)
+ mb.addAction(str);
+
+ const int panelWidth = style.pixelMetric(QStyle::PM_MenuBarPanelWidth);
+ const int hmargin = style.pixelMetric(QStyle::PM_MenuBarHMargin);
+ const int vmargin = style.pixelMetric(QStyle::PM_MenuBarVMargin);
+ const int spacing = style.pixelMetric(QStyle::PM_MenuBarItemSpacing);
+
+ mb.show();
+ QRect result;
+ foreach(QAction *action, mb.actions()) {
+ const QRect actionRect = mb.actionGeometry(action);
+ if (!result.isNull()) //this is the first item
+ QCOMPARE(actionRect.left() - result.right() - 1, spacing);
+ result |= actionRect;
+ QCOMPARE(result.x(), panelWidth + hmargin + spacing);
+ QCOMPARE(result.y(), panelWidth + vmargin);
+ }
+
+ //this code is copied from QMenuBar
+ //there is no public member that allows to initialize a styleoption instance
+ QStyleOptionMenuItem opt;
+ opt.rect = mb.rect();
+ opt.menuRect = mb.rect();
+ opt.state = QStyle::State_None;
+ opt.menuItemType = QStyleOptionMenuItem::Normal;
+ opt.checkType = QStyleOptionMenuItem::NotCheckable;
+ opt.palette = mb.palette();
+
+ QSize resSize = QSize(result.x(), result.y()) + result.size()
+ + QSize(panelWidth + hmargin, panelWidth + vmargin);
+
+
+ resSize = style.sizeFromContents(QStyle::CT_MenuBar, &opt,
+ resSize.expandedTo(QApplication::globalStrut()),
+ &mb);
+
+ QCOMPARE(resSize, mb.sizeHint());
+}
+
#if defined(QT3_SUPPORT)
void tst_QMenuBar::indexBasedInsertion_data()
diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp
index 95d19e2..f4cff2b 100644
--- a/tests/auto/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp
@@ -108,6 +108,7 @@ class tst_QMetaObject : public QObject
Q_PROPERTY(int value6 READ value6 NOTIFY value6Changed)
Q_PROPERTY(MyStruct value7 READ value7 WRITE setVal7 NOTIFY value7Changed)
Q_PROPERTY(int value8 READ value8 NOTIFY value8Changed)
+ Q_PROPERTY(int value9 READ value9 CONSTANT)
public:
enum EnumType { EnumType1 };
@@ -137,6 +138,8 @@ public:
int value8() const { return 1; }
+ int value9() const { return 1; }
+
QList<QVariant> value4;
QVariantList value5;
@@ -159,6 +162,7 @@ private slots:
void customPropertyType();
void checkScope();
void propertyNotify();
+ void propertyConstant();
void stdSet();
void classInfo();
@@ -605,6 +609,19 @@ void tst_QMetaObject::invokeCustomTypes()
QCOMPARE(obj.sum, 3);
}
+namespace NamespaceWithConstructibleClass
+{
+
+class ConstructibleClass : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE ConstructibleClass(QObject *parent = 0)
+ : QObject(parent) {}
+};
+
+}
+
void tst_QMetaObject::invokeMetaConstructor()
{
const QMetaObject *mo = &QtTestObject::staticMetaObject;
@@ -619,6 +636,15 @@ void tst_QMetaObject::invokeMetaConstructor()
QCOMPARE(obj2->parent(), (QObject*)&obj);
QVERIFY(qobject_cast<QtTestObject*>(obj2) != 0);
}
+ // class in namespace
+ const QMetaObject *nsmo = &NamespaceWithConstructibleClass::ConstructibleClass::staticMetaObject;
+ {
+ QtTestObject obj;
+ QObject *obj2 = nsmo->newInstance(Q_ARG(QObject*, &obj));
+ QVERIFY(obj2 != 0);
+ QCOMPARE(obj2->parent(), (QObject*)&obj);
+ QVERIFY(qobject_cast<NamespaceWithConstructibleClass::ConstructibleClass*>(obj2) != 0);
+ }
}
void tst_QMetaObject::normalizedSignature_data()
@@ -763,6 +789,19 @@ void tst_QMetaObject::propertyNotify()
QCOMPARE(signal.signature(), (const char *)0);
}
+void tst_QMetaObject::propertyConstant()
+{
+ const QMetaObject *mo = metaObject();
+
+ QMetaProperty prop = mo->property(mo->indexOfProperty("value8"));
+ QVERIFY(prop.isValid());
+ QVERIFY(!prop.isConstant());
+
+ prop = mo->property(mo->indexOfProperty("value9"));
+ QVERIFY(prop.isValid());
+ QVERIFY(prop.isConstant());
+}
+
class ClassInfoTestObjectA : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qnetworkaccessmanager_and_qprogressdialog/qnetworkaccessmanager_and_qprogressdialog.pro b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/qnetworkaccessmanager_and_qprogressdialog.pro
new file mode 100644
index 0000000..7ed5b07
--- /dev/null
+++ b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/qnetworkaccessmanager_and_qprogressdialog.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+SOURCES += tst_qnetworkaccessmanager_and_qprogressdialog.cpp
+QT += network
+
+
diff --git a/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp
new file mode 100644
index 0000000..62e4ce5
--- /dev/null
+++ b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtGui>
+#include <QtCore>
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtNetwork/QNetworkRequest>
+#include <QtNetwork/QNetworkReply>
+#include <qdebug.h>
+
+#include "../network-settings.h"
+
+
+class tst_QNetworkAccessManager_And_QProgressDialog : public QObject
+{
+Q_OBJECT
+private slots:
+ void downloadCheck();
+};
+
+class DownloadCheckWidget : public QWidget
+{
+ Q_OBJECT;
+public:
+ DownloadCheckWidget(QWidget *parent = 0) : QWidget(parent)
+ , progressDlg(this), netmanager(this)
+ , lateReadyRead(true)
+ {
+ progressDlg.setRange(1, 100);
+ QMetaObject::invokeMethod(this, "go", Qt::QueuedConnection);
+ }
+ bool lateReadyRead;
+public slots:
+ void go()
+ {
+ QNetworkReply *reply = netmanager.get(
+ QNetworkRequest(
+ QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile")
+ ));
+ connect(reply, SIGNAL(downloadProgress(qint64, qint64)),
+ this, SLOT(dataReadProgress(qint64, qint64)));
+ connect(reply, SIGNAL(readyRead()),
+ this, SLOT(dataReadyRead()));
+ connect(reply, SIGNAL(finished()), this, SLOT(finishedFromReply()));
+
+ progressDlg.exec();
+ }
+ void dataReadProgress(qint64 done, qint64 total)
+ {
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+ progressDlg.setMaximum(total);
+ progressDlg.setValue(done);
+ }
+ void dataReadyRead()
+ {
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+ lateReadyRead = true;
+ }
+ void finishedFromReply()
+ {
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+ lateReadyRead = false;
+ reply->deleteLater();
+ QTestEventLoop::instance().exitLoop();
+ }
+
+
+private:
+ QProgressDialog progressDlg;
+ QNetworkAccessManager netmanager;
+};
+
+void tst_QNetworkAccessManager_And_QProgressDialog::downloadCheck()
+{
+ DownloadCheckWidget widget;
+ widget.show();
+ // run and exit on finished()
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ // run some more to catch the late readyRead() (or: to not catch it)
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(QTestEventLoop::instance().timeout());
+ // the following fails when a readyRead() was received after finished()
+ QVERIFY(!widget.lateReadyRead);
+}
+
+
+
+QTEST_MAIN(tst_QNetworkAccessManager_And_QProgressDialog)
+#include "tst_qnetworkaccessmanager_and_qprogressdialog.moc"
diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp
index f52d44e..b3736ab 100644
--- a/tests/auto/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/qpixmap/tst_qpixmap.cpp
@@ -854,12 +854,7 @@ void tst_QPixmap::toWinHBITMAP()
BITMAP bitmap_info;
memset(&bitmap_info, 0, sizeof(BITMAP));
- int res;
- QT_WA({
- res = GetObjectW(bitmap, sizeof(BITMAP), &bitmap_info);
- } , {
- res = GetObjectA(bitmap, sizeof(BITMAP), &bitmap_info);
- });
+ int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info);
QVERIFY(res);
QCOMPARE(100, (int) bitmap_info.bmWidth);
diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp
index a30e9f9..e76c8ef 100644
--- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp
+++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp
@@ -111,6 +111,7 @@ private slots:
void operationsInStates();
void oneKeyValue();
void updateOnSetKeyValues();
+ void restart();
};
tst_QPropertyAnimation::tst_QPropertyAnimation()
@@ -395,8 +396,13 @@ void tst_QPropertyAnimation::duration0()
animation.setEndValue(43);
QVERIFY(!animation.currentValue().isValid());
QCOMPARE(animation.currentValue().toInt(), 0);
+ animation.setStartValue(42);
+ QVERIFY(animation.currentValue().isValid());
+ QCOMPARE(animation.currentValue().toInt(), 42);
+
QCOMPARE(o.property("ole").toInt(), 42);
animation.setDuration(0);
+ QCOMPARE(animation.currentValue().toInt(), 43); //it is at the end
animation.start();
QCOMPARE(animation.state(), QAnimationGroup::Stopped);
QCOMPARE(animation.currentTime(), 0);
@@ -559,6 +565,9 @@ void tst_QPropertyAnimation::startWithoutStartValue()
QTest::qWait(200);
QCOMPARE(anim.state(), QVariantAnimation::Stopped);
+ current = anim.currentValue().toInt();
+ QCOMPARE(current, 100);
+ QCOMPARE(o.property("ole").toInt(), current);
anim.setEndValue(110);
anim.start();
@@ -954,5 +963,53 @@ void tst_QPropertyAnimation::updateOnSetKeyValues()
QCOMPARE(animation2.currentValue().toInt(), animation.currentValue().toInt());
}
+
+//this class will 'throw' an error in the test lib
+// if the property ole is set to ErrorValue
+class MyErrorObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int ole READ ole WRITE setOle)
+public:
+
+ static const int ErrorValue = 10000;
+
+ MyErrorObject() : m_ole(0) { }
+ int ole() const { return m_ole; }
+ void setOle(int o)
+ {
+ QVERIFY(o != ErrorValue);
+ m_ole = o;
+ }
+
+private:
+ int m_ole;
+
+
+};
+
+void tst_QPropertyAnimation::restart()
+{
+ //here we check that be restarting an animation
+ //it doesn't get an bogus intermediate value (end value)
+ //because the time is not yet reset to 0
+ MyErrorObject o;
+ o.setOle(100);
+ QCOMPARE(o.property("ole").toInt(), 100);
+
+ QPropertyAnimation anim(&o, "ole");
+ anim.setEndValue(200);
+ anim.start();
+ anim.setCurrentTime(anim.duration());
+ QCOMPARE(anim.state(), QAbstractAnimation::Stopped);
+ QCOMPARE(o.property("ole").toInt(), 200);
+
+ //we'll check that the animation never gets a wrong value when starting it
+ //after having changed the end value
+ anim.setEndValue(MyErrorObject::ErrorValue);
+ anim.start();
+}
+
+
QTEST_MAIN(tst_QPropertyAnimation)
#include "tst_qpropertyanimation.moc"
diff --git a/tests/auto/qpushbutton/tst_qpushbutton.cpp b/tests/auto/qpushbutton/tst_qpushbutton.cpp
index cf79ffc..7a81dbf 100644
--- a/tests/auto/qpushbutton/tst_qpushbutton.cpp
+++ b/tests/auto/qpushbutton/tst_qpushbutton.cpp
@@ -51,6 +51,8 @@
#include <qtimer.h>
#include <QDialog>
#include <QGridLayout>
+#include <QStyleFactory>
+#include <QTabWidget>
Q_DECLARE_METATYPE(QPushButton*)
@@ -90,6 +92,8 @@ private slots:
void toggled();
void isEnabled();
void defaultAndAutoDefault();
+ void sizeHint_data();
+ void sizeHint();
/*
void state();
void group();
@@ -590,5 +594,77 @@ void tst_QPushButton::defaultAndAutoDefault()
}
}
+void tst_QPushButton::sizeHint_data()
+{
+ QTest::addColumn<QString>("stylename");
+ QTest::newRow("motif") << QString::fromAscii("motif");
+ QTest::newRow("cde") << QString::fromAscii("cde");
+ QTest::newRow("windows") << QString::fromAscii("windows");
+ QTest::newRow("cleanlooks") << QString::fromAscii("cleanlooks");
+ QTest::newRow("gtk") << QString::fromAscii("gtk");
+ QTest::newRow("mac") << QString::fromAscii("mac");
+ QTest::newRow("plastique") << QString::fromAscii("plastique");
+ QTest::newRow("windowsxp") << QString::fromAscii("windowsxp");
+ QTest::newRow("windowsvista") << QString::fromAscii("windowsvista");
+}
+
+void tst_QPushButton::sizeHint()
+{
+ QFETCH(QString, stylename);
+
+ QStyle *style = QStyleFactory::create(stylename);
+ if (!style)
+ QSKIP(qPrintable(QString::fromLatin1("Qt has been compiled without style: %1")
+ .arg(stylename)), SkipSingle);
+ QApplication::setStyle(style);
+
+// Test 1
+ {
+ QPushButton *button = new QPushButton("123");
+ QSize initSizeHint = button->sizeHint();
+
+ QDialog *dialog = new QDialog;
+ QWidget *widget = new QWidget(dialog);
+ button->setParent(widget);
+ button->sizeHint();
+
+ widget->setParent(0);
+ delete dialog;
+ button->setDefault(false);
+ QCOMPARE(button->sizeHint(), initSizeHint);
+ delete button;
+ }
+
+// Test 2
+ {
+ QWidget *tab1 = new QWidget;
+ QHBoxLayout *layout1 = new QHBoxLayout(tab1);
+ QPushButton *button1_1 = new QPushButton("123");
+ QPushButton *button1_2 = new QPushButton("123");
+ layout1->addWidget(button1_1);
+ layout1->addWidget(button1_2);
+
+ QWidget *tab2 = new QWidget;
+ QHBoxLayout *layout2 = new QHBoxLayout(tab2);
+ QPushButton *button2_1 = new QPushButton("123");
+ QPushButton *button2_2 = new QPushButton("123");
+ layout2->addWidget(button2_1);
+ layout2->addWidget(button2_2);
+
+ QDialog *dialog = new QDialog;
+ QTabWidget *tabWidget = new QTabWidget;
+ tabWidget->addTab(tab1, "1");
+ tabWidget->addTab(tab2, "2");
+ QVBoxLayout *mainLayout = new QVBoxLayout(dialog);
+ mainLayout->addWidget(tabWidget);
+ dialog->show();
+ tabWidget->setCurrentWidget(tab2);
+ tabWidget->setCurrentWidget(tab1);
+ QTest::qWait(100);
+
+ QCOMPARE(button1_2->size(), button2_2->size());
+ }
+}
+
QTEST_MAIN(tst_QPushButton)
#include "tst_qpushbutton.moc"
diff --git a/tests/auto/qrect/tst_qrect.cpp b/tests/auto/qrect/tst_qrect.cpp
index cdb5560..5a91636 100644
--- a/tests/auto/qrect/tst_qrect.cpp
+++ b/tests/auto/qrect/tst_qrect.cpp
@@ -4125,6 +4125,7 @@ void tst_QRect::unitedRect_data()
QTest::newRow("test 13") << QRect() << QRect(10, 10, 10, 10) << QRect(10, 10, 10, 10);
QTest::newRow("test 14") << QRect(10, 10, 10, 10) << QRect() << QRect(10, 10, 10, 10);
QTest::newRow("test 15") << QRect() << QRect() << QRect();
+ QTest::newRow("test 16") << QRect(0, 0, 100, 0) << QRect(0, 0, 0, 100) << QRect(0, 0, 100, 100);
}
void tst_QRect::unitedRect()
@@ -4160,6 +4161,7 @@ void tst_QRect::unitedRectF_data()
QTest::newRow("test 13") << QRectF() << QRectF(10, 10, 10, 10) << QRectF(10, 10, 10, 10);
QTest::newRow("test 14") << QRectF(10, 10, 10, 10) << QRectF() << QRectF(10, 10, 10, 10);
QTest::newRow("test 15") << QRectF() << QRectF() << QRectF();
+ QTest::newRow("test 16") << QRectF(0, 0, 100, 0) << QRectF(0, 0, 0, 100) << QRectF(0, 0, 100, 100);
}
void tst_QRect::unitedRectF()
diff --git a/tests/auto/qscriptengine/qscriptengine.pro b/tests/auto/qscriptengine/qscriptengine.pro
index cf3ced3..b5aa621 100644
--- a/tests/auto/qscriptengine/qscriptengine.pro
+++ b/tests/auto/qscriptengine/qscriptengine.pro
@@ -1,6 +1,7 @@
load(qttest_p4)
QT += script
SOURCES += tst_qscriptengine.cpp
+DEFINES += SRCDIR=\\\"$$PWD\\\"
wince*: {
addFiles.sources = script
diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp
index b63236e..c17454d 100644
--- a/tests/auto/qscriptengine/tst_qscriptengine.cpp
+++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp
@@ -101,6 +101,7 @@ private slots:
void automaticSemicolonInsertion();
void abortEvaluation();
void isEvaluating();
+ void printFunctionWithCustomHandler();
void printThrowsException();
void errorConstructors();
void argumentsProperty();
@@ -1561,7 +1562,7 @@ static QScriptValue __import__(QScriptContext *ctx, QScriptEngine *eng)
void tst_QScriptEngine::importExtension()
{
QStringList libPaths = QCoreApplication::instance()->libraryPaths();
- QCoreApplication::instance()->setLibraryPaths(QStringList() << ".");
+ QCoreApplication::instance()->setLibraryPaths(QStringList() << SRCDIR);
QStringList availableExtensions;
{
@@ -2473,6 +2474,33 @@ void tst_QScriptEngine::isEvaluating()
}
}
+static QtMsgType theMessageType;
+static QString theMessage;
+
+static void myMsgHandler(QtMsgType type, const char *msg)
+{
+ theMessageType = type;
+ theMessage = QString::fromLatin1(msg);
+}
+
+void tst_QScriptEngine::printFunctionWithCustomHandler()
+{
+ QScriptEngine eng;
+ QtMsgHandler oldHandler = qInstallMsgHandler(myMsgHandler);
+ QVERIFY(eng.globalObject().property("print").isFunction());
+ theMessageType = QtSystemMsg;
+ QVERIFY(theMessage.isEmpty());
+ QVERIFY(eng.evaluate("print('test')").isUndefined());
+ QCOMPARE(theMessageType, QtDebugMsg);
+ QCOMPARE(theMessage, QString::fromLatin1("test"));
+ theMessageType = QtSystemMsg;
+ theMessage.clear();
+ QVERIFY(eng.evaluate("print(3, true, 'little pigs')").isUndefined());
+ QCOMPARE(theMessageType, QtDebugMsg);
+ QCOMPARE(theMessage, QString::fromLatin1("3 true little pigs"));
+ qInstallMsgHandler(oldHandler);
+}
+
void tst_QScriptEngine::printThrowsException()
{
QScriptEngine eng;
diff --git a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro
index b8109cc..f6a6aeb 100644
--- a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro
+++ b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro
@@ -1,6 +1,7 @@
load(qttest_p4)
QT = core script
SOURCES += tst_qscriptjstestsuite.cpp
+DEFINES += SRCDIR=\\\"$$PWD\\\"
wince*: {
testFiles.sources = tests
diff --git a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp
index 66004f8..0194730 100644
--- a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp
+++ b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp
@@ -389,7 +389,7 @@ int tst_Suite::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
tst_Suite::tst_Suite()
{
- testsDir = QDir(".");
+ testsDir = QDir(SRCDIR);
bool testsFound = testsDir.cd("tests");
if (!testsFound) {
qWarning("*** no tests/ dir!");
diff --git a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp
index fa519de..14d3283 100644
--- a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp
+++ b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp
@@ -736,6 +736,8 @@ void tst_QScriptExtQObject::getSetStaticProperty()
// test that we do value conversion if necessary when setting properties
{
QScriptValue br = m_engine->evaluate("myObject.brushProperty");
+ QVERIFY(br.isVariant());
+ QVERIFY(!br.strictlyEquals(m_engine->evaluate("myObject.brushProperty")));
QCOMPARE(qscriptvalue_cast<QBrush>(br), m_myObject->brushProperty());
QCOMPARE(qscriptvalue_cast<QColor>(br), m_myObject->brushProperty().color());
@@ -838,6 +840,14 @@ void tst_QScriptExtQObject::getSetStaticProperty()
mobj.setProperty("intProperty", m_engine->newFunction(getSetProperty),
QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
}
+
+ // method properties are persistent
+ {
+ QScriptValue slot = m_engine->evaluate("myObject.mySlot");
+ QVERIFY(slot.isFunction());
+ QScriptValue sameSlot = m_engine->evaluate("myObject.mySlot");
+ QVERIFY(sameSlot.strictlyEquals(slot));
+ }
}
void tst_QScriptExtQObject::getSetDynamicProperty()
@@ -1954,7 +1964,7 @@ void tst_QScriptExtQObject::classEnums()
QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.AllAbility").toInt32()),
MyQObject::AllAbility);
- QScriptValue::PropertyFlags expectedEnumFlags = QScriptValue::ReadOnly;
+ QScriptValue::PropertyFlags expectedEnumFlags = QScriptValue::ReadOnly | QScriptValue::Undeletable;
QCOMPARE(myClass.propertyFlags("FooPolicy"), expectedEnumFlags);
QCOMPARE(myClass.propertyFlags("BarPolicy"), expectedEnumFlags);
QCOMPARE(myClass.propertyFlags("BazPolicy"), expectedEnumFlags);
@@ -2005,6 +2015,15 @@ void tst_QScriptExtQObject::classEnums()
QCOMPARE(m_myObject->qtFunctionActuals().size(), 0);
QCOMPARE(ret.isNumber(), true);
}
+
+ // enum properties are not deletable or writable
+ QVERIFY(!m_engine->evaluate("delete MyQObject.BazPolicy").toBool());
+ myClass.setProperty("BazPolicy", QScriptValue());
+ QCOMPARE(static_cast<MyQObject::Policy>(myClass.property("BazPolicy").toInt32()),
+ MyQObject::BazPolicy);
+ myClass.setProperty("BazPolicy", MyQObject::FooPolicy);
+ QCOMPARE(static_cast<MyQObject::Policy>(myClass.property("BazPolicy").toInt32()),
+ MyQObject::BazPolicy);
}
QT_BEGIN_NAMESPACE
diff --git a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro
index 9e35801..c07ab53 100644
--- a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro
+++ b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro
@@ -1,6 +1,7 @@
load(qttest_p4)
QT = core script
SOURCES += tst_qscriptv8testsuite.cpp
+DEFINES += SRCDIR=\\\"$$PWD\\\"
wince*: {
testFiles.sources = tests
diff --git a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp
index 77bfeb5..50eb19f 100644
--- a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp
+++ b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp
@@ -193,7 +193,7 @@ int tst_Suite::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
tst_Suite::tst_Suite()
{
- testsDir = QDir(".");
+ testsDir = QDir(SRCDIR);
bool testsFound = testsDir.cd("tests");
if (!testsFound) {
qWarning("*** no tests/ dir!");
diff --git a/tests/auto/qsettings/tst_qsettings.cpp b/tests/auto/qsettings/tst_qsettings.cpp
index f682d37..f0f446d 100644
--- a/tests/auto/qsettings/tst_qsettings.cpp
+++ b/tests/auto/qsettings/tst_qsettings.cpp
@@ -3010,12 +3010,6 @@ void tst_QSettings::oldWriteEntry_QString_QString()
QSettings readSettings("software.org", "KillerAPP");
QFETCH( QString, s );
bool ok = FALSE;
-#ifdef Q_OS_WIN
- if (qWinVersion() & Qt::WV_DOS_based) {
- QEXPECT_FAIL("data2", "Windows 9x does not support unicode characters in the registry", Abort);
- QEXPECT_FAIL("data5", "Windows 9x does not support unicode characters in the registry", Abort);
- }
-#endif
QCOMPARE( readSettings.readEntry( "/Trolltech/QSettingsTesting/String", QString::null, &ok ), s );
QVERIFY( ok );
}
diff --git a/tests/auto/qsharedmemory/src/qsystemlock_win.cpp b/tests/auto/qsharedmemory/src/qsystemlock_win.cpp
index 94d90ce..a50b77b 100644
--- a/tests/auto/qsharedmemory/src/qsystemlock_win.cpp
+++ b/tests/auto/qsharedmemory/src/qsystemlock_win.cpp
@@ -75,32 +75,24 @@ HANDLE QSystemLockPrivate::handle()
// Create it if it doesn't already exists.
if (semaphore == 0) {
QString safeName = makeKeyFileName();
- QT_WA({
- semaphore = CreateSemaphoreW(0, MAX_LOCKS, MAX_LOCKS, (TCHAR*)safeName.utf16());
- }, {
- semaphore = CreateSemaphoreA(0, MAX_LOCKS, MAX_LOCKS, safeName.toLocal8Bit().constData());
- });
+ semaphore = CreateSemaphore(0, MAX_LOCKS, MAX_LOCKS, (wchar_t*)safeName.utf16());
if (semaphore == 0) {
setErrorString(QLatin1String("QSystemLockPrivate::handle"));
- return 0;
- }
+ return 0;
+ }
}
if (semaphoreLock == 0) {
- QString safeLockName = QSharedMemoryPrivate::makePlatformSafeKey(key + QLatin1String("lock"), QLatin1String("qipc_systemlock_"));
- QT_WA({
- semaphoreLock = CreateSemaphoreW(0,
- 1, 1, (TCHAR*)safeLockName.utf16());
- }, {
- semaphoreLock = CreateSemaphoreA(0,
- 1, 1, safeLockName.toLocal8Bit().constData());
- });
+ QString safeLockName = QSharedMemoryPrivate::makePlatformSafeKey(key + QLatin1String("lock"), QLatin1String("qipc_systemlock_"));
+ semaphoreLock = CreateSemaphore(0, 1, 1, (wchar_t*)safeLockName.utf16());
+
if (semaphoreLock == 0) {
setErrorString(QLatin1String("QSystemLockPrivate::handle"));
- return 0;
- }
+ return 0;
+ }
}
+
return semaphore;
}
diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
index 795ce76..db93fc9 100644
--- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
+++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-
+#define QT_SHAREDPOINTER_TRACK_POINTERS
#include "qsharedpointer.h"
#include "externaltests.h"
#include <QtTest/QtTest>
@@ -908,7 +908,7 @@ void tst_QSharedPointer::invalidConstructs_data()
QTest::newRow("implicit-initialization3")
<< &QTest::QExternalTest::tryCompileFail
<< "QWeakPointer<Data> ptr = new Data;";
- QTest::newRow("implicit-initialization1")
+ QTest::newRow("implicit-initialization4")
<< &QTest::QExternalTest::tryCompileFail
<< "QWeakPointer<Data> ptr;"
"ptr = new Data;";
@@ -972,11 +972,13 @@ void tst_QSharedPointer::invalidConstructs_data()
<< &QTest::QExternalTest::tryCompileFail
<< "QSharedPointer<Data> ptr1;\n"
"QSharedPointer<int> ptr2 = qSharedPointerCast<int>(ptr1);";
+#ifndef QTEST_NO_RTTI
QTest::newRow("invalid-cast2")
<< &QTest::QExternalTest::tryCompileFail
<< "QSharedPointer<Data> ptr1;\n"
"QSharedPointer<int> ptr2 = qSharedPointerDynamicCast<int>(ptr1);";
- QTest::newRow("implicit-initialization1")
+#endif
+ QTest::newRow("invalid-cast3")
<< &QTest::QExternalTest::tryCompileFail
<< "QSharedPointer<Data> ptr1;\n"
"QSharedPointer<int> ptr2 = qSharedPointerConstCast<int>(ptr1);";
@@ -995,6 +997,7 @@ void tst_QSharedPointer::invalidConstructs()
test.setDebugMode(true);
test.setQtModules(QTest::QExternalTest::QtCore);
test.setProgramHeader(
+ "#define QT_SHAREDPOINTER_TRACK_POINTERS\n"
"#include <QtCore/qsharedpointer.h>\n"
"\n"
"struct Data { int i; };\n"
@@ -1023,7 +1026,12 @@ void tst_QSharedPointer::invalidConstructs()
QByteArray body = code.toLatin1();
- if (!(test.*testFunction)(body)) {
+ bool result = (test.*testFunction)(body);
+ if (qgetenv("QTEST_EXTERNAL_DEBUG").toInt() > 0) {
+ qDebug("External test output:");
+ printf("%s\n", test.standardError().constData());
+ }
+ if (!result) {
qWarning("External code testing failed\nCode:\n%s\n", body.constData());
QFAIL("Fail");
}
diff --git a/tests/auto/qspinbox/tst_qspinbox.cpp b/tests/auto/qspinbox/tst_qspinbox.cpp
index d161c85..d6a208d 100644
--- a/tests/auto/qspinbox/tst_qspinbox.cpp
+++ b/tests/auto/qspinbox/tst_qspinbox.cpp
@@ -65,6 +65,7 @@
#include <QDoubleSpinBox>
#include <QVBoxLayout>
#include <QKeySequence>
+#include <QStackedWidget>
#include <QDebug>
#include "../../shared/util.h"
@@ -142,6 +143,9 @@ private slots:
void specialValue();
void textFromValue();
+
+ void sizeHint();
+
public slots:
void valueChangedHelper(const QString &);
void valueChangedHelper(int);
@@ -956,5 +960,45 @@ void tst_QSpinBox::textFromValue()
QCOMPARE(spinBox.textFromValue(INT_MIN), QString::number(INT_MIN));
}
+class sizeHint_SpinBox : public QSpinBox
+{
+public:
+ QSize sizeHint() const
+ {
+ ++sizeHintRequests;
+ return QSpinBox::sizeHint();
+ }
+ mutable int sizeHintRequests;
+};
+
+void tst_QSpinBox::sizeHint()
+{
+ QWidget *widget = new QWidget;
+ QHBoxLayout *layout = new QHBoxLayout(widget);
+ sizeHint_SpinBox *spinBox = new sizeHint_SpinBox;
+ layout->addWidget(spinBox);
+ widget->show();
+ QTest::qWait(100);
+
+ // Prefix
+ spinBox->sizeHintRequests = 0;
+ spinBox->setPrefix(QLatin1String("abcdefghij"));
+ qApp->processEvents();
+ QVERIFY(spinBox->sizeHintRequests > 0);
+
+ // Suffix
+ spinBox->sizeHintRequests = 0;
+ spinBox->setSuffix(QLatin1String("abcdefghij"));
+ qApp->processEvents();
+ QVERIFY(spinBox->sizeHintRequests > 0);
+
+ // Range
+ spinBox->sizeHintRequests = 0;
+ spinBox->setRange(0, 1234567890);
+ spinBox->setValue(spinBox->maximum());
+ qApp->processEvents();
+ QVERIFY(spinBox->sizeHintRequests > 0);
+}
+
QTEST_MAIN(tst_QSpinBox)
#include "tst_qspinbox.moc"
diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h
index a490a2f..c6b65a4 100644
--- a/tests/auto/qsqldatabase/tst_databases.h
+++ b/tests/auto/qsqldatabase/tst_databases.h
@@ -217,7 +217,7 @@ public:
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3309, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 5.0.18 Linux
// addDb( "QMYSQL3", "testdb", "troll", "trond", "iceblink.nokia.troll.no" ); // MySQL 5.0.13 Windows
// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql4-nokia.trolltech.com.au" ); // MySQL 4.1.22-2.el4 linux
-// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux
+// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no" ); // V7.2 NOT SUPPORTED!
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5434 ); // V7.2 NOT SUPPORTED! Multi-byte
@@ -238,8 +238,8 @@ public:
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird2-nokia.trolltech.com.au" ); // Firebird 2.1.1
// use in-memory database to prevent local files
- addDb("QSQLITE", ":memory:");
-// addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") );
+// addDb("QSQLITE", ":memory:");
+ addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") );
// addDb( "QSQLITE2", QDir::toNativeSeparators(QDir::tempPath()+"/foo2.db") );
// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.nokia.troll.no\\ICEBLINK", "troll", "trond", "" );
// addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" );
@@ -251,6 +251,8 @@ public:
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "testuser", "Ee4Gabf6_", "" );
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2003" );
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2008" );
+// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
+// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
}
void open()
@@ -316,44 +318,75 @@ public:
QSqlQuery q( db );
QStringList dbtables=db.tables();
- foreach(QString tableName, tableNames)
+ foreach(const QString &tableName, tableNames)
{
wasDropped = true;
QString table=tableName;
if ( db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName))
table = db.driver()->stripDelimiters(table, QSqlDriver::TableName);
- if ( dbtables.contains( table, Qt::CaseSensitive ) )
- wasDropped = q.exec( "drop table " + tableName);
- else if ( dbtables.contains( table, Qt::CaseInsensitive ) )
- wasDropped = q.exec( "drop table " + tableName);
-
- if ( !wasDropped )
- qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError().text() << "tables:" << dbtables;
+ if ( dbtables.contains( table, Qt::CaseInsensitive ) ) {
+ foreach(const QString &table2, dbtables.filter(table, Qt::CaseInsensitive)) {
+ if(table2.compare(table.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
+ table=db.driver()->escapeIdentifier(table2, QSqlDriver::TableName);
+ wasDropped = q.exec( "drop table " + table);
+ dbtables.removeAll(table);
+ }
+ }
+ }
+ if ( !wasDropped ) {
+ qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError();
+// qWarning() << "last query:" << q.lastQuery();
+// qWarning() << "dbtables:" << dbtables;
+// qWarning() << "db.tables():" << db.tables();
+ }
}
}
+ static void safeDropTable( QSqlDatabase db, const QString& tableName )
+ {
+ safeDropTables(db, QStringList() << tableName);
+ }
+
static void safeDropViews( QSqlDatabase db, const QStringList &viewNames )
{
if ( isMSAccess( db ) ) // Access is sooo stupid.
safeDropTables( db, viewNames );
+ bool wasDropped;
+ QSqlQuery q( db );
QStringList dbtables=db.tables(QSql::Views);
foreach(QString viewName, viewNames)
{
- if ( dbtables.contains( viewName, Qt::CaseInsensitive ) ) {
- QSqlQuery q( "drop view " + viewName, db );
-
- if ( !q.isActive() )
- qWarning() << "unable to drop view" << viewName << ':' << q.lastError().text();
- } else if ( db.driverName().startsWith( "QMYSQL" )
- && dbtables.contains( viewName, Qt::CaseInsensitive ) ) { // MySql is a bit stupid too
- QSqlQuery q( "drop view " + viewName, db );
+ wasDropped = true;
+ QString view=viewName;
+ if ( db.driver()->isIdentifierEscaped(view, QSqlDriver::TableName))
+ view = db.driver()->stripDelimiters(view, QSqlDriver::TableName);
+
+ if ( dbtables.contains( view, Qt::CaseInsensitive ) ) {
+ foreach(const QString &view2, dbtables.filter(view, Qt::CaseInsensitive)) {
+ if(view2.compare(view.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
+ view=db.driver()->escapeIdentifier(view2, QSqlDriver::TableName);
+ wasDropped = q.exec( "drop view " + view);
+ dbtables.removeAll(view);
+ }
+ }
}
+
+ if ( !wasDropped )
+ qWarning() << dbToString(db) << "unable to drop view" << viewName << ':' << q.lastError();
+// << "\nlast query:" << q.lastQuery()
+// << "\ndbtables:" << dbtables
+// << "\ndb.tables(QSql::Views):" << db.tables(QSql::Views);
}
}
+ static void safeDropView( QSqlDatabase db, const QString& tableName )
+ {
+ safeDropViews(db, QStringList() << tableName);
+ }
+
// returns the type name of the blob datatype for the database db.
// blobSize is only used if the db doesn't have a generic blob type
static QString blobTypeName( QSqlDatabase db, int blobSize = 10000 )
diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
index cce4602..23b1eb5 100644
--- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
+++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
@@ -249,7 +249,7 @@ struct FieldDef {
// excluding the primary key field
static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db)
{
- tst_Databases::safeDropTables(db, QStringList() << qTableName("qtestfields"));
+ tst_Databases::safeDropTable(db, qTableName("qtestfields"));
QSqlQuery q(db);
// construct a create table statement consisting of all fieldtypes
QString qs = "create table " + qTableName("qtestfields");
@@ -298,6 +298,7 @@ void tst_QSqlDatabase::createTestTables(QSqlDatabase db)
q.exec("set table_type=innodb");
if (tst_Databases::isSqlServer(db)) {
QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON"));
+ QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF"));
}
// please never ever change this table; otherwise fix all tests ;)
@@ -354,7 +355,7 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
q.exec("drop schema " + qTableName("qtestschema") + " cascade");
if (testWhiteSpaceNames(db.driverName()))
- tableNames << (qTableName("qtest") + " test");
+ tableNames << db.driver()->escapeIdentifier(qTableName("qtest") + " test", QSqlDriver::TableName);
tst_Databases::safeDropTables(db, tableNames);
}
@@ -540,11 +541,6 @@ void tst_QSqlDatabase::tables()
QVERIFY(tables.contains(qTableName("temp_tab"), Qt::CaseInsensitive));
QVERIFY(tables.contains(qTableName("qtest"), Qt::CaseInsensitive));
- if (tst_Databases::isMSAccess(db))
- QSqlQuery("drop table " + qTableName("qtest_view"), db);
- else
- QSqlQuery("drop view " + qTableName("qtest_view"), db);
-
if (db.driverName().startsWith("QPSQL")) {
QVERIFY(tables.contains(qTableName("qtest") + " test"));
}
diff --git a/tests/auto/qsqldriver/tst_qsqldriver.cpp b/tests/auto/qsqldriver/tst_qsqldriver.cpp
index bbd7483..6d428df 100644
--- a/tests/auto/qsqldriver/tst_qsqldriver.cpp
+++ b/tests/auto/qsqldriver/tst_qsqldriver.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
+** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
@@ -34,7 +34,7 @@
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
+** contact the sales department at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -85,9 +85,7 @@ void tst_QSqlDriver::recreateTestTables(QSqlDatabase db)
{
QSqlQuery q(db);
- QStringList tableNames;
- tableNames << qTableName( "relTEST1" );
- tst_Databases::safeDropTables( db, tableNames );
+ tst_Databases::safeDropTable( db, qTableName( "relTEST1" ) );
QVERIFY_SQL( q, exec("create table " + qTableName("relTEST1") +
" (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
@@ -105,11 +103,9 @@ void tst_QSqlDriver::initTestCase()
void tst_QSqlDriver::cleanupTestCase()
{
- QStringList tableNames;
- tableNames << qTableName( "relTEST1" );
foreach (const QString &dbName, dbs.dbNames) {
QSqlDatabase db = QSqlDatabase::database(dbName);
- tst_Databases::safeDropTables( db, tableNames );
+ tst_Databases::safeDropTable( db, qTableName( "relTEST1" ) );
}
dbs.close();
}
diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp
index 825db6c..ab7f0c9 100644
--- a/tests/auto/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp
@@ -175,13 +175,14 @@ private slots:
void emptyTableNavigate();
#ifdef NOT_READY_YET
- void task_217003_data() { generic_data(); }
- void task_217003();
void task_229811();
void task_229811_data() { generic_data(); }
void task_234422_data() { generic_data(); }
void task_234422();
#endif
+ void task_217003_data() { generic_data(); }
+ void task_217003();
+
void task_250026_data() { generic_data("QODBC"); }
void task_250026();
void task_205701_data() { generic_data("QMYSQL"); }
@@ -289,7 +290,8 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db )
<< qTableName( "bindtest" )
<< qTableName( "more_results" )
<< qTableName( "blobstest" )
- << qTableName( "oraRowId" );
+ << qTableName( "oraRowId" )
+ << qTableName( "qtest_batch" );
if ( db.driverName().startsWith("QSQLITE") )
tablenames << qTableName( "record_sqlite" );
@@ -299,10 +301,10 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db )
tablenames << qTableName( "qtest_lockedtable" );
-#ifdef NOT_READY_YET
tablenames << qTableName( "Planet" );
-#endif
+
tablenames << qTableName( "task_250026" );
+ tablenames << qTableName( "task_234422" );
tst_Databases::safeDropTables( db, tablenames );
}
@@ -1902,71 +1904,48 @@ void tst_QSqlQuery::batchExec()
QSKIP( "Database can't do BatchOperations", SkipSingle );
QSqlQuery q( db );
+ QString tableName = qTableName( "qtest_batch" );
- q.exec( "drop table " + qTableName( "qtest_batch" ) );
-
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_batch" ) + " (id int, name varchar(20), dt date, num numeric(8, 4))" ) );
-
- QVERIFY_SQL( q, prepare( "insert into " + qTableName( "qtest_batch" ) + " (id, name, dt, num) values (?, ?, ?, ?)" ) );
+ QVERIFY_SQL( q, exec( "create table " + tableName + " (id int, name varchar(20), dt date, num numeric(8, 4))" ) );
+ QVERIFY_SQL( q, prepare( "insert into " + tableName + " (id, name, dt, num) values (?, ?, ?, ?)" ) );
QVariantList intCol;
-
intCol << 1 << 2 << QVariant( QVariant::Int );
QVariantList charCol;
-
charCol << QLatin1String( "harald" ) << QLatin1String( "boris" ) << QVariant( QVariant::String );
QVariantList dateCol;
-
QDateTime dt = QDateTime( QDate::currentDate(), QTime( 1, 2, 3 ) );
-
dateCol << dt << dt.addDays( -1 ) << QVariant( QVariant::DateTime );
QVariantList numCol;
-
numCol << 2.3 << 3.4 << QVariant( QVariant::Double );
q.addBindValue( intCol );
-
q.addBindValue( charCol );
-
q.addBindValue( dateCol );
-
q.addBindValue( numCol );
QVERIFY_SQL( q, execBatch() );
-
- QVERIFY_SQL( q, exec( "select id, name, dt, num from " + qTableName( "qtest_batch" ) + " order by id" ) );
+ QVERIFY_SQL( q, exec( "select id, name, dt, num from " + tableName + " order by id" ) );
QVERIFY( q.next() );
-
QCOMPARE( q.value( 0 ).toInt(), 1 );
-
QCOMPARE( q.value( 1 ).toString(), QString( "harald" ) );
-
QCOMPARE( q.value( 2 ).toDateTime(), dt );
-
QCOMPARE( q.value( 3 ).toDouble(), 2.3 );
QVERIFY( q.next() );
-
QCOMPARE( q.value( 0 ).toInt(), 2 );
-
QCOMPARE( q.value( 1 ).toString(), QString( "boris" ) );
-
QCOMPARE( q.value( 2 ).toDateTime(), dt.addDays( -1 ) );
-
QCOMPARE( q.value( 3 ).toDouble(), 3.4 );
QVERIFY( q.next() );
-
QVERIFY( q.value( 0 ).isNull() );
-
QVERIFY( q.value( 1 ).isNull() );
-
QVERIFY( q.value( 2 ).isNull() );
-
QVERIFY( q.value( 3 ).isNull() );
}
@@ -2344,6 +2323,8 @@ void tst_QSqlQuery::sqlite_finish()
QString tableName = qTableName( "qtest_lockedtable" );
QSqlQuery q( db );
+
+ tst_Databases::safeDropTable( db2, tableName );
q.exec( "CREATE TABLE " + tableName + " (pk_id INTEGER PRIMARY KEY, whatever TEXT)" );
q.exec( "INSERT INTO " + tableName + " values(1, 'whatever')" );
q.exec( "INSERT INTO " + tableName + " values(2, 'whatever more')" );
@@ -2361,7 +2342,8 @@ void tst_QSqlQuery::sqlite_finish()
q.finish();
QVERIFY_SQL( q2, exec( "DELETE FROM " + tableName + " WHERE pk_id=2" ) );
QCOMPARE( q2.numRowsAffected(), 1 );
- q.exec( "DROP TABLE " + tableName );
+
+ tst_Databases::safeDropTable( db2, tableName );
}
QSqlDatabase::removeDatabase( "sqlite_finish_sqlite" );
@@ -2574,71 +2556,47 @@ void tst_QSqlQuery::blobsPreparedQuery()
QString tableName = qTableName( "blobstest" );
QSqlQuery q( db );
-
q.setForwardOnly( true ); // This is needed to make the test work with DB2.
-
QString shortBLOB( "abc" );
-
QString longerBLOB( "abcdefghijklmnopqrstuvxyz¿ÀëïöÌ¡ " );
// In PostgreSQL a BLOB is not called a BLOB, but a BYTEA! :-)
// ... and in SQL Server it can be called a lot, but IMAGE will do.
QString typeName( "BLOB" );
-
if ( db.driverName().startsWith( "QPSQL" ) )
typeName = "BYTEA";
else if ( db.driverName().startsWith( "QODBC" ) )
typeName = "IMAGE";
QVERIFY_SQL( q, exec( QString( "CREATE TABLE %1(id INTEGER, data %2)" ).arg( tableName ).arg( typeName ) ) );
-
q.prepare( QString( "INSERT INTO %1(id, data) VALUES(:id, :data)" ).arg( tableName ) );
-
q.bindValue( ":id", 1 );
-
q.bindValue( ":data", shortBLOB.toAscii() );
-
QVERIFY_SQL( q, exec() );
q.bindValue( ":id", 2 );
-
q.bindValue( ":data", longerBLOB.toAscii() );
-
QVERIFY_SQL( q, exec() );
// Two executions and result sets
q.prepare( QString( "SELECT data FROM %1 WHERE id = ?" ).arg( tableName ) );
-
q.bindValue( 0, QVariant( 1 ) );
-
QVERIFY_SQL( q, exec() );
-
QVERIFY_SQL( q, next() );
-
QCOMPARE( q.value( 0 ).toString(), shortBLOB );
q.bindValue( 0, QVariant( 2 ) );
-
QVERIFY_SQL( q, exec() );
-
QVERIFY_SQL( q, next() );
-
QCOMPARE( q.value( 0 ).toString(), longerBLOB );
// Only one execution and result set
q.prepare( QString( "SELECT id, data FROM %1 ORDER BY id" ).arg( tableName ) );
-
QVERIFY_SQL( q, exec() );
-
QVERIFY_SQL( q, next() );
-
QCOMPARE( q.value( 1 ).toString(), shortBLOB );
-
QVERIFY_SQL( q, next() );
-
QCOMPARE( q.value( 1 ).toString(), longerBLOB );
-
- q.exec( QString( "DROP TABLE %1" ).arg( tableName ) );
}
// There were problems with navigating past the end of a table returning an error on mysql
@@ -2658,7 +2616,6 @@ void tst_QSqlQuery::emptyTableNavigate()
}
}
-#ifdef NOT_READY_YET
void tst_QSqlQuery::task_217003()
{
QFETCH( QString, dbName );
@@ -2685,7 +2642,6 @@ void tst_QSqlQuery::task_217003()
QVERIFY_SQL( q, seek( 1 ) );
QCOMPARE( q.value( 0 ).toString(), QString( "Venus" ) );
}
-#endif
void tst_QSqlQuery::task_250026()
{
@@ -2792,7 +2748,6 @@ void tst_QSqlQuery::task_234422()
QString tableName = qTableName( "task_234422" );
- query.exec("DROP TABLE " + tableName);
QVERIFY_SQL(query,exec("CREATE TABLE " + tableName + " (id int primary key, "
"name varchar(20), homecountry varchar(2))"));
for (int i = 0; i < m_airlines.count(); ++i) {
diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
index 4588af8..e2dace8 100644
--- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
+++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
@@ -86,6 +86,9 @@ private slots:
void escapedRelations();
void escapedTableName();
void whiteSpaceInIdentifiers();
+
+private:
+ void dropTestTables( QSqlDatabase db );
};
@@ -100,18 +103,9 @@ void tst_QSqlRelationalTableModel::initTestCase_data()
void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db)
{
- QSqlQuery q(db);
-
- QStringList tableNames;
- tableNames << qTableName( "reltest1" )
- << qTableName( "reltest2" )
- << qTableName( "reltest3" )
- << qTableName( "reltest4" )
- << qTableName( "reltest5" )
- << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName)
- << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName);
- tst_Databases::safeDropTables( db, tableNames );
+ dropTestTables(db);
+ QSqlQuery q(db);
QVERIFY_SQL( q, exec("create table " + qTableName("reltest1") +
" (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
QVERIFY_SQL( q, exec("insert into " + qTableName("reltest1") + " values(1, 'harry', 1, 2)"));
@@ -157,20 +151,27 @@ void tst_QSqlRelationalTableModel::initTestCase()
void tst_QSqlRelationalTableModel::cleanupTestCase()
{
+ foreach (const QString &dbName, dbs.dbNames) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE( db );
+ dropTestTables( QSqlDatabase::database(dbName) );
+ }
+ dbs.close();
+}
+
+void tst_QSqlRelationalTableModel::dropTestTables( QSqlDatabase db )
+{
QStringList tableNames;
tableNames << qTableName( "reltest1" )
<< qTableName( "reltest2" )
<< qTableName( "reltest3" )
<< qTableName( "reltest4" )
- << qTableName( "reltest5" );
- foreach (const QString &dbName, dbs.dbNames) {
- QSqlDatabase db = QSqlDatabase::database(dbName);
- QStringList tables = tableNames;
- tables << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName)
- << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName);
- tst_Databases::safeDropTables( db, tables );
- }
- dbs.close();
+ << qTableName( "reltest5" )
+ << qTableName( "rel test6", db.driver() )
+ << qTableName( "rel test7", db.driver() )
+ << qTableName("CASETEST1", db.driver() )
+ << qTableName("casetest1", db.driver() );
+ tst_Databases::safeDropTables( db, tableNames );
}
void tst_QSqlRelationalTableModel::init()
@@ -916,11 +917,6 @@ void tst_QSqlRelationalTableModel::casing()
if (db.driverName().startsWith("QSQLITE"))
QSKIP("The casing test for SQLITE is irrelevant since SQLITE is case insensitive", SkipAll);
- QStringList tableNames;
- tableNames << qTableName("CASETEST1", db.driver()).toUpper();
- tableNames << qTableName("casetest1", db.driver());
- tst_Databases::safeDropTables(db, tableNames);
-
QSqlQuery q(db);
QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() +
" (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
@@ -974,8 +970,6 @@ void tst_QSqlRelationalTableModel::casing()
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr"));
-
- tst_Databases::safeDropTables(db, tableNames);
}
void tst_QSqlRelationalTableModel::escapedRelations()
diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
index aa882be..1445f34 100644
--- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -899,7 +899,7 @@ void tst_QSqlTableModel::sqlite_attachedDatabase()
QVERIFY_SQL( q, exec("INSERT INTO atest2 VALUES(2, 'attached-atest2')"));
QSqlQuery q2(db);
- tst_Databases::safeDropTables(db, QStringList() << "atest");
+ tst_Databases::safeDropTable(db, "atest");
QVERIFY_SQL(q2, exec("CREATE TABLE atest(id int, text varchar(20))"));
QVERIFY_SQL(q2, exec("INSERT INTO atest VALUES(3, 'main')"));
QVERIFY_SQL(q2, exec("ATTACH DATABASE \""+attachedDb.databaseName()+"\" as adb"));
diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp
index 553833c..a859866 100644
--- a/tests/auto/qstatemachine/tst_qstatemachine.cpp
+++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp
@@ -151,6 +151,8 @@ private slots:
void defaultGlobalRestorePolicy();
void globalRestorePolicySetToRestore();
void globalRestorePolicySetToDoNotRestore();
+
+ void noInitialStateForInitialState();
//void restorePolicyNotInherited();
//void mixedRestoreProperties();
@@ -345,7 +347,7 @@ void tst_QStateMachine::transitionEntersParent()
void tst_QStateMachine::defaultErrorState()
{
QStateMachine machine;
- QVERIFY(machine.errorState() != 0);
+ QCOMPARE(machine.errorState(), reinterpret_cast<QAbstractState *>(0));
QState *brokenState = new QState();
brokenState->setObjectName("MyInitialState");
@@ -364,9 +366,7 @@ void tst_QStateMachine::defaultErrorState()
QCOMPARE(machine.error(), QStateMachine::NoInitialStateError);
QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'MyInitialState'"));
-
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(machine.errorState()));
+ QCOMPARE(machine.isRunning(), false);
}
class CustomErrorState: public QState
@@ -424,6 +424,7 @@ void tst_QStateMachine::customGlobalErrorState()
QCoreApplication::processEvents();
+ QCOMPARE(machine.isRunning(), true);
QCOMPARE(machine.configuration().count(), 1);
QVERIFY(machine.configuration().contains(customErrorState));
QCOMPARE(customErrorState->error, QStateMachine::NoInitialStateError);
@@ -459,6 +460,7 @@ void tst_QStateMachine::customLocalErrorStateInBrokenState()
machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
QCoreApplication::processEvents();
+ QCOMPARE(machine.isRunning(), true);
QCOMPARE(machine.configuration().count(), 1);
QVERIFY(machine.configuration().contains(customErrorState));
QCOMPARE(customErrorState->error, QStateMachine::NoInitialStateError);
@@ -494,8 +496,7 @@ void tst_QStateMachine::customLocalErrorStateInOtherState()
machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(machine.errorState()));
+ QCOMPARE(machine.isRunning(), false);
}
void tst_QStateMachine::customLocalErrorStateInParentOfBrokenState()
@@ -529,6 +530,7 @@ void tst_QStateMachine::customLocalErrorStateInParentOfBrokenState()
machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
QCoreApplication::processEvents();
+ QCOMPARE(machine.isRunning(), true);
QCOMPARE(machine.configuration().count(), 1);
QVERIFY(machine.configuration().contains(customErrorState));
}
@@ -607,6 +609,7 @@ void tst_QStateMachine::errorStateHasChildren()
machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
QCoreApplication::processEvents();
+ QCOMPARE(machine.isRunning(), true);
QCOMPARE(machine.configuration().count(), 2);
QVERIFY(machine.configuration().contains(customErrorState));
QVERIFY(machine.configuration().contains(childOfErrorState));
@@ -620,7 +623,6 @@ void tst_QStateMachine::errorStateHasErrors()
customErrorState->setObjectName("customErrorState");
machine.addState(customErrorState);
- QAbstractState *oldErrorState = machine.errorState();
machine.setErrorState(customErrorState);
QState *childOfErrorState = new QState(customErrorState);
@@ -647,8 +649,7 @@ void tst_QStateMachine::errorStateHasErrors()
QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'customErrorState'");
QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(oldErrorState)); // Fall back to default
+ QCOMPARE(machine.isRunning(), false);
QCOMPARE(machine.error(), QStateMachine::NoInitialStateError);
QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'customErrorState'"));
}
@@ -680,8 +681,7 @@ void tst_QStateMachine::errorStateIsRootState()
QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'brokenState'");
QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(machine.errorState()));
+ QCOMPARE(machine.isRunning(), false);
}
void tst_QStateMachine::errorStateEntersParentFirst()
@@ -759,7 +759,6 @@ void tst_QStateMachine::errorStateEntersParentFirst()
void tst_QStateMachine::customErrorStateIsNull()
{
QStateMachine machine;
- QAbstractState *oldErrorState = machine.errorState();
machine.rootState()->setErrorState(0);
QState *initialState = new QState();
@@ -780,8 +779,7 @@ void tst_QStateMachine::customErrorStateIsNull()
QCoreApplication::processEvents();
QCOMPARE(machine.errorState(), reinterpret_cast<QAbstractState *>(0));
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(oldErrorState));
+ QCOMPARE(machine.isRunning(), false);
}
void tst_QStateMachine::clearError()
@@ -797,6 +795,7 @@ void tst_QStateMachine::clearError()
machine.start();
QCoreApplication::processEvents();
+ QCOMPARE(machine.isRunning(), true);
QCOMPARE(machine.error(), QStateMachine::NoInitialStateError);
QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'brokenState'"));
@@ -862,6 +861,7 @@ void tst_QStateMachine::historyStateHasNowhereToGo()
machine.postEvent(new QEvent(QEvent::User));
QCoreApplication::processEvents();
+ QCOMPARE(machine.isRunning(), true);
QCOMPARE(machine.configuration().count(), 1);
QVERIFY(machine.configuration().contains(machine.errorState()));
QCOMPARE(machine.error(), QStateMachine::NoDefaultStateInHistoryStateError);
@@ -920,8 +920,7 @@ void tst_QStateMachine::transitionToStateNotInGraph()
QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 'initialState'");
QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(qobject_cast<QState*>(machine.rootState())->errorState()));
+ QCOMPARE(machine.isRunning(), false);
}
void tst_QStateMachine::customErrorStateNotInGraph()
@@ -932,7 +931,7 @@ void tst_QStateMachine::customErrorStateNotInGraph()
errorState.setObjectName("errorState");
QTest::ignoreMessage(QtWarningMsg, "QState::setErrorState: error state cannot belong to a different state machine");
machine.setErrorState(&errorState);
- QVERIFY(&errorState != machine.errorState());
+ QCOMPARE(machine.errorState(), reinterpret_cast<QAbstractState *>(0));
QState *initialBrokenState = new QState(machine.rootState());
initialBrokenState->setObjectName("initialBrokenState");
@@ -942,9 +941,8 @@ void tst_QStateMachine::customErrorStateNotInGraph()
machine.start();
QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'initialBrokenState'");
QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(machine.errorState()));
+
+ QCOMPARE(machine.isRunning(), false);
}
void tst_QStateMachine::restoreProperties()
@@ -1019,8 +1017,7 @@ void tst_QStateMachine::addAndRemoveState()
{
QStateMachine machine;
QStatePrivate *root_d = QStatePrivate::get(machine.rootState());
- QCOMPARE(root_d->childStates().size(), 1); // the error state
- QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState());
+ QCOMPARE(root_d->childStates().size(), 0);
QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: cannot add null state");
machine.addState(0);
@@ -1031,9 +1028,8 @@ void tst_QStateMachine::addAndRemoveState()
machine.addState(s1);
QCOMPARE(s1->machine(), &machine);
QCOMPARE(s1->parentState(), machine.rootState());
- QCOMPARE(root_d->childStates().size(), 2);
- QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState());
- QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s1);
+ QCOMPARE(root_d->childStates().size(), 1);
+ QCOMPARE(root_d->childStates().at(0), (QAbstractState*)s1);
QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine");
machine.addState(s1);
@@ -1042,24 +1038,21 @@ void tst_QStateMachine::addAndRemoveState()
QCOMPARE(s2->parentState(), (QState*)0);
machine.addState(s2);
QCOMPARE(s2->parentState(), machine.rootState());
- QCOMPARE(root_d->childStates().size(), 3);
- QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState());
- QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s1);
- QCOMPARE(root_d->childStates().at(2), (QAbstractState*)s2);
+ QCOMPARE(root_d->childStates().size(), 2);
+ QCOMPARE(root_d->childStates().at(0), (QAbstractState*)s1);
+ QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s2);
QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine");
machine.addState(s2);
machine.removeState(s1);
QCOMPARE(s1->parentState(), (QState*)0);
- QCOMPARE(root_d->childStates().size(), 2);
- QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState());
- QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s2);
+ QCOMPARE(root_d->childStates().size(), 1);
+ QCOMPARE(root_d->childStates().at(0), (QAbstractState*)s2);
machine.removeState(s2);
QCOMPARE(s2->parentState(), (QState*)0);
- QCOMPARE(root_d->childStates().size(), 1);
- QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState());
+ QCOMPARE(root_d->childStates().size(), 0);
QTest::ignoreMessage(QtWarningMsg, "QStateMachine::removeState: cannot remove null state");
machine.removeState(0);
@@ -1067,10 +1060,10 @@ void tst_QStateMachine::addAndRemoveState()
{
QStateMachine machine2;
{
- char warning[256];
- sprintf(warning, "QStateMachine::removeState: state %p's machine (%p) is different from this machine (%p)",
- machine2.rootState(), &machine2, &machine);
- QTest::ignoreMessage(QtWarningMsg, warning);
+ QString warning;
+ warning.sprintf("QStateMachine::removeState: state %p's machine (%p) is different from this machine (%p)",
+ machine2.rootState(), &machine2, &machine);
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
machine.removeState(machine2.rootState());
}
// ### check this behavior
@@ -1129,9 +1122,9 @@ void tst_QStateMachine::stateEntryAndExit()
QCOMPARE(trans->sourceState(), (QState*)s2);
QCOMPARE(trans->targetState(), (QAbstractState*)s3);
{
- char warning[256];
- sprintf(warning, "QState::removeTransition: transition %p's source state (%p) is different from this state (%p)", trans, s2, s1);
- QTest::ignoreMessage(QtWarningMsg, warning);
+ QString warning;
+ warning.sprintf("QState::removeTransition: transition %p's source state (%p) is different from this state (%p)", trans, s2, s1);
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
s1->removeTransition(trans);
}
s2->removeTransition(trans);
@@ -1147,9 +1140,9 @@ void tst_QStateMachine::stateEntryAndExit()
machine.setInitialState(s1);
QCOMPARE(machine.initialState(), (QAbstractState*)s1);
{
- char warning[256];
- sprintf(warning, "QState::setInitialState: state %p is not a child of this state (%p)", machine.rootState(), machine.rootState());
- QTest::ignoreMessage(QtWarningMsg, warning);
+ QString warning;
+ warning.sprintf("QState::setInitialState: state %p is not a child of this state (%p)", machine.rootState(), machine.rootState());
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
machine.setInitialState(machine.rootState());
QCOMPARE(machine.initialState(), (QAbstractState*)s1);
}
@@ -1614,9 +1607,9 @@ void tst_QStateMachine::parallelStates()
s1_2_1->addTransition(s1_2_f);
s1_2->setInitialState(s1_2_1);
{
- char warning[256];
- sprintf(warning, "QState::setInitialState: ignoring attempt to set initial state of parallel state group %p", s1);
- QTest::ignoreMessage(QtWarningMsg, warning);
+ QString warning;
+ warning.sprintf("QState::setInitialState: ignoring attempt to set initial state of parallel state group %p", s1);
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
s1->setInitialState(0);
}
machine.addState(s1);
@@ -2286,9 +2279,9 @@ void tst_QStateMachine::historyStates()
QCOMPARE(s0h->defaultState(), (QAbstractState*)0);
s0h->setDefaultState(s00);
QCOMPARE(s0h->defaultState(), (QAbstractState*)s00);
- char warning[256];
- sprintf(warning, "QHistoryState::setDefaultState: state %p does not belong to this history state's group (%p)", s0, s0);
- QTest::ignoreMessage(QtWarningMsg, warning);
+ QString warning;
+ warning.sprintf("QHistoryState::setDefaultState: state %p does not belong to this history state's group (%p)", s0, s0);
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
s0h->setDefaultState(s0);
QState *s1 = new QState(root);
QFinalState *s2 = new QFinalState(root);
@@ -2393,12 +2386,10 @@ void tst_QStateMachine::targetStateWithNoParent()
QSignalSpy finishedSpy(&machine, SIGNAL(finished()));
machine.start();
QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 's1'");
- QTRY_COMPARE(machine.isRunning(), true);
QTRY_COMPARE(startedSpy.count(), 1);
- QCOMPARE(stoppedSpy.count(), 0);
+ QCOMPARE(machine.isRunning(), false);
+ QCOMPARE(stoppedSpy.count(), 1);
QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(machine.errorState()));
QCOMPARE(machine.error(), QStateMachine::NoCommonAncestorForTransitionError);
}
@@ -2453,6 +2444,25 @@ void tst_QStateMachine::defaultGlobalRestorePolicy()
QCOMPARE(propertyHolder->property("b").toInt(), 4);
}
+void tst_QStateMachine::noInitialStateForInitialState()
+{
+ QStateMachine machine;
+
+ QState *initialState = new QState(machine.rootState());
+ initialState->setObjectName("initialState");
+ machine.setInitialState(initialState);
+
+ QState *childState = new QState(initialState);
+
+ QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: "
+ "Missing initial state in compound state 'initialState'");
+ machine.start();
+ QCoreApplication::processEvents();
+
+ QCOMPARE(machine.isRunning(), false);
+ QCOMPARE(int(machine.error()), int(QStateMachine::NoInitialStateError));
+}
+
/*
void tst_QStateMachine::restorePolicyNotInherited()
{
diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp
index e172c33..85dbda0 100644
--- a/tests/auto/qstring/tst_qstring.cpp
+++ b/tests/auto/qstring/tst_qstring.cpp
@@ -3997,15 +3997,15 @@ void tst_QString::localeAwareCompare()
# if defined(Q_OS_WINCE)
DWORD oldLcid = GetUserDefaultLCID();
SetUserDefaultLCID(locale);
- if (locale != GetUserDefaultLCID()) {
+
+ QCOMPARE(locale, GetUserDefaultLCID());
# else
DWORD oldLcid = GetThreadLocale();
SetThreadLocale(locale);
- if (locale != GetThreadLocale()) {
+ QCOMPARE(locale, GetThreadLocale());
# endif
- QSKIP("SetThreadLocale() not supported on Win9x", SkipSingle);
- }
+
#elif defined (Q_WS_MAC)
QSKIP("Setting the locale is not supported on OS X (you can set the C locale, but that won't affect CFStringCompare which is used to compare strings)", SkipAll);
#else
diff --git a/tests/auto/qstyle/qstyle.pro b/tests/auto/qstyle/qstyle.pro
index 71ee2e6..ba0908a 100644
--- a/tests/auto/qstyle/qstyle.pro
+++ b/tests/auto/qstyle/qstyle.pro
@@ -2,9 +2,12 @@ load(qttest_p4)
SOURCES += tst_qstyle.cpp
wince*: {
+ DEFINES += SRCDIR=\\\".\\\"
addPixmap.sources = task_25863.png
addPixmap.path = .
DEPLOYMENT += addPixmap
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
}
diff --git a/tests/auto/qstyle/tst_qstyle.cpp b/tests/auto/qstyle/tst_qstyle.cpp
index 667d459..2cb5080 100644
--- a/tests/auto/qstyle/tst_qstyle.cpp
+++ b/tests/auto/qstyle/tst_qstyle.cpp
@@ -91,7 +91,7 @@
#include <windows.h>
static bool qt_wince_is_smartphone() {
- TCHAR tszPlatform[64];
+ wchar_t tszPlatform[64];
if (SystemParametersInfo(SPI_GETPLATFORMTYPE,
sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0))
if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (QString::fromLatin1("Smartphone").utf16()), tszPlatform))
@@ -257,7 +257,8 @@ void tst_QStyle::drawItemPixmap()
{
testWidget->resize(300, 300);
testWidget->show();
- QPixmap p("task_25863.png", "PNG");
+
+ QPixmap p(QString(SRCDIR) + "/task_25863.png", "PNG");
QPixmap actualPix = QPixmap::grabWidget(testWidget);
QVERIFY(pixmapsAreEqual(&actualPix,&p));
testWidget->hide();
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index f11aff9..7b62eae 100644
--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
@@ -80,6 +80,7 @@ private slots:
void opacity();
void paths();
void displayMode();
+ void strokeInherit();
#ifndef QT_NO_COMPRESS
void testGzLoading();
@@ -925,5 +926,128 @@ void tst_QSvgRenderer::displayMode()
}
}
+void tst_QSvgRenderer::strokeInherit()
+{
+ static const char *svgs[] = {
+ // Reference.
+ "<svg viewBox=\"0 0 200 30\">"
+ " <g stroke=\"blue\" stroke-width=\"20\" stroke-linecap=\"butt\""
+ " stroke-linejoin=\"miter\" stroke-miterlimit=\"1\" stroke-dasharray=\"20,10\""
+ " stroke-dashoffset=\"10\" stroke-opacity=\"0.5\">"
+ " <polyline fill=\"none\" points=\"10 10 100 10 100 20 190 20\"/>"
+ " </g>"
+ " <g stroke=\"green\" stroke-width=\"0\" stroke-dasharray=\"3,3,1\" stroke-dashoffset=\"4.5\">"
+ " <polyline fill=\"none\" points=\"10 25 80 25\"/>"
+ " </g>"
+ "</svg>",
+ // stroke
+ "<svg viewBox=\"0 0 200 30\">"
+ " <g stroke=\"none\" stroke-width=\"20\" stroke-linecap=\"butt\""
+ " stroke-linejoin=\"miter\" stroke-miterlimit=\"1\" stroke-dasharray=\"20,10\""
+ " stroke-dashoffset=\"10\" stroke-opacity=\"0.5\">"
+ " <polyline fill=\"none\" points=\"10 10 100 10 100 20 190 20\" stroke=\"blue\"/>"
+ " </g>"
+ " <g stroke=\"yellow\" stroke-width=\"0\" stroke-dasharray=\"3,3,1\" stroke-dashoffset=\"4.5\">"
+ " <polyline fill=\"none\" points=\"10 25 80 25\" stroke=\"green\"/>"
+ " </g>"
+ "</svg>",
+ // stroke-width
+ "<svg viewBox=\"0 0 200 30\">"
+ " <g stroke=\"blue\" stroke-width=\"0\" stroke-linecap=\"butt\""
+ " stroke-linejoin=\"miter\" stroke-miterlimit=\"1\" stroke-dasharray=\"20,10\""
+ " stroke-dashoffset=\"10\" stroke-opacity=\"0.5\">"
+ " <polyline fill=\"none\" points=\"10 10 100 10 100 20 190 20\" stroke-width=\"20\"/>"
+ " </g>"
+ " <g stroke=\"green\" stroke-width=\"10\" stroke-dasharray=\"3,3,1\" stroke-dashoffset=\"4.5\">"
+ " <polyline fill=\"none\" points=\"10 25 80 25\" stroke-width=\"0\"/>"
+ " </g>"
+ "</svg>",
+ // stroke-linecap
+ "<svg viewBox=\"0 0 200 30\">"
+ " <g stroke=\"blue\" stroke-width=\"20\" stroke-linecap=\"round\""
+ " stroke-linejoin=\"miter\" stroke-miterlimit=\"1\" stroke-dasharray=\"20,10\""
+ " stroke-dashoffset=\"10\" stroke-opacity=\"0.5\">"
+ " <polyline fill=\"none\" points=\"10 10 100 10 100 20 190 20\" stroke-linecap=\"butt\"/>"
+ " </g>"
+ " <g stroke=\"green\" stroke-width=\"0\" stroke-dasharray=\"3,3,1\" stroke-dashoffset=\"4.5\">"
+ " <polyline fill=\"none\" points=\"10 25 80 25\"/>"
+ " </g>"
+ "</svg>",
+ // stroke-linejoin
+ "<svg viewBox=\"0 0 200 30\">"
+ " <g stroke=\"blue\" stroke-width=\"20\" stroke-linecap=\"butt\""
+ " stroke-linejoin=\"round\" stroke-miterlimit=\"1\" stroke-dasharray=\"20,10\""
+ " stroke-dashoffset=\"10\" stroke-opacity=\"0.5\">"
+ " <polyline fill=\"none\" points=\"10 10 100 10 100 20 190 20\" stroke-linejoin=\"miter\"/>"
+ " </g>"
+ " <g stroke=\"green\" stroke-width=\"0\" stroke-dasharray=\"3,3,1\" stroke-dashoffset=\"4.5\">"
+ " <polyline fill=\"none\" points=\"10 25 80 25\"/>"
+ " </g>"
+ "</svg>",
+ // stroke-miterlimit
+ "<svg viewBox=\"0 0 200 30\">"
+ " <g stroke=\"blue\" stroke-width=\"20\" stroke-linecap=\"butt\""
+ " stroke-linejoin=\"miter\" stroke-miterlimit=\"2\" stroke-dasharray=\"20,10\""
+ " stroke-dashoffset=\"10\" stroke-opacity=\"0.5\">"
+ " <polyline fill=\"none\" points=\"10 10 100 10 100 20 190 20\" stroke-miterlimit=\"1\"/>"
+ " </g>"
+ " <g stroke=\"green\" stroke-width=\"0\" stroke-dasharray=\"3,3,1\" stroke-dashoffset=\"4.5\">"
+ " <polyline fill=\"none\" points=\"10 25 80 25\"/>"
+ " </g>"
+ "</svg>",
+ // stroke-dasharray
+ "<svg viewBox=\"0 0 200 30\">"
+ " <g stroke=\"blue\" stroke-width=\"20\" stroke-linecap=\"butt\""
+ " stroke-linejoin=\"miter\" stroke-miterlimit=\"1\" stroke-dasharray=\"1,1,1,1,1,1,3,1,3,1,3,1,1,1,1,1,1,3\""
+ " stroke-dashoffset=\"10\" stroke-opacity=\"0.5\">"
+ " <polyline fill=\"none\" points=\"10 10 100 10 100 20 190 20\" stroke-dasharray=\"20,10\"/>"
+ " </g>"
+ " <g stroke=\"green\" stroke-width=\"0\" stroke-dasharray=\"none\" stroke-dashoffset=\"4.5\">"
+ " <polyline fill=\"none\" points=\"10 25 80 25\" stroke-dasharray=\"3,3,1\"/>"
+ " </g>"
+ "</svg>",
+ // stroke-dashoffset
+ "<svg viewBox=\"0 0 200 30\">"
+ " <g stroke=\"blue\" stroke-width=\"20\" stroke-linecap=\"butt\""
+ " stroke-linejoin=\"miter\" stroke-miterlimit=\"1\" stroke-dasharray=\"20,10\""
+ " stroke-dashoffset=\"0\" stroke-opacity=\"0.5\">"
+ " <polyline fill=\"none\" points=\"10 10 100 10 100 20 190 20\" stroke-dashoffset=\"10\"/>"
+ " </g>"
+ " <g stroke=\"green\" stroke-width=\"0\" stroke-dasharray=\"3,3,1\" stroke-dashoffset=\"0\">"
+ " <polyline fill=\"none\" points=\"10 25 80 25\" stroke-dashoffset=\"4.5\"/>"
+ " </g>"
+ "</svg>",
+ // stroke-opacity
+ "<svg viewBox=\"0 0 200 30\">"
+ " <g stroke=\"blue\" stroke-width=\"20\" stroke-linecap=\"butt\""
+ " stroke-linejoin=\"miter\" stroke-miterlimit=\"1\" stroke-dasharray=\"20,10\""
+ " stroke-dashoffset=\"10\" stroke-opacity=\"0\">"
+ " <polyline fill=\"none\" points=\"10 10 100 10 100 20 190 20\" stroke-opacity=\"0.5\"/>"
+ " </g>"
+ " <g stroke=\"green\" stroke-width=\"0\" stroke-dasharray=\"3,3,1\" stroke-dashoffset=\"4.5\">"
+ " <polyline fill=\"none\" points=\"10 25 80 25\"/>"
+ " </g>"
+ "</svg>"
+ };
+
+ const int COUNT = sizeof(svgs) / sizeof(svgs[0]);
+ QImage images[COUNT];
+ QPainter p;
+
+ for (int i = 0; i < COUNT; ++i) {
+ QByteArray data(svgs[i]);
+ QSvgRenderer renderer(data);
+ QVERIFY(renderer.isValid());
+ images[i] = QImage(200, 30, QImage::Format_ARGB32_Premultiplied);
+ images[i].fill(-1);
+ p.begin(&images[i]);
+ renderer.render(&p);
+ p.end();
+ if (i != 0) {
+ QCOMPARE(images[0], images[i]);
+ }
+ }
+}
+
QTEST_MAIN(tst_QSvgRenderer)
#include "tst_qsvgrenderer.moc"
diff --git a/tests/auto/qtcpserver/tst_qtcpserver.cpp b/tests/auto/qtcpserver/tst_qtcpserver.cpp
index a06c871..5c82cbb 100644
--- a/tests/auto/qtcpserver/tst_qtcpserver.cpp
+++ b/tests/auto/qtcpserver/tst_qtcpserver.cpp
@@ -274,42 +274,35 @@ void tst_QTcpServer::ipv4LoopbackPerformanceTest()
QTcpSocket *clientB = server.nextPendingConnection();
QVERIFY(clientB);
-#if defined(Q_WS_WIN)
- if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) {
- QSKIP("Dont run performance tests on QSysInfo::WV_DOS_based systems, overloads the system", SkipAll);
- } else
-#endif
- {
- QByteArray buffer(16384, '@');
- QTime stopWatch;
- stopWatch.start();
- qlonglong totalWritten = 0;
- while (stopWatch.elapsed() < 5000) {
- QVERIFY(clientA.write(buffer.data(), buffer.size()) > 0);
- clientA.flush();
- totalWritten += buffer.size();
- while (clientB->waitForReadyRead(100)) {
- if (clientB->bytesAvailable() == 16384)
- break;
- }
- clientB->read(buffer.data(), buffer.size());
- clientB->write(buffer.data(), buffer.size());
- clientB->flush();
- totalWritten += buffer.size();
- while (clientA.waitForReadyRead(100)) {
- if (clientA.bytesAvailable() == 16384)
- break;
- }
- clientA.read(buffer.data(), buffer.size());
+ QByteArray buffer(16384, '@');
+ QTime stopWatch;
+ stopWatch.start();
+ qlonglong totalWritten = 0;
+ while (stopWatch.elapsed() < 5000) {
+ QVERIFY(clientA.write(buffer.data(), buffer.size()) > 0);
+ clientA.flush();
+ totalWritten += buffer.size();
+ while (clientB->waitForReadyRead(100)) {
+ if (clientB->bytesAvailable() == 16384)
+ break;
}
+ clientB->read(buffer.data(), buffer.size());
+ clientB->write(buffer.data(), buffer.size());
+ clientB->flush();
+ totalWritten += buffer.size();
+ while (clientA.waitForReadyRead(100)) {
+ if (clientA.bytesAvailable() == 16384)
+ break;
+ }
+ clientA.read(buffer.data(), buffer.size());
+ }
- qDebug("\t\t%s: %.1fMB/%.1fs: %.1fMB/s",
- server.serverAddress().toString().toLatin1().constData(),
- totalWritten / (1024.0 * 1024.0),
- stopWatch.elapsed() / 1000.0,
- (totalWritten / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
+ qDebug("\t\t%s: %.1fMB/%.1fs: %.1fMB/s",
+ server.serverAddress().toString().toLatin1().constData(),
+ totalWritten / (1024.0 * 1024.0),
+ stopWatch.elapsed() / 1000.0,
+ (totalWritten / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
- }
delete clientB;
}
@@ -378,42 +371,35 @@ void tst_QTcpServer::ipv4PerformanceTest()
QTcpSocket *clientB = server.nextPendingConnection();
QVERIFY(clientB);
-#if defined(Q_WS_WIN)
- if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) {
- QSKIP("Dont run performance tests on QSysInfo::WV_DOS_based systems, overloads the system", SkipAll);
- } else
-#endif
- {
-
- QByteArray buffer(16384, '@');
- QTime stopWatch;
- stopWatch.start();
- qlonglong totalWritten = 0;
- while (stopWatch.elapsed() < 5000) {
- qlonglong writtenA = clientA.write(buffer.data(), buffer.size());
- clientA.flush();
- totalWritten += buffer.size();
- while (clientB->waitForReadyRead(100)) {
- if (clientB->bytesAvailable() == writtenA)
- break;
- }
- clientB->read(buffer.data(), buffer.size());
- qlonglong writtenB = clientB->write(buffer.data(), buffer.size());
- clientB->flush();
- totalWritten += buffer.size();
- while (clientA.waitForReadyRead(100)) {
- if (clientA.bytesAvailable() == writtenB)
- break;
- }
- clientA.read(buffer.data(), buffer.size());
+ QByteArray buffer(16384, '@');
+ QTime stopWatch;
+ stopWatch.start();
+ qlonglong totalWritten = 0;
+ while (stopWatch.elapsed() < 5000) {
+ qlonglong writtenA = clientA.write(buffer.data(), buffer.size());
+ clientA.flush();
+ totalWritten += buffer.size();
+ while (clientB->waitForReadyRead(100)) {
+ if (clientB->bytesAvailable() == writtenA)
+ break;
}
-
- qDebug("\t\t%s: %.1fMB/%.1fs: %.1fMB/s",
- probeSocket.localAddress().toString().toLatin1().constData(),
- totalWritten / (1024.0 * 1024.0),
- stopWatch.elapsed() / 1000.0,
- (totalWritten / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
+ clientB->read(buffer.data(), buffer.size());
+ qlonglong writtenB = clientB->write(buffer.data(), buffer.size());
+ clientB->flush();
+ totalWritten += buffer.size();
+ while (clientA.waitForReadyRead(100)) {
+ if (clientA.bytesAvailable() == writtenB)
+ break;
+ }
+ clientA.read(buffer.data(), buffer.size());
}
+
+ qDebug("\t\t%s: %.1fMB/%.1fs: %.1fMB/s",
+ probeSocket.localAddress().toString().toLatin1().constData(),
+ totalWritten / (1024.0 * 1024.0),
+ stopWatch.elapsed() / 1000.0,
+ (totalWritten / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
+
delete clientB;
}
diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
index d7c0574..66896a8 100644
--- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -88,6 +88,7 @@ private slots:
void rename();
void renameFdLeak();
void reOpenThroughQFile();
+ void keepOpenMode();
public:
};
@@ -439,5 +440,37 @@ void tst_QTemporaryFile::reOpenThroughQFile()
QCOMPARE(file.readAll(), data);
}
+void tst_QTemporaryFile::keepOpenMode()
+{
+ QByteArray data("abcdefghij");
+
+ {
+ QTemporaryFile file;
+ QVERIFY(((QFile &)file).open(QIODevice::WriteOnly));
+ QVERIFY(QIODevice::WriteOnly == file.openMode());
+
+ QCOMPARE(file.write(data), (qint64)data.size());
+ file.close();
+
+ QVERIFY(((QFile &)file).open(QIODevice::ReadOnly));
+ QVERIFY(QIODevice::ReadOnly == file.openMode());
+ QCOMPARE(file.readAll(), data);
+ }
+
+ {
+ QTemporaryFile file;
+ QVERIFY(file.open());
+ QCOMPARE(file.write(data), (qint64)data.size());
+ QVERIFY(file.rename("temporary-file.txt"));
+
+ QVERIFY(((QFile &)file).open(QIODevice::ReadOnly));
+ QVERIFY(QIODevice::ReadOnly == file.openMode());
+ QCOMPARE(file.readAll(), data);
+
+ QVERIFY(((QFile &)file).open(QIODevice::WriteOnly));
+ QVERIFY(QIODevice::WriteOnly == file.openMode());
+ }
+}
+
QTEST_MAIN(tst_QTemporaryFile)
#include "tst_qtemporaryfile.moc"
diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp
index 5fb62a5..43b7553 100644
--- a/tests/auto/qtimer/tst_qtimer.cpp
+++ b/tests/auto/qtimer/tst_qtimer.cpp
@@ -253,7 +253,7 @@ void tst_QTimer::livelock()
QEXPECT_FAIL("non-zero timer", "", Continue);
#elif defined(Q_OS_WIN)
if (QSysInfo::WindowsVersion < QSysInfo::WV_XP)
- QEXPECT_FAIL("non-zero timer", "Multimedia timers are not available on Win2K/9x", Continue);
+ QEXPECT_FAIL("non-zero timer", "Multimedia timers are not available on Windows 2000", Continue);
#endif
QVERIFY(tester.postEventAtRightTime);
}
diff --git a/tests/auto/qtouchevent/qtouchevent.pro b/tests/auto/qtouchevent/qtouchevent.pro
new file mode 100644
index 0000000..8f6aa87
--- /dev/null
+++ b/tests/auto/qtouchevent/qtouchevent.pro
@@ -0,0 +1,3 @@
+SOURCES=tst_qtouchevent.cpp
+TARGET=tst_qtouchevent
+QT+=testlib
diff --git a/tests/auto/qtouchevent/tst_qtouchevent.cpp b/tests/auto/qtouchevent/tst_qtouchevent.cpp
new file mode 100644
index 0000000..0d584cd
--- /dev/null
+++ b/tests/auto/qtouchevent/tst_qtouchevent.cpp
@@ -0,0 +1,798 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include <QtTest>
+
+class tst_QTouchEventWidget : public QWidget
+{
+public:
+ QList<QTouchEvent::TouchPoint> touchBeginPoints, touchUpdatePoints, touchEndPoints;
+ bool seenTouchBegin, seenTouchUpdate, seenTouchEnd;
+ bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd;
+
+ tst_QTouchEventWidget()
+ : QWidget()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ touchBeginPoints.clear();
+ touchUpdatePoints.clear();
+ touchEndPoints.clear();
+ seenTouchBegin = seenTouchUpdate = seenTouchEnd = false;
+ acceptTouchBegin = acceptTouchUpdate = acceptTouchEnd = true;
+ }
+
+ bool event(QEvent *event)
+ {
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ if (seenTouchBegin) qWarning("TouchBegin: already seen a TouchBegin");
+ if (seenTouchUpdate) qWarning("TouchBegin: TouchUpdate cannot happen before TouchBegin");
+ if (seenTouchEnd) qWarning("TouchBegin: TouchEnd cannot happen before TouchBegin");
+ seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd;
+ touchBeginPoints = static_cast<QTouchEvent *>(event)->touchPoints();
+ event->setAccepted(acceptTouchBegin);
+ break;
+ case QEvent::TouchUpdate:
+ if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin");
+ if (seenTouchEnd) qWarning("TouchUpdate: TouchEnd cannot happen before TouchUpdate");
+ seenTouchUpdate = seenTouchBegin && !seenTouchEnd;
+ touchUpdatePoints = static_cast<QTouchEvent *>(event)->touchPoints();
+ event->setAccepted(acceptTouchUpdate);
+ break;
+ case QEvent::TouchEnd:
+ if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin");
+ if (seenTouchEnd) qWarning("TouchEnd: already seen a TouchEnd");
+ seenTouchEnd = seenTouchBegin && !seenTouchEnd;
+ touchEndPoints = static_cast<QTouchEvent *>(event)->touchPoints();
+ event->setAccepted(acceptTouchEnd);
+ break;
+ default:
+ return QWidget::event(event);
+ }
+ return true;
+ }
+};
+
+class tst_QTouchEvent : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QTouchEvent() { }
+ ~tst_QTouchEvent() { }
+
+private slots:
+ void touchDisabledByDefault();
+ void touchEventAcceptedByDefault();
+ void touchBeginPropagatesWhenIgnored();
+ void touchUpdateAndEndNeverPropagate();
+ void basicRawEventTranslation();
+ void multiPointRawEventTranslationOnTouchScreen();
+ void multiPointRawEventTranslationOnTouchPad();
+};
+
+void tst_QTouchEvent::touchDisabledByDefault()
+{
+ // the widget attribute is not enabled by default
+ QWidget widget;
+ QVERIFY(!widget.testAttribute(Qt::WA_AcceptTouchEvents));
+
+ // events should not be accepted since they are not enabled
+ QList<QTouchEvent::TouchPoint> touchPoints;
+ touchPoints.append(QTouchEvent::TouchPoint(0));
+ QTouchEvent touchEvent(QEvent::TouchBegin,
+ QTouchEvent::TouchScreen,
+ Qt::NoModifier,
+ Qt::TouchPointPressed,
+ touchPoints);
+ bool res = QApplication::sendEvent(&widget, &touchEvent);
+ QVERIFY(!res);
+ QVERIFY(!touchEvent.isAccepted());
+}
+
+void tst_QTouchEvent::touchEventAcceptedByDefault()
+{
+ // enabling touch events should automatically accept touch events
+ QWidget widget;
+ widget.setAttribute(Qt::WA_AcceptTouchEvents);
+
+ // QWidget handles touch event by converting them into a mouse event, so the event is both
+ // accepted and handled (res == true)
+ QList<QTouchEvent::TouchPoint> touchPoints;
+ touchPoints.append(QTouchEvent::TouchPoint(0));
+ QTouchEvent touchEvent(QEvent::TouchBegin,
+ QTouchEvent::TouchScreen,
+ Qt::NoModifier,
+ Qt::TouchPointPressed,
+ touchPoints);
+ bool res = QApplication::sendEvent(&widget, &touchEvent);
+ QVERIFY(res);
+ QVERIFY(touchEvent.isAccepted());
+
+ // tst_QTouchEventWidget does handle, sending succeeds
+ tst_QTouchEventWidget touchWidget;
+ touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ touchEvent.ignore();
+ res = QApplication::sendEvent(&touchWidget, &touchEvent);
+ QVERIFY(res);
+ QVERIFY(touchEvent.isAccepted());
+}
+
+void tst_QTouchEvent::touchBeginPropagatesWhenIgnored()
+{
+ tst_QTouchEventWidget window, child, grandchild;
+ child.setParent(&window);
+ grandchild.setParent(&child);
+
+ // all widgets accept touch events, grandchild ignores, so child sees the event, but not window
+ window.setAttribute(Qt::WA_AcceptTouchEvents);
+ child.setAttribute(Qt::WA_AcceptTouchEvents);
+ grandchild.setAttribute(Qt::WA_AcceptTouchEvents);
+ grandchild.acceptTouchBegin = false;
+
+ QList<QTouchEvent::TouchPoint> touchPoints;
+ touchPoints.append(QTouchEvent::TouchPoint(0));
+ QTouchEvent touchEvent(QEvent::TouchBegin,
+ QTouchEvent::TouchScreen,
+ Qt::NoModifier,
+ Qt::TouchPointPressed,
+ touchPoints);
+ bool res = QApplication::sendEvent(&grandchild, &touchEvent);
+ QVERIFY(res);
+ QVERIFY(touchEvent.isAccepted());
+ QVERIFY(grandchild.seenTouchBegin);
+ QVERIFY(child.seenTouchBegin);
+ QVERIFY(!window.seenTouchBegin);
+
+ // disable touch on grandchild. even though it doesn't accept it, child should still get the
+ // TouchBegin
+ grandchild.reset();
+ child.reset();
+ window.reset();
+ grandchild.setAttribute(Qt::WA_AcceptTouchEvents, false);
+
+ touchEvent.ignore();
+ res = QApplication::sendEvent(&grandchild, &touchEvent);
+ QVERIFY(res);
+ QVERIFY(touchEvent.isAccepted());
+ QVERIFY(!grandchild.seenTouchBegin);
+ QVERIFY(child.seenTouchBegin);
+ QVERIFY(!window.seenTouchBegin);
+}
+
+void tst_QTouchEvent::touchUpdateAndEndNeverPropagate()
+{
+ tst_QTouchEventWidget window, child;
+ child.setParent(&window);
+
+ window.setAttribute(Qt::WA_AcceptTouchEvents);
+ child.setAttribute(Qt::WA_AcceptTouchEvents);
+ child.acceptTouchUpdate = false;
+ child.acceptTouchEnd = false;
+
+ QList<QTouchEvent::TouchPoint> touchPoints;
+ touchPoints.append(QTouchEvent::TouchPoint(0));
+ QTouchEvent touchBeginEvent(QEvent::TouchBegin,
+ QTouchEvent::TouchScreen,
+ Qt::NoModifier,
+ Qt::TouchPointPressed,
+ touchPoints);
+ bool res = QApplication::sendEvent(&child, &touchBeginEvent);
+ QVERIFY(res);
+ QVERIFY(touchBeginEvent.isAccepted());
+ QVERIFY(child.seenTouchBegin);
+ QVERIFY(!window.seenTouchBegin);
+
+ // send the touch update to the child, but ignore it, it doesn't propagate
+ QTouchEvent touchUpdateEvent(QEvent::TouchUpdate,
+ QTouchEvent::TouchScreen,
+ Qt::NoModifier,
+ Qt::TouchPointMoved,
+ touchPoints);
+ res = QApplication::sendEvent(&child, &touchUpdateEvent);
+ QVERIFY(res);
+ QVERIFY(!touchUpdateEvent.isAccepted());
+ QVERIFY(child.seenTouchUpdate);
+ QVERIFY(!window.seenTouchUpdate);
+
+ // send the touch end, same thing should happen as with touch update
+ QTouchEvent touchEndEvent(QEvent::TouchEnd,
+ QTouchEvent::TouchScreen,
+ Qt::NoModifier,
+ Qt::TouchPointReleased,
+ touchPoints);
+ res = QApplication::sendEvent(&child, &touchEndEvent);
+ QVERIFY(res);
+ QVERIFY(!touchEndEvent.isAccepted());
+ QVERIFY(child.seenTouchEnd);
+ QVERIFY(!window.seenTouchEnd);
+}
+
+QPointF normalized(const QPointF &pos, const QRectF &rect)
+{
+ return QPointF(pos.x() / rect.width(), pos.y() / rect.height());
+}
+
+void tst_QTouchEvent::basicRawEventTranslation()
+{
+ tst_QTouchEventWidget touchWidget;
+ touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ touchWidget.setGeometry(100, 100, 400, 300);
+
+ QPointF pos = touchWidget.rect().center();
+ QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint());
+ QPointF delta(10, 10);
+ QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget);
+
+ QTouchEvent::TouchPoint rawTouchPoint;
+ rawTouchPoint.setId(0);
+
+ // this should be translated to a TouchBegin
+ rawTouchPoint.setState(Qt::TouchPointPressed);
+ rawTouchPoint.setScreenPos(screenPos);
+ rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
+ qt_translateRawTouchEvent(&touchWidget,
+ QTouchEvent::TouchScreen,
+ QList<QTouchEvent::TouchPoint>() << rawTouchPoint);
+ QVERIFY(touchWidget.seenTouchBegin);
+ QVERIFY(!touchWidget.seenTouchUpdate);
+ QVERIFY(!touchWidget.seenTouchEnd);
+ QCOMPARE(touchWidget.touchBeginPoints.count(), 1);
+ QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first();
+ QCOMPARE(touchBeginPoint.id(), rawTouchPoint.id());
+ QCOMPARE(touchBeginPoint.state(), rawTouchPoint.state());
+ QCOMPARE(touchBeginPoint.pos(), pos);
+ QCOMPARE(touchBeginPoint.startPos(), pos);
+ QCOMPARE(touchBeginPoint.lastPos(), pos);
+ QCOMPARE(touchBeginPoint.scenePos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchBeginPoint.startScenePos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchBeginPoint.lastScenePos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchBeginPoint.screenPos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchBeginPoint.startScreenPos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchBeginPoint.lastScreenPos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchBeginPoint.normalizedPos(), rawTouchPoint.normalizedPos());
+ QCOMPARE(touchBeginPoint.startNormalizedPos(), touchBeginPoint.normalizedPos());
+ QCOMPARE(touchBeginPoint.lastNormalizedPos(), touchBeginPoint.normalizedPos());
+ QCOMPARE(touchBeginPoint.rect(), QRectF(pos, QSizeF(0, 0)));
+ QCOMPARE(touchBeginPoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0)));
+ QCOMPARE(touchBeginPoint.sceneRect(), touchBeginPoint.screenRect());
+ QCOMPARE(touchBeginPoint.pressure(), qreal(1.));
+
+ // moving the point should translate to TouchUpdate
+ rawTouchPoint.setState(Qt::TouchPointMoved);
+ rawTouchPoint.setScreenPos(screenPos + delta);
+ rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
+ qt_translateRawTouchEvent(&touchWidget,
+ QTouchEvent::TouchScreen,
+ QList<QTouchEvent::TouchPoint>() << rawTouchPoint);
+ QVERIFY(touchWidget.seenTouchBegin);
+ QVERIFY(touchWidget.seenTouchUpdate);
+ QVERIFY(!touchWidget.seenTouchEnd);
+ QCOMPARE(touchWidget.touchUpdatePoints.count(), 1);
+ QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first();
+ QCOMPARE(touchUpdatePoint.id(), rawTouchPoint.id());
+ QCOMPARE(touchUpdatePoint.state(), rawTouchPoint.state());
+ QCOMPARE(touchUpdatePoint.pos(), pos + delta);
+ QCOMPARE(touchUpdatePoint.startPos(), pos);
+ QCOMPARE(touchUpdatePoint.lastPos(), pos);
+ QCOMPARE(touchUpdatePoint.scenePos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchUpdatePoint.startScenePos(), screenPos);
+ QCOMPARE(touchUpdatePoint.lastScenePos(), screenPos);
+ QCOMPARE(touchUpdatePoint.screenPos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchUpdatePoint.startScreenPos(), screenPos);
+ QCOMPARE(touchUpdatePoint.lastScreenPos(), screenPos);
+ QCOMPARE(touchUpdatePoint.normalizedPos(), rawTouchPoint.normalizedPos());
+ QCOMPARE(touchUpdatePoint.startNormalizedPos(), touchBeginPoint.normalizedPos());
+ QCOMPARE(touchUpdatePoint.lastNormalizedPos(), touchBeginPoint.normalizedPos());
+ QCOMPARE(touchUpdatePoint.rect(), QRectF(pos + delta, QSizeF(0, 0)));
+ QCOMPARE(touchUpdatePoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0)));
+ QCOMPARE(touchUpdatePoint.sceneRect(), touchUpdatePoint.screenRect());
+ QCOMPARE(touchUpdatePoint.pressure(), qreal(1.));
+
+ // releasing the point translates to TouchEnd
+ rawTouchPoint.setState(Qt::TouchPointReleased);
+ rawTouchPoint.setScreenPos(screenPos + delta + delta);
+ rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry));
+ qt_translateRawTouchEvent(&touchWidget,
+ QTouchEvent::TouchScreen,
+ QList<QTouchEvent::TouchPoint>() << rawTouchPoint);
+ QVERIFY(touchWidget.seenTouchBegin);
+ QVERIFY(touchWidget.seenTouchUpdate);
+ QVERIFY(touchWidget.seenTouchEnd);
+ QCOMPARE(touchWidget.touchEndPoints.count(), 1);
+ QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first();
+ QCOMPARE(touchEndPoint.id(), rawTouchPoint.id());
+ QCOMPARE(touchEndPoint.state(), rawTouchPoint.state());
+ QCOMPARE(touchEndPoint.pos(), pos + delta + delta);
+ QCOMPARE(touchEndPoint.startPos(), pos);
+ QCOMPARE(touchEndPoint.lastPos(), pos + delta);
+ QCOMPARE(touchEndPoint.scenePos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchEndPoint.startScenePos(), screenPos);
+ QCOMPARE(touchEndPoint.lastScenePos(), screenPos + delta);
+ QCOMPARE(touchEndPoint.screenPos(), rawTouchPoint.screenPos());
+ QCOMPARE(touchEndPoint.startScreenPos(), screenPos);
+ QCOMPARE(touchEndPoint.lastScreenPos(), screenPos + delta);
+ QCOMPARE(touchEndPoint.normalizedPos(), rawTouchPoint.normalizedPos());
+ QCOMPARE(touchEndPoint.startNormalizedPos(), touchBeginPoint.normalizedPos());
+ QCOMPARE(touchEndPoint.lastNormalizedPos(), touchUpdatePoint.normalizedPos());
+ QCOMPARE(touchEndPoint.rect(), QRectF(pos + delta + delta, QSizeF(0, 0)));
+ QCOMPARE(touchEndPoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0)));
+ QCOMPARE(touchEndPoint.sceneRect(), touchEndPoint.screenRect());
+ QCOMPARE(touchEndPoint.pressure(), qreal(0.));
+}
+
+void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen()
+{
+ tst_QTouchEventWidget touchWidget;
+ touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ touchWidget.setGeometry(100, 100, 400, 300);
+
+ tst_QTouchEventWidget leftWidget;
+ leftWidget.setParent(&touchWidget);
+ leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ leftWidget.setGeometry(0, 100, 100, 100);
+ leftWidget.show();
+
+ tst_QTouchEventWidget rightWidget;
+ rightWidget.setParent(&touchWidget);
+ rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ rightWidget.setGeometry(300, 100, 100, 100);
+ rightWidget.show();
+
+ QPointF leftPos = leftWidget.rect().center();
+ QPointF rightPos = rightWidget.rect().center();
+ QPointF centerPos = touchWidget.rect().center();
+ QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint());
+ QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint());
+ QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint());
+ QPointF delta(10, 10);
+ QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget);
+
+ QList<QTouchEvent::TouchPoint> rawTouchPoints;
+ rawTouchPoints.append(QTouchEvent::TouchPoint(0));
+ rawTouchPoints.append(QTouchEvent::TouchPoint(1));
+
+ // generate TouchBegins on both leftWidget and rightWidget
+ rawTouchPoints[0].setState(Qt::TouchPointPressed);
+ rawTouchPoints[0].setScreenPos(leftScreenPos);
+ rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
+ rawTouchPoints[1].setState(Qt::TouchPointPressed);
+ rawTouchPoints[1].setScreenPos(rightScreenPos);
+ rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
+ qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints);
+ QVERIFY(!touchWidget.seenTouchBegin);
+ QVERIFY(!touchWidget.seenTouchUpdate);
+ QVERIFY(!touchWidget.seenTouchEnd);
+ QVERIFY(leftWidget.seenTouchBegin);
+ QVERIFY(!leftWidget.seenTouchUpdate);
+ QVERIFY(!leftWidget.seenTouchEnd);
+ QVERIFY(rightWidget.seenTouchBegin);
+ QVERIFY(!rightWidget.seenTouchUpdate);
+ QVERIFY(!rightWidget.seenTouchEnd);
+ QCOMPARE(leftWidget.touchBeginPoints.count(), 1);
+ QCOMPARE(rightWidget.touchBeginPoints.count(), 1);
+ {
+ QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchBeginPoints.first();
+ QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
+ QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
+ QCOMPARE(leftTouchPoint.pos(), leftPos);
+ QCOMPARE(leftTouchPoint.startPos(), leftPos);
+ QCOMPARE(leftTouchPoint.lastPos(), leftPos);
+ QCOMPARE(leftTouchPoint.scenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.screenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.rect(), QRectF(leftPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.sceneRect(), QRectF(leftScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.screenRect(), QRectF(leftScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.pressure(), qreal(1.));
+
+ QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchBeginPoints.first();
+ QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
+ QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
+ QCOMPARE(rightTouchPoint.pos(), rightPos);
+ QCOMPARE(rightTouchPoint.startPos(), rightPos);
+ QCOMPARE(rightTouchPoint.lastPos(), rightPos);
+ QCOMPARE(rightTouchPoint.scenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.screenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.rect(), QRectF(rightPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.sceneRect(), QRectF(rightScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.screenRect(), QRectF(rightScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
+ }
+
+ // generate TouchUpdates on both leftWidget and rightWidget
+ rawTouchPoints[0].setState(Qt::TouchPointMoved);
+ rawTouchPoints[0].setScreenPos(centerScreenPos);
+ rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
+ rawTouchPoints[1].setState(Qt::TouchPointMoved);
+ rawTouchPoints[1].setScreenPos(centerScreenPos);
+ rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
+ qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints);
+ QVERIFY(!touchWidget.seenTouchBegin);
+ QVERIFY(!touchWidget.seenTouchUpdate);
+ QVERIFY(!touchWidget.seenTouchEnd);
+ QVERIFY(leftWidget.seenTouchBegin);
+ QVERIFY(leftWidget.seenTouchUpdate);
+ QVERIFY(!leftWidget.seenTouchEnd);
+ QVERIFY(rightWidget.seenTouchBegin);
+ QVERIFY(rightWidget.seenTouchUpdate);
+ QVERIFY(!rightWidget.seenTouchEnd);
+ QCOMPARE(leftWidget.touchUpdatePoints.count(), 1);
+ QCOMPARE(rightWidget.touchUpdatePoints.count(), 1);
+ {
+ QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchUpdatePoints.first();
+ QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
+ QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
+ QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
+ QCOMPARE(leftTouchPoint.startPos(), leftPos);
+ QCOMPARE(leftTouchPoint.lastPos(), leftPos);
+ QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
+ QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
+ QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.pressure(), qreal(1.));
+
+ QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchUpdatePoints.first();
+ QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
+ QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
+ QCOMPARE(rightTouchPoint.pos(), QPointF(rightWidget.mapFromParent(centerPos.toPoint())));
+ QCOMPARE(rightTouchPoint.startPos(), rightPos);
+ QCOMPARE(rightTouchPoint.lastPos(), rightPos);
+ QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
+ QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
+ QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.rect(), QRectF(rightWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
+ }
+
+ // generate TouchEnds on both leftWidget and rightWidget
+ rawTouchPoints[0].setState(Qt::TouchPointReleased);
+ rawTouchPoints[0].setScreenPos(centerScreenPos);
+ rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
+ rawTouchPoints[1].setState(Qt::TouchPointReleased);
+ rawTouchPoints[1].setScreenPos(centerScreenPos);
+ rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
+ qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints);
+ QVERIFY(!touchWidget.seenTouchBegin);
+ QVERIFY(!touchWidget.seenTouchUpdate);
+ QVERIFY(!touchWidget.seenTouchEnd);
+ QVERIFY(leftWidget.seenTouchBegin);
+ QVERIFY(leftWidget.seenTouchUpdate);
+ QVERIFY(leftWidget.seenTouchEnd);
+ QVERIFY(rightWidget.seenTouchBegin);
+ QVERIFY(rightWidget.seenTouchUpdate);
+ QVERIFY(rightWidget.seenTouchEnd);
+ QCOMPARE(leftWidget.touchEndPoints.count(), 1);
+ QCOMPARE(rightWidget.touchEndPoints.count(), 1);
+ {
+ QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchEndPoints.first();
+ QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
+ QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
+ QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
+ QCOMPARE(leftTouchPoint.startPos(), leftPos);
+ QCOMPARE(leftTouchPoint.lastPos(), leftTouchPoint.pos());
+ QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
+ QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScenePos(), leftTouchPoint.scenePos());
+ QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
+ QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScreenPos(), leftTouchPoint.screenPos());
+ QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.pressure(), qreal(0.));
+
+ QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchEndPoints.first();
+ QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
+ QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
+ QCOMPARE(rightTouchPoint.pos(), QPointF(rightWidget.mapFromParent(centerPos.toPoint())));
+ QCOMPARE(rightTouchPoint.startPos(), rightPos);
+ QCOMPARE(rightTouchPoint.lastPos(), rightTouchPoint.pos());
+ QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
+ QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScenePos(), rightTouchPoint.scenePos());
+ QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
+ QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScreenPos(), rightTouchPoint.screenPos());
+ QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.rect(), QRectF(rightWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.pressure(), qreal(0.));
+ }
+}
+
+void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad()
+{
+ tst_QTouchEventWidget touchWidget;
+ touchWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ touchWidget.setGeometry(100, 100, 400, 300);
+
+ tst_QTouchEventWidget leftWidget;
+ leftWidget.setParent(&touchWidget);
+ leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ leftWidget.setGeometry(0, 100, 100, 100);
+ leftWidget.show();
+
+ tst_QTouchEventWidget rightWidget;
+ rightWidget.setParent(&touchWidget);
+ rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ rightWidget.setGeometry(300, 100, 100, 100);
+ rightWidget.show();
+
+ QPointF leftPos = leftWidget.rect().center();
+ QPointF rightPos = rightWidget.rect().center();
+ QPointF centerPos = touchWidget.rect().center();
+ QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint());
+ QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint());
+ QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint());
+ QPointF delta(10, 10);
+ QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget);
+
+ QList<QTouchEvent::TouchPoint> rawTouchPoints;
+ rawTouchPoints.append(QTouchEvent::TouchPoint(0));
+ rawTouchPoints.append(QTouchEvent::TouchPoint(1));
+
+ // generate TouchBegin on leftWidget only
+ rawTouchPoints[0].setState(Qt::TouchPointPressed);
+ rawTouchPoints[0].setScreenPos(leftScreenPos);
+ rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
+ rawTouchPoints[1].setState(Qt::TouchPointPressed);
+ rawTouchPoints[1].setScreenPos(rightScreenPos);
+ rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
+ qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchPad, rawTouchPoints);
+ QVERIFY(!touchWidget.seenTouchBegin);
+ QVERIFY(!touchWidget.seenTouchUpdate);
+ QVERIFY(!touchWidget.seenTouchEnd);
+ QVERIFY(leftWidget.seenTouchBegin);
+ QVERIFY(!leftWidget.seenTouchUpdate);
+ QVERIFY(!leftWidget.seenTouchEnd);
+ QVERIFY(!rightWidget.seenTouchBegin);
+ QVERIFY(!rightWidget.seenTouchUpdate);
+ QVERIFY(!rightWidget.seenTouchEnd);
+ QCOMPARE(leftWidget.touchBeginPoints.count(), 2);
+ QCOMPARE(rightWidget.touchBeginPoints.count(), 0);
+ {
+ QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchBeginPoints.at(0);
+ QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
+ QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
+ QCOMPARE(leftTouchPoint.pos(), leftPos);
+ QCOMPARE(leftTouchPoint.startPos(), leftPos);
+ QCOMPARE(leftTouchPoint.lastPos(), leftPos);
+ QCOMPARE(leftTouchPoint.scenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.screenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.rect(), QRectF(leftPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.sceneRect(), QRectF(leftScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.screenRect(), QRectF(leftScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.pressure(), qreal(1.));
+
+ QTouchEvent::TouchPoint rightTouchPoint = leftWidget.touchBeginPoints.at(1);
+ QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
+ QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
+ QCOMPARE(rightTouchPoint.pos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
+ QCOMPARE(rightTouchPoint.startPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
+ QCOMPARE(rightTouchPoint.lastPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
+ QCOMPARE(rightTouchPoint.scenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.screenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.rect(), QRectF(leftWidget.mapFromGlobal(rightScreenPos.toPoint()), QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.sceneRect(), QRectF(rightScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.screenRect(), QRectF(rightScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
+ }
+
+ // generate TouchUpdate on leftWidget
+ rawTouchPoints[0].setState(Qt::TouchPointMoved);
+ rawTouchPoints[0].setScreenPos(centerScreenPos);
+ rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
+ rawTouchPoints[1].setState(Qt::TouchPointMoved);
+ rawTouchPoints[1].setScreenPos(centerScreenPos);
+ rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
+ qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchPad, rawTouchPoints);
+ QVERIFY(!touchWidget.seenTouchBegin);
+ QVERIFY(!touchWidget.seenTouchUpdate);
+ QVERIFY(!touchWidget.seenTouchEnd);
+ QVERIFY(leftWidget.seenTouchBegin);
+ QVERIFY(leftWidget.seenTouchUpdate);
+ QVERIFY(!leftWidget.seenTouchEnd);
+ QVERIFY(!rightWidget.seenTouchBegin);
+ QVERIFY(!rightWidget.seenTouchUpdate);
+ QVERIFY(!rightWidget.seenTouchEnd);
+ QCOMPARE(leftWidget.touchUpdatePoints.count(), 2);
+ QCOMPARE(rightWidget.touchUpdatePoints.count(), 0);
+ {
+ QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchUpdatePoints.at(0);
+ QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
+ QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
+ QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
+ QCOMPARE(leftTouchPoint.startPos(), leftPos);
+ QCOMPARE(leftTouchPoint.lastPos(), leftPos);
+ QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
+ QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
+ QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.pressure(), qreal(1.));
+
+ QTouchEvent::TouchPoint rightTouchPoint = leftWidget.touchUpdatePoints.at(1);
+ QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
+ QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
+ QCOMPARE(rightTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
+ QCOMPARE(rightTouchPoint.startPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
+ QCOMPARE(rightTouchPoint.lastPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
+ QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
+ QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
+ QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.pressure(), qreal(1.));
+ }
+
+ // generate TouchEnd on leftWidget
+ rawTouchPoints[0].setState(Qt::TouchPointReleased);
+ rawTouchPoints[0].setScreenPos(centerScreenPos);
+ rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry));
+ rawTouchPoints[1].setState(Qt::TouchPointReleased);
+ rawTouchPoints[1].setScreenPos(centerScreenPos);
+ rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry));
+ qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchPad, rawTouchPoints);
+ QVERIFY(!touchWidget.seenTouchBegin);
+ QVERIFY(!touchWidget.seenTouchUpdate);
+ QVERIFY(!touchWidget.seenTouchEnd);
+ QVERIFY(leftWidget.seenTouchBegin);
+ QVERIFY(leftWidget.seenTouchUpdate);
+ QVERIFY(leftWidget.seenTouchEnd);
+ QVERIFY(!rightWidget.seenTouchBegin);
+ QVERIFY(!rightWidget.seenTouchUpdate);
+ QVERIFY(!rightWidget.seenTouchEnd);
+ QCOMPARE(leftWidget.touchEndPoints.count(), 2);
+ QCOMPARE(rightWidget.touchEndPoints.count(), 0);
+ {
+ QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchEndPoints.at(0);
+ QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id());
+ QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state());
+ QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
+ QCOMPARE(leftTouchPoint.startPos(), leftPos);
+ QCOMPARE(leftTouchPoint.lastPos(), leftTouchPoint.pos());
+ QCOMPARE(leftTouchPoint.scenePos(), centerScreenPos);
+ QCOMPARE(leftTouchPoint.startScenePos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScenePos(), leftTouchPoint.scenePos());
+ QCOMPARE(leftTouchPoint.screenPos(), centerScreenPos);
+ QCOMPARE(leftTouchPoint.startScreenPos(), leftScreenPos);
+ QCOMPARE(leftTouchPoint.lastScreenPos(), leftTouchPoint.screenPos());
+ QCOMPARE(leftTouchPoint.normalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.startNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.lastNormalizedPos(), rawTouchPoints[0].normalizedPos());
+ QCOMPARE(leftTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(leftTouchPoint.pressure(), qreal(0.));
+
+ QTouchEvent::TouchPoint rightTouchPoint = leftWidget.touchEndPoints.at(1);
+ QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id());
+ QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state());
+ QCOMPARE(rightTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint())));
+ QCOMPARE(rightTouchPoint.startPos(), QPointF(leftWidget.mapFromGlobal(rightScreenPos.toPoint())));
+ QCOMPARE(rightTouchPoint.lastPos(), rightTouchPoint.pos());
+ QCOMPARE(rightTouchPoint.scenePos(), centerScreenPos);
+ QCOMPARE(rightTouchPoint.startScenePos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScenePos(), rightTouchPoint.scenePos());
+ QCOMPARE(rightTouchPoint.screenPos(), centerScreenPos);
+ QCOMPARE(rightTouchPoint.startScreenPos(), rightScreenPos);
+ QCOMPARE(rightTouchPoint.lastScreenPos(), rightTouchPoint.screenPos());
+ QCOMPARE(rightTouchPoint.normalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.startNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.lastNormalizedPos(), rawTouchPoints[1].normalizedPos());
+ QCOMPARE(rightTouchPoint.rect(), QRectF(leftWidget.mapFromParent(centerPos.toPoint()), QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.sceneRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.screenRect(), QRectF(centerScreenPos, QSizeF(0, 0)));
+ QCOMPARE(rightTouchPoint.pressure(), qreal(0.));
+ }
+}
+
+QTEST_MAIN(tst_QTouchEvent)
+
+#include "tst_qtouchevent.moc"
diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp
index 60d7391..ea551da 100644
--- a/tests/auto/qurl/tst_qurl.cpp
+++ b/tests/auto/qurl/tst_qurl.cpp
@@ -608,18 +608,6 @@ void tst_QUrl::setUrl()
}
{
- QString bigStr(QLatin1String("abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ"));
- QUrl url;
- url.setHost(bigStr);
- QVERIFY(url.isValid());
- QCOMPARE(url.host().toLower(), bigStr.toLower());
- }
-
- {
QUrl url;
url.setUrl("hello.com#?");
QVERIFY(url.isValid());
@@ -1398,8 +1386,6 @@ void tst_QUrl::i18n_data()
QTest::newRow("øl") << QString::fromLatin1("http://ole:passord@www.øl.no/index.html?ole=æsemann&ilder gud=hei#top")
<< QByteArray("http://ole:passord@www.xn--l-4ga.no/index.html?ole=%C3%A6semann&ilder%20gud=hei#top");
- QTest::newRow("øl") << QString::fromLatin1("http://ole:passord@www.øl.no/index.html?ole=æsemann&ilder gud=hei#top")
- << QByteArray("http://ole:passord@www.xn--l-4ga.no/index.html?ole=%C3%A6semann&ilder%20gud=hei#top");
QTest::newRow("räksmörgås") << QString::fromLatin1("http://www.räksmörgås.no/")
<< QByteArray("http://www.xn--rksmrgs-5wao1o.no/");
QTest::newRow("bühler") << QString::fromLatin1("http://www.bühler.no/")
@@ -2412,9 +2398,7 @@ void tst_QUrl::hasQueryItem()
void tst_QUrl::nameprep()
{
QUrl url(QString::fromUtf8("http://www.fu""\xc3""\x9f""ball.de/"));
- QUrl url2 = QUrl::fromEncoded("http://www.xn--fuball-cta.de/");
- QCOMPARE(url2.toString(), QString::fromLatin1("http://www.fussball.de/"));
- QCOMPARE(url.toString(), url2.toString()); // should be identical
+ QCOMPARE(url.toString(), QString::fromLatin1("http://www.fussball.de/"));
}
void tst_QUrl::isValid()
@@ -2425,19 +2409,18 @@ void tst_QUrl::isValid()
QCOMPARE(url.path(), QString("A=B"));
}
{
- QUrl url = QUrl::fromEncoded("http://strange<username>@ok_hostname/", QUrl::StrictMode);
+ QUrl url = QUrl::fromEncoded("http://strange<username>@ok-hostname/", QUrl::StrictMode);
QVERIFY(!url.isValid());
// < and > are not allowed in userinfo in strict mode
}
{
- QUrl url = QUrl::fromEncoded("http://strange<username>@ok_hostname/");
+ QUrl url = QUrl::fromEncoded("http://strange<username>@ok-hostname/");
QVERIFY(url.isValid());
// < and > are allowed in tolerant mode
}
{
QUrl url = QUrl::fromEncoded("http://strange;hostname/here");
- QVERIFY(url.isValid());
- QCOMPARE(url.host(), QString("strange;hostname"));
+ QVERIFY(!url.isValid());
QCOMPARE(url.path(), QString("/here"));
}
}
@@ -3488,7 +3471,6 @@ void tst_QUrl::setAuthority_data()
QTest::addColumn<QString>("authority");
QTest::addColumn<QString>("url");
QTest::newRow("Plain auth") << QString("62.70.27.22:21") << QString("//62.70.27.22:21");
- QTest::newRow("Auth with empty port") << QString("62.70.27.22:") << QString("//62.70.27.22:");
QTest::newRow("Yet another plain auth") << QString("192.168.1.1:21") << QString("//192.168.1.1:21");
QTest::newRow("Auth without port") << QString("192.168.1.1") << QString("//192.168.1.1");
QTest::newRow("Auth w/full hostname without port") << QString("shusaku.troll.no") << QString("//shusaku.troll.no");
@@ -3496,7 +3478,6 @@ void tst_QUrl::setAuthority_data()
QTest::newRow("Auth w/full hostname that ends with number, without port") << QString("shusaku.troll.no.2") << QString("//shusaku.troll.no.2");
QTest::newRow("Auth w/hostname that ends with number, without port") << QString("shusaku2") << QString("//shusaku2");
QTest::newRow("Empty auth") << QString() << QString();
- QTest::newRow("Single") << QString(":") << QString("//:");
}
void tst_QUrl::setAuthority()
diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp
index 0310276..63e47ab 100644
--- a/tests/auto/qvariant/tst_qvariant.cpp
+++ b/tests/auto/qvariant/tst_qvariant.cpp
@@ -255,6 +255,7 @@ private slots:
void convertByteArrayToBool() const;
void convertByteArrayToBool_data() const;
void toIntFromQString() const;
+ void task256984_setValue();
};
Q_DECLARE_METATYPE(QDate)
@@ -2967,5 +2968,21 @@ void tst_QVariant::toIntFromQString() const
QVERIFY(ok);
}
+void tst_QVariant::task256984_setValue()
+{
+ QTransform t; //we just take a value so that we're sure that it will be shared
+ QVariant v1 = t;
+ QVERIFY( v1.isDetached() );
+ QVariant v2 = v1;
+ QVERIFY( !v1.isDetached() );
+ QVERIFY( !v2.isDetached() );
+
+ qVariantSetValue(v2, 3); //set an integer value
+
+ QVERIFY( v1.isDetached() );
+ QVERIFY( v2.isDetached() );
+}
+
+
QTEST_MAIN(tst_QVariant)
#include "tst_qvariant.moc"
diff --git a/tests/auto/qwebhistory/.gitignore b/tests/auto/qwebhistory/.gitignore
new file mode 100644
index 0000000..2bdefcd
--- /dev/null
+++ b/tests/auto/qwebhistory/.gitignore
@@ -0,0 +1 @@
+tst_qwebhistory
diff --git a/tests/auto/qwebhistory/dummy.cpp b/tests/auto/qwebhistory/dummy.cpp
new file mode 100644
index 0000000..0c034f3
--- /dev/null
+++ b/tests/auto/qwebhistory/dummy.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+
+QTEST_NOOP_MAIN
+
diff --git a/tests/auto/qwebhistory/qwebhistory.pro b/tests/auto/qwebhistory/qwebhistory.pro
new file mode 100644
index 0000000..232f478
--- /dev/null
+++ b/tests/auto/qwebhistory/qwebhistory.pro
@@ -0,0 +1,14 @@
+load(qttest_p4)
+contains(QT_CONFIG,webkit) {
+ DEFINES += QTEST_WEBKIT
+ QT += webkit network
+ isEmpty(QT_BUILD_TREE):QT_BUILD_TREE=$(QTDIR)
+ isEmpty(QT_SOURCE_TREE):QT_SOURCE_TREE=$$fromfile($$QT_BUILD_TREE/.qmake.cache, QT_SOURCE_TREE)
+
+ TESTDIR = $$QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/tests/qwebhistory
+ VPATH += $$TESTDIR
+ include($$TESTDIR/qwebhistory.pro)
+} else {
+ SOURCES += dummy.cpp
+}
+
diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp
index 6727b05..04ec77d 100644
--- a/tests/auto/qwidget/tst_qwidget.cpp
+++ b/tests/auto/qwidget/tst_qwidget.cpp
@@ -106,7 +106,7 @@
// taken from qguifunctions_wce.cpp
#define SPI_GETPLATFORMTYPE 257
bool qt_wince_is_platform(const QString &platformString) {
- TCHAR tszPlatform[64];
+ wchar_t tszPlatform[64];
if (SystemParametersInfo(SPI_GETPLATFORMTYPE,
sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0))
if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform))
@@ -252,6 +252,7 @@ private slots:
void moveChild_data();
void moveChild();
+ void showAndMoveChild();
void subtractOpaqueSiblings();
@@ -3432,9 +3433,9 @@ static QString visibleWindowTitle(QWidget *window, Qt::WindowState state = Qt::W
#ifdef Q_WS_WIN
Q_UNUSED(state);
const size_t maxTitleLength = 256;
- WCHAR title[maxTitleLength];
- GetWindowTextW(window->winId(), title, maxTitleLength);
- vTitle = QString::fromUtf16((ushort *)title);
+ wchar_t title[maxTitleLength];
+ GetWindowText(window->winId(), title, maxTitleLength);
+ vTitle = QString::fromWCharArray(title);
#elif defined(Q_WS_X11)
/*
We can't check what the window manager displays, but we can
@@ -3978,6 +3979,7 @@ public:
:QWidget(parent)
{
setAttribute(Qt::WA_StaticContents);
+ setAttribute(Qt::WA_OpaquePaintEvent);
setPalette(Qt::red); // Make sure we have an opaque palette.
setAutoFillBackground(true);
gotPaintEvent = false;
@@ -5318,6 +5320,33 @@ void tst_QWidget::moveChild()
parent.color);
}
+void tst_QWidget::showAndMoveChild()
+{
+ QWidget parent(0, Qt::FramelessWindowHint);
+ parent.resize(300, 300);
+ parent.setPalette(Qt::red);
+ parent.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&parent);
+#endif
+ QTest::qWait(200);
+
+ const QPoint tlwOffset = parent.geometry().topLeft();
+ QWidget child(&parent);
+ child.resize(100, 100);
+ child.setPalette(Qt::blue);
+ child.setAutoFillBackground(true);
+
+ // Ensure that the child is repainted correctly when moved right after show.
+ // NB! Do NOT processEvents() (or qWait()) in between show() and move().
+ child.show();
+ child.move(150, 150);
+ qApp->processEvents();
+
+ VERIFY_COLOR(child.geometry().translated(tlwOffset), Qt::blue);
+ VERIFY_COLOR(QRegion(parent.geometry()) - child.geometry().translated(tlwOffset), Qt::red);
+}
+
void tst_QWidget::subtractOpaqueSiblings()
{
#ifdef QT_MAC_USE_COCOA
diff --git a/tests/auto/qwineventnotifier/tst_qwineventnotifier.cpp b/tests/auto/qwineventnotifier/tst_qwineventnotifier.cpp
index 24d28c5..4b00773 100644
--- a/tests/auto/qwineventnotifier/tst_qwineventnotifier.cpp
+++ b/tests/auto/qwineventnotifier/tst_qwineventnotifier.cpp
@@ -110,12 +110,9 @@ void tst_QWinEventNotifier::simple_timerSet()
void tst_QWinEventNotifier::simple()
{
- QT_WA({
- simpleHEvent = CreateEventW(0, TRUE, FALSE, 0);
- }, {
- simpleHEvent = CreateEventA(0, TRUE, FALSE, 0);
- });
+ simpleHEvent = CreateEvent(0, TRUE, FALSE, 0);
QVERIFY(simpleHEvent);
+
QWinEventNotifier n(simpleHEvent);
QObject::connect(&n, SIGNAL(activated(HANDLE)), this, SLOT(simple_activated()));
simpleActivated = false;
diff --git a/tests/auto/qwizard/tst_qwizard.cpp b/tests/auto/qwizard/tst_qwizard.cpp
index 71e1c3e..e5074b3 100644
--- a/tests/auto/qwizard/tst_qwizard.cpp
+++ b/tests/auto/qwizard/tst_qwizard.cpp
@@ -112,6 +112,7 @@ private slots:
void task161658_alignments();
void task177022_setFixedSize();
void task248107_backButton();
+ void task255350_fieldObjectDestroyed();
/*
Things that could be added:
@@ -2517,5 +2518,26 @@ void tst_QWizard::task248107_backButton()
QCOMPARE(wizard.currentPage(), &page1);
}
+class WizardPage_task255350 : public QWizardPage
+{
+public:
+ QLineEdit *lineEdit;
+ WizardPage_task255350()
+ : lineEdit(new QLineEdit)
+ {
+ registerField("dummy*", lineEdit);
+ }
+};
+
+void tst_QWizard::task255350_fieldObjectDestroyed()
+{
+ QWizard wizard;
+ WizardPage_task255350 *page = new WizardPage_task255350;
+ int id = wizard.addPage(page);
+ delete page->lineEdit;
+ wizard.removePage(id); // don't crash!
+ delete page;
+}
+
QTEST_MAIN(tst_QWizard)
#include "tst_qwizard.moc"
diff --git a/tests/auto/qxmlquery/tst_qxmlquery.cpp b/tests/auto/qxmlquery/tst_qxmlquery.cpp
index 28af641..30b3f50 100644
--- a/tests/auto/qxmlquery/tst_qxmlquery.cpp
+++ b/tests/auto/qxmlquery/tst_qxmlquery.cpp
@@ -155,6 +155,9 @@ private Q_SLOTS:
void setFocusQIODeviceAvoidVariableClash() const;
void setFocusQIODeviceFailure() const;
void setFocusQIODeviceTriggerWarnings() const;
+ void setFocusQString() const;
+ void setFocusQStringFailure() const;
+ void setFocusQStringSignature() const;
void recompilationWithEvaluateToResultFailing() const;
void secondEvaluationWithEvaluateToResultFailing() const;
void recompilationWithEvaluateToReceiver() const;
@@ -1894,6 +1897,55 @@ void tst_QXmlQuery::setFocusQIODeviceFailure() const
}
}
+void tst_QXmlQuery::setFocusQString() const
+{
+ QXmlQuery query;
+
+ /* Basic use of focus. */
+ {
+ QVERIFY(query.setFocus(QLatin1String("<e>textNode</e>")));
+ query.setQuery(QLatin1String("string()"));
+ QVERIFY(query.isValid());
+ QString out;
+ query.evaluateTo(&out);
+ QCOMPARE(out, QString::fromLatin1("textNode\n"));
+ }
+
+ /* Set to a new focus, make sure it changes and works. */
+ {
+ QVERIFY(query.setFocus(QLatin1String("<e>newFocus</e>")));
+ QString out;
+ query.evaluateTo(&out);
+ QCOMPARE(out, QString::fromLatin1("newFocus\n"));
+ }
+}
+
+void tst_QXmlQuery::setFocusQStringFailure() const
+{
+ QXmlQuery query;
+ MessageSilencer silencer;
+
+ query.setMessageHandler(&silencer);
+ QVERIFY(!query.setFocus(QLatin1String("<notWellformed")));
+
+ /* Let's try the slight special case of a null string. */
+ QVERIFY(!query.setFocus(QString()));
+}
+
+void tst_QXmlQuery::setFocusQStringSignature() const
+{
+ QXmlQuery query;
+ MessageSilencer silencer;
+ query.setMessageHandler(&silencer);
+
+ const QString argument;
+ /* We should take a const ref. */
+ query.setFocus(argument);
+
+ /* We should return a bool. */
+ static_cast<bool>(query.setFocus(QString()));
+}
+
void tst_QXmlQuery::setFocusQIODeviceTriggerWarnings() const
{
/* A null pointer. */
diff --git a/tests/auto/qxmlstream/tst_qxmlstream.cpp b/tests/auto/qxmlstream/tst_qxmlstream.cpp
index 32fdb91..1533913 100644
--- a/tests/auto/qxmlstream/tst_qxmlstream.cpp
+++ b/tests/auto/qxmlstream/tst_qxmlstream.cpp
@@ -561,6 +561,8 @@ private slots:
void garbageInXMLPrologDefaultCodec() const;
void garbageInXMLPrologUTF8Explicitly() const;
void clear() const;
+ void checkCommentIndentation() const;
+ void checkCommentIndentation_data() const;
private:
static QByteArray readFile(const QString &filename);
@@ -1392,5 +1394,55 @@ void tst_QXmlStream::clear() const // task 228768
QCOMPARE(reader.tokenType(), QXmlStreamReader::EndDocument);
}
+void tst_QXmlStream::checkCommentIndentation_data() const
+{
+
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("expectedOutput");
+
+ QString simpleInput = "<a><!-- bla --></a>";
+ QString simpleOutput = "<?xml version=\"1.0\"?>\n"
+ "<a>\n"
+ " <!-- bla -->\n"
+ "</a>\n";
+ QTest::newRow("simple-comment") << simpleInput << simpleOutput;
+
+ QString advancedInput = "<a><!-- bla --><!-- bla --><b><!-- bla --><c><!-- bla --></c><!-- bla --></b></a>";
+ QString advancedOutput = "<?xml version=\"1.0\"?>\n"
+ "<a>\n"
+ " <!-- bla -->\n"
+ " <!-- bla -->\n"
+ " <b>\n"
+ " <!-- bla -->\n"
+ " <c>\n"
+ " <!-- bla -->\n"
+ " </c>\n"
+ " <!-- bla -->\n"
+ " </b>\n"
+ "</a>\n";
+ QTest::newRow("advanced-comment") << advancedInput << advancedOutput;
+}
+
+void tst_QXmlStream::checkCommentIndentation() const // task 256468
+{
+ QFETCH(QString, input);
+ QFETCH(QString, expectedOutput);
+ QString output;
+ QXmlStreamReader reader(input);
+ QXmlStreamWriter writer(&output);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(3);
+
+ while (!reader.atEnd()) {
+ reader.readNext();
+ if (reader.error()) {
+ QFAIL("error reading XML input");
+ } else {
+ writer.writeCurrentToken(reader);
+ }
+ }
+ QCOMPARE(output, expectedOutput);
+}
+
#include "tst_qxmlstream.moc"
// vim: et:ts=4:sw=4:sts=4
diff --git a/tests/auto/tests.xml b/tests/auto/tests.xml
index d2f378d..a5386b2 100644
--- a/tests/auto/tests.xml
+++ b/tests/auto/tests.xml
@@ -9,6 +9,9 @@
<Test name="exceptionsafety" location="tests/auto/exceptionsafety/tst_exceptionsafety" />
<Test name="headers" location="tests/auto/headers/tst_headers" />
<Test name="languagechange" location="tests/auto/languagechange/tst_languagechange" />
+ <Test name="lrelease" location="tests/auto/linguist/lrelease/tst_lrelease" />
+ <Test name="lconvert" location="tests/auto/linguist/lconvert/tst_convert" />
+ <Test name="lupdate" location="tests/auto/linguist/lupdate/tst_lupdate" />
<Test name="macgui" location="tests/auto/macgui/tst_macgui" platforms="macx-g++" />
<Test name="mediaobject" location="tests/auto/mediaobject/tst_mediaobject" />
<Test name="moc" location="tests/auto/moc/tst_moc" />
@@ -412,6 +415,9 @@
<Test id="exceptionsafety" />
<Test id="headers" />
<Test id="languagechange" />
+ <Test id="lrelease" />
+ <Test id="lconvert" />
+ <Test id="lupdate" />
<Test id="macgui" />
<Test id="mediaobject" />
<Test id="moc" />
diff --git a/tests/auto/windowsmobile/test/tst_windowsmobile.cpp b/tests/auto/windowsmobile/test/tst_windowsmobile.cpp
index 8c7c021..654e19f 100644
--- a/tests/auto/windowsmobile/test/tst_windowsmobile.cpp
+++ b/tests/auto/windowsmobile/test/tst_windowsmobile.cpp
@@ -72,7 +72,7 @@ public:
#ifdef Q_OS_WINCE_WM
bool qt_wince_is_platform(const QString &platformString) {
- TCHAR tszPlatform[64];
+ wchar_t tszPlatform[64];
if (SystemParametersInfo(SPI_GETPLATFORMTYPE,
sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0))
if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform))